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