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