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