1 /*	$OpenBSD: if.c,v 1.8 2003/06/02 20:06:17 millert Exp $	*/
2 
3 /*
4  * Copyright (c) 1983, 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 #if !defined(lint)
33 static char sccsid[] = "@(#)if.c	8.1 (Berkeley) 6/5/93";
34 #else
35 static char rcsid[] = "$OpenBSD: if.c,v 1.8 2003/06/02 20:06:17 millert Exp $";
36 #endif
37 
38 #include "defs.h"
39 #include "pathnames.h"
40 
41 struct	interface *ifnet;		/* all interfaces */
42 int	tot_interfaces;			/* # of remote and local interfaces */
43 int	rip_interfaces;			/* # of interfaces doing RIP */
44 int	foundloopback;			/* valid flag for loopaddr */
45 naddr	loopaddr;			/* our address on loopback */
46 
47 struct timeval ifinit_timer;
48 
49 int	have_ripv1_out;			/* have a RIPv1 interface */
50 int	have_ripv1_in;
51 
52 
53 /* Find the interface with an address
54  */
55 struct interface *
ifwithaddr(naddr addr,int bcast,int remote)56 ifwithaddr(naddr addr,
57 	   int	bcast,			/* notice IFF_BROADCAST address */
58 	   int	remote)			/* include IS_REMOTE interfaces */
59 {
60 	struct interface *ifp, *possible = 0;
61 
62 	for (ifp = ifnet; ifp; ifp = ifp->int_next) {
63 		if (ifp->int_addr == addr
64 		    || ((ifp->int_if_flags & IFF_BROADCAST)
65 			&& ifp->int_brdaddr == addr
66 			&& bcast)) {
67 			if ((ifp->int_state & IS_REMOTE) && !remote)
68 				continue;
69 
70 			if (!(ifp->int_state & IS_BROKE)
71 			    && !(ifp->int_state & IS_PASSIVE))
72 				return ifp;
73 
74 			possible = ifp;
75 		}
76 	}
77 
78 	return possible;
79 }
80 
81 
82 /* find the interface with a name
83  */
84 struct interface *
ifwithname(char * name,naddr addr)85 ifwithname(char *name,			/* "ec0" or whatever */
86 	   naddr addr)			/* 0 or network address */
87 {
88 	struct interface *ifp;
89 
90 
91 	for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) {
92 		if (!strcmp(ifp->int_name, name)
93 		    && (ifp->int_addr == addr
94 			|| (addr == 0 && !(ifp->int_state & IS_ALIAS))))
95 			return ifp;
96 	}
97 	return 0;
98 }
99 
100 
101 struct interface *
ifwithindex(u_short index)102 ifwithindex(u_short index)
103 {
104 	struct interface *ifp;
105 
106 
107 	for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) {
108 		if (ifp->int_index == index)
109 			return ifp;
110 	}
111 	return 0;
112 }
113 
114 
115 /* Find an interface from which the specified address
116  * should have come from.  Used for figuring out which
117  * interface a packet came in on -- for tracing.
118  */
119 struct interface *
iflookup(naddr addr)120 iflookup(naddr addr)
121 {
122 	struct interface *ifp, *maybe;
123 
124 	maybe = 0;
125 	for (ifp = ifnet; ifp; ifp = ifp->int_next) {
126 		if (ifp->int_if_flags & IFF_POINTOPOINT) {
127 			if (ifp->int_dstaddr == addr)
128 				/* finished with a match */
129 				return ifp;
130 
131 		} else {
132 			/* finished with an exact match */
133 			if (ifp->int_addr == addr)
134 				return ifp;
135 			if ((ifp->int_if_flags & IFF_BROADCAST)
136 			    && ifp->int_brdaddr == addr)
137 				return ifp;
138 
139 			/* Look for the longest approximate match.
140 			 */
141 			if (on_net(addr, ifp->int_net, ifp->int_mask)
142 			    && (maybe == 0
143 				|| ifp->int_mask > maybe->int_mask))
144 				maybe = ifp;
145 		}
146 	}
147 
148 	return maybe;
149 }
150 
151 
152 /* Return the classical netmask for an IP address.
153  */
154 naddr
std_mask(naddr addr)155 std_mask(naddr addr)			/* in network order */
156 {
157 	NTOHL(addr);			/* was a host, not a network */
158 
159 	if (addr == 0)			/* default route has mask 0 */
160 		return 0;
161 	if (IN_CLASSA(addr))
162 		return IN_CLASSA_NET;
163 	if (IN_CLASSB(addr))
164 		return IN_CLASSB_NET;
165 	return IN_CLASSC_NET;
166 }
167 
168 
169 /* Find the netmask that would be inferred by RIPv1 listeners
170  *	on the given interface for a given network.
171  *	If no interface is specified, look for the best fitting	interface.
172  */
173 naddr
ripv1_mask_net(naddr addr,struct interface * ifp)174 ripv1_mask_net(naddr addr,		/* in network byte order */
175 	       struct interface *ifp)	/* as seen on this interface */
176 {
177 	naddr mask = 0;
178 
179 	if (addr == 0)			/* default always has 0 mask */
180 		return mask;
181 
182 	if (ifp != 0) {
183 		/* If the target network is that of the associated interface
184 		 * on which it arrived, then use the netmask of the interface.
185 		 */
186 		if (on_net(addr, ifp->int_net, ifp->int_std_mask))
187 			mask = ifp->int_ripv1_mask;
188 
189 	} else {
190 		/* Examine all interfaces, and if it the target seems
191 		 * to have the same network number of an interface, use the
192 		 * netmask of that interface.  If there is more than one
193 		 * such interface, prefer the interface with the longest
194 		 * match.
195 		 */
196 		for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) {
197 			if (on_net(addr, ifp->int_std_net, ifp->int_std_mask)
198 			    && ifp->int_ripv1_mask > mask)
199 				mask = ifp->int_ripv1_mask;
200 		}
201 	}
202 
203 	/* Otherwise, make the classic A/B/C guess.
204 	 */
205 	if (mask == 0)
206 		mask = std_mask(addr);
207 
208 	return mask;
209 }
210 
211 
212 naddr
ripv1_mask_host(naddr addr,struct interface * ifp)213 ripv1_mask_host(naddr addr,		/* in network byte order */
214 		struct interface *ifp)	/* as seen on this interface */
215 {
216 	naddr mask = ripv1_mask_net(addr, ifp);
217 
218 
219 	/* If the computed netmask does not mask the address,
220 	 * then assume it is a host address
221 	 */
222 	if ((ntohl(addr) & ~mask) != 0)
223 		mask = HOST_MASK;
224 	return mask;
225 }
226 
227 
228 /* See if a IP address looks reasonable as a destination
229  */
230 int					/* 0=bad */
check_dst(naddr addr)231 check_dst(naddr addr)
232 {
233 	NTOHL(addr);
234 
235 	if (IN_CLASSA(addr)) {
236 		if (addr == 0)
237 			return 1;	/* default */
238 
239 		addr >>= IN_CLASSA_NSHIFT;
240 		return (addr != 0 && addr != IN_LOOPBACKNET);
241 	}
242 
243 	return (IN_CLASSB(addr) || IN_CLASSC(addr));
244 }
245 
246 
247 /* Delete an interface.
248  */
249 static void
ifdel(struct interface * ifp)250 ifdel(struct interface *ifp)
251 {
252 	struct ip_mreq m;
253 	struct interface *ifp1;
254 
255 
256 	trace_if("Del", ifp);
257 
258 	ifp->int_state |= IS_BROKE;
259 
260 	/* unlink the interface
261 	 */
262 	if (rip_sock_mcast == ifp)
263 		rip_sock_mcast = 0;
264 	if (ifp->int_next != 0)
265 		ifp->int_next->int_prev = ifp->int_prev;
266 	if (ifp->int_prev != 0)
267 		ifp->int_prev->int_next = ifp->int_next;
268 	else
269 		ifnet = ifp->int_next;
270 
271 	if (!(ifp->int_state & IS_ALIAS)) {
272 		/* delete aliases
273 		 */
274 		for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) {
275 			if (ifp1 != ifp
276 			    && !strcmp(ifp->int_name, ifp1->int_name))
277 				ifdel(ifp1);
278 		}
279 
280 		if ((ifp->int_if_flags & IFF_MULTICAST)
281 #ifdef MCAST_PPP_BUG
282 		    && !(ifp->int_if_flags & IFF_POINTOPOINT)
283 #endif
284 		    && rip_sock >= 0) {
285 			m.imr_multiaddr.s_addr = htonl(INADDR_RIP_GROUP);
286 			m.imr_interface.s_addr = ((ifp->int_if_flags
287 						   & IFF_POINTOPOINT)
288 						  ? ifp->int_dstaddr
289 						  : ifp->int_addr);
290 			if (setsockopt(rip_sock,IPPROTO_IP,IP_DROP_MEMBERSHIP,
291 				       &m, sizeof(m)) < 0
292 			    && errno != EADDRNOTAVAIL
293 			    && !TRACEACTIONS)
294 				LOGERR("setsockopt(IP_DROP_MEMBERSHIP RIP)");
295 		}
296 		if (ifp->int_rip_sock >= 0) {
297 			(void)close(ifp->int_rip_sock);
298 			ifp->int_rip_sock = -1;
299 			fix_select();
300 		}
301 
302 		tot_interfaces--;
303 		if (!IS_RIP_OFF(ifp->int_state))
304 			rip_interfaces--;
305 
306 		/* Zap all routes associated with this interface.
307 		 * Assume routes just using gateways beyond this interface will
308 		 * timeout naturally, and have probably already died.
309 		 */
310 		(void)rn_walktree(rhead, walk_bad, 0);
311 
312 		set_rdisc_mg(ifp, 0);
313 		if_bad_rdisc(ifp);
314 	}
315 
316 	free(ifp);
317 }
318 
319 
320 /* Mark an interface ill.
321  */
322 void
if_sick(struct interface * ifp)323 if_sick(struct interface *ifp)
324 {
325 	if (0 == (ifp->int_state & (IS_SICK | IS_BROKE))) {
326 		ifp->int_state |= IS_SICK;
327 		trace_if("Chg", ifp);
328 
329 		LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL);
330 	}
331 }
332 
333 
334 /* Mark an interface dead.
335  */
336 void
if_bad(struct interface * ifp)337 if_bad(struct interface *ifp)
338 {
339 	struct interface *ifp1;
340 
341 
342 	if (ifp->int_state & IS_BROKE)
343 		return;
344 
345 	LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL);
346 
347 	ifp->int_state |= (IS_BROKE | IS_SICK);
348 	ifp->int_state &= ~(IS_RIP_QUERIED | IS_ACTIVE);
349 	ifp->int_data.ts = 0;
350 
351 	trace_if("Chg", ifp);
352 
353 	if (!(ifp->int_state & IS_ALIAS)) {
354 		for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) {
355 			if (ifp1 != ifp
356 			    && !strcmp(ifp->int_name, ifp1->int_name))
357 				if_bad(ifp1);
358 		}
359 		(void)rn_walktree(rhead, walk_bad, 0);
360 		if_bad_rdisc(ifp);
361 	}
362 }
363 
364 
365 /* Mark an interface alive
366  */
367 int					/* 1=it was dead */
if_ok(struct interface * ifp,char * type)368 if_ok(struct interface *ifp,
369       char *type)
370 {
371 	struct interface *ifp1;
372 
373 
374 	if (!(ifp->int_state & IS_BROKE)) {
375 		if (ifp->int_state & IS_SICK) {
376 			trace_act("%sinterface %s to %s working better\n",
377 				  type,
378 				  ifp->int_name, naddr_ntoa(ifp->int_addr));
379 			ifp->int_state &= ~IS_SICK;
380 		}
381 		return 0;
382 	}
383 
384 	msglog("%sinterface %s to %s restored",
385 	       type, ifp->int_name, naddr_ntoa(ifp->int_addr));
386 	ifp->int_state &= ~(IS_BROKE | IS_SICK);
387 	ifp->int_data.ts = 0;
388 
389 	if (!(ifp->int_state & IS_ALIAS)) {
390 		for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) {
391 			if (ifp1 != ifp
392 			    && !strcmp(ifp->int_name, ifp1->int_name))
393 				if_ok(ifp1, type);
394 		}
395 		if_ok_rdisc(ifp);
396 	}
397 	return 1;
398 }
399 
400 
401 /* disassemble routing message
402  */
403 void
rt_xaddrs(struct rt_addrinfo * info,struct sockaddr * sa,struct sockaddr * lim,int addrs)404 rt_xaddrs(struct rt_addrinfo *info,
405 	  struct sockaddr *sa,
406 	  struct sockaddr *lim,
407 	  int addrs)
408 {
409 	int i;
410 #ifdef _HAVE_SA_LEN
411 	static struct sockaddr sa_zero;
412 #endif
413 #ifdef sgi
414 #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) \
415 		    : sizeof(__uint64_t))
416 #else
417 #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \
418 		    : sizeof(long))
419 #endif
420 
421 
422 	bzero(info, sizeof(*info));
423 	info->rti_addrs = addrs;
424 	for (i = 0; i < RTAX_MAX && sa < lim; i++) {
425 		if ((addrs & (1 << i)) == 0)
426 			continue;
427 #ifdef _HAVE_SA_LEN
428 		info->rti_info[i] = (sa->sa_len != 0) ? sa : &sa_zero;
429 		sa = (struct sockaddr *)((char*)(sa)
430 					 + ROUNDUP(sa->sa_len));
431 #else
432 		info->rti_info[i] = sa;
433 		sa = (struct sockaddr *)((char*)(sa)
434 					 + ROUNDUP(_FAKE_SA_LEN_DST(sa)));
435 #endif
436 	}
437 }
438 
439 
440 /* Find the network interfaces which have configured themselves.
441  *	This must be done regularly, if only for extra addresses
442  *	that come and go on interfaces.
443  */
444 void
ifinit(void)445 ifinit(void)
446 {
447 	static char *sysctl_buf;
448 	static size_t sysctl_buf_size = 0;
449 	uint complaints = 0;
450 	static u_int prev_complaints = 0;
451 #	define COMP_NOT_INET	0x001
452 #	define COMP_WIERD	0x002
453 #	define COMP_NOADDR	0x004
454 #	define COMP_BADADDR	0x008
455 #	define COMP_NODST	0x010
456 #	define COMP_NOBADR	0x020
457 #	define COMP_NOMASK	0x040
458 #	define COMP_DUP		0x080
459 #	define COMP_BAD_METRIC	0x100
460 #	define COMP_NETMASK	0x200
461 
462 	struct interface ifs, ifs0, *ifp, *ifp1;
463 	struct rt_entry *rt;
464 	size_t needed;
465 	int mib[6];
466 	struct if_msghdr *ifm;
467 	struct ifa_msghdr *ifam, *ifam_lim, *ifam2;
468 	struct sockaddr_dl *sdl;
469 	int in, ierr, out, oerr;
470 	struct intnet *intnetp;
471 	struct rt_addrinfo info;
472 #ifdef SIOCGIFMETRIC
473 	struct ifreq ifr;
474 #endif
475 
476 
477 	ifinit_timer.tv_sec = now.tv_sec + (supplier
478 					    ? CHECK_ACT_INTERVAL
479 					    : CHECK_QUIET_INTERVAL);
480 
481 	/* mark all interfaces so we can get rid of thost that disappear */
482 	for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next)
483 		ifp->int_state &= ~(IS_CHECKED | IS_DUP);
484 
485 	/* Fetch the interface list, without too many system calls
486 	 * since we do it repeatedly.
487 	 */
488 	mib[0] = CTL_NET;
489 	mib[1] = PF_ROUTE;
490 	mib[2] = 0;
491 	mib[3] = AF_INET;
492 	mib[4] = NET_RT_IFLIST;
493 	mib[5] = 0;
494 	for (;;) {
495 		if ((needed = sysctl_buf_size) != 0) {
496 			if (sysctl(mib, 6, sysctl_buf,&needed, 0, 0) >= 0)
497 				break;
498 			if (errno != ENOMEM && errno != EFAULT)
499 				BADERR(1, "ifinit: get interface table");
500 			free(sysctl_buf);
501 			needed = 0;
502 		}
503 		if (sysctl(mib, 6, 0, &needed, 0, 0) < 0)
504 			BADERR(1,"ifinit: route-sysctl-estimate");
505 		sysctl_buf = rtmalloc(sysctl_buf_size = needed, "ifinit");
506 	}
507 
508 	ifam_lim = (struct ifa_msghdr *)(sysctl_buf + needed);
509 	for (ifam = (struct ifa_msghdr *)sysctl_buf;
510 	     ifam < ifam_lim;
511 	     ifam = ifam2) {
512 
513 		ifam2 = (struct ifa_msghdr*)((char*)ifam + ifam->ifam_msglen);
514 
515 		if (ifam->ifam_type == RTM_IFINFO) {
516 			ifm = (struct if_msghdr *)ifam;
517 			/* make prototype structure for the IP aliases
518 			 */
519 			bzero(&ifs0, sizeof(ifs0));
520 			ifs0.int_rip_sock = -1;
521 			ifs0.int_index = ifm->ifm_index;
522 			ifs0.int_if_flags = ifm->ifm_flags;
523 			ifs0.int_state = IS_CHECKED;
524 			ifs0.int_act_time = now.tv_sec;
525 			ifs0.int_data.ts = now.tv_sec;
526 			ifs0.int_data.ipackets = ifm->ifm_data.ifi_ipackets;
527 			ifs0.int_data.ierrors = ifm->ifm_data.ifi_ierrors;
528 			ifs0.int_data.opackets = ifm->ifm_data.ifi_opackets;
529 			ifs0.int_data.oerrors = ifm->ifm_data.ifi_oerrors;
530 #ifdef sgi
531 			ifs0.int_data.odrops = ifm->ifm_data.ifi_odrops;
532 #endif
533 			sdl = (struct sockaddr_dl *)(ifm + 1);
534 			sdl->sdl_data[sdl->sdl_nlen] = 0;
535 			continue;
536 		}
537 		if (ifam->ifam_type != RTM_NEWADDR) {
538 			logbad(1,"ifinit: out of sync");
539 			continue;
540 		}
541 
542 		rt_xaddrs(&info, (struct sockaddr *)(ifam+1),
543 			  (struct sockaddr *)ifam2,
544 			  ifam->ifam_addrs);
545 
546 		if (INFO_IFA(&info) == 0) {
547 			if (iff_alive(ifs.int_if_flags)) {
548 				if (!(prev_complaints & COMP_NOADDR))
549 					msglog("%s has no address",
550 					       sdl->sdl_data);
551 				complaints |= COMP_NOADDR;
552 			}
553 			continue;
554 		}
555 		if (INFO_IFA(&info)->sa_family != AF_INET) {
556 			if (iff_alive(ifs.int_if_flags)) {
557 				if (!(prev_complaints & COMP_NOT_INET))
558 					trace_act("%s: not AF_INET\n",
559 						  sdl->sdl_data);
560 				complaints |= COMP_NOT_INET;
561 			}
562 			continue;
563 		}
564 
565 		memmove(&ifs, &ifs0, sizeof(ifs0));
566 		ifs0.int_state |= IS_ALIAS;	/* next will be an alias */
567 
568 		ifs.int_addr = S_ADDR(INFO_IFA(&info));
569 
570 		if (ntohl(ifs.int_addr)>>24 == 0
571 		    || ntohl(ifs.int_addr)>>24 == 0xff) {
572 			if (iff_alive(ifs.int_if_flags)) {
573 				if (!(prev_complaints & COMP_BADADDR))
574 					msglog("%s has a bad address",
575 					       sdl->sdl_data);
576 				complaints |= COMP_BADADDR;
577 			}
578 			continue;
579 		}
580 
581 		if (ifs.int_if_flags & IFF_BROADCAST) {
582 			if (INFO_MASK(&info) == 0) {
583 				if (iff_alive(ifs.int_if_flags)) {
584 					if (!(prev_complaints & COMP_NOMASK))
585 						msglog("%s has no netmask",
586 						       sdl->sdl_data);
587 					complaints |= COMP_NOMASK;
588 				}
589 				continue;
590 			}
591 			ifs.int_dstaddr = ifs.int_addr;
592 			ifs.int_mask = ntohl(S_ADDR(INFO_MASK(&info)));
593 			ifs.int_ripv1_mask = ifs.int_mask;
594 			ifs.int_net = ntohl(ifs.int_addr) & ifs.int_mask;
595 			ifs.int_std_mask = std_mask(ifs.int_addr);
596 			if (ifs.int_mask != ifs.int_std_mask)
597 				ifs.int_state |= IS_SUBNET;
598 
599 			if (INFO_BRD(&info) == 0) {
600 				if (iff_alive(ifs.int_if_flags)) {
601 					if (!(prev_complaints & COMP_NOBADR))
602 						msglog("%s has no"
603 						       " broadcast address",
604 						       sdl->sdl_data);
605 					complaints |= COMP_NOBADR;
606 				}
607 				continue;
608 			}
609 			ifs.int_brdaddr = S_ADDR(INFO_BRD(&info));
610 
611 		} else if (ifs.int_if_flags & IFF_POINTOPOINT) {
612 			if (INFO_BRD(&info) == 0
613 			    || INFO_BRD(&info)->sa_family != AF_INET) {
614 				if (iff_alive(ifs.int_if_flags)) {
615 					if (!(prev_complaints & COMP_NODST))
616 						msglog("%s has a bad"
617 						       " destination address",
618 						       sdl->sdl_data);
619 					complaints |= COMP_NODST;
620 				}
621 				continue;
622 			}
623 			ifs.int_dstaddr = S_ADDR(INFO_BRD(&info));
624 			if (ntohl(ifs.int_dstaddr)>>24 == 0
625 			    || ntohl(ifs.int_dstaddr)>>24 == 0xff) {
626 				if (iff_alive(ifs.int_if_flags)) {
627 					if (!(prev_complaints & COMP_NODST))
628 						msglog("%s has a bad"
629 						       " destination address",
630 						       sdl->sdl_data);
631 					complaints |= COMP_NODST;
632 				}
633 				continue;
634 			}
635 			ifs.int_mask = HOST_MASK;
636 			ifs.int_ripv1_mask = ntohl(S_ADDR(INFO_MASK(&info)));
637 			ifs.int_net = ntohl(ifs.int_dstaddr);
638 			ifs.int_std_mask = std_mask(ifs.int_dstaddr);
639 
640 		} else if (ifs.int_if_flags & IFF_LOOPBACK) {
641 			ifs.int_state |= IS_PASSIVE | IS_NO_RIP;
642 			ifs.int_dstaddr = ifs.int_addr;
643 			ifs.int_mask = HOST_MASK;
644 			ifs.int_ripv1_mask = HOST_MASK;
645 			ifs.int_net = ntohl(ifs.int_dstaddr);
646 			ifs.int_std_mask = std_mask(ifs.int_dstaddr);
647 			if (!foundloopback) {
648 				foundloopback = 1;
649 				loopaddr = ifs.int_addr;
650 			}
651 
652 		} else {
653 			if (!(prev_complaints & COMP_WIERD))
654 				trace_act("%s is neither broadcast"
655 					  " nor point-to-point nor loopback",
656 					  sdl->sdl_data);
657 			complaints |= COMP_WIERD;
658 			continue;
659 		}
660 		ifs.int_std_net = ifs.int_net & ifs.int_std_mask;
661 		ifs.int_std_addr = htonl(ifs.int_std_net);
662 
663 		/* Use a minimum metric of one.  Treat the interface metric
664 		 * (default 0) as an increment to the hop count of one.
665 		 *
666 		 * The metric obtained from the routing socket dump of
667 		 * interface addresses is wrong.  It is not set by the
668 		 * SIOCSIFMETRIC ioctl.
669 		 */
670 #ifdef SIOCGIFMETRIC
671 		strncpy(ifr.ifr_name, sdl->sdl_data, sizeof(ifr.ifr_name));
672 		if (ioctl(rt_sock, SIOCGIFMETRIC, &ifr) < 0) {
673 			DBGERR(1, "ioctl(SIOCGIFMETRIC)");
674 			ifs.int_metric = 0;
675 		} else {
676 			ifs.int_metric = ifr.ifr_metric;
677 		}
678 #else
679 		ifs.int_metric = ifam->ifam_metric;
680 #endif
681 		if (ifs.int_metric > HOPCNT_INFINITY) {
682 			ifs.int_metric = 0;
683 			if (!(prev_complaints & COMP_BAD_METRIC)
684 			    && iff_alive(ifs.int_if_flags)) {
685 				complaints |= COMP_BAD_METRIC;
686 				msglog("%s has a metric of %d",
687 				       sdl->sdl_data, ifs.int_metric);
688 			}
689 		}
690 
691 		/* See if this is a familiar interface.
692 		 * If so, stop worrying about it if it is the same.
693 		 * Start it over if it now is to somewhere else, as happens
694 		 * frequently with PPP and SLIP.
695 		 */
696 		ifp = ifwithname(sdl->sdl_data, ((ifs.int_state & IS_ALIAS)
697 						 ? ifs.int_addr
698 						 : 0));
699 		if (ifp != 0) {
700 			ifp->int_state |= IS_CHECKED;
701 
702 			if (0 != ((ifp->int_if_flags ^ ifs.int_if_flags)
703 				  & (IFF_BROADCAST
704 				     | IFF_LOOPBACK
705 				     | IFF_POINTOPOINT
706 				     | IFF_MULTICAST))
707 			    || 0 != ((ifp->int_state ^ ifs.int_state)
708 				     & IS_ALIAS)
709 			    || ifp->int_addr != ifs.int_addr
710 			    || ifp->int_brdaddr != ifs.int_brdaddr
711 			    || ifp->int_dstaddr != ifs.int_dstaddr
712 			    || ifp->int_mask != ifs.int_mask
713 			    || ifp->int_metric != ifs.int_metric) {
714 				/* Forget old information about
715 				 * a changed interface.
716 				 */
717 				trace_act("interface %s has changed\n",
718 					  ifp->int_name);
719 				ifdel(ifp);
720 				ifp = 0;
721 			}
722 		}
723 
724 		if (ifp != 0) {
725 			/* The primary representative of an alias worries
726 			 * about how things are working.
727 			 */
728 			if (ifp->int_state & IS_ALIAS)
729 				continue;
730 
731 			/* note interfaces that have been turned off
732 			 */
733 			if (!iff_alive(ifs.int_if_flags)) {
734 				if (iff_alive(ifp->int_if_flags)) {
735 					msglog("interface %s to %s turned off",
736 					       ifp->int_name,
737 					       naddr_ntoa(ifp->int_addr));
738 					if_bad(ifp);
739 					ifp->int_if_flags &= ~IFF_UP_RUNNING;
740 				}
741 				continue;
742 			}
743 			/* or that were off and are now ok */
744 			if (!iff_alive(ifp->int_if_flags)) {
745 				ifp->int_if_flags |= IFF_UP_RUNNING;
746 				(void)if_ok(ifp, "");
747 			}
748 
749 			/* If it has been long enough,
750 			 * see if the interface is broken.
751 			 */
752 			if (now.tv_sec < ifp->int_data.ts+CHECK_BAD_INTERVAL)
753 				continue;
754 
755 			in = ifs.int_data.ipackets - ifp->int_data.ipackets;
756 			ierr = ifs.int_data.ierrors - ifp->int_data.ierrors;
757 			out = ifs.int_data.opackets - ifp->int_data.opackets;
758 			oerr = ifs.int_data.oerrors - ifp->int_data.oerrors;
759 #ifdef sgi
760 			/* Through at least IRIX 6.2, PPP and SLIP
761 			 * count packets dropped by  the filters.
762 			 * But FDDI rings stuck non-operational count
763 			 * dropped packets as they wait for improvement.
764 			 */
765 			if (!(ifp->int_if_flags & IFF_POINTOPOINT))
766 				oerr += (ifs.int_data.odrops
767 					 - ifp->int_data.odrops);
768 #endif
769 			/* If the interface just awoke, restart the counters.
770 			 */
771 			if (ifp->int_data.ts == 0) {
772 				ifp->int_data = ifs.int_data;
773 				continue;
774 			}
775 			ifp->int_data = ifs.int_data;
776 
777 			/* Withhold judgement when the short error
778 			 * counters wrap or the interface is reset.
779 			 */
780 			if (ierr < 0 || in < 0 || oerr < 0 || out < 0) {
781 				LIM_SEC(ifinit_timer,
782 					now.tv_sec+CHECK_BAD_INTERVAL);
783 				continue;
784 			}
785 
786 			/* Withhold judgement when there is no traffic
787 			 */
788 			if (in == 0 && out == 0 && ierr == 0 && oerr == 0)
789 				continue;
790 
791 			/* It is bad if input or output is not working.
792 			 * Require presistent problems before marking it dead.
793 			 */
794 			if ((in <= ierr && ierr > 0)
795 			    || (out <= oerr && oerr > 0)) {
796 				if (!(ifp->int_state & IS_SICK)) {
797 					trace_act("interface %s to %s"
798 						  " sick: in=%d ierr=%d"
799 						  " out=%d oerr=%d\n",
800 						  ifp->int_name,
801 						  naddr_ntoa(ifp->int_addr),
802 						  in, ierr, out, oerr);
803 					if_sick(ifp);
804 					continue;
805 				}
806 				if (!(ifp->int_state & IS_BROKE)) {
807 					msglog("interface %s to %s bad:"
808 					       " in=%d ierr=%d out=%d oerr=%d",
809 					       ifp->int_name,
810 					       naddr_ntoa(ifp->int_addr),
811 					       in, ierr, out, oerr);
812 					if_bad(ifp);
813 				}
814 				continue;
815 			}
816 
817 			/* otherwise, it is active and healthy
818 			 */
819 			ifp->int_act_time = now.tv_sec;
820 			(void)if_ok(ifp, "");
821 			continue;
822 		}
823 
824 		/* This is a new interface.
825 		 * If it is dead, forget it.
826 		 */
827 		if (!iff_alive(ifs.int_if_flags))
828 			continue;
829 
830 		/* See if it duplicates an existing interface.
831 		 */
832 		for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) {
833 			if (ifp->int_mask != ifs.int_mask)
834 				continue;
835 			if (((ifp->int_addr != ifs.int_addr
836 			      && ifs.int_mask != HOST_MASK)
837 			     || (ifp->int_dstaddr != ifs.int_dstaddr
838 				 && ifs.int_mask == HOST_MASK)))
839 				continue;
840 			if (!iff_alive(ifp->int_if_flags))
841 				continue;
842 			/* Let one of our real interfaces be marked
843 			 * passive.
844 			 */
845 			if ((ifp->int_state & IS_PASSIVE)
846 			    && !(ifp->int_state & IS_EXTERNAL))
847 				continue;
848 
849 			/* It does duplicate an existing interface,
850 			 * so complain about it, mark the other one
851 			 * duplicated, and for get this one.
852 			 */
853 			if (!(prev_complaints & COMP_DUP)) {
854 				complaints |= COMP_DUP;
855 				msglog("%s is duplicated by %s at %s",
856 				       sdl->sdl_data, ifp->int_name,
857 				       naddr_ntoa(ifp->int_addr));
858 			}
859 			ifp->int_state |= IS_DUP;
860 			break;
861 		}
862 		if (ifp != 0)
863 			continue;
864 
865 		/* It is new and ok.  So make it real
866 		 */
867 		strncpy(ifs.int_name, sdl->sdl_data,
868 			MIN(sizeof(ifs.int_name)-1, sdl->sdl_nlen));
869 		get_parms(&ifs);
870 
871 		/* Add it to the list of interfaces
872 		 */
873 		ifp = (struct interface *)rtmalloc(sizeof(*ifp), "ifinit");
874 		memmove(ifp, &ifs, sizeof(*ifp));
875 		if (ifnet != 0) {
876 			ifp->int_next = ifnet;
877 			ifnet->int_prev = ifp;
878 		}
879 		ifnet = ifp;
880 		trace_if("Add", ifp);
881 
882 		/* Notice likely bad netmask.
883 		 */
884 		if (!(prev_complaints & COMP_NETMASK)
885 		    && !(ifp->int_if_flags & IFF_POINTOPOINT)) {
886 			for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) {
887 				if (ifp1->int_mask == ifp->int_mask)
888 					continue;
889 				if (ifp1->int_if_flags & IFF_POINTOPOINT)
890 					continue;
891 				if (on_net(ifp->int_addr,
892 					   ifp1->int_net, ifp1->int_mask)
893 				    || on_net(ifp1->int_addr,
894 					      ifp->int_net, ifp->int_mask)) {
895 					msglog("possible netmask problem"
896 					       " betwen %s:%s and %s:%s",
897 					       ifp->int_name,
898 					       addrname(htonl(ifp->int_net),
899 							ifp->int_mask, 1),
900 					       ifp1->int_name,
901 					       addrname(htonl(ifp1->int_net),
902 							ifp1->int_mask, 1));
903 					complaints |= COMP_NETMASK;
904 				}
905 			}
906 		}
907 
908 		/* Count the # of directly connected networks.
909 		 */
910 		if (!(ifp->int_state & IS_ALIAS)) {
911 			if (!(ifp->int_if_flags & IFF_LOOPBACK))
912 				tot_interfaces++;
913 			if (!IS_RIP_OFF(ifp->int_state))
914 				rip_interfaces++;
915 		}
916 
917 		if_ok_rdisc(ifp);
918 		rip_on(ifp);
919 	}
920 
921 	/* If we are multi-homed and have at least one interface
922 	 * listening to RIP, then output by default.
923 	 */
924 	if (!supplier_set && rip_interfaces > 1)
925 		set_supplier();
926 
927 	/* If we are multi-homed, optionally advertise a route to
928 	 * our main address.
929 	 */
930 	if (advertise_mhome
931 	    || (tot_interfaces > 1
932 		&& mhome
933 		&& (ifp = ifwithaddr(myaddr, 0, 0)) != 0
934 		&& foundloopback)) {
935 		advertise_mhome = 1;
936 		rt = rtget(myaddr, HOST_MASK);
937 		if (rt != 0) {
938 			if (rt->rt_ifp != ifp
939 			    || rt->rt_router != loopaddr) {
940 				rtdelete(rt);
941 				rt = 0;
942 			} else {
943 				rtchange(rt, rt->rt_state | RS_MHOME,
944 					 loopaddr, loopaddr,
945 					 0, 0, ifp, rt->rt_time, 0);
946 			}
947 		}
948 		if (rt == 0)
949 			rtadd(myaddr, HOST_MASK, loopaddr, loopaddr,
950 			      0, 0, RS_MHOME, ifp);
951 	}
952 
953 	for (ifp = ifnet; ifp != 0; ifp = ifp1) {
954 		ifp1 = ifp->int_next;	/* because we may delete it */
955 
956 		/* Forget any interfaces that have disappeared.
957 		 */
958 		if (!(ifp->int_state & (IS_CHECKED | IS_REMOTE))) {
959 			trace_act("interface %s has disappeared\n",
960 				  ifp->int_name);
961 			ifdel(ifp);
962 			continue;
963 		}
964 
965 		if ((ifp->int_state & IS_BROKE)
966 		    && !(ifp->int_state & IS_PASSIVE))
967 			LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL);
968 
969 		/* If we ever have a RIPv1 interface, assume we always will.
970 		 * It might come back if it ever goes away.
971 		 */
972 		if (!(ifp->int_state & IS_NO_RIPV1_OUT) && supplier)
973 			have_ripv1_out = 1;
974 		if (!(ifp->int_state & IS_NO_RIPV1_IN))
975 			have_ripv1_in = 1;
976 	}
977 
978 	for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) {
979 		/* Ensure there is always a network route for interfaces,
980 		 * after any dead interfaces have been deleted, which
981 		 * might affect routes for point-to-point links.
982 		 */
983 		addrouteforif(ifp);
984 
985 		/* Add routes to the local end of point-to-point interfaces
986 		 * using loopback.
987 		 */
988 		if ((ifp->int_if_flags & IFF_POINTOPOINT)
989 		    && !(ifp->int_state & IS_REMOTE)
990 		    && foundloopback) {
991 			/* Delete any routes to the network address through
992 			 * foreign routers. Remove even static routes.
993 			 */
994 			del_static(ifp->int_addr, HOST_MASK, 0);
995 			rt = rtget(ifp->int_addr, HOST_MASK);
996 			if (rt != 0 && rt->rt_router != loopaddr) {
997 				rtdelete(rt);
998 				rt = 0;
999 			}
1000 			if (rt != 0) {
1001 				if (!(rt->rt_state & RS_LOCAL)
1002 				    || rt->rt_metric > ifp->int_metric) {
1003 					ifp1 = ifp;
1004 				} else {
1005 					ifp1 = rt->rt_ifp;
1006 				}
1007 				rtchange(rt,((rt->rt_state & ~RS_NET_SYN)
1008 					     | (RS_IF|RS_LOCAL)),
1009 					 loopaddr, loopaddr,
1010 					 0, 0, ifp1, rt->rt_time, 0);
1011 			} else {
1012 				rtadd(ifp->int_addr, HOST_MASK,
1013 				      loopaddr, loopaddr,
1014 				      0, 0, (RS_IF | RS_LOCAL), ifp);
1015 			}
1016 		}
1017 	}
1018 
1019 	/* add the authority routes */
1020 	for (intnetp = intnets; intnetp!=0; intnetp = intnetp->intnet_next) {
1021 		rt = rtget(intnetp->intnet_addr, intnetp->intnet_mask);
1022 		if (rt != 0
1023 		    && !(rt->rt_state & RS_NO_NET_SYN)
1024 		    && !(rt->rt_state & RS_NET_INT)) {
1025 			rtdelete(rt);
1026 			rt = 0;
1027 		}
1028 		if (rt == 0)
1029 			rtadd(intnetp->intnet_addr, intnetp->intnet_mask,
1030 			      loopaddr, loopaddr, intnetp->intnet_metric-1,
1031 			      0, RS_NET_SYN | RS_NET_INT, 0);
1032 	}
1033 
1034 	prev_complaints = complaints;
1035 }
1036 
1037 
1038 static void
check_net_syn(struct interface * ifp)1039 check_net_syn(struct interface *ifp)
1040 {
1041 	struct rt_entry *rt;
1042 
1043 
1044 	/* Turn on the need to automatically synthesize a network route
1045 	 * for this interface only if we are running RIPv1 on some other
1046 	 * interface that is on a different class-A,B,or C network.
1047 	 */
1048 	if (have_ripv1_out || have_ripv1_in) {
1049 		ifp->int_state |= IS_NEED_NET_SYN;
1050 		rt = rtget(ifp->int_std_addr, ifp->int_std_mask);
1051 		if (rt != 0
1052 		    && 0 == (rt->rt_state & RS_NO_NET_SYN)
1053 		    && (!(rt->rt_state & RS_NET_SYN)
1054 			|| rt->rt_metric > ifp->int_metric)) {
1055 			rtdelete(rt);
1056 			rt = 0;
1057 		}
1058 		if (rt == 0)
1059 			rtadd(ifp->int_std_addr, ifp->int_std_mask,
1060 			      ifp->int_addr, ifp->int_addr,
1061 			      ifp->int_metric, 0, RS_NET_SYN, ifp);
1062 
1063 	} else {
1064 		ifp->int_state &= ~IS_NEED_NET_SYN;
1065 
1066 		rt = rtget(ifp->int_std_addr,
1067 			   ifp->int_std_mask);
1068 		if (rt != 0
1069 		    && (rt->rt_state & RS_NET_SYN)
1070 		    && rt->rt_ifp == ifp)
1071 			rtbad_sub(rt);
1072 	}
1073 }
1074 
1075 
1076 /* Add route for interface if not currently installed.
1077  * Create route to other end if a point-to-point link,
1078  * otherwise a route to this (sub)network.
1079  */
1080 void
addrouteforif(struct interface * ifp)1081 addrouteforif(struct interface *ifp)
1082 {
1083 	struct rt_entry *rt;
1084 	naddr dst, gate;
1085 
1086 
1087 	/* skip sick interfaces
1088 	 */
1089 	if (ifp->int_state & IS_BROKE)
1090 		return;
1091 
1092 	/* If the interface on a subnet, then install a RIPv1 route to
1093 	 * the network as well (unless it is sick).
1094 	 */
1095 	if (ifp->int_state & IS_SUBNET)
1096 		check_net_syn(ifp);
1097 
1098 	if (ifp->int_state & IS_REMOTE) {
1099 		dst = ifp->int_addr;
1100 		gate = ifp->int_dstaddr;
1101 		/* If we are going to send packets to the gateway,
1102 		 * it must be reachable using our physical interfaces
1103 		 */
1104 		if (!(ifp->int_state & IS_EXTERNAL)
1105 		    && !rtfind(ifp->int_dstaddr)
1106 		    && ifp->int_transitions == 0) {
1107 			msglog("unreachable gateway %s in "
1108 			       _PATH_GATEWAYS" entry %s",
1109 			       naddr_ntoa(gate), ifp->int_name);
1110 			return;
1111 		}
1112 
1113 	} else {
1114 		dst = (0 != (ifp->int_if_flags & (IFF_POINTOPOINT
1115 						  | IFF_LOOPBACK))
1116 		       ? ifp->int_dstaddr
1117 		       : htonl(ifp->int_net));
1118 		gate = ifp->int_addr;
1119 	}
1120 
1121 	/* We are finished if the correct main interface route exists.
1122 	 * The right route must be for the right interface, not synthesized
1123 	 * from a subnet, be a "gateway" or not as appropriate, and so forth.
1124 	 */
1125 	del_static(dst, ifp->int_mask, 0);
1126 	rt = rtget(dst, ifp->int_mask);
1127 	if (rt != 0) {
1128 		if ((rt->rt_ifp != ifp
1129 		     || rt->rt_router != ifp->int_addr)
1130 		    && (!(ifp->int_state & IS_DUP)
1131 			|| rt->rt_ifp == 0
1132 			|| (rt->rt_ifp->int_state & IS_BROKE))) {
1133 			rtdelete(rt);
1134 			rt = 0;
1135 		} else {
1136 			rtchange(rt, ((rt->rt_state | RS_IF)
1137 				      & ~(RS_NET_SYN | RS_LOCAL)),
1138 				 ifp->int_addr, ifp->int_addr,
1139 				 ifp->int_metric, 0, ifp, now.tv_sec, 0);
1140 		}
1141 	}
1142 	if (rt == 0) {
1143 		if (ifp->int_transitions++ > 0)
1144 			trace_act("re-install interface %s\n",
1145 				  ifp->int_name);
1146 
1147 		rtadd(dst, ifp->int_mask, gate, gate,
1148 		      ifp->int_metric, 0, RS_IF, ifp);
1149 	}
1150 }
1151