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