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