Merge branch 'vendor/GCC50'
[dragonfly.git] / sbin / routed / input.c
1 /*
2  * Copyright (c) 1983, 1988, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgment:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * $FreeBSD: src/sbin/routed/input.c,v 1.7.2.1 2001/08/01 09:01:45 obrien Exp $
34  */
35
36 #include "defs.h"
37
38 #if !defined(sgi) && !defined(__NetBSD__)
39 static char sccsid[] __attribute__((unused)) = "@(#)input.c     8.1 (Berkeley) 6/5/93";
40 #elif defined(__NetBSD__)
41 #include <sys/cdefs.h>
42 __RCSID("$NetBSD$");
43 #endif
44
45 static void input(struct sockaddr_in *, struct interface *, struct interface *,
46                   struct rip *, int);
47 static void input_route(naddr, naddr, struct rt_spare *, struct netinfo *);
48 static int ck_passwd(struct interface *, struct rip *, void *,
49                      naddr, struct msg_limit *);
50
51
52 /* process RIP input
53  */
54 void
55 read_rip(int sock,
56          struct interface *sifp)
57 {
58         struct sockaddr_in from;
59         struct interface *aifp;
60         int cc;
61         socklen_t fromlen;
62 #ifdef USE_PASSIFNAME
63         static struct msg_limit  bad_name;
64         struct {
65                 char    ifname[IFNAMSIZ];
66                 union pkt_buf pbuf;
67         } inbuf;
68 #else
69         struct {
70                 union pkt_buf pbuf;
71         } inbuf;
72 #endif
73
74
75         for (;;) {
76                 fromlen = sizeof(from);
77                 cc = recvfrom(sock, &inbuf, sizeof(inbuf), 0,
78                               (struct sockaddr*)&from, &fromlen);
79                 if (cc <= 0) {
80                         if (cc < 0 && errno != EWOULDBLOCK)
81                                 LOGERR("recvfrom(rip)");
82                         break;
83                 }
84                 if (fromlen != sizeof(struct sockaddr_in))
85                         logbad(1,"impossible recvfrom(rip) fromlen=%d",
86                                fromlen);
87
88                 /* aifp is the "authenticated" interface via which the packet
89                  *      arrived.  In fact, it is only the interface on which
90                  *      the packet should have arrived based on is source
91                  *      address.
92                  * sifp is interface associated with the socket through which
93                  *      the packet was received.
94                  */
95 #ifdef USE_PASSIFNAME
96                 if ((cc -= sizeof(inbuf.ifname)) < 0)
97                         logbad(0,"missing USE_PASSIFNAME; only %d bytes",
98                                cc+sizeof(inbuf.ifname));
99
100                 /* check the remote interfaces first */
101                 for (aifp = remote_if; aifp; aifp = aifp->int_rlink) {
102                         if (aifp->int_addr == from.sin_addr.s_addr)
103                                 break;
104                 }
105                 if (aifp == NULL) {
106                         aifp = ifwithname(inbuf.ifname, 0);
107                         if (aifp == NULL) {
108                                 msglim(&bad_name, from.sin_addr.s_addr,
109                                        "impossible interface name %.*s",
110                                        IFNAMSIZ, inbuf.ifname);
111                         } else if (((aifp->int_if_flags & IFF_POINTOPOINT)
112                                     && aifp->int_dstaddr!=from.sin_addr.s_addr)
113                                    || (!(aifp->int_if_flags & IFF_POINTOPOINT)
114                                        && !on_net(from.sin_addr.s_addr,
115                                                   aifp->int_net,
116                                                   aifp->int_mask))) {
117                                 /* If it came via the wrong interface, do not
118                                  * trust it.
119                                  */
120                                 aifp = NULL;
121                         }
122                 }
123 #else
124                 aifp = iflookup(from.sin_addr.s_addr);
125 #endif
126                 if (sifp == NULL)
127                         sifp = aifp;
128
129                 input(&from, sifp, aifp, &inbuf.pbuf.rip, cc);
130         }
131 }
132
133
134 /* Process a RIP packet
135  */
136 static void
137 input(struct sockaddr_in *from,         /* received from this IP address */
138       struct interface *sifp,           /* interface of incoming socket */
139       struct interface *aifp,           /* "authenticated" interface */
140       struct rip *rip,
141       int cc)
142 {
143 #       define FROM_NADDR from->sin_addr.s_addr
144         static struct msg_limit use_auth, bad_len, bad_mask;
145         static struct msg_limit unk_router, bad_router, bad_nhop;
146
147         struct rt_entry *rt;
148         struct rt_spare new;
149         struct netinfo *n, *lim;
150         struct interface *ifp1;
151         naddr gate, mask, v1_mask, dst, ddst_h = 0;
152         struct auth *ap;
153         struct tgate *tg = NULL;
154         struct tgate_net *tn;
155         int i, j;
156
157         /* Notice when we hear from a remote gateway
158          */
159         if (aifp != NULL
160             && (aifp->int_state & IS_REMOTE))
161                 aifp->int_act_time = now.tv_sec;
162
163         trace_rip("Recv", "from", from, sifp, rip, cc);
164
165         if (rip->rip_vers == 0) {
166                 msglim(&bad_router, FROM_NADDR,
167                        "RIP version 0, cmd %d, packet received from %s",
168                        rip->rip_cmd, naddr_ntoa(FROM_NADDR));
169                 return;
170         } else if (rip->rip_vers > RIPv2) {
171                 rip->rip_vers = RIPv2;
172         }
173         if (cc > (int)OVER_MAXPACKETSIZE) {
174                 msglim(&bad_router, FROM_NADDR,
175                        "packet at least %d bytes too long received from %s",
176                        cc-MAXPACKETSIZE, naddr_ntoa(FROM_NADDR));
177                 return;
178         }
179
180         n = rip->rip_nets;
181         lim = (struct netinfo *)((char*)rip + cc);
182
183         /* Notice authentication.
184          * As required by section 4.2 in RFC 1723, discard authenticated
185          * RIPv2 messages, but only if configured for that silliness.
186          *
187          * RIPv2 authentication is lame.  Why authenticate queries?
188          * Why should a RIPv2 implementation with authentication disabled
189          * not be able to listen to RIPv2 packets with authentication, while
190          * RIPv1 systems will listen?  Crazy!
191          */
192         if (!auth_ok
193             && rip->rip_vers == RIPv2
194             && n < lim && n->n_family == RIP_AF_AUTH) {
195                 msglim(&use_auth, FROM_NADDR,
196                        "RIPv2 message with authentication from %s discarded",
197                        naddr_ntoa(FROM_NADDR));
198                 return;
199         }
200
201         switch (rip->rip_cmd) {
202         case RIPCMD_REQUEST:
203                 /* For mere requests, be a little sloppy about the source
204                  */
205                 if (aifp == NULL)
206                         aifp = sifp;
207
208                 /* Are we talking to ourself or a remote gateway?
209                  */
210                 ifp1 = ifwithaddr(FROM_NADDR, 0, 1);
211                 if (ifp1) {
212                         if (ifp1->int_state & IS_REMOTE) {
213                                 /* remote gateway */
214                                 aifp = ifp1;
215                                 if (check_remote(aifp)) {
216                                         aifp->int_act_time = now.tv_sec;
217                                         if_ok(aifp, "remote ");
218                                 }
219                         } else if (from->sin_port == htons(RIP_PORT)) {
220                                 trace_pkt("    discard our own RIP request");
221                                 return;
222                         }
223                 }
224
225                 /* did the request come from a router?
226                  */
227                 if (from->sin_port == htons(RIP_PORT)) {
228                         /* yes, ignore the request if RIP is off so that
229                          * the router does not depend on us.
230                          */
231                         if (rip_sock < 0
232                             || (aifp != NULL
233                                 && IS_RIP_OUT_OFF(aifp->int_state))) {
234                                 trace_pkt("    discard request while RIP off");
235                                 return;
236                         }
237                 }
238
239                 /* According to RFC 1723, we should ignore unauthenticated
240                  * queries.  That is too silly to bother with.  Sheesh!
241                  * Are forwarding tables supposed to be secret, when
242                  * a bad guy can infer them with test traffic?  When RIP
243                  * is still the most common router-discovery protocol
244                  * and so hosts need to send queries that will be answered?
245                  * What about `rtquery`?
246                  * Maybe on firewalls you'd care, but not enough to
247                  * give up the diagnostic facilities of remote probing.
248                  */
249
250                 if (n >= lim) {
251                         msglim(&bad_len, FROM_NADDR, "empty request from %s",
252                                naddr_ntoa(FROM_NADDR));
253                         return;
254                 }
255                 if (cc%sizeof(*n) != sizeof(struct rip)%sizeof(*n)) {
256                         msglim(&bad_len, FROM_NADDR,
257                                "request of bad length (%d) from %s",
258                                cc, naddr_ntoa(FROM_NADDR));
259                 }
260
261                 if (rip->rip_vers == RIPv2
262                     && (aifp == NULL || (aifp->int_state & IS_NO_RIPV1_OUT))) {
263                         v12buf.buf->rip_vers = RIPv2;
264                         /* If we have a secret but it is a cleartext secret,
265                          * do not disclose our secret unless the other guy
266                          * already knows it.
267                          */
268                         ap = find_auth(aifp);
269                         if (ap != NULL && ap->type == RIP_AUTH_PW
270                             && n->n_family == RIP_AF_AUTH
271                             && !ck_passwd(aifp,rip,lim,FROM_NADDR,&use_auth))
272                                 ap = NULL;
273                 } else {
274                         v12buf.buf->rip_vers = RIPv1;
275                         ap = NULL;
276                 }
277                 clr_ws_buf(&v12buf, ap);
278
279                 do {
280                         n->n_metric = ntohl(n->n_metric);
281
282                         /* A single entry with family RIP_AF_UNSPEC and
283                          * metric HOPCNT_INFINITY means "all routes".
284                          * We respond to routers only if we are acting
285                          * as a supplier, or to anyone other than a router
286                          * (i.e. a query).
287                          */
288                         if (n->n_family == RIP_AF_UNSPEC
289                             && n->n_metric == HOPCNT_INFINITY) {
290                                 /* Answer a query from a utility program
291                                  * with all we know.
292                                  */
293                                 if (aifp == NULL) {
294                                         trace_pkt("ignore remote query");
295                                         return;
296                                 }
297                                 if (from->sin_port != htons(RIP_PORT)) {
298                                         supply(from, aifp, OUT_QUERY, 0,
299                                                rip->rip_vers, ap != NULL);
300                                         return;
301                                 }
302
303                                 /* A router trying to prime its tables.
304                                  * Filter the answer in the about same way
305                                  * broadcasts are filtered.
306                                  *
307                                  * Only answer a router if we are a supplier
308                                  * to keep an unwary host that is just starting
309                                  * from picking us as a router.
310                                  */
311                                 if (aifp == NULL) {
312                                         trace_pkt("ignore distant router");
313                                         return;
314                                 }
315                                 if (!supplier
316                                     || IS_RIP_OFF(aifp->int_state)) {
317                                         trace_pkt("ignore; not supplying");
318                                         return;
319                                 }
320
321                                 /* Do not answer a RIPv1 router if
322                                  * we are sending RIPv2.  But do offer
323                                  * poor man's router discovery.
324                                  */
325                                 if ((aifp->int_state & IS_NO_RIPV1_OUT)
326                                     && rip->rip_vers == RIPv1) {
327                                         if (!(aifp->int_state & IS_PM_RDISC)) {
328                                             trace_pkt("ignore; sending RIPv2");
329                                             return;
330                                         }
331
332                                         v12buf.n->n_family = RIP_AF_INET;
333                                         v12buf.n->n_dst = RIP_DEFAULT;
334                                         i = aifp->int_d_metric;
335                                         if (NULL != (rt = rtget(RIP_DEFAULT, 0)))
336                                             i = MIN(i, (rt->rt_metric
337                                                         +aifp->int_metric+1));
338                                         v12buf.n->n_metric = htonl(i);
339                                         v12buf.n++;
340                                         break;
341                                 }
342
343                                 /* Respond with RIPv1 instead of RIPv2 if
344                                  * that is what we are broadcasting on the
345                                  * interface to keep the remote router from
346                                  * getting the wrong initial idea of the
347                                  * routes we send.
348                                  */
349                                 supply(from, aifp, OUT_UNICAST, 0,
350                                        (aifp->int_state & IS_NO_RIPV1_OUT)
351                                        ? RIPv2 : RIPv1,
352                                        ap != NULL);
353                                 return;
354                         }
355
356                         /* Ignore authentication */
357                         if (n->n_family == RIP_AF_AUTH)
358                                 continue;
359
360                         if (n->n_family != RIP_AF_INET) {
361                                 msglim(&bad_router, FROM_NADDR,
362                                        "request from %s for unsupported"
363                                        " (af %d) %s",
364                                        naddr_ntoa(FROM_NADDR),
365                                        ntohs(n->n_family),
366                                        naddr_ntoa(n->n_dst));
367                                 return;
368                         }
369
370                         /* We are being asked about a specific destination.
371                          */
372                         dst = n->n_dst;
373                         if (!check_dst(dst)) {
374                                 msglim(&bad_router, FROM_NADDR,
375                                        "bad queried destination %s from %s",
376                                        naddr_ntoa(dst),
377                                        naddr_ntoa(FROM_NADDR));
378                                 return;
379                         }
380
381                         /* decide what mask was intended */
382                         if (rip->rip_vers == RIPv1
383                             || 0 == (mask = ntohl(n->n_mask))
384                             || 0 != (ntohl(dst) & ~mask))
385                                 mask = ripv1_mask_host(dst, aifp);
386
387                         /* try to find the answer */
388                         rt = rtget(dst, mask);
389                         if (!rt && dst != RIP_DEFAULT)
390                                 rt = rtfind(n->n_dst);
391
392                         if (v12buf.buf->rip_vers != RIPv1)
393                                 v12buf.n->n_mask = mask;
394                         if (rt == NULL) {
395                                 /* we do not have the answer */
396                                 v12buf.n->n_metric = HOPCNT_INFINITY;
397                         } else {
398                                 /* we have the answer, so compute the
399                                  * right metric and next hop.
400                                  */
401                                 v12buf.n->n_family = RIP_AF_INET;
402                                 v12buf.n->n_dst = dst;
403                                 v12buf.n->n_metric = (rt->rt_metric+1
404                                                       + ((aifp!=NULL)
405                                                           ? aifp->int_metric
406                                                           : 1));
407                                 if (v12buf.n->n_metric > HOPCNT_INFINITY)
408                                         v12buf.n->n_metric = HOPCNT_INFINITY;
409                                 if (v12buf.buf->rip_vers != RIPv1) {
410                                         v12buf.n->n_tag = rt->rt_tag;
411                                         v12buf.n->n_mask = mask;
412                                         if (aifp != NULL
413                                             && on_net(rt->rt_gate,
414                                                       aifp->int_net,
415                                                       aifp->int_mask)
416                                             && rt->rt_gate != aifp->int_addr)
417                                             v12buf.n->n_nhop = rt->rt_gate;
418                                 }
419                         }
420                         v12buf.n->n_metric = htonl(v12buf.n->n_metric);
421
422                         /* Stop paying attention if we fill the output buffer.
423                          */
424                         if (++v12buf.n >= v12buf.lim)
425                                 break;
426                 } while (++n < lim);
427
428                 /* Send the answer about specific routes.
429                  */
430                 if (ap != NULL && ap->type == RIP_AUTH_MD5)
431                         end_md5_auth(&v12buf, ap);
432
433                 if (from->sin_port != htons(RIP_PORT)) {
434                         /* query */
435                         output(OUT_QUERY, from, aifp,
436                                v12buf.buf,
437                                ((char *)v12buf.n - (char*)v12buf.buf));
438                 } else if (supplier) {
439                         output(OUT_UNICAST, from, aifp,
440                                v12buf.buf,
441                                ((char *)v12buf.n - (char*)v12buf.buf));
442                 } else {
443                         /* Only answer a router if we are a supplier
444                          * to keep an unwary host that is just starting
445                          * from picking us an a router.
446                          */
447                         ;
448                 }
449                 return;
450
451         case RIPCMD_TRACEON:
452         case RIPCMD_TRACEOFF:
453                 /* Notice that trace messages are turned off for all possible
454                  * abuse if _PATH_TRACE is undefined in pathnames.h.
455                  * Notice also that because of the way the trace file is
456                  * handled in trace.c, no abuse is plausible even if
457                  * _PATH_TRACE_ is defined.
458                  *
459                  * First verify message came from a privileged port. */
460                 if (ntohs(from->sin_port) > IPPORT_RESERVED) {
461                         msglog("trace command from untrusted port on %s",
462                                naddr_ntoa(FROM_NADDR));
463                         return;
464                 }
465                 if (aifp == NULL) {
466                         msglog("trace command from unknown router %s",
467                                naddr_ntoa(FROM_NADDR));
468                         return;
469                 }
470                 if (rip->rip_cmd == RIPCMD_TRACEON) {
471                         rip->rip_tracefile[cc-4] = '\0';
472                         set_tracefile((char*)rip->rip_tracefile,
473                                       "trace command: %s\n", 0);
474                 } else {
475                         trace_off("tracing turned off by %s",
476                                   naddr_ntoa(FROM_NADDR));
477                 }
478                 return;
479
480         case RIPCMD_RESPONSE:
481                 if (cc%sizeof(*n) != sizeof(struct rip)%sizeof(*n)) {
482                         msglim(&bad_len, FROM_NADDR,
483                                "response of bad length (%d) from %s",
484                                cc, naddr_ntoa(FROM_NADDR));
485                 }
486
487                 /* verify message came from a router */
488                 if (from->sin_port != ntohs(RIP_PORT)) {
489                         msglim(&bad_router, FROM_NADDR,
490                                "    discard RIP response from unknown port"
491                                " %d on host %s", ntohs(from->sin_port),
492                                 naddr_ntoa(FROM_NADDR));
493                         return;
494                 }
495
496                 if (rip_sock < 0) {
497                         trace_pkt("    discard response while RIP off");
498                         return;
499                 }
500
501                 /* Are we talking to ourself or a remote gateway?
502                  */
503                 ifp1 = ifwithaddr(FROM_NADDR, 0, 1);
504                 if (ifp1) {
505                         if (ifp1->int_state & IS_REMOTE) {
506                                 /* remote gateway */
507                                 aifp = ifp1;
508                                 if (check_remote(aifp)) {
509                                         aifp->int_act_time = now.tv_sec;
510                                         if_ok(aifp, "remote ");
511                                 }
512                         } else {
513                                 trace_pkt("    discard our own RIP response");
514                                 return;
515                         }
516                 }
517
518                 /* Accept routing packets from routers directly connected
519                  * via broadcast or point-to-point networks, and from
520                  * those listed in /etc/gateways.
521                  */
522                 if (aifp == NULL) {
523                         msglim(&unk_router, FROM_NADDR,
524                                "   discard response from %s"
525                                " via unexpected interface",
526                                naddr_ntoa(FROM_NADDR));
527                         return;
528                 }
529                 if (IS_RIP_IN_OFF(aifp->int_state)) {
530                         trace_pkt("    discard RIPv%d response"
531                                   " via disabled interface %s",
532                                   rip->rip_vers, aifp->int_name);
533                         return;
534                 }
535
536                 if (n >= lim) {
537                         msglim(&bad_len, FROM_NADDR, "empty response from %s",
538                                naddr_ntoa(FROM_NADDR));
539                         return;
540                 }
541
542                 if (((aifp->int_state & IS_NO_RIPV1_IN)
543                      && rip->rip_vers == RIPv1)
544                     || ((aifp->int_state & IS_NO_RIPV2_IN)
545                         && rip->rip_vers != RIPv1)) {
546                         trace_pkt("    discard RIPv%d response",
547                                   rip->rip_vers);
548                         return;
549                 }
550
551                 /* Ignore routes via dead interface.
552                  */
553                 if (aifp->int_state & IS_BROKE) {
554                         trace_pkt("discard response via broken interface %s",
555                                   aifp->int_name);
556                         return;
557                 }
558
559                 /* If the interface cares, ignore bad routers.
560                  * Trace but do not log this problem, because where it
561                  * happens, it happens frequently.
562                  */
563                 if (aifp->int_state & IS_DISTRUST) {
564                         tg = tgates;
565                         while (tg->tgate_addr != FROM_NADDR) {
566                                 tg = tg->tgate_next;
567                                 if (tg == NULL) {
568                                         trace_pkt("    discard RIP response"
569                                                   " from untrusted router %s",
570                                                   naddr_ntoa(FROM_NADDR));
571                                         return;
572                                 }
573                         }
574                 }
575
576                 /* Authenticate the packet if we have a secret.
577                  * If we do not have any secrets, ignore the error in
578                  * RFC 1723 and accept it regardless.
579                  */
580                 if (aifp->int_auth[0].type != RIP_AUTH_NONE
581                     && rip->rip_vers != RIPv1
582                     && !ck_passwd(aifp,rip,lim,FROM_NADDR,&use_auth))
583                         return;
584
585                 do {
586                         if (n->n_family == RIP_AF_AUTH)
587                                 continue;
588
589                         n->n_metric = ntohl(n->n_metric);
590                         dst = n->n_dst;
591                         if (n->n_family != RIP_AF_INET
592                             && (n->n_family != RIP_AF_UNSPEC
593                                 || dst != RIP_DEFAULT)) {
594                                 msglim(&bad_router, FROM_NADDR,
595                                        "route from %s to unsupported"
596                                        " address family=%d destination=%s",
597                                        naddr_ntoa(FROM_NADDR),
598                                        n->n_family,
599                                        naddr_ntoa(dst));
600                                 continue;
601                         }
602                         if (!check_dst(dst)) {
603                                 msglim(&bad_router, FROM_NADDR,
604                                        "bad destination %s from %s",
605                                        naddr_ntoa(dst),
606                                        naddr_ntoa(FROM_NADDR));
607                                 return;
608                         }
609                         if (n->n_metric == 0
610                             || n->n_metric > HOPCNT_INFINITY) {
611                                 msglim(&bad_router, FROM_NADDR,
612                                        "bad metric %d from %s"
613                                        " for destination %s",
614                                        n->n_metric,
615                                        naddr_ntoa(FROM_NADDR),
616                                        naddr_ntoa(dst));
617                                 return;
618                         }
619
620                         /* Notice the next-hop.
621                          */
622                         gate = FROM_NADDR;
623                         if (n->n_nhop != 0) {
624                                 if (rip->rip_vers == RIPv1) {
625                                         n->n_nhop = 0;
626                                 } else {
627                                     /* Use it only if it is valid. */
628                                     if (on_net(n->n_nhop,
629                                                aifp->int_net, aifp->int_mask)
630                                         && check_dst(n->n_nhop)) {
631                                             gate = n->n_nhop;
632                                     } else {
633                                             msglim(&bad_nhop, FROM_NADDR,
634                                                    "router %s to %s"
635                                                    " has bad next hop %s",
636                                                    naddr_ntoa(FROM_NADDR),
637                                                    naddr_ntoa(dst),
638                                                    naddr_ntoa(n->n_nhop));
639                                             n->n_nhop = 0;
640                                     }
641                                 }
642                         }
643
644                         if (rip->rip_vers == RIPv1
645                             || 0 == (mask = ntohl(n->n_mask))) {
646                                 mask = ripv1_mask_host(dst,aifp);
647                         } else if ((ntohl(dst) & ~mask) != 0) {
648                                 msglim(&bad_mask, FROM_NADDR,
649                                        "router %s sent bad netmask"
650                                        " %#lx with %s",
651                                        naddr_ntoa(FROM_NADDR),
652                                        (u_long)mask,
653                                        naddr_ntoa(dst));
654                                 continue;
655                         }
656                         if (rip->rip_vers == RIPv1)
657                                 n->n_tag = 0;
658
659                         /* Adjust metric according to incoming interface..
660                          */
661                         n->n_metric += aifp->int_metric;
662                         if (n->n_metric > HOPCNT_INFINITY)
663                                 n->n_metric = HOPCNT_INFINITY;
664
665                         /* Should we trust this route from this router? */
666                         if (tg && (tn = tg->tgate_nets)->mask != 0) {
667                                 for (i = 0; i < MAX_TGATE_NETS; i++, tn++) {
668                                         if (on_net(dst, tn->net, tn->mask)
669                                             && tn->mask <= mask)
670                                             break;
671                                 }
672                                 if (i >= MAX_TGATE_NETS || tn->mask == 0) {
673                                         trace_pkt("   ignored unauthorized %s",
674                                                   addrname(dst,mask,0));
675                                         continue;
676                                 }
677                         }
678
679                         /* Recognize and ignore a default route we faked
680                          * which is being sent back to us by a machine with
681                          * broken split-horizon.
682                          * Be a little more paranoid than that, and reject
683                          * default routes with the same metric we advertised.
684                          */
685                         if (aifp->int_d_metric != 0
686                             && dst == RIP_DEFAULT
687                             && (int)n->n_metric >= aifp->int_d_metric)
688                                 continue;
689
690                         /* We can receive aggregated RIPv2 routes that must
691                          * be broken down before they are transmitted by
692                          * RIPv1 via an interface on a subnet.
693                          * We might also receive the same routes aggregated
694                          * via other RIPv2 interfaces.
695                          * This could cause duplicate routes to be sent on
696                          * the RIPv1 interfaces.  "Longest matching variable
697                          * length netmasks" lets RIPv2 listeners understand,
698                          * but breaking down the aggregated routes for RIPv1
699                          * listeners can produce duplicate routes.
700                          *
701                          * Breaking down aggregated routes here bloats
702                          * the daemon table, but does not hurt the kernel
703                          * table, since routes are always aggregated for
704                          * the kernel.
705                          *
706                          * Notice that this does not break down network
707                          * routes corresponding to subnets.  This is part
708                          * of the defense against RS_NET_SYN.
709                          */
710                         if (have_ripv1_out
711                             && (((rt = rtget(dst,mask)) == NULL
712                                  || !(rt->rt_state & RS_NET_SYN)))
713                             && (v1_mask = ripv1_mask_net(dst,0)) > mask) {
714                                 ddst_h = v1_mask & -v1_mask;
715                                 i = (v1_mask & ~mask)/ddst_h;
716                                 if (i >= 511) {
717                                         /* Punt if we would have to generate
718                                          * an unreasonable number of routes.
719                                          */
720                                         if (TRACECONTENTS)
721                                             trace_misc("accept %s-->%s as 1"
722                                                        " instead of %d routes",
723                                                        addrname(dst,mask,0),
724                                                        naddr_ntoa(FROM_NADDR),
725                                                        i+1);
726                                         i = 0;
727                                 } else {
728                                         mask = v1_mask;
729                                 }
730                         } else {
731                                 i = 0;
732                         }
733
734                         new.rts_gate = gate;
735                         new.rts_router = FROM_NADDR;
736                         new.rts_metric = n->n_metric;
737                         new.rts_tag = n->n_tag;
738                         new.rts_time = now.tv_sec;
739                         new.rts_ifp = aifp;
740                         new.rts_de_ag = i;
741                         j = 0;
742                         for (;;) {
743                                 input_route(dst, mask, &new, n);
744                                 if (++j > i)
745                                         break;
746                                 dst = htonl(ntohl(dst) + ddst_h);
747                         }
748                 } while (++n < lim);
749                 break;
750         }
751 #undef FROM_NADDR
752 }
753
754
755 /* Process a single input route.
756  */
757 static void
758 input_route(naddr dst,                  /* network order */
759             naddr mask,
760             struct rt_spare *new,
761             struct netinfo *n)
762 {
763         int i;
764         struct rt_entry *rt;
765         struct rt_spare *rts, *rts0;
766         struct interface *ifp1;
767
768
769         /* See if the other guy is telling us to send our packets to him.
770          * Sometimes network routes arrive over a point-to-point link for
771          * the network containing the address(es) of the link.
772          *
773          * If our interface is broken, switch to using the other guy.
774          */
775         ifp1 = ifwithaddr(dst, 1, 1);
776         if (ifp1 != NULL
777             && (!(ifp1->int_state & IS_BROKE)
778                 || (ifp1->int_state & IS_PASSIVE)))
779                 return;
780
781         /* Look for the route in our table.
782          */
783         rt = rtget(dst, mask);
784
785         /* Consider adding the route if we do not already have it.
786          */
787         if (rt == NULL) {
788                 /* Ignore unknown routes being poisoned.
789                  */
790                 if (new->rts_metric == HOPCNT_INFINITY)
791                         return;
792
793                 /* Ignore the route if it points to us */
794                 if (n->n_nhop != 0
795                     && 0 != ifwithaddr(n->n_nhop, 1, 0))
796                         return;
797
798                 /* If something has not gone crazy and tried to fill
799                  * our memory, accept the new route.
800                  */
801                 if (total_routes < MAX_ROUTES)
802                         rtadd(dst, mask, 0, new);
803                 return;
804         }
805
806         /* We already know about the route.  Consider this update.
807          *
808          * If (rt->rt_state & RS_NET_SYN), then this route
809          * is the same as a network route we have inferred
810          * for subnets we know, in order to tell RIPv1 routers
811          * about the subnets.
812          *
813          * It is impossible to tell if the route is coming
814          * from a distant RIPv2 router with the standard
815          * netmask because that router knows about the entire
816          * network, or if it is a round-about echo of a
817          * synthetic, RIPv1 network route of our own.
818          * The worst is that both kinds of routes might be
819          * received, and the bad one might have the smaller
820          * metric.  Partly solve this problem by never
821          * aggregating into such a route.  Also keep it
822          * around as long as the interface exists.
823          */
824
825         rts0 = rt->rt_spares;
826         for (rts = rts0, i = NUM_SPARES; i != 0; i--, rts++) {
827                 if (rts->rts_router == new->rts_router)
828                         break;
829                 /* Note the worst slot to reuse,
830                  * other than the current slot.
831                  */
832                 if (rts0 == rt->rt_spares
833                     || BETTER_LINK(rt, rts0, rts))
834                         rts0 = rts;
835         }
836         if (i != 0) {
837                 /* Found a route from the router already in the table.
838                  */
839
840                 /* If the new route is a route broken down from an
841                  * aggregated route, and if the previous route is either
842                  * not a broken down route or was broken down from a finer
843                  * netmask, and if the previous route is current,
844                  * then forget this one.
845                  */
846                 if (new->rts_de_ag > rts->rts_de_ag
847                     && now_stale <= rts->rts_time)
848                         return;
849
850                 /* Keep poisoned routes around only long enough to pass
851                  * the poison on.  Use a new timestamp for good routes.
852                  */
853                 if (rts->rts_metric == HOPCNT_INFINITY
854                     && new->rts_metric == HOPCNT_INFINITY)
855                         new->rts_time = rts->rts_time;
856
857                 /* If this is an update for the router we currently prefer,
858                  * then note it.
859                  */
860                 if (i == NUM_SPARES) {
861                         rtchange(rt, rt->rt_state, new, 0);
862                         /* If the route got worse, check for something better.
863                          */
864                         if (new->rts_metric > rts->rts_metric)
865                                 rtswitch(rt, 0);
866                         return;
867                 }
868
869                 /* This is an update for a spare route.
870                  * Finished if the route is unchanged.
871                  */
872                 if (rts->rts_gate == new->rts_gate
873                     && rts->rts_metric == new->rts_metric
874                     && rts->rts_tag == new->rts_tag) {
875                         trace_upslot(rt, rts, new);
876                         *rts = *new;
877                         return;
878                 }
879                 /* Forget it if it has gone bad.
880                  */
881                 if (new->rts_metric == HOPCNT_INFINITY) {
882                         rts_delete(rt, rts);
883                         return;
884                 }
885
886         } else {
887                 /* The update is for a route we know about,
888                  * but not from a familiar router.
889                  *
890                  * Ignore the route if it points to us.
891                  */
892                 if (n->n_nhop != 0
893                     && 0 != ifwithaddr(n->n_nhop, 1, 0))
894                         return;
895
896                 /* the loop above set rts0=worst spare */
897                 rts = rts0;
898
899                 /* Save the route as a spare only if it has
900                  * a better metric than our worst spare.
901                  * This also ignores poisoned routes (those
902                  * received with metric HOPCNT_INFINITY).
903                  */
904                 if (new->rts_metric >= rts->rts_metric)
905                         return;
906         }
907
908         trace_upslot(rt, rts, new);
909         *rts = *new;
910
911         /* try to switch to a better route */
912         rtswitch(rt, rts);
913 }
914
915
916 static int                              /* 0 if bad */
917 ck_passwd(struct interface *aifp,
918           struct rip *rip,
919           void *lim,
920           naddr from,
921           struct msg_limit *use_authp)
922 {
923 #       define NA (rip->rip_auths)
924         struct netauth *na2;
925         struct auth *ap;
926         MD5_CTX md5_ctx;
927         u_char hash[RIP_AUTH_PW_LEN];
928         int i, len;
929
930
931         if ((void *)NA >= lim || NA->a_family != RIP_AF_AUTH) {
932                 msglim(use_authp, from, "missing password from %s",
933                        naddr_ntoa(from));
934                 return 0;
935         }
936
937         /* accept any current (+/- 24 hours) password
938          */
939         for (ap = aifp->int_auth, i = 0; i < MAX_AUTH_KEYS; i++, ap++) {
940                 if (ap->type != NA->a_type
941                     || (u_long)ap->start > (u_long)clk.tv_sec+DAY
942                     || (u_long)ap->end+DAY < (u_long)clk.tv_sec)
943                         continue;
944
945                 if (NA->a_type == RIP_AUTH_PW) {
946                         if (!memcmp(NA->au.au_pw, ap->key, RIP_AUTH_PW_LEN))
947                                 return 1;
948
949                 } else {
950                         /* accept MD5 secret with the right key ID
951                          */
952                         if (NA->au.a_md5.md5_keyid != ap->keyid)
953                                 continue;
954
955                         len = ntohs(NA->au.a_md5.md5_pkt_len);
956                         if ((len-sizeof(*rip)) % sizeof(*NA) != 0
957                             || len != (char *)lim-(char*)rip-(int)sizeof(*NA)) {
958                                 msglim(use_authp, from,
959                                        "wrong MD5 RIPv2 packet length of %d"
960                                        " instead of %d from %s",
961                                        len, (int)((char *)lim-(char *)rip
962                                                   -sizeof(*NA)),
963                                        naddr_ntoa(from));
964                                 return 0;
965                         }
966                         na2 = (struct netauth *)((char *)rip+len);
967
968                         /* Given a good hash value, these are not security
969                          * problems so be generous and accept the routes,
970                          * after complaining.
971                          */
972                         if (TRACEPACKETS) {
973                                 if (NA->au.a_md5.md5_auth_len
974                                     != RIP_AUTH_MD5_LEN)
975                                         msglim(use_authp, from,
976                                                "unknown MD5 RIPv2 auth len %#x"
977                                                " instead of %#x from %s",
978                                                NA->au.a_md5.md5_auth_len,
979                                                RIP_AUTH_MD5_LEN,
980                                                naddr_ntoa(from));
981                                 if (na2->a_family != RIP_AF_AUTH)
982                                         msglim(use_authp, from,
983                                                "unknown MD5 RIPv2 family %#x"
984                                                " instead of %#x from %s",
985                                                na2->a_family, RIP_AF_AUTH,
986                                                naddr_ntoa(from));
987                                 if (na2->a_type != ntohs(1))
988                                         msglim(use_authp, from,
989                                                "MD5 RIPv2 hash has %#x"
990                                                " instead of %#x from %s",
991                                                na2->a_type, ntohs(1),
992                                                naddr_ntoa(from));
993                         }
994
995                         MD5Init(&md5_ctx);
996                         MD5Update(&md5_ctx, (u_char *)rip, len);
997                         MD5Update(&md5_ctx, ap->key, RIP_AUTH_MD5_LEN);
998                         MD5Final(hash, &md5_ctx);
999                         if (!memcmp(hash, na2->au.au_pw, sizeof(hash)))
1000                                 return 1;
1001                 }
1002         }
1003
1004         msglim(use_authp, from, "bad password from %s",
1005                naddr_ntoa(from));
1006         return 0;
1007 #undef NA
1008 }