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