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