xref: /freebsd/sbin/routed/input.c (revision e627b39baccd1ec9129690167cf5e6d860509655)
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 #if !defined(lint) && !defined(sgi) && !defined(__NetBSD__)
35 static char sccsid[] = "@(#)input.c	8.1 (Berkeley) 6/5/93";
36 #elif defined(__NetBSD__)
37 static char rcsid[] = "$NetBSD$";
38 #endif
39 #ident "$Revision: 1.16 $"
40 
41 #include "defs.h"
42 
43 static void input(struct sockaddr_in *, struct interface*, struct rip *, int);
44 static void input_route(struct interface *, naddr,
45 			naddr, naddr, naddr, struct netinfo *);
46 
47 
48 /* process RIP input
49  */
50 void
51 read_rip(int sock,
52 	 struct interface *ifp)
53 {
54 	struct sockaddr_in from;
55 	int fromlen, cc;
56 	union pkt_buf inbuf;
57 
58 
59 	for (;;) {
60 		fromlen = sizeof(from);
61 		cc = recvfrom(sock, &inbuf, sizeof(inbuf), 0,
62 			      (struct sockaddr*)&from, &fromlen);
63 		if (cc <= 0) {
64 			if (cc < 0 && errno != EWOULDBLOCK)
65 				LOGERR("recvfrom(rip)");
66 			break;
67 		}
68 		if (fromlen != sizeof(struct sockaddr_in))
69 			logbad(1,"impossible recvfrom(rip) fromlen=%d",
70 			       fromlen);
71 
72 		input(&from, ifp, &inbuf.rip, cc);
73 	}
74 }
75 
76 
77 /* Process a RIP packet
78  */
79 static void
80 input(struct sockaddr_in *from,		/* received from this IP address */
81       struct interface *sifp,		/* interface by which it arrived */
82       struct rip *rip,
83       int size)
84 {
85 #	define FROM_NADDR from->sin_addr.s_addr
86 	static naddr use_auth, bad_len, bad_mask;
87 	static naddr unk_router, bad_router, bad_nhop;
88 
89 	struct interface *aifp;		/* interface if via 1 hop */
90 	struct rt_entry *rt;
91 	struct netinfo *n, *lim;
92 	struct interface *ifp1;
93 	naddr gate, mask, v1_mask, dst, ddst_h;
94 	int i;
95 
96 	aifp = iflookup(from->sin_addr.s_addr);
97 	if (sifp == 0)
98 		sifp = aifp;
99 
100 	if (sifp != 0)
101 		sifp->int_state |= IS_ACTIVE;
102 
103 	trace_rip("Recv", "from", from, sifp, rip, size);
104 
105 	if (rip->rip_vers == 0) {
106 		if (from->sin_addr.s_addr != bad_router)
107 			msglog("RIP version 0, cmd %d, packet received"
108 			       " from %s",
109 			       rip->rip_cmd, naddr_ntoa(FROM_NADDR));
110 		bad_router = from->sin_addr.s_addr;
111 		return;
112 	} else if (rip->rip_vers > RIPv2) {
113 		rip->rip_vers = RIPv2;
114 	}
115 	if (size > MAXPACKETSIZE) {
116 		if (from->sin_addr.s_addr != bad_router)
117 			msglog("packet at least %d bytes too long received"
118 			       " from %s",
119 			       size-MAXPACKETSIZE, naddr_ntoa(FROM_NADDR));
120 		bad_router = from->sin_addr.s_addr;
121 		return;
122 	}
123 
124 	n = rip->rip_nets;
125 	lim = (struct netinfo *)((char*)rip + size);
126 
127 	/* Notice authentication.
128 	 * As required by section 4.2 in RFC 1723, discard authenticated
129 	 * RIPv2 messages, but only if configured for that silliness.
130 	 *
131 	 * RIPv2 authentication is lame, since snooping on the wire makes
132 	 * its simple passwords evident.  Also, why authenticate queries?
133 	 * Why should a RIPv2 implementation with authentication disabled
134 	 * not be able to listen to RIPv2 packets with authenication, while
135 	 * RIPv1 systems will listen?  Crazy!
136 	 */
137 	if (!auth_ok
138 	    && rip->rip_vers == RIPv2
139 	    && n < lim && n->n_family == RIP_AF_AUTH) {
140 		if (from->sin_addr.s_addr != use_auth)
141 			msglog("RIPv2 message with authentication"
142 			       " from %s discarded",
143 			       naddr_ntoa(FROM_NADDR));
144 		use_auth = from->sin_addr.s_addr;
145 		trace_pkt("discard authenticated RIPv2 message\n");
146 		return;
147 	}
148 
149 	switch (rip->rip_cmd) {
150 	case RIPCMD_REQUEST:
151 		/* did the request come from a router?
152 		 */
153 		if (from->sin_port == htons(RIP_PORT)) {
154 			/* yes, ignore it if RIP is off so that it does not
155 			 * depend on us.
156 			 */
157 			if (rip_sock < 0) {
158 				trace_pkt("ignore request while RIP off\n");
159 				return;
160 			}
161 
162 			/* Ignore the request if we talking to ourself
163 			 * (and not a remote gateway).
164 			 */
165 			if (ifwithaddr(FROM_NADDR, 0, 0) != 0) {
166 				trace_pkt("discard our own RIP request\n");
167 				return;
168 			}
169 		}
170 
171 		/* According to RFC 1723, we should ignore unathenticated
172 		 * queries.  That is too silly to bother with.  Sheesh!
173 		 * Are forwarding tables supposed to be secret?  When
174 		 * a bad guy can infer them with test traffic?
175 		 * Maybe on firewalls you'd care, but not enough to
176 		 * give up the diagnostic facilities of remote probing.
177 		 */
178 
179 		if (n >= lim
180 		    || size%sizeof(*n) != sizeof(struct rip)%sizeof(*n)) {
181 			if (from->sin_addr.s_addr != bad_len)
182 				msglog("request of bad length (%d) from %s",
183 				       size, naddr_ntoa(FROM_NADDR));
184 			bad_len = from->sin_addr.s_addr;
185 		}
186 		for (; n < lim; n++) {
187 			n->n_metric = ntohl(n->n_metric);
188 
189 			/* A single entry with family RIP_AF_UNSPEC and
190 			 * metric HOPCNT_INFINITY means "all routes".
191 			 * We respond to routers only if we are acting
192 			 * as a supplier, or to anyone other than a router
193 			 * (i.e. a query).
194 			 */
195 			if (n->n_family == RIP_AF_UNSPEC
196 			    && n->n_metric == HOPCNT_INFINITY
197 			    && n == rip->rip_nets
198 			    && n+1 == lim) {
199 				if (from->sin_port != htons(RIP_PORT)) {
200 					/* Answer a query from a utility
201 					 * program with all we know.
202 					 */
203 					supply(from, sifp, OUT_QUERY, 0,
204 					       rip->rip_vers);
205 					return;
206 				}
207 				/* A router trying to prime its tables.
208 				 * Filter the answer in the about same way
209 				 * broadcasts are filtered.
210 				 *
211 				 * Only answer a router if we are a supplier
212 				 * to keep an unwary host that is just starting
213 				 * from picking us as a router.  Respond with
214 				 * RIPv1 instead of RIPv2 if that is what we
215 				 * are broadcasting on the interface to keep
216 				 * the remote router from getting the wrong
217 				 * initial idea of the routes we send.
218 				 */
219 				if (!supplier
220 				    || aifp == 0
221 				    || (aifp->int_state & IS_PASSIVE)
222 				    || (aifp->int_state & IS_ALIAS)
223 				    || ((aifp->int_state & IS_NO_RIPV1_OUT)
224 					&& (aifp->int_state&IS_NO_RIPV2_OUT)))
225 					return;
226 
227 				supply(from, aifp, OUT_UNICAST, 0,
228 				       (aifp->int_state&IS_NO_RIPV1_OUT)
229 				       ? RIPv2 : RIPv1);
230 				return;
231 			}
232 
233 			if (n->n_family != RIP_AF_INET) {
234 				if (from->sin_addr.s_addr != bad_router)
235 					msglog("request from %s"
236 					       " for unsupported (af %d) %s",
237 					       naddr_ntoa(FROM_NADDR),
238 					       ntohs(n->n_family),
239 					       naddr_ntoa(n->n_dst));
240 				bad_router = from->sin_addr.s_addr;
241 				return;
242 			}
243 
244 			dst = n->n_dst;
245 			if (!check_dst(dst)) {
246 				if (from->sin_addr.s_addr != bad_router)
247 					msglog("bad queried destination"
248 					       " %s from %s",
249 					       naddr_ntoa(dst),
250 					       naddr_ntoa(FROM_NADDR));
251 				bad_router = from->sin_addr.s_addr;
252 				return;
253 			}
254 
255 			if (rip->rip_vers == RIPv1
256 			    || 0 == (mask = ntohl(n->n_mask))
257 			    || 0 != (ntohl(dst) & ~mask))
258 				mask = ripv1_mask_host(dst,sifp);
259 
260 			rt = rtget(dst, mask);
261 			if (!rt && dst != RIP_DEFAULT)
262 				rt = rtfind(n->n_dst);
263 
264 			n->n_tag = 0;
265 			n->n_nhop = 0;
266 			if (rip->rip_vers == RIPv1) {
267 				n->n_mask = 0;
268 			} else {
269 				n->n_mask = mask;
270 			}
271 			if (rt == 0) {
272 				n->n_metric = HOPCNT_INFINITY;
273 			} else {
274 				n->n_metric = rt->rt_metric+1;
275 				n->n_metric += (sifp!=0)?sifp->int_metric : 1;
276 				if (n->n_metric > HOPCNT_INFINITY)
277 					n->n_metric = HOPCNT_INFINITY;
278 				if (rip->rip_vers != RIPv1) {
279 					n->n_tag = rt->rt_tag;
280 					if (sifp != 0
281 					    && on_net(rt->rt_gate,
282 						      sifp->int_net,
283 						      sifp->int_mask)
284 					    && rt->rt_gate != sifp->int_addr)
285 						n->n_nhop = rt->rt_gate;
286 				}
287 			}
288 			HTONL(n->n_metric);
289 		}
290 		/* Answer about specific routes.
291 		 * Only answer a router if we are a supplier
292 		 * to keep an unwary host that is just starting
293 		 * from picking us an a router.
294 		 */
295 		rip->rip_cmd = RIPCMD_RESPONSE;
296 		rip->rip_res1 = 0;
297 		if (rip->rip_vers != RIPv1)
298 			rip->rip_vers = RIPv2;
299 		if (from->sin_port != htons(RIP_PORT)) {
300 			/* query */
301 			(void)output(OUT_QUERY, from, sifp, rip, size);
302 		} else if (supplier) {
303 			(void)output(OUT_UNICAST, from, sifp, rip, size);
304 		}
305 		return;
306 
307 	case RIPCMD_TRACEON:
308 	case RIPCMD_TRACEOFF:
309 		/* verify message came from a privileged port */
310 		if (ntohs(from->sin_port) > IPPORT_RESERVED) {
311 			msglog("trace command from untrusted port on %s",
312 			       naddr_ntoa(FROM_NADDR));
313 			return;
314 		}
315 		if (aifp == 0) {
316 			msglog("trace command from unknown router %s",
317 			       naddr_ntoa(FROM_NADDR));
318 			return;
319 		}
320 		if (rip->rip_cmd == RIPCMD_TRACEON) {
321 			rip->rip_tracefile[size-4] = '\0';
322 			trace_on((char*)rip->rip_tracefile, 0);
323 		} else {
324 			trace_off("tracing turned off by %s\n",
325 				  naddr_ntoa(FROM_NADDR));
326 		}
327 		return;
328 
329 	case RIPCMD_RESPONSE:
330 		if (size%sizeof(*n) != sizeof(struct rip)%sizeof(*n)) {
331 			if (from->sin_addr.s_addr != bad_len)
332 				msglog("response of bad length (%d) from %s",
333 				       size, naddr_ntoa(FROM_NADDR));
334 			bad_len = from->sin_addr.s_addr;
335 		}
336 
337 		/* verify message came from a router */
338 		if (from->sin_port != ntohs(RIP_PORT)) {
339 			trace_pkt("discard RIP response from unknown port\n");
340 			return;
341 		}
342 
343 		if (rip_sock < 0) {
344 			trace_pkt("discard response while RIP off\n");
345 			return;
346 		}
347 
348 		/* Are we talking to ourself or a remote gateway?
349 		 */
350 		ifp1 = ifwithaddr(FROM_NADDR, 0, 1);
351 		if (ifp1) {
352 			if (ifp1->int_state & IS_REMOTE) {
353 				if (ifp1->int_state & IS_PASSIVE) {
354 					msglog("bogus input from %s on"
355 					       " supposedly passive %s",
356 					       naddr_ntoa(FROM_NADDR),
357 					       ifp1->int_name);
358 				} else {
359 					ifp1->int_act_time = now.tv_sec;
360 					if (if_ok(ifp1, "remote "))
361 						addrouteforif(ifp1);
362 				}
363 			} else {
364 				trace_pkt("discard our own RIP response\n");
365 			}
366 			return;
367 		}
368 
369 		/* Check the router from which message originated. We accept
370 		 * routing packets from routers directly connected via
371 		 * broadcast or point-to-point networks, and from
372 		 * those listed in /etc/gateways.
373 		 */
374 		if (!aifp) {
375 			if (from->sin_addr.s_addr != unk_router)
376 				msglog("discard packet from unknown router %s"
377 				       " or via unidentified interface",
378 				       naddr_ntoa(FROM_NADDR));
379 			unk_router = from->sin_addr.s_addr;
380 			return;
381 		}
382 		if (aifp->int_state & IS_PASSIVE) {
383 			trace_act("discard packet from %s"
384 				  " via passive interface %s\n",
385 				  naddr_ntoa(FROM_NADDR),
386 				  aifp->int_name);
387 			return;
388 		}
389 
390 		/* Check required version
391 		 */
392 		if (((aifp->int_state & IS_NO_RIPV1_IN)
393 		     && rip->rip_vers == RIPv1)
394 		    || ((aifp->int_state & IS_NO_RIPV2_IN)
395 			&& rip->rip_vers != RIPv1)) {
396 			trace_pkt("discard RIPv%d response\n",
397 				  rip->rip_vers);
398 			return;
399 		}
400 
401 		/* Ignore routes via dead interface.
402 		 */
403 		if (aifp->int_state & IS_BROKE) {
404 			trace_pkt("discard response via broken interface %s\n",
405 				  aifp->int_name);
406 			return;
407 		}
408 
409 		/* Authenticate the packet if we have a secret.
410 		 */
411 		if (aifp->int_passwd[0] != '\0') {
412 			if (n >= lim
413 			    || n->n_family != RIP_AF_AUTH
414 			    || ((struct netauth*)n)->a_type != RIP_AUTH_PW) {
415 				if (from->sin_addr.s_addr != use_auth)
416 					msglog("missing password from %s",
417 					       naddr_ntoa(FROM_NADDR));
418 				use_auth = from->sin_addr.s_addr;
419 				return;
420 
421 			} else if (0 != bcmp(((struct netauth*)n)->au.au_pw,
422 					     aifp->int_passwd,
423 					     sizeof(aifp->int_passwd))) {
424 				if (from->sin_addr.s_addr != use_auth)
425 					msglog("bad password from %s",
426 					       naddr_ntoa(FROM_NADDR));
427 				use_auth = from->sin_addr.s_addr;
428 				return;
429 			}
430 		}
431 
432 		for (; n < lim; n++) {
433 			if (n->n_family == RIP_AF_AUTH)
434 				continue;
435 
436 			NTOHL(n->n_metric);
437 			dst = n->n_dst;
438 			if (n->n_family != RIP_AF_INET
439 			    && (n->n_family != RIP_AF_UNSPEC
440 				|| dst != RIP_DEFAULT)) {
441 				if (from->sin_addr.s_addr != bad_router)
442 					msglog("route from %s to unsupported"
443 					       " address family %d,"
444 					       " destination %s",
445 					       naddr_ntoa(FROM_NADDR),
446 					       n->n_family,
447 					       naddr_ntoa(dst));
448 				bad_router = from->sin_addr.s_addr;
449 				continue;
450 			}
451 			if (!check_dst(dst)) {
452 				if (from->sin_addr.s_addr != bad_router)
453 					msglog("bad destination %s from %s",
454 					       naddr_ntoa(dst),
455 					       naddr_ntoa(FROM_NADDR));
456 				bad_router = from->sin_addr.s_addr;
457 				return;
458 			}
459 			if (n->n_metric == 0
460 			    || n->n_metric > HOPCNT_INFINITY) {
461 				if (from->sin_addr.s_addr != bad_router)
462 					msglog("bad metric %d from %s"
463 					       " for destination %s",
464 					       n->n_metric,
465 					       naddr_ntoa(FROM_NADDR),
466 					       naddr_ntoa(dst));
467 				bad_router = from->sin_addr.s_addr;
468 				return;
469 			}
470 
471 			/* Notice the next-hop.
472 			 */
473 			gate = from->sin_addr.s_addr;
474 			if (n->n_nhop != 0) {
475 				if (rip->rip_vers == RIPv2) {
476 					n->n_nhop = 0;
477 				} else {
478 				    /* Use it only if it is valid. */
479 				    if (on_net(n->n_nhop,
480 					       aifp->int_net, aifp->int_mask)
481 					&& check_dst(n->n_nhop)) {
482 					    gate = n->n_nhop;
483 				    } else {
484 					if (bad_nhop != from->sin_addr.s_addr)
485 						msglog("router %s to %s has"
486 						       " bad next hop %s",
487 						       naddr_ntoa(FROM_NADDR),
488 						       naddr_ntoa(dst),
489 						       naddr_ntoa(n->n_nhop));
490 					bad_nhop = from->sin_addr.s_addr;
491 					n->n_nhop = 0;
492 				    }
493 				}
494 			}
495 
496 			if (rip->rip_vers == RIPv1
497 			    || 0 == (mask = ntohl(n->n_mask))) {
498 				mask = ripv1_mask_host(dst,aifp);
499 			} else if ((ntohl(dst) & ~mask) != 0) {
500 				if (bad_mask != from->sin_addr.s_addr) {
501 					msglog("router %s sent bad netmask"
502 					       " %#x with %s",
503 					       naddr_ntoa(FROM_NADDR),
504 					       mask,
505 					       naddr_ntoa(dst));
506 					bad_mask = from->sin_addr.s_addr;
507 				}
508 				continue;
509 			}
510 			if (rip->rip_vers == RIPv1)
511 				n->n_tag = 0;
512 
513 			/* Adjust metric according to incoming interface..
514 			 */
515 			n->n_metric += aifp->int_metric;
516 			if (n->n_metric > HOPCNT_INFINITY)
517 				n->n_metric = HOPCNT_INFINITY;
518 
519 			/* Recognize and ignore a default route we faked
520 			 * which is being sent back to us by a machine with
521 			 * broken split-horizon.
522 			 * Be a little more paranoid than that, and reject
523 			 * default routes with the same metric we advertised.
524 			 */
525 			if (aifp->int_d_metric != 0
526 			    && dst == RIP_DEFAULT
527 			    && n->n_metric >= aifp->int_d_metric)
528 				continue;
529 
530 			/* We can receive aggregated RIPv2 routes that must
531 			 * be broken down before they are transmitted by
532 			 * RIPv1 via an interface on a subnet.
533 			 * We might also receive the same routes aggregated
534 			 * via other RIPv2 interfaces.
535 			 * This could cause duplicate routes to be sent on
536 			 * the RIPv1 interfaces.  "Longest matching variable
537 			 * length netmasks" lets RIPv2 listeners understand,
538 			 * but breaking down the aggregated routes for RIPv1
539 			 * listeners can produce duplicate routes.
540 			 *
541 			 * Breaking down aggregated routes here bloats
542 			 * the daemon table, but does not hurt the kernel
543 			 * table, since routes are always aggregated for
544 			 * the kernel.
545 			 *
546 			 * Notice that this does not break down network
547 			 * routes corresponding to subnets.  This is part
548 			 * of the defense against RS_NET_SYN.
549 			 */
550 			if (have_ripv1_out
551 			    && (v1_mask = ripv1_mask_net(dst,0)) > mask
552 			    && (((rt = rtget(dst,mask)) == 0
553 				 || !(rt->rt_state & RS_NET_SYN)))) {
554 				ddst_h = v1_mask & -v1_mask;
555 				i = (v1_mask & ~mask)/ddst_h;
556 				if (i >= 511) {
557 					/* Punt if we would have to generate
558 					 * an unreasonable number of routes.
559 					 */
560 #ifdef DEBUG
561 					msglog("accept %s from %s as 1"
562 					       " instead of %d routes",
563 					       addrname(dst,mask,0),
564 					       naddr_ntoa(FROM_NADDR),
565 					       i+1);
566 #endif
567 					i = 0;
568 				} else {
569 					mask = v1_mask;
570 				}
571 			} else {
572 				i = 0;
573 			}
574 
575 			for (;;) {
576 				input_route(aifp, FROM_NADDR,
577 					    dst, mask, gate, n);
578 				if (i-- == 0)
579 					break;
580 				dst = htonl(ntohl(dst) + ddst_h);
581 			}
582 		}
583 		break;
584 	}
585 }
586 
587 
588 /* Process a single input route.
589  */
590 static void
591 input_route(struct interface *ifp,
592 	    naddr from,
593 	    naddr dst,
594 	    naddr mask,
595 	    naddr gate,
596 	    struct netinfo *n)
597 {
598 	int i;
599 	struct rt_entry *rt;
600 	struct rt_spare *rts, *rts0;
601 	struct interface *ifp1;
602 	time_t new_time;
603 
604 
605 	/* See if the other guy is telling us to send our packets to him.
606 	 * Sometimes network routes arrive over a point-to-point link for
607 	 * the network containing the address(es) of the link.
608 	 *
609 	 * If our interface is broken, switch to using the other guy.
610 	 */
611 	ifp1 = ifwithaddr(dst, 1, 1);
612 	if (ifp1 != 0
613 	    && !(ifp1->int_state & IS_BROKE))
614 		return;
615 
616 	/* Look for the route in our table.
617 	 */
618 	rt = rtget(dst, mask);
619 
620 	/* Consider adding the route if we do not already have it.
621 	 */
622 	if (rt == 0) {
623 		/* Ignore unknown routes being poisoned.
624 		 */
625 		if (n->n_metric == HOPCNT_INFINITY)
626 			return;
627 
628 		/* Ignore the route if it points to us */
629 		if (n->n_nhop != 0
630 		    && 0 != ifwithaddr(n->n_nhop, 1, 0))
631 			return;
632 
633 		/* If something has not gone crazy and tried to fill
634 		 * our memory, accept the new route.
635 		 */
636 		if (total_routes < MAX_ROUTES)
637 			rtadd(dst, mask, gate, from, n->n_metric,
638 			      n->n_tag, 0, ifp);
639 		return;
640 	}
641 
642 	/* We already know about the route.  Consider this update.
643 	 *
644 	 * If (rt->rt_state & RS_NET_SYN), then this route
645 	 * is the same as a network route we have inferred
646 	 * for subnets we know, in order to tell RIPv1 routers
647 	 * about the subnets.
648 	 *
649 	 * It is impossible to tell if the route is coming
650 	 * from a distant RIPv2 router with the standard
651 	 * netmask because that router knows about the entire
652 	 * network, or if it is a round-about echo of a
653 	 * synthetic, RIPv1 network route of our own.
654 	 * The worst is that both kinds of routes might be
655 	 * received, and the bad one might have the smaller
656 	 * metric.  Partly solve this problem by never
657 	 * aggregating into such a route.  Also keep it
658 	 * around as long as the interface exists.
659 	 */
660 
661 	rts0 = rt->rt_spares;
662 	for (rts = rts0, i = NUM_SPARES; i != 0; i--, rts++) {
663 		if (rts->rts_router == from)
664 			break;
665 		/* Note the worst slot to reuse,
666 		 * other than the current slot.
667 		 */
668 		if (rts0 == rt->rt_spares
669 		    || BETTER_LINK(rt, rts0, rts))
670 			rts0 = rts;
671 	}
672 	if (i != 0) {
673 		/* Found the router
674 		 */
675 		int old_metric = rts->rts_metric;
676 
677 		/* Keep poisoned routes around only long enough to pass
678 		 * the poison on.  Get a new timestamp for good routes.
679 		 */
680 		new_time =((old_metric == HOPCNT_INFINITY)
681 			   ? rts->rts_time
682 			   : now.tv_sec);
683 
684 		/* If this is an update for the router we currently prefer,
685 		 * then note it.
686 		 */
687 		if (i == NUM_SPARES) {
688 			rtchange(rt,rt->rt_state, gate,rt->rt_router,
689 				 n->n_metric, n->n_tag, ifp, new_time, 0);
690 			/* If the route got worse, check for something better.
691 			 */
692 			if (n->n_metric > old_metric)
693 				rtswitch(rt, 0);
694 			return;
695 		}
696 
697 		/* This is an update for a spare route.
698 		 * Finished if the route is unchanged.
699 		 */
700 		if (rts->rts_gate == gate
701 		    && old_metric == n->n_metric
702 		    && rts->rts_tag == n->n_tag) {
703 			rts->rts_time = new_time;
704 			return;
705 		}
706 
707 	} else {
708 		/* The update is for a route we know about,
709 		 * but not from a familiar router.
710 		 *
711 		 * Ignore the route if it points to us.
712 		 */
713 		if (n->n_nhop != 0
714 		    && 0 != ifwithaddr(n->n_nhop, 1, 0))
715 			return;
716 
717 		rts = rts0;
718 
719 		/* Save the route as a spare only if it has
720 		 * a better metric than our worst spare.
721 		 * This also ignores poisoned routes (those
722 		 * received with metric HOPCNT_INFINITY).
723 		 */
724 		if (n->n_metric >= rts->rts_metric)
725 			return;
726 
727 		new_time = now.tv_sec;
728 	}
729 
730 	trace_upslot(rt, rts, gate, from, ifp, n->n_metric,n->n_tag, new_time);
731 
732 	rts->rts_gate = gate;
733 	rts->rts_router = from;
734 	rts->rts_metric = n->n_metric;
735 	rts->rts_tag = n->n_tag;
736 	rts->rts_time = new_time;
737 	rts->rts_ifp = ifp;
738 
739 	/* try to switch to a better route */
740 	rtswitch(rt, rts);
741 }
742