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