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