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