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