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