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