if.c revision 37908
1119419Sobrien/*
286752Sfjoe * Copyright (c) 1983, 1993
386752Sfjoe *	The Regents of the University of California.  All rights reserved.
486752Sfjoe *
586752Sfjoe * Redistribution and use in source and binary forms, with or without
686752Sfjoe * modification, are permitted provided that the following conditions
786752Sfjoe * are met:
886752Sfjoe * 1. Redistributions of source code must retain the above copyright
986752Sfjoe *    notice, this list of conditions and the following disclaimer.
1086752Sfjoe * 2. Redistributions in binary form must reproduce the above copyright
1186752Sfjoe *    notice, this list of conditions and the following disclaimer in the
1286752Sfjoe *    documentation and/or other materials provided with the distribution.
1386752Sfjoe * 3. All advertising materials mentioning features or use of this software
1486752Sfjoe *    must display the following acknowledgement:
1586752Sfjoe *	This product includes software developed by the University of
1686752Sfjoe *	California, Berkeley and its contributors.
1786752Sfjoe * 4. Neither the name of the University nor the names of its contributors
1886752Sfjoe *    may be used to endorse or promote products derived from this software
1986752Sfjoe *    without specific prior written permission.
2086752Sfjoe *
2186752Sfjoe * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2286752Sfjoe * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2386752Sfjoe * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2486752Sfjoe * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2586752Sfjoe * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2686752Sfjoe * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2786752Sfjoe * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28119419Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29119419Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30119419Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3186752Sfjoe * SUCH DAMAGE.
3286752Sfjoe */
3386752Sfjoe
3486752Sfjoe#ifndef lint
3586752Sfjoe#if 0
3686752Sfjoestatic char sccsid[] = "@(#)if.c	8.1 (Berkeley) 6/5/93";
3786752Sfjoe#endif
3886752Sfjoestatic const char rcsid[] =
3986752Sfjoe	"$Id$";
4086752Sfjoe#endif /* not lint */
4186752Sfjoe
4286752Sfjoe#include "defs.h"
4386752Sfjoe#include "pathnames.h"
4486752Sfjoe
4586752Sfjoestruct interface *ifnet;		/* all interfaces */
46119287Simp
47119287Simp/* hash table for all interfaces, big enough to tolerate ridiculous
4886752Sfjoe * numbers of IP aliases.  Crazy numbers of aliases such as 7000
4986752Sfjoe * still will not do well, but not just in looking up interfaces
5086752Sfjoe * by name or address.
5186752Sfjoe */
5286752Sfjoe#define AHASH_LEN 211			/* must be prime */
5386752Sfjoe#define AHASH(a) &ahash_tbl[(a)%AHASH_LEN]
54180263Sjhbstruct interface *ahash_tbl[AHASH_LEN];
5586752Sfjoe
5686752Sfjoe#define BHASH_LEN 211			/* must be prime */
5786752Sfjoe#define BHASH(a) &bhash_tbl[(a)%BHASH_LEN]
5886752Sfjoestruct interface *bhash_tbl[BHASH_LEN];
5986752Sfjoe
60180263Sjhbstruct interface *remote_if;		/* remote interfaces */
6186752Sfjoe
6286752Sfjoe/* hash for physical interface names.
6386752Sfjoe * Assume there are never more 100 or 200 real interfaces, and that
6486752Sfjoe * aliases are put on the end of the hash chains.
6586752Sfjoe */
6686752Sfjoe#define NHASH_LEN 97
6786752Sfjoestruct interface *nhash_tbl[NHASH_LEN];
6886752Sfjoe
6986752Sfjoeint	tot_interfaces;			/* # of remote and local interfaces */
7086752Sfjoeint	rip_interfaces;			/* # of interfaces doing RIP */
7186752Sfjoeint	foundloopback;			/* valid flag for loopaddr */
72113506Smdoddnaddr	loopaddr;			/* our address on loopback */
73113506Smdodd
7486752Sfjoestruct timeval ifinit_timer;
7586752Sfjoestatic struct timeval last_ifinit;
7686752Sfjoe
7786752Sfjoeint	have_ripv1_out;			/* have a RIPv1 interface */
7886752Sfjoeint	have_ripv1_in;
7986752Sfjoe
80180263Sjhb
8186752Sfjoestatic struct interface**
82101393Sfjoenhash(register char *p)
83101393Sfjoe{
8486752Sfjoe	register u_int i;
8586752Sfjoe
8686752Sfjoe	for (i = 0; *p != '\0'; p++) {
8786752Sfjoe		i = ((i<<1) & 0x7fffffff) | ((i>>31) & 1);
8886752Sfjoe		i ^= *p;
8986752Sfjoe	}
90101400Sfjoe	return &nhash_tbl[i % NHASH_LEN];
9186752Sfjoe}
9286752Sfjoe
9386752Sfjoe
9486752Sfjoe/* Link a new interface into the lists and hash tables.
9586752Sfjoe */
9686752Sfjoevoid
97119690Sjhbif_link(struct interface *ifp)
9886752Sfjoe{
9986752Sfjoe	struct interface **hifp;
10086752Sfjoe
101180263Sjhb	ifp->int_prev = &ifnet;
10286752Sfjoe	ifp->int_next = ifnet;
10386752Sfjoe	if (ifnet != 0)
10486752Sfjoe		ifnet->int_prev = &ifp->int_next;
10586752Sfjoe	ifnet = ifp;
10686752Sfjoe
107101400Sfjoe	hifp = AHASH(ifp->int_addr);
108101400Sfjoe	ifp->int_ahash_prev = hifp;
109101400Sfjoe	if ((ifp->int_ahash = *hifp) != 0)
110101400Sfjoe		(*hifp)->int_ahash_prev = &ifp->int_ahash;
11186752Sfjoe	*hifp = ifp;
112180263Sjhb
11386752Sfjoe	if (ifp->int_if_flags & IFF_BROADCAST) {
11486752Sfjoe		hifp = BHASH(ifp->int_brdaddr);
11586752Sfjoe		ifp->int_bhash_prev = hifp;
11686752Sfjoe		if ((ifp->int_bhash = *hifp) != 0)
11786752Sfjoe			(*hifp)->int_bhash_prev = &ifp->int_bhash;
11886752Sfjoe		*hifp = ifp;
11986752Sfjoe	}
12086752Sfjoe
12186752Sfjoe	if (ifp->int_state & IS_REMOTE) {
12286752Sfjoe		ifp->int_rlink_prev = &remote_if;
12386752Sfjoe		ifp->int_rlink = remote_if;
12486752Sfjoe		if (remote_if != 0)
12586752Sfjoe			remote_if->int_rlink_prev = &ifp->int_rlink;
12686752Sfjoe		remote_if = ifp;
12786752Sfjoe	}
12886752Sfjoe
129180263Sjhb	hifp = nhash(ifp->int_name);
13086752Sfjoe	if (ifp->int_state & IS_ALIAS) {
131127135Snjl		/* put aliases on the end of the hash chain */
132127135Snjl		while (*hifp != 0)
13386752Sfjoe			hifp = &(*hifp)->int_nhash;
134180263Sjhb	}
135180263Sjhb	ifp->int_nhash_prev = hifp;
13686752Sfjoe	if ((ifp->int_nhash = *hifp) != 0)
13786752Sfjoe		(*hifp)->int_nhash_prev = &ifp->int_nhash;
13886752Sfjoe	*hifp = ifp;
13986752Sfjoe}
14086752Sfjoe
14186752Sfjoe
142180263Sjhb/* Find the interface with an address
143180263Sjhb */
144180263Sjhbstruct interface *
145180263Sjhbifwithaddr(naddr addr,
146180263Sjhb	   int	bcast,			/* notice IFF_BROADCAST address */
147180263Sjhb	   int	remote)			/* include IS_REMOTE interfaces */
148180263Sjhb{
149180263Sjhb	struct interface *ifp, *possible = 0;
150180263Sjhb
151180263Sjhb	remote = (remote == 0) ? IS_REMOTE : 0;
152180263Sjhb
153180263Sjhb	for (ifp = *AHASH(addr); ifp; ifp = ifp->int_ahash) {
154180263Sjhb		if (ifp->int_addr != addr)
155180263Sjhb			continue;
156180263Sjhb		if ((ifp->int_state & remote) != 0)
157180263Sjhb			continue;
158180263Sjhb		if ((ifp->int_state & (IS_BROKE | IS_PASSIVE)) == 0)
159180263Sjhb			return ifp;
160180263Sjhb		possible = ifp;
161180263Sjhb	}
162180263Sjhb
163180263Sjhb	if (possible || !bcast)
164180263Sjhb		return possible;
165180263Sjhb
166180263Sjhb	for (ifp = *BHASH(addr); ifp; ifp = ifp->int_bhash) {
167180263Sjhb		if (ifp->int_brdaddr != addr)
16886752Sfjoe			continue;
16986752Sfjoe		if ((ifp->int_state & remote) != 0)
17086752Sfjoe			continue;
171180263Sjhb		if ((ifp->int_state & (IS_BROKE | IS_PASSIVE)) == 0)
17286752Sfjoe			return ifp;
17386752Sfjoe		possible = ifp;
17486752Sfjoe	}
17586752Sfjoe
176180263Sjhb	return possible;
177180263Sjhb}
178180263Sjhb
179180263Sjhb
180180263Sjhb/* find the interface with a name
181180263Sjhb */
182180263Sjhbstruct interface *
183180263Sjhbifwithname(char *name,			/* "ec0" or whatever */
184180263Sjhb	   naddr addr)			/* 0 or network address */
185180263Sjhb{
186180263Sjhb	struct interface *ifp;
187180263Sjhb
188180263Sjhb	for (;;) {
189180263Sjhb		for (ifp = *nhash(name); ifp != 0; ifp = ifp->int_nhash) {
190180263Sjhb			/* If the network address is not specified,
191180263Sjhb			 * ignore any alias interfaces.  Otherwise, look
192			 * for the interface with the target name and address.
193			 */
194			if (!strcmp(ifp->int_name, name)
195			    && ((addr == 0 && !(ifp->int_state & IS_ALIAS))
196				|| (ifp->int_addr == addr)))
197				return ifp;
198		}
199
200		/* If there is no known interface, maybe there is a
201		 * new interface.  So just once look for new interfaces.
202		 */
203		if (last_ifinit.tv_sec == now.tv_sec
204		    && last_ifinit.tv_usec == now.tv_usec)
205			return 0;
206		ifinit();
207	}
208}
209
210
211struct interface *
212ifwithindex(u_short index)
213{
214	struct interface *ifp;
215
216
217	for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) {
218		if (ifp->int_index == index)
219			return ifp;
220	}
221	return 0;
222}
223
224
225/* Find an interface from which the specified address
226 * should have come from.  Used for figuring out which
227 * interface a packet came in on.
228 */
229struct interface *
230iflookup(naddr addr)
231{
232	struct interface *ifp, *maybe;
233
234	maybe = 0;
235	for (;;) {
236		for (ifp = ifnet; ifp; ifp = ifp->int_next) {
237			if (ifp->int_if_flags & IFF_POINTOPOINT) {
238				/* finished with a match */
239				if (ifp->int_dstaddr == addr)
240					return ifp;
241
242			} else {
243				/* finished with an exact match */
244				if (ifp->int_addr == addr)
245					return ifp;
246
247				/* Look for the longest approximate match.
248				 */
249				if (on_net(addr, ifp->int_net, ifp->int_mask)
250				    && (maybe == 0
251					|| ifp->int_mask > maybe->int_mask))
252					maybe = ifp;
253			}
254		}
255
256		if (maybe != 0
257		    || (last_ifinit.tv_sec == now.tv_sec
258			&& last_ifinit.tv_usec == now.tv_usec))
259			return maybe;
260
261		/* If there is no known interface, maybe there is a
262		 * new interface.  So just once look for new interfaces.
263		 */
264		ifinit();
265	}
266}
267
268
269/* Return the classical netmask for an IP address.
270 */
271naddr					/* host byte order */
272std_mask(naddr addr)			/* network byte order */
273{
274	NTOHL(addr);			/* was a host, not a network */
275
276	if (addr == 0)			/* default route has mask 0 */
277		return 0;
278	if (IN_CLASSA(addr))
279		return IN_CLASSA_NET;
280	if (IN_CLASSB(addr))
281		return IN_CLASSB_NET;
282	return IN_CLASSC_NET;
283}
284
285
286/* Find the netmask that would be inferred by RIPv1 listeners
287 *	on the given interface for a given network.
288 *	If no interface is specified, look for the best fitting	interface.
289 */
290naddr
291ripv1_mask_net(naddr addr,		/* in network byte order */
292	       struct interface *ifp)	/* as seen on this interface */
293{
294	naddr mask = 0;
295
296	if (addr == 0)			/* default always has 0 mask */
297		return mask;
298
299	if (ifp != 0) {
300		/* If the target network is that of the associated interface
301		 * on which it arrived, then use the netmask of the interface.
302		 */
303		if (on_net(addr, ifp->int_net, ifp->int_std_mask))
304			mask = ifp->int_ripv1_mask;
305
306	} else {
307		/* Examine all interfaces, and if it the target seems
308		 * to have the same network number of an interface, use the
309		 * netmask of that interface.  If there is more than one
310		 * such interface, prefer the interface with the longest
311		 * match.
312		 */
313		for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) {
314			if (on_net(addr, ifp->int_std_net, ifp->int_std_mask)
315			    && ifp->int_ripv1_mask > mask)
316				mask = ifp->int_ripv1_mask;
317		}
318	}
319
320	/* Otherwise, make the classic A/B/C guess.
321	 */
322	if (mask == 0)
323		mask = std_mask(addr);
324
325	return mask;
326}
327
328
329naddr
330ripv1_mask_host(naddr addr,		/* in network byte order */
331		struct interface *ifp)	/* as seen on this interface */
332{
333	naddr mask = ripv1_mask_net(addr, ifp);
334
335
336	/* If the computed netmask does not mask the address,
337	 * then assume it is a host address
338	 */
339	if ((ntohl(addr) & ~mask) != 0)
340		mask = HOST_MASK;
341	return mask;
342}
343
344
345/* See if a IP address looks reasonable as a destination
346 */
347int					/* 0=bad */
348check_dst(naddr addr)
349{
350	NTOHL(addr);
351
352	if (IN_CLASSA(addr)) {
353		if (addr == 0)
354			return 1;	/* default */
355
356		addr >>= IN_CLASSA_NSHIFT;
357		return (addr != 0 && addr != IN_LOOPBACKNET);
358	}
359
360	return (IN_CLASSB(addr) || IN_CLASSC(addr));
361}
362
363
364/* See a new interface duplicates an existing interface.
365 */
366struct interface *
367check_dup(naddr addr,			/* IP address, so network byte order */
368	  naddr dstaddr,		/* ditto */
369	  naddr mask,			/* mask, so host byte order */
370	  int if_flags)
371{
372	struct interface *ifp;
373
374	for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) {
375		if (ifp->int_mask != mask)
376			continue;
377
378		if (!iff_alive(ifp->int_if_flags))
379			continue;
380
381		/* The local address can only be shared with a point-to-
382		 * point link.
383		 */
384		if (ifp->int_addr == addr
385		    && (((if_flags|ifp->int_if_flags) & IFF_POINTOPOINT) == 0))
386			return ifp;
387
388		if (on_net(ifp->int_dstaddr, ntohl(dstaddr),mask))
389			return ifp;
390	}
391	return 0;
392}
393
394
395/* See that a remote gateway is reachable.
396 *	Note that the answer can change as real interfaces come and go.
397 */
398int					/* 0=bad */
399check_remote(struct interface *ifp)
400{
401	struct rt_entry *rt;
402
403	/* do not worry about other kinds */
404	if (!(ifp->int_state & IS_REMOTE))
405	    return 1;
406
407	rt = rtfind(ifp->int_addr);
408	if (rt != 0
409	    && rt->rt_ifp != 0
410	    &&on_net(ifp->int_addr,
411		     rt->rt_ifp->int_net, rt->rt_ifp->int_mask))
412		return 1;
413
414	/* the gateway cannot be reached directly from one of our
415	 * interfaces
416	 */
417	if (!(ifp->int_state & IS_BROKE)) {
418		msglog("unreachable gateway %s in "_PATH_GATEWAYS,
419		       naddr_ntoa(ifp->int_addr));
420		if_bad(ifp);
421	}
422	return 0;
423}
424
425
426/* Delete an interface.
427 */
428static void
429ifdel(struct interface *ifp)
430{
431	struct ip_mreq m;
432	struct interface *ifp1;
433
434
435	trace_if("Del", ifp);
436
437	ifp->int_state |= IS_BROKE;
438
439	/* unlink the interface
440	 */
441	*ifp->int_prev = ifp->int_next;
442	if (ifp->int_next != 0)
443		ifp->int_next->int_prev = ifp->int_prev;
444	*ifp->int_ahash_prev = ifp->int_ahash;
445	if (ifp->int_ahash != 0)
446		ifp->int_ahash->int_ahash_prev = ifp->int_ahash_prev;
447	*ifp->int_nhash_prev = ifp->int_nhash;
448	if (ifp->int_nhash != 0)
449		ifp->int_nhash->int_nhash_prev = ifp->int_nhash_prev;
450	if (ifp->int_if_flags & IFF_BROADCAST) {
451		*ifp->int_bhash_prev = ifp->int_bhash;
452		if (ifp->int_bhash != 0)
453			ifp->int_bhash->int_bhash_prev = ifp->int_bhash_prev;
454	}
455	if (ifp->int_state & IS_REMOTE) {
456		*ifp->int_rlink_prev = ifp->int_rlink;
457		if (ifp->int_rlink != 0)
458			ifp->int_rlink->int_rlink_prev = ifp->int_rlink_prev;
459	}
460
461	if (!(ifp->int_state & IS_ALIAS)) {
462		/* delete aliases when the main interface dies
463		 */
464		for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) {
465			if (ifp1 != ifp
466			    && !strcmp(ifp->int_name, ifp1->int_name))
467				ifdel(ifp1);
468		}
469
470		if ((ifp->int_if_flags & IFF_MULTICAST)
471#ifdef MCAST_PPP_BUG
472		    && !(ifp->int_if_flags & IFF_POINTOPOINT)
473#endif
474		    && rip_sock >= 0) {
475			m.imr_multiaddr.s_addr = htonl(INADDR_RIP_GROUP);
476			m.imr_interface.s_addr = ((ifp->int_if_flags
477						   & IFF_POINTOPOINT)
478						  ? ifp->int_dstaddr
479						  : ifp->int_addr);
480			if (setsockopt(rip_sock,IPPROTO_IP,IP_DROP_MEMBERSHIP,
481				       &m, sizeof(m)) < 0
482			    && errno != EADDRNOTAVAIL
483			    && !TRACEACTIONS)
484				LOGERR("setsockopt(IP_DROP_MEMBERSHIP RIP)");
485			if (rip_sock_mcast == ifp)
486				rip_sock_mcast = 0;
487		}
488		if (ifp->int_rip_sock >= 0) {
489			(void)close(ifp->int_rip_sock);
490			ifp->int_rip_sock = -1;
491			fix_select();
492		}
493
494		tot_interfaces--;
495		if (!IS_RIP_OFF(ifp->int_state))
496			rip_interfaces--;
497
498		/* Zap all routes associated with this interface.
499		 * Assume routes just using gateways beyond this interface will
500		 * timeout naturally, and have probably already died.
501		 */
502		(void)rn_walktree(rhead, walk_bad, 0);
503
504		set_rdisc_mg(ifp, 0);
505		if_bad_rdisc(ifp);
506	}
507
508	free(ifp);
509}
510
511
512/* Mark an interface ill.
513 */
514void
515if_sick(struct interface *ifp)
516{
517	if (0 == (ifp->int_state & (IS_SICK | IS_BROKE))) {
518		ifp->int_state |= IS_SICK;
519		ifp->int_act_time = NEVER;
520		trace_if("Chg", ifp);
521
522		LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL);
523	}
524}
525
526
527/* Mark an interface dead.
528 */
529void
530if_bad(struct interface *ifp)
531{
532	struct interface *ifp1;
533
534
535	if (ifp->int_state & IS_BROKE)
536		return;
537
538	LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL);
539
540	ifp->int_state |= (IS_BROKE | IS_SICK);
541	ifp->int_act_time = NEVER;
542	ifp->int_query_time = NEVER;
543	ifp->int_data.ts = 0;
544
545	trace_if("Chg", ifp);
546
547	if (!(ifp->int_state & IS_ALIAS)) {
548		for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) {
549			if (ifp1 != ifp
550			    && !strcmp(ifp->int_name, ifp1->int_name))
551				if_bad(ifp1);
552		}
553		(void)rn_walktree(rhead, walk_bad, 0);
554		if_bad_rdisc(ifp);
555	}
556}
557
558
559/* Mark an interface alive
560 */
561int					/* 1=it was dead */
562if_ok(struct interface *ifp,
563      char *type)
564{
565	struct interface *ifp1;
566
567
568	if (!(ifp->int_state & IS_BROKE)) {
569		if (ifp->int_state & IS_SICK) {
570			trace_act("%sinterface %s to %s working better",
571				  type,
572				  ifp->int_name, naddr_ntoa(ifp->int_dstaddr));
573			ifp->int_state &= ~IS_SICK;
574		}
575		return 0;
576	}
577
578	msglog("%sinterface %s to %s restored",
579	       type, ifp->int_name, naddr_ntoa(ifp->int_dstaddr));
580	ifp->int_state &= ~(IS_BROKE | IS_SICK);
581	ifp->int_data.ts = 0;
582
583	if (!(ifp->int_state & IS_ALIAS)) {
584		for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) {
585			if (ifp1 != ifp
586			    && !strcmp(ifp->int_name, ifp1->int_name))
587				if_ok(ifp1, type);
588		}
589		if_ok_rdisc(ifp);
590	}
591
592	if (ifp->int_state & IS_REMOTE) {
593		if (!addrouteforif(ifp))
594			return 0;
595	}
596	return 1;
597}
598
599
600#ifdef _HAVE_SA_LEN
601static struct sockaddr sa_zero = { sizeof(struct sockaddr), AF_INET };
602#endif
603/*
604 * disassemble routing message
605 * copied bug for bug from the BSD kernel
606 */
607void
608rt_xaddrs(struct rt_addrinfo *info,
609	  struct sockaddr *sa,
610	  struct sockaddr *lim,
611	  int addrs)
612{
613	char  *sa_limit; /* next byte after the sockaddr */
614	int i;
615	int len;
616#ifdef sgi
617#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) \
618		    : sizeof(__uint64_t))
619#else
620#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \
621		    : sizeof(long))
622#endif
623
624
625	bzero(info, sizeof(*info));
626	info->rti_addrs = addrs;
627	for (i = 0; i < RTAX_MAX && sa < lim; i++) {
628		if ((addrs & (1 << i)) == 0)
629			continue;
630#ifdef _HAVE_SA_LEN
631		len = sa->sa_len;
632
633		/* Check the sockaddr doesn't go past the end of the buffer. */
634		/* Cope with buggy (malicious?) sender.*/
635		if (len) {
636			sa_limit = ((char*)sa) + len;
637			if ( sa_limit > (char *)lim ) /* equal is ok */
638				return;
639		} else {
640			/*
641			 * We allow the last broken sockaddr
642			 * to be replaced by a good null one
643			 * because some old versions of routing stuff
644			 * would do this (4.4 route(1) for example).
645			 * This should go away eventually.
646			 */
647			info->rti_info[i] = &sa_zero;
648			return; /* this one had unknown length */
649		}
650#else
651		len = _FAKE_SA_LEN_DST(sa);
652#endif
653		info->rti_info[i] = sa;
654		sa = (struct sockaddr *)((char*)(sa) + ROUNDUP(len));
655	}
656}
657
658
659/* Find the network interfaces which have configured themselves.
660 *	This must be done regularly, if only for extra addresses
661 *	that come and go on interfaces.
662 */
663void
664ifinit(void)
665{
666	static char *sysctl_buf;
667	static size_t sysctl_buf_size = 0;
668	uint complaints = 0;
669	static u_int prev_complaints = 0;
670#	define COMP_NOT_INET	0x001
671#	define COMP_NOADDR	0x002
672#	define COMP_BADADDR	0x004
673#	define COMP_NODST	0x008
674#	define COMP_NOBADR	0x010
675#	define COMP_NOMASK	0x020
676#	define COMP_DUP		0x040
677#	define COMP_BAD_METRIC	0x080
678#	define COMP_NETMASK	0x100
679
680	struct interface ifs, ifs0, *ifp, *ifp1;
681	struct rt_entry *rt;
682	size_t needed;
683	int mib[6];
684	struct if_msghdr *ifm;
685	struct ifa_msghdr *ifam, *ifam_lim, *ifam2;
686	int in, ierr, out, oerr;
687	struct intnet *intnetp;
688	struct rt_addrinfo info;
689#ifdef SIOCGIFMETRIC
690	struct ifreq ifr;
691#endif
692
693
694	last_ifinit = now;
695	ifinit_timer.tv_sec = now.tv_sec + (supplier
696					    ? CHECK_ACT_INTERVAL
697					    : CHECK_QUIET_INTERVAL);
698
699	/* mark all interfaces so we can get rid of those that disappear */
700	for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next)
701		ifp->int_state &= ~(IS_CHECKED | IS_DUP);
702
703	/* Fetch the interface list, without too many system calls
704	 * since we do it repeatedly.
705	 */
706	mib[0] = CTL_NET;
707	mib[1] = PF_ROUTE;
708	mib[2] = 0;
709	mib[3] = AF_INET;
710	mib[4] = NET_RT_IFLIST;
711	mib[5] = 0;
712	for (;;) {
713		if ((needed = sysctl_buf_size) != 0) {
714			if (sysctl(mib, 6, sysctl_buf,&needed, 0, 0) >= 0)
715				break;
716			if (errno != ENOMEM && errno != EFAULT)
717				BADERR(1, "ifinit: get interface table");
718			free(sysctl_buf);
719			needed = 0;
720		}
721		if (sysctl(mib, 6, 0, &needed, 0, 0) < 0)
722			BADERR(1,"ifinit: route-sysctl-estimate");
723		sysctl_buf = rtmalloc(sysctl_buf_size = needed, "ifinit");
724	}
725
726	ifam_lim = (struct ifa_msghdr *)(sysctl_buf + needed);
727	for (ifam = (struct ifa_msghdr *)sysctl_buf;
728	     ifam < ifam_lim;
729	     ifam = ifam2) {
730
731		ifam2 = (struct ifa_msghdr*)((char*)ifam + ifam->ifam_msglen);
732
733		if (ifam->ifam_type == RTM_IFINFO) {
734			struct sockaddr_dl *sdl;
735
736			ifm = (struct if_msghdr *)ifam;
737			/* make prototype structure for the IP aliases
738			 */
739			bzero(&ifs0, sizeof(ifs0));
740			ifs0.int_rip_sock = -1;
741			ifs0.int_index = ifm->ifm_index;
742			ifs0.int_if_flags = ifm->ifm_flags;
743			ifs0.int_state = IS_CHECKED;
744			ifs0.int_query_time = NEVER;
745			ifs0.int_act_time = now.tv_sec;
746			ifs0.int_data.ts = now.tv_sec;
747			ifs0.int_data.ipackets = ifm->ifm_data.ifi_ipackets;
748			ifs0.int_data.ierrors = ifm->ifm_data.ifi_ierrors;
749			ifs0.int_data.opackets = ifm->ifm_data.ifi_opackets;
750			ifs0.int_data.oerrors = ifm->ifm_data.ifi_oerrors;
751#ifdef sgi
752			ifs0.int_data.odrops = ifm->ifm_data.ifi_odrops;
753#endif
754			sdl = (struct sockaddr_dl *)(ifm + 1);
755			sdl->sdl_data[sdl->sdl_nlen] = 0;
756			strncpy(ifs0.int_name, sdl->sdl_data,
757				MIN(sizeof(ifs0.int_name), sdl->sdl_nlen));
758			continue;
759		}
760		if (ifam->ifam_type != RTM_NEWADDR) {
761			logbad(1,"ifinit: out of sync");
762			continue;
763		}
764		rt_xaddrs(&info, (struct sockaddr *)(ifam+1),
765			  (struct sockaddr *)ifam2,
766			  ifam->ifam_addrs);
767
768		/* Prepare for the next address of this interface, which
769		 * will be an alias.
770		 * Do not output RIP or Router-Discovery packets via aliases.
771		 */
772		bcopy(&ifs0, &ifs, sizeof(ifs));
773		ifs0.int_state |= (IS_ALIAS | IS_NO_RIP | IS_NO_RDISC);
774
775		if (INFO_IFA(&info) == 0) {
776			if (iff_alive(ifs.int_if_flags)) {
777				if (!(prev_complaints & COMP_NOADDR))
778					msglog("%s has no address",
779					       ifs.int_name);
780				complaints |= COMP_NOADDR;
781			}
782			continue;
783		}
784		if (INFO_IFA(&info)->sa_family != AF_INET) {
785			if (iff_alive(ifs.int_if_flags)) {
786				if (!(prev_complaints & COMP_NOT_INET))
787					trace_act("%s: not AF_INET",
788						  ifs.int_name);
789				complaints |= COMP_NOT_INET;
790			}
791			continue;
792		}
793
794		ifs.int_addr = S_ADDR(INFO_IFA(&info));
795
796		if (ntohl(ifs.int_addr)>>24 == 0
797		    || ntohl(ifs.int_addr)>>24 == 0xff) {
798			if (iff_alive(ifs.int_if_flags)) {
799				if (!(prev_complaints & COMP_BADADDR))
800					msglog("%s has a bad address",
801					       ifs.int_name);
802				complaints |= COMP_BADADDR;
803			}
804			continue;
805		}
806
807		if (ifs.int_if_flags & IFF_LOOPBACK) {
808			ifs.int_state |= IS_PASSIVE | IS_NO_RIP | IS_NO_RDISC;
809			ifs.int_dstaddr = ifs.int_addr;
810			ifs.int_mask = HOST_MASK;
811			ifs.int_ripv1_mask = HOST_MASK;
812			ifs.int_std_mask = std_mask(ifs.int_dstaddr);
813			ifs.int_net = ntohl(ifs.int_dstaddr);
814			if (!foundloopback) {
815				foundloopback = 1;
816				loopaddr = ifs.int_addr;
817			}
818
819		} else if (ifs.int_if_flags & IFF_POINTOPOINT) {
820			if (INFO_BRD(&info) == 0
821			    || INFO_BRD(&info)->sa_family != AF_INET) {
822				if (iff_alive(ifs.int_if_flags)) {
823					if (!(prev_complaints & COMP_NODST))
824						msglog("%s has a bad"
825						       " destination address",
826						       ifs.int_name);
827					complaints |= COMP_NODST;
828				}
829				continue;
830			}
831			ifs.int_dstaddr = S_ADDR(INFO_BRD(&info));
832			if (ntohl(ifs.int_dstaddr)>>24 == 0
833			    || ntohl(ifs.int_dstaddr)>>24 == 0xff) {
834				if (iff_alive(ifs.int_if_flags)) {
835					if (!(prev_complaints & COMP_NODST))
836						msglog("%s has a bad"
837						       " destination address",
838						       ifs.int_name);
839					complaints |= COMP_NODST;
840				}
841				continue;
842			}
843			ifs.int_mask = HOST_MASK;
844			ifs.int_ripv1_mask = ntohl(S_ADDR(INFO_MASK(&info)));
845			ifs.int_std_mask = std_mask(ifs.int_dstaddr);
846			ifs.int_net = ntohl(ifs.int_dstaddr);
847
848		}  else {
849			if (INFO_MASK(&info) == 0) {
850				if (iff_alive(ifs.int_if_flags)) {
851					if (!(prev_complaints & COMP_NOMASK))
852						msglog("%s has no netmask",
853						       ifs.int_name);
854					complaints |= COMP_NOMASK;
855				}
856				continue;
857			}
858			ifs.int_dstaddr = ifs.int_addr;
859			ifs.int_mask = ntohl(S_ADDR(INFO_MASK(&info)));
860			ifs.int_ripv1_mask = ifs.int_mask;
861			ifs.int_std_mask = std_mask(ifs.int_addr);
862			ifs.int_net = ntohl(ifs.int_addr) & ifs.int_mask;
863			if (ifs.int_mask != ifs.int_std_mask)
864				ifs.int_state |= IS_SUBNET;
865
866			if (ifs.int_if_flags & IFF_BROADCAST) {
867				if (INFO_BRD(&info) == 0) {
868					if (iff_alive(ifs.int_if_flags)) {
869					    if (!(prev_complaints
870						  & COMP_NOBADR))
871						msglog("%s has"
872						       "no broadcast address",
873						       ifs.int_name);
874					    complaints |= COMP_NOBADR;
875					}
876					continue;
877				}
878				ifs.int_brdaddr = S_ADDR(INFO_BRD(&info));
879			}
880		}
881		ifs.int_std_net = ifs.int_net & ifs.int_std_mask;
882		ifs.int_std_addr = htonl(ifs.int_std_net);
883
884		/* Use a minimum metric of one.  Treat the interface metric
885		 * (default 0) as an increment to the hop count of one.
886		 *
887		 * The metric obtained from the routing socket dump of
888		 * interface addresses is wrong.  It is not set by the
889		 * SIOCSIFMETRIC ioctl.
890		 */
891#ifdef SIOCGIFMETRIC
892		strncpy(ifr.ifr_name, ifs.int_name, sizeof(ifr.ifr_name));
893		if (ioctl(rt_sock, SIOCGIFMETRIC, &ifr) < 0) {
894			DBGERR(1, "ioctl(SIOCGIFMETRIC)");
895			ifs.int_metric = 0;
896		} else {
897			ifs.int_metric = ifr.ifr_metric;
898		}
899#else
900		ifs.int_metric = ifam->ifam_metric;
901#endif
902		if (ifs.int_metric > HOPCNT_INFINITY) {
903			ifs.int_metric = 0;
904			if (!(prev_complaints & COMP_BAD_METRIC)
905			    && iff_alive(ifs.int_if_flags)) {
906				complaints |= COMP_BAD_METRIC;
907				msglog("%s has a metric of %d",
908				       ifs.int_name, ifs.int_metric);
909			}
910		}
911
912		/* See if this is a familiar interface.
913		 * If so, stop worrying about it if it is the same.
914		 * Start it over if it now is to somewhere else, as happens
915		 * frequently with PPP and SLIP.
916		 */
917		ifp = ifwithname(ifs.int_name, ((ifs.int_state & IS_ALIAS)
918						? ifs.int_addr
919						: 0));
920		if (ifp != 0) {
921			ifp->int_state |= IS_CHECKED;
922
923			if (0 != ((ifp->int_if_flags ^ ifs.int_if_flags)
924				  & (IFF_BROADCAST
925				     | IFF_LOOPBACK
926				     | IFF_POINTOPOINT
927				     | IFF_MULTICAST))
928			    || 0 != ((ifp->int_state ^ ifs.int_state)
929				     & IS_ALIAS)
930			    || ifp->int_addr != ifs.int_addr
931			    || ifp->int_brdaddr != ifs.int_brdaddr
932			    || ifp->int_dstaddr != ifs.int_dstaddr
933			    || ifp->int_mask != ifs.int_mask
934			    || ifp->int_metric != ifs.int_metric) {
935				/* Forget old information about
936				 * a changed interface.
937				 */
938				trace_act("interface %s has changed",
939					  ifp->int_name);
940				ifdel(ifp);
941				ifp = 0;
942			}
943		}
944
945		if (ifp != 0) {
946			/* The primary representative of an alias worries
947			 * about how things are working.
948			 */
949			if (ifp->int_state & IS_ALIAS)
950				continue;
951
952			/* note interfaces that have been turned off
953			 */
954			if (!iff_alive(ifs.int_if_flags)) {
955				if (iff_alive(ifp->int_if_flags)) {
956					msglog("interface %s to %s turned off",
957					       ifp->int_name,
958					       naddr_ntoa(ifp->int_dstaddr));
959					if_bad(ifp);
960					ifp->int_if_flags &= ~IFF_UP_RUNNING;
961				}
962				continue;
963			}
964			/* or that were off and are now ok */
965			if (!iff_alive(ifp->int_if_flags)) {
966				ifp->int_if_flags |= IFF_UP_RUNNING;
967				(void)if_ok(ifp, "");
968			}
969
970			/* If it has been long enough,
971			 * see if the interface is broken.
972			 */
973			if (now.tv_sec < ifp->int_data.ts+CHECK_BAD_INTERVAL)
974				continue;
975
976			in = ifs.int_data.ipackets - ifp->int_data.ipackets;
977			ierr = ifs.int_data.ierrors - ifp->int_data.ierrors;
978			out = ifs.int_data.opackets - ifp->int_data.opackets;
979			oerr = ifs.int_data.oerrors - ifp->int_data.oerrors;
980#ifdef sgi
981			/* Through at least IRIX 6.2, PPP and SLIP
982			 * count packets dropped by  the filters.
983			 * But FDDI rings stuck non-operational count
984			 * dropped packets as they wait for improvement.
985			 */
986			if (!(ifp->int_if_flags & IFF_POINTOPOINT))
987				oerr += (ifs.int_data.odrops
988					 - ifp->int_data.odrops);
989#endif
990			/* If the interface just awoke, restart the counters.
991			 */
992			if (ifp->int_data.ts == 0) {
993				ifp->int_data = ifs.int_data;
994				continue;
995			}
996			ifp->int_data = ifs.int_data;
997
998			/* Withhold judgment when the short error
999			 * counters wrap or the interface is reset.
1000			 */
1001			if (ierr < 0 || in < 0 || oerr < 0 || out < 0) {
1002				LIM_SEC(ifinit_timer,
1003					now.tv_sec+CHECK_BAD_INTERVAL);
1004				continue;
1005			}
1006
1007			/* Withhold judgement when there is no traffic
1008			 */
1009			if (in == 0 && out == 0 && ierr == 0 && oerr == 0)
1010				continue;
1011
1012			/* It is bad if input or output is not working.
1013			 * Require presistent problems before marking it dead.
1014			 */
1015			if ((in <= ierr && ierr > 0)
1016			    || (out <= oerr && oerr > 0)) {
1017				if (!(ifp->int_state & IS_SICK)) {
1018					trace_act("interface %s to %s"
1019						  " sick: in=%d ierr=%d"
1020						  " out=%d oerr=%d",
1021						  ifp->int_name,
1022						  naddr_ntoa(ifp->int_dstaddr),
1023						  in, ierr, out, oerr);
1024					if_sick(ifp);
1025					continue;
1026				}
1027				if (!(ifp->int_state & IS_BROKE)) {
1028					msglog("interface %s to %s broken:"
1029					       " in=%d ierr=%d out=%d oerr=%d",
1030					       ifp->int_name,
1031					       naddr_ntoa(ifp->int_dstaddr),
1032					       in, ierr, out, oerr);
1033					if_bad(ifp);
1034				}
1035				continue;
1036			}
1037
1038			/* otherwise, it is active and healthy
1039			 */
1040			ifp->int_act_time = now.tv_sec;
1041			(void)if_ok(ifp, "");
1042			continue;
1043		}
1044
1045		/* This is a new interface.
1046		 * If it is dead, forget it.
1047		 */
1048		if (!iff_alive(ifs.int_if_flags))
1049			continue;
1050
1051		/* If it duplicates an existing interface,
1052		 * complain about it, mark the other one
1053		 * duplicated, and forget this one.
1054		 */
1055		ifp = check_dup(ifs.int_addr,ifs.int_dstaddr,ifs.int_mask,
1056				ifs.int_if_flags);
1057		if (ifp != 0) {
1058			if (!(prev_complaints & COMP_DUP)) {
1059				complaints |= COMP_DUP;
1060				msglog("%s (%s%s%s) is duplicated by"
1061				       " %s (%s%s%s)",
1062				       ifs.int_name,
1063				       addrname(ifs.int_addr,ifs.int_mask,1),
1064				       ((ifs.int_if_flags & IFF_POINTOPOINT)
1065					? "-->" : ""),
1066				       ((ifs.int_if_flags & IFF_POINTOPOINT)
1067					? naddr_ntoa(ifs.int_dstaddr) : ""),
1068				       ifp->int_name,
1069				       addrname(ifp->int_addr,ifp->int_mask,1),
1070				       ((ifp->int_if_flags & IFF_POINTOPOINT)
1071					? "-->" : ""),
1072				       ((ifp->int_if_flags & IFF_POINTOPOINT)
1073					? naddr_ntoa(ifp->int_dstaddr) : ""));
1074			}
1075			ifp->int_state |= IS_DUP;
1076			continue;
1077		}
1078
1079		if (0 == (ifs.int_if_flags & (IFF_POINTOPOINT | IFF_BROADCAST))
1080		    && !(ifs.int_state & IS_PASSIVE)) {
1081			trace_act("%s is neither broadcast, point-to-point,"
1082				  " nor loopback",
1083				  ifs.int_name);
1084			if (!(ifs.int_state & IFF_MULTICAST))
1085				ifs.int_state |= IS_NO_RDISC;
1086		}
1087
1088
1089		/* It is new and ok.   Add it to the list of interfaces
1090		 */
1091		ifp = (struct interface *)rtmalloc(sizeof(*ifp), "ifinit");
1092		bcopy(&ifs, ifp, sizeof(*ifp));
1093		get_parms(ifp);
1094		if_link(ifp);
1095		trace_if("Add", ifp);
1096
1097		/* Notice likely bad netmask.
1098		 */
1099		if (!(prev_complaints & COMP_NETMASK)
1100		    && !(ifp->int_if_flags & IFF_POINTOPOINT)
1101		    && ifp->int_addr != RIP_DEFAULT) {
1102			for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) {
1103				if (ifp1->int_mask == ifp->int_mask)
1104					continue;
1105				if (ifp1->int_if_flags & IFF_POINTOPOINT)
1106					continue;
1107				if (ifp1->int_dstaddr == RIP_DEFAULT)
1108					continue;
1109				if (on_net(ifp->int_dstaddr,
1110					   ifp1->int_net, ifp1->int_mask)
1111				    || on_net(ifp1->int_dstaddr,
1112					      ifp->int_net, ifp->int_mask)) {
1113					msglog("possible netmask problem"
1114					       " between %s:%s and %s:%s",
1115					       ifp->int_name,
1116					       addrname(htonl(ifp->int_net),
1117							ifp->int_mask, 1),
1118					       ifp1->int_name,
1119					       addrname(htonl(ifp1->int_net),
1120							ifp1->int_mask, 1));
1121					complaints |= COMP_NETMASK;
1122				}
1123			}
1124		}
1125
1126		if (!(ifp->int_state & IS_ALIAS)) {
1127			/* Count the # of directly connected networks.
1128			 */
1129			if (!(ifp->int_if_flags & IFF_LOOPBACK))
1130				tot_interfaces++;
1131			if (!IS_RIP_OFF(ifp->int_state))
1132				rip_interfaces++;
1133
1134			/* turn on router discovery and RIP If needed */
1135			if_ok_rdisc(ifp);
1136			rip_on(ifp);
1137		}
1138	}
1139
1140	/* If we are multi-homed and have at least two interfaces
1141	 * listening to RIP, then output by default.
1142	 */
1143	if (!supplier_set && rip_interfaces > 1)
1144		set_supplier();
1145
1146	/* If we are multi-homed, optionally advertise a route to
1147	 * our main address.
1148	 */
1149	if (advertise_mhome
1150	    || (tot_interfaces > 1
1151		&& mhome
1152		&& (ifp = ifwithaddr(myaddr, 0, 0)) != 0
1153		&& foundloopback)) {
1154		advertise_mhome = 1;
1155		rt = rtget(myaddr, HOST_MASK);
1156		if (rt != 0) {
1157			if (rt->rt_ifp != ifp
1158			    || rt->rt_router != loopaddr) {
1159				rtdelete(rt);
1160				rt = 0;
1161			} else {
1162				rtchange(rt, rt->rt_state | RS_MHOME,
1163					 loopaddr, loopaddr,
1164					 0, 0, ifp, rt->rt_time, 0);
1165			}
1166		}
1167		if (rt == 0)
1168			rtadd(myaddr, HOST_MASK, loopaddr, loopaddr,
1169			      0, 0, RS_MHOME, ifp);
1170	}
1171
1172	for (ifp = ifnet; ifp != 0; ifp = ifp1) {
1173		ifp1 = ifp->int_next;	/* because we may delete it */
1174
1175		/* Forget any interfaces that have disappeared.
1176		 */
1177		if (!(ifp->int_state & (IS_CHECKED | IS_REMOTE))) {
1178			trace_act("interface %s has disappeared",
1179				  ifp->int_name);
1180			ifdel(ifp);
1181			continue;
1182		}
1183
1184		if ((ifp->int_state & IS_BROKE)
1185		    && !(ifp->int_state & IS_PASSIVE))
1186			LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL);
1187
1188		/* If we ever have a RIPv1 interface, assume we always will.
1189		 * It might come back if it ever goes away.
1190		 */
1191		if (!(ifp->int_state & IS_NO_RIPV1_OUT) && supplier)
1192			have_ripv1_out = 1;
1193		if (!(ifp->int_state & IS_NO_RIPV1_IN))
1194			have_ripv1_in = 1;
1195	}
1196
1197	for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) {
1198		/* Ensure there is always a network route for interfaces,
1199		 * after any dead interfaces have been deleted, which
1200		 * might affect routes for point-to-point links.
1201		 */
1202		if (!addrouteforif(ifp))
1203			continue;
1204
1205		/* Add routes to the local end of point-to-point interfaces
1206		 * using loopback.
1207		 */
1208		if ((ifp->int_if_flags & IFF_POINTOPOINT)
1209		    && !(ifp->int_state & IS_REMOTE)
1210		    && foundloopback) {
1211			/* Delete any routes to the network address through
1212			 * foreign routers. Remove even static routes.
1213			 */
1214			del_static(ifp->int_addr, HOST_MASK, 0);
1215			rt = rtget(ifp->int_addr, HOST_MASK);
1216			if (rt != 0 && rt->rt_router != loopaddr) {
1217				rtdelete(rt);
1218				rt = 0;
1219			}
1220			if (rt != 0) {
1221				if (!(rt->rt_state & RS_LOCAL)
1222				    || rt->rt_metric > ifp->int_metric) {
1223					ifp1 = ifp;
1224				} else {
1225					ifp1 = rt->rt_ifp;
1226				}
1227				rtchange(rt,((rt->rt_state & ~RS_NET_SYN)
1228					     | (RS_IF|RS_LOCAL)),
1229					 loopaddr, loopaddr,
1230					 0, 0, ifp1, rt->rt_time, 0);
1231			} else {
1232				rtadd(ifp->int_addr, HOST_MASK,
1233				      loopaddr, loopaddr,
1234				      0, 0, (RS_IF | RS_LOCAL), ifp);
1235			}
1236		}
1237	}
1238
1239	/* add the authority routes */
1240	for (intnetp = intnets; intnetp!=0; intnetp = intnetp->intnet_next) {
1241		rt = rtget(intnetp->intnet_addr, intnetp->intnet_mask);
1242		if (rt != 0
1243		    && !(rt->rt_state & RS_NO_NET_SYN)
1244		    && !(rt->rt_state & RS_NET_INT)) {
1245			rtdelete(rt);
1246			rt = 0;
1247		}
1248		if (rt == 0)
1249			rtadd(intnetp->intnet_addr, intnetp->intnet_mask,
1250			      loopaddr, loopaddr, intnetp->intnet_metric-1,
1251			      0, RS_NET_SYN | RS_NET_INT, 0);
1252	}
1253
1254	prev_complaints = complaints;
1255}
1256
1257
1258static void
1259check_net_syn(struct interface *ifp)
1260{
1261	struct rt_entry *rt;
1262
1263
1264	/* Turn on the need to automatically synthesize a network route
1265	 * for this interface only if we are running RIPv1 on some other
1266	 * interface that is on a different class-A,B,or C network.
1267	 */
1268	if (have_ripv1_out || have_ripv1_in) {
1269		ifp->int_state |= IS_NEED_NET_SYN;
1270		rt = rtget(ifp->int_std_addr, ifp->int_std_mask);
1271		if (rt != 0
1272		    && 0 == (rt->rt_state & RS_NO_NET_SYN)
1273		    && (!(rt->rt_state & RS_NET_SYN)
1274			|| rt->rt_metric > ifp->int_metric)) {
1275			rtdelete(rt);
1276			rt = 0;
1277		}
1278		if (rt == 0)
1279			rtadd(ifp->int_std_addr, ifp->int_std_mask,
1280			      ifp->int_addr, ifp->int_addr,
1281			      ifp->int_metric, 0, RS_NET_SYN, ifp);
1282
1283	} else {
1284		ifp->int_state &= ~IS_NEED_NET_SYN;
1285
1286		rt = rtget(ifp->int_std_addr,
1287			   ifp->int_std_mask);
1288		if (rt != 0
1289		    && (rt->rt_state & RS_NET_SYN)
1290		    && rt->rt_ifp == ifp)
1291			rtbad_sub(rt);
1292	}
1293}
1294
1295
1296/* Add route for interface if not currently installed.
1297 * Create route to other end if a point-to-point link,
1298 * otherwise a route to this (sub)network.
1299 */
1300int					/* 0=bad interface */
1301addrouteforif(struct interface *ifp)
1302{
1303	struct rt_entry *rt;
1304	naddr dst, gate;
1305
1306
1307	/* skip sick interfaces
1308	 */
1309	if (ifp->int_state & IS_BROKE)
1310		return 0;
1311
1312	/* If the interface on a subnet, then install a RIPv1 route to
1313	 * the network as well (unless it is sick).
1314	 */
1315	if (ifp->int_state & IS_SUBNET)
1316		check_net_syn(ifp);
1317
1318	gate = ifp->int_addr;
1319	dst = (0 != (ifp->int_if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK))
1320	       ? ifp->int_dstaddr
1321	       : htonl(ifp->int_net));
1322
1323	/* If we are going to send packets to the gateway,
1324	 * it must be reachable using our physical interfaces
1325	 */
1326	if ((ifp->int_state & IS_REMOTE)
1327	    && !(ifp->int_state & IS_EXTERNAL)
1328	    && !check_remote(ifp))
1329		return 0;
1330
1331	/* We are finished if the correct main interface route exists.
1332	 * The right route must be for the right interface, not synthesized
1333	 * from a subnet, be a "gateway" or not as appropriate, and so forth.
1334	 */
1335	del_static(dst, ifp->int_mask, 0);
1336	rt = rtget(dst, ifp->int_mask);
1337	if (rt != 0) {
1338		if ((rt->rt_ifp != ifp
1339		     || rt->rt_router != ifp->int_addr)
1340		    && (!(ifp->int_state & IS_DUP)
1341			|| rt->rt_ifp == 0
1342			|| (rt->rt_ifp->int_state & IS_BROKE))) {
1343			rtdelete(rt);
1344			rt = 0;
1345		} else {
1346			rtchange(rt, ((rt->rt_state | RS_IF)
1347				      & ~(RS_NET_SYN | RS_LOCAL)),
1348				 ifp->int_addr, ifp->int_addr,
1349				 ifp->int_metric, 0, ifp, now.tv_sec, 0);
1350		}
1351	}
1352	if (rt == 0) {
1353		if (ifp->int_transitions++ > 0)
1354			trace_act("re-install interface %s",
1355				  ifp->int_name);
1356
1357		rtadd(dst, ifp->int_mask, gate, gate,
1358		      ifp->int_metric, 0, RS_IF, ifp);
1359	}
1360
1361	return 1;
1362}
1363