xref: /freebsd/sbin/routed/input.c (revision a8445737e740901f5f2c8d24c12ef7fc8b00134e)
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 acknowledgement:
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 
34 #ifndef lint
35 #if 0
36 static char sccsid[] = "@(#)input.c	8.1 (Berkeley) 6/5/93";
37 #endif
38 static const char rcsid[] =
39 	"$Id$";
40 #endif /* not lint */
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 authentication, 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 unauthenticated
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\n",
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 		 */
809 		if (rts->rts_gate == gate
810 		    && old_metric == n->n_metric
811 		    && rts->rts_tag == n->n_tag) {
812 			rts->rts_time = new_time;
813 			return;
814 		}
815 
816 	} else {
817 		/* The update is for a route we know about,
818 		 * but not from a familiar router.
819 		 *
820 		 * Ignore the route if it points to us.
821 		 */
822 		if (n->n_nhop != 0
823 		    && 0 != ifwithaddr(n->n_nhop, 1, 0))
824 			return;
825 
826 		rts = rts0;
827 
828 		/* Save the route as a spare only if it has
829 		 * a better metric than our worst spare.
830 		 * This also ignores poisoned routes (those
831 		 * received with metric HOPCNT_INFINITY).
832 		 */
833 		if (n->n_metric >= rts->rts_metric)
834 			return;
835 
836 		new_time = now.tv_sec;
837 	}
838 
839 	trace_upslot(rt, rts, gate, from, ifp, n->n_metric,n->n_tag, new_time);
840 
841 	rts->rts_gate = gate;
842 	rts->rts_router = from;
843 	rts->rts_metric = n->n_metric;
844 	rts->rts_tag = n->n_tag;
845 	rts->rts_time = new_time;
846 	rts->rts_ifp = ifp;
847 
848 	/* try to switch to a better route */
849 	rtswitch(rt, rts);
850 }
851 
852 
853 static int				/* 0 if bad */
854 ck_passwd(struct interface *aifp,
855 	  struct rip *rip,
856 	  void *lim,
857 	  naddr from,
858 	  struct msg_limit *use_authp)
859 {
860 #	define NA (rip->rip_auths)
861 	struct netauth *na2;
862 	struct auth *ap;
863 	MD5_CTX md5_ctx;
864 	u_char hash[RIP_AUTH_PW_LEN];
865 	int i;
866 
867 
868 	if ((void *)NA >= lim || NA->a_family != RIP_AF_AUTH) {
869 		msglim(use_authp, from, "missing password from %s",
870 		       naddr_ntoa(from));
871 		return 0;
872 	}
873 
874 	/* accept any current (+/- 24 hours) password
875 	 */
876 	for (ap = aifp->int_auth, i = 0; i < MAX_AUTH_KEYS; i++, ap++) {
877 		if (ap->type != NA->a_type
878 		    || (u_long)ap->start > (u_long)clk.tv_sec+DAY
879 		    || (u_long)ap->end+DAY < (u_long)clk.tv_sec)
880 			continue;
881 
882 		if (NA->a_type == RIP_AUTH_PW) {
883 			if (!bcmp(NA->au.au_pw, ap->key, RIP_AUTH_PW_LEN))
884 				return 1;
885 
886 		} else {
887 			/* accept MD5 secret with the right key ID
888 			 */
889 			if (NA->au.a_md5.md5_keyid != ap->keyid)
890 				continue;
891 
892 			na2 = (struct netauth *)((char *)(NA+1)
893 						 + NA->au.a_md5.md5_pkt_len);
894 			if (NA->au.a_md5.md5_pkt_len % sizeof(*NA) != 0
895 			    || lim < (void *)(na2+1)) {
896 				msglim(use_authp, from,
897 				       "bad MD5 RIP-II pkt length %d from %s",
898 				       NA->au.a_md5.md5_pkt_len,
899 				       naddr_ntoa(from));
900 				return 0;
901 			}
902 			MD5Init(&md5_ctx);
903 			MD5Update(&md5_ctx, (u_char *)NA,
904 				  (char *)na2->au.au_pw - (char *)NA);
905 			MD5Update(&md5_ctx,
906 				  (u_char *)ap->key, sizeof(ap->key));
907 			MD5Final(hash, &md5_ctx);
908 			if (na2->a_family != RIP_AF_AUTH
909 			    || na2->a_type != 1
910 			    || NA->au.a_md5.md5_auth_len != RIP_AUTH_PW_LEN
911 			    || bcmp(hash, na2->au.au_pw, sizeof(hash)))
912 				return 0;
913 			return 1;
914 		}
915 	}
916 
917 	msglim(use_authp, from, "bad password from %s",
918 	       naddr_ntoa(from));
919 	return 0;
920 #undef NA
921 }
922