xref: /titanic_41/usr/src/cmd/cmd-inet/usr.sbin/in.routed/if.c (revision 982ec2c2dc1163bc65216b4f07a4aa7c13c6aaf2)
1  /*
2   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3   * Use is subject to license terms.
4   *
5   * Copyright (c) 1983, 1993
6   *	The Regents of the University of California.  All rights reserved.
7   *
8   * Redistribution and use in source and binary forms, with or without
9   * modification, are permitted provided that the following conditions
10   * are met:
11   * 1. Redistributions of source code must retain the above copyright
12   *    notice, this list of conditions and the following disclaimer.
13   * 2. Redistributions in binary form must reproduce the above copyright
14   *    notice, this list of conditions and the following disclaimer in the
15   *    documentation and/or other materials provided with the distribution.
16   * 3. All advertising materials mentioning features or use of this software
17   *    must display the following acknowledgment:
18   *	This product includes software developed by the University of
19   *	California, Berkeley and its contributors.
20   * 4. Neither the name of the University nor the names of its contributors
21   *    may be used to endorse or promote products derived from this software
22   *    without specific prior written permission.
23   *
24   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27   * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34   * SUCH DAMAGE.
35   *
36   * $FreeBSD: src/sbin/routed/if.c,v 1.8 2000/08/11 08:24:38 sheldonh Exp $
37   */
38  
39  #include "defs.h"
40  #include "pathnames.h"
41  #include <sys/sockio.h>
42  #include <inet/ip.h>
43  #include <kstat.h>
44  #include <stropts.h>
45  #include <fcntl.h>
46  #include <stddef.h>
47  #include <assert.h>
48  
49  /* linked list of all interfaces */
50  struct interface *ifnet;
51  
52  /*
53   * Acceptable sizes (in number of interfaces) for the interface hash
54   * tables.  These must all be prime.  The interface hash tables all
55   * start with a size of hash_table_sizes[0], and increase as needed.
56   */
57  size_t hash_table_sizes[] = { 67, 131, 257, 521, 1031, 2053, 4099, 0 };
58  
59  struct htbl {
60  	void		**htbl_ptrs;
61  	uint_t		(*htbl_hash)(const void *, size_t);
62  	size_t		htbl_link_off;	/* offset of the linkage structure */
63  	size_t		htbl_key_off;	/* offset of the key value (rehash) */
64  	size_t		htbl_size;	/* size of the hash */
65  	uint_t		htbl_size_index;
66  	uint_t		htbl_ifcount;	/* count of entries */
67  	boolean_t	htbl_grow;	/* growth allowed */
68  };
69  
70  /* Get first element -- for iteration */
71  #define	HFIRST(htbl, arg) \
72  	((htbl)->htbl_ptrs[(htbl)->htbl_hash((arg), 0) % (htbl)->htbl_size])
73  
74  /* Add an element to a hash */
75  #define	HADD(htbl, strp) \
76  	hash_link((htbl), (htbl)->htbl_hash((strp), (htbl)->htbl_key_off), \
77  	    (strp))
78  
79  uint_t	tot_interfaces;			/* # of remote and local interfaces */
80  uint_t	rip_interfaces;			/* # of interfaces doing RIP */
81  uint_t	ripout_interfaces;		/* # of interfaces advertising RIP */
82  uint_t	fwd_interfaces;			/* # of interfaces ip_forwarding=1 */
83  static boolean_t foundloopback;		/* valid flag for loopaddr */
84  in_addr_t	loopaddr;		/* our address on loopback */
85  static struct	rt_spare loop_rts;
86  
87  struct timeval ifscan_timer;
88  static struct timeval last_ifscan;
89  #define	IF_RESCAN_DELAY() \
90  	(last_ifscan.tv_sec == now.tv_sec && \
91  	    last_ifscan.tv_usec == now.tv_usec && \
92  	    timercmp(&ifscan_timer, &now, > /* */))
93  
94  boolean_t		have_ripv1_out;	/* have a RIPv1 interface */
95  static boolean_t	have_ripv1_in;
96  
97  static void		if_bad(struct interface *, boolean_t);
98  static boolean_t	addrouteforif(struct interface *);
99  static int	get_if_kstats(struct interface *, struct phyi_data *);
100  static uint_t	ahash(const void *, uint_t);
101  static uint_t	ihash(const void *, uint_t);
102  static uint_t	nhash(const void *, uint_t);
103  static void	htbl_grow(struct htbl *);
104  
105  /*
106   * Table of all interfaces, hashed by interface address.  For remote
107   * interfaces, the gateway address is used.
108   */
109  static struct htbl ahash_tbl = {
110      NULL, ahash, offsetof(struct interface, int_ahash),
111      offsetof(struct interface, int_addr),
112      0, 0, 0, _B_TRUE };
113  /*
114   * Table of broadcast capable interfaces, hashed by interface broadcast
115   * address.
116   */
117  static struct htbl bhash_tbl = {
118      NULL, ahash, offsetof(struct interface, int_bhash),
119      offsetof(struct interface, int_brdaddr),
120      0, 0, 0, _B_TRUE };
121  /*
122   * Table of physical_interface structures (lists of interfaces by ifIndex),
123   * hashed by interface index.
124   */
125  static struct htbl ihash_tbl = {
126      NULL, ihash, offsetof(struct physical_interface, phyi_link),
127      offsetof(struct physical_interface, phyi_index),
128      0, 0, 0, _B_TRUE };
129  /*
130   * Table of all interfaces, hashed by interface name.
131   */
132  static struct htbl nhash_tbl = {
133      NULL, nhash, offsetof(struct interface, int_nhash),
134      offsetof(struct interface, int_name),
135      0, 0, 0, _B_TRUE };
136  
137  static struct physical_interface dummy_phyi;
138  struct interface dummy_ifp;
139  
140  /* Hash based on an IP address. */
141  static uint_t
ahash(const void * arg,size_t voffs)142  ahash(const void *arg, size_t voffs)
143  {
144  	/* LINTED */
145  	return ((uint_t)*(const in_addr_t *)((const char *)arg + voffs));
146  }
147  
148  static uint_t
ihash(const void * arg,size_t voffs)149  ihash(const void *arg, size_t voffs)
150  {
151  	/* LINTED */
152  	return ((uint_t)*(const uint32_t *)((const char *)arg + voffs));
153  }
154  
155  static uint_t
nhash(const void * arg,size_t voffs)156  nhash(const void *arg, size_t voffs)
157  {
158  	const char *cp = (const char *)arg + voffs;
159  	uint_t i;
160  
161  	for (i = 0; *cp != '\0'; cp++) {
162  		i = ((i<<1) & 0x7fffffff) | ((i>>30) & 0x00000003);
163  		i ^= *cp;
164  	}
165  	return (i);
166  }
167  
168  /*
169   * Add an element to the head of the list.
170   */
171  static void
link_in(void ** head,void * strp,size_t loffs)172  link_in(void **head, void *strp, size_t loffs)
173  {
174  	struct hlinkage *hlp;
175  
176  	/* LINTED: alignment known to be good. */
177  	hlp = (struct hlinkage *)((char *)strp + loffs);
178  	hlp->hl_prev = head;
179  	if ((hlp->hl_next = *head) != NULL) {
180  		/* LINTED */
181  		((struct hlinkage *)((char *)*head + loffs))->hl_prev =
182  		    &hlp->hl_next;
183  	}
184  	*head = strp;
185  }
186  
187  /* Remove from a list */
188  static void
link_out(void * strp,size_t loffs)189  link_out(void *strp, size_t loffs)
190  {
191  	struct hlinkage *hlp;
192  
193  	/* LINTED: alignment known to be good. */
194  	hlp = (struct hlinkage *)((char *)strp + loffs);
195  	if ((*hlp->hl_prev = hlp->hl_next) != NULL) {
196  		/* LINTED */
197  		((struct hlinkage *)((char *)hlp->hl_next + loffs))->hl_prev =
198  		    hlp->hl_prev;
199  	}
200  }
201  
202  /* Add to a hash */
203  static void
hash_link(struct htbl * htbl,uint_t hval,void * strp)204  hash_link(struct htbl *htbl, uint_t hval, void *strp)
205  {
206  	void **hep;
207  
208  	if (htbl->htbl_grow && htbl->htbl_ifcount >= htbl->htbl_size * 5)
209  		htbl_grow(htbl);
210  
211  	hep = &htbl->htbl_ptrs[hval % htbl->htbl_size];
212  	link_in(hep, strp, htbl->htbl_link_off);
213  	htbl->htbl_ifcount++;
214  }
215  
216  /* Remove from a hash */
217  static void
hash_unlink(struct htbl * htbl,void * strp)218  hash_unlink(struct htbl *htbl, void *strp)
219  {
220  	link_out(strp, htbl->htbl_link_off);
221  	htbl->htbl_ifcount--;
222  }
223  
224  static void
dummy_ifp_init(void)225  dummy_ifp_init(void)
226  {
227  	dummy_phyi.phyi_interface = &dummy_ifp;
228  	dummy_ifp.int_phys = &dummy_phyi;
229  	(void) strcpy(dummy_phyi.phyi_name, "wildcard");
230  	(void) strcpy(dummy_ifp.int_name, "wildcard");
231  	dummy_ifp.int_dstaddr = dummy_ifp.int_addr = INADDR_NONE;
232  	dummy_ifp.int_mask = IP_HOST_MASK;
233  	dummy_ifp.int_metric = HOPCNT_INFINITY;
234  	dummy_ifp.int_state = (IS_BROKE|IS_PASSIVE|IS_NO_RIP|IS_NO_RDISC);
235  	dummy_ifp.int_std_mask = std_mask(dummy_ifp.int_addr);
236  	dummy_ifp.int_std_net = dummy_ifp.int_net & dummy_ifp.int_std_mask;
237  	dummy_ifp.int_std_addr = htonl(dummy_ifp.int_std_net);
238  }
239  
240  /* allocate the interface hash tables */
241  void
iftbl_alloc(void)242  iftbl_alloc(void)
243  {
244  	size_t initial_size = hash_table_sizes[0];
245  
246  	errno = 0;
247  	ahash_tbl.htbl_ptrs = calloc(initial_size, sizeof (void *));
248  	bhash_tbl.htbl_ptrs = calloc(initial_size, sizeof (void *));
249  	ihash_tbl.htbl_ptrs = calloc(initial_size, sizeof (void *));
250  	nhash_tbl.htbl_ptrs = calloc(initial_size, sizeof (void *));
251  
252  	if (errno != 0)
253  		BADERR(_B_FALSE, "Unable to allocate interface tables");
254  
255  	ahash_tbl.htbl_size = initial_size;
256  	bhash_tbl.htbl_size = initial_size;
257  	ihash_tbl.htbl_size = initial_size;
258  	nhash_tbl.htbl_size = initial_size;
259  
260  	dummy_ifp_init();
261  }
262  
263  
264  static void
htbl_grow(struct htbl * htbl)265  htbl_grow(struct htbl *htbl)
266  {
267  	void *strp;
268  	void **new_ptrs, **saved_old_ptrs, **old_ptrs;
269  	size_t new_size, old_size;
270  	static uint_t failed_count;
271  
272  	if ((new_size = hash_table_sizes[htbl->htbl_size_index + 1]) == 0)
273  		return;
274  
275  	if ((new_ptrs = calloc(new_size, sizeof (void *))) == NULL) {
276  		/*
277  		 * This is not fatal since we already have a
278  		 * functional, yet crowded, interface table.
279  		 */
280  		if (++failed_count % 100 == 1)
281  			msglog("%sunable to grow interface hash table: %s",
282  			    failed_count > 1 ? "Still " : "",
283  			    rip_strerror(errno));
284  		return;
285  	}
286  
287  	failed_count = 0;
288  
289  	saved_old_ptrs = old_ptrs = htbl->htbl_ptrs;
290  	old_size = htbl->htbl_size;
291  	htbl->htbl_ptrs = new_ptrs;
292  	htbl->htbl_size = new_size;
293  	htbl->htbl_size_index++;
294  	htbl->htbl_ifcount = 0;
295  
296  	/*
297  	 * Go through the list of structures, and re-link each into
298  	 * this new table.
299  	 */
300  	htbl->htbl_grow = _B_FALSE;
301  	while (old_size-- > 0) {
302  		strp = *old_ptrs++;
303  		HADD(htbl, strp);
304  	}
305  
306  	htbl->htbl_grow = _B_TRUE;
307  	free(saved_old_ptrs);
308  }
309  
310  /* Link a new interface into the lists and hash tables. */
311  void
if_link(struct interface * ifp,uint32_t ifindex)312  if_link(struct interface *ifp, uint32_t ifindex)
313  {
314  	struct physical_interface *phyi;
315  
316  	link_in((void **)&ifnet, ifp, offsetof(struct interface, int_link));
317  
318  	HADD(&ahash_tbl, ifp);
319  	HADD(&nhash_tbl, ifp);
320  
321  	if (ifp->int_if_flags & IFF_BROADCAST)
322  		HADD(&bhash_tbl, ifp);
323  
324  	if (ifindex != 0) {
325  		for (phyi = HFIRST(&ihash_tbl, &ifindex);
326  		    phyi != NULL; phyi = phyi->phyi_link.hl_next) {
327  			if (phyi->phyi_index == ifindex)
328  				break;
329  		}
330  		if (phyi == NULL) {
331  			size_t size;
332  
333  			phyi = rtmalloc(sizeof (*phyi), "physical_interface");
334  			(void) memset(phyi, 0, sizeof (*phyi));
335  			phyi->phyi_index = ifindex;
336  			/* LINTED */
337  			assert(IF_NAME_LEN >= IF_NAMESIZE);
338  
339  			size = strcspn(ifp->int_name, ":");
340  			(void) strncpy(phyi->phyi_name, ifp->int_name,
341  			    size);
342  			phyi->phyi_name[size] = '\0';
343  			HADD(&ihash_tbl, phyi);
344  		}
345  		link_in((void **)&phyi->phyi_interface, ifp,
346  		    offsetof(struct interface, int_ilist));
347  		ifp->int_phys = phyi;
348  	}
349  }
350  
351  /* Find the interface with an address */
352  struct interface *
ifwithaddr(in_addr_t addr,boolean_t bcast,boolean_t remote)353  ifwithaddr(in_addr_t addr,
354      boolean_t bcast,	/* notice IFF_BROADCAST address */
355      boolean_t remote)	/* include IS_REMOTE interfaces */
356  {
357  	struct interface *ifp, *possible = NULL;
358  	uint32_t remote_state;
359  
360  	remote_state = (!remote ? IS_REMOTE : 0);
361  
362  	for (ifp = HFIRST(&ahash_tbl, &addr); ifp != NULL;
363  	    ifp = ifp->int_ahash.hl_next) {
364  		if (ifp->int_addr != addr)
365  			continue;
366  		if (ifp->int_state & remote_state)
367  			continue;
368  		if (!(ifp->int_state & (IS_BROKE | IS_PASSIVE)))
369  			return (ifp);
370  		possible = ifp;
371  	}
372  
373  	if (possible != NULL || !bcast)
374  		return (possible);
375  
376  	for (ifp = HFIRST(&bhash_tbl, &addr); ifp != NULL;
377  	    ifp = ifp->int_bhash.hl_next) {
378  		if (ifp->int_brdaddr != addr)
379  			continue;
380  		if (ifp->int_state & remote_state)
381  			continue;
382  		if (!(ifp->int_state & (IS_BROKE | IS_PASSIVE)))
383  			return (ifp);
384  		possible = ifp;
385  	}
386  
387  	return (possible);
388  }
389  
390  
391  /* find the interface with the specified name ("hme0" for example) */
392  struct interface *
ifwithname(const char * name)393  ifwithname(const char *name)
394  {
395  	struct interface *ifp;
396  
397  	for (;;) {
398  		for (ifp = HFIRST(&nhash_tbl, name); ifp != NULL;
399  		    ifp = ifp->int_nhash.hl_next) {
400  			if (strcmp(ifp->int_name, name) == 0)
401  				return (ifp);
402  		}
403  
404  		/*
405  		 * If there is no known interface, maybe there is a
406  		 * new interface.  So just once look for new interfaces.
407  		 */
408  		if (IF_RESCAN_DELAY())
409  			return (NULL);
410  		ifscan();
411  	}
412  }
413  
414  /* Return physical interface with the specified name */
415  struct physical_interface *
phys_byname(const char * name)416  phys_byname(const char *name)
417  {
418  	int nlen;
419  	size_t i;
420  	struct physical_interface *phyi;
421  
422  	nlen = strcspn(name, ":");
423  	for (i = 0; i < ihash_tbl.htbl_size; i++) {
424  		for (phyi = ihash_tbl.htbl_ptrs[i]; phyi != NULL;
425  		    phyi = phyi->phyi_link.hl_next) {
426  			if (strncmp(phyi->phyi_name, name, nlen) == 0 &&
427  			    phyi->phyi_name[nlen] == '\0')
428  				return (phyi);
429  		}
430  	}
431  	return (NULL);
432  }
433  
434  struct interface *
findremoteif(in_addr_t addr)435  findremoteif(in_addr_t addr)
436  {
437  	struct interface *ifp;
438  
439  	for (ifp = HFIRST(&ahash_tbl, &addr); ifp != NULL;
440  	    ifp = ifp->int_ahash.hl_next) {
441  		if ((ifp->int_state & IS_REMOTE) && ifp->int_addr == addr)
442  			return (ifp);
443  	}
444  
445  	return (NULL);
446  }
447  
448  struct interface *
findifaddr(in_addr_t addr)449  findifaddr(in_addr_t addr)
450  {
451  	struct interface *ifp;
452  
453  	for (ifp = HFIRST(&ahash_tbl, &addr); ifp != NULL;
454  	    ifp = ifp->int_ahash.hl_next) {
455  		if (ifp->int_addr == addr)
456  			return (ifp);
457  	}
458  
459  	return (NULL);
460  }
461  
462  /*
463   * Return the first interface with the given index.
464   */
465  struct interface *
ifwithindex(ulong_t index,boolean_t rescan_ok)466  ifwithindex(ulong_t index,
467      boolean_t rescan_ok)
468  {
469  	struct physical_interface *phyi;
470  
471  	for (;;) {
472  		for (phyi = HFIRST(&ihash_tbl, &index); phyi != NULL;
473  		    phyi = phyi->phyi_link.hl_next) {
474  			if (phyi->phyi_index == index)
475  				return (phyi->phyi_interface);
476  		}
477  
478  		/*
479  		 * If there is no known interface, maybe there is a
480  		 * new interface.  So just once look for new interfaces.
481  		 */
482  		if (!rescan_ok || IF_RESCAN_DELAY())
483  			return (NULL);
484  		rescan_ok = _B_FALSE;
485  		ifscan();
486  	}
487  }
488  
489  /*
490   * Returns true only if given ifp has the exact address else returns
491   * false and sets best if an ifp matches partially and is a better
492   * match than the previous one passed via best.
493   */
494  boolean_t
addr_on_ifp(in_addr_t addr,struct interface * ifp,struct interface ** best)495  addr_on_ifp(in_addr_t addr, struct interface *ifp,
496      struct interface **best)
497  {
498  	struct interface *p_best = *best;
499  
500  	/*
501  	 * Don't use a duplicate interface since it is unusable for output.
502  	 */
503  	if (ifp->int_state & IS_DUP)
504  		return (_B_FALSE);
505  
506  	if (ifp->int_if_flags & IFF_POINTOPOINT) {
507  		if (ifp->int_dstaddr == addr) {
508  			*best = NULL;
509  			return (_B_TRUE);
510  		}
511  	} else {
512  		if (ifp->int_addr == addr) {
513  			if (IS_PASSIVE_IFP(ifp))
514  				trace_misc("addr_on_ifp "
515  				    "returning passive intf %s",
516  				    ifp->int_name);
517  			*best = NULL;
518  			return (_B_TRUE);
519  		}
520  
521  		/* Look for the longest approximate match. */
522  		if (on_net(addr, ifp->int_net, ifp->int_mask) &&
523  		    (p_best == NULL ||
524  		    ifp->int_mask > p_best->int_mask)) {
525  			*best = ifp;
526  		}
527  	}
528  	return (_B_FALSE);
529  }
530  
531  /*
532   * Find an interface which should be receiving packets sent from the
533   * given address.  Used as a last ditch effort for figuring out which
534   * interface a packet came in on.  Also used for finding out which
535   * interface points towards the gateway of static routes learned from
536   * the kernel.
537   */
538  struct interface *
iflookup(in_addr_t addr)539  iflookup(in_addr_t addr)
540  {
541  	struct interface *ifp, *maybe;
542  
543  	maybe = NULL;
544  	for (;;) {
545  		for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
546  
547  			/* Exact match found */
548  			if (addr_on_ifp(addr, ifp, &maybe))
549  				return (ifp);
550  		}
551  
552  		/*
553  		 * If there is no known interface, maybe there is a
554  		 * new interface.  So just once look for new interfaces.
555  		 */
556  		if (maybe == NULL && !IF_RESCAN_DELAY())
557  			ifscan();
558  		else
559  			break;
560  	}
561  
562  	if (maybe != NULL && IS_PASSIVE_IFP(maybe)) {
563  		trace_misc("iflookup returning passive intf %s",
564  		    maybe->int_name);
565  	}
566  	return (maybe);
567  }
568  
569  /*
570   * Find the netmask that would be inferred by RIPv1 listeners
571   *	on the given interface for a given network.
572   *	If no interface is specified, look for the best fitting	interface.
573   */
574  in_addr_t
ripv1_mask_net(in_addr_t addr,const struct interface * ifp)575  ripv1_mask_net(in_addr_t addr,	/* in network byte order */
576      const struct interface *ifp)	/* as seen on this interface */
577  {
578  	const struct r1net *r1p;
579  	in_addr_t mask = 0;
580  
581  	if (addr == 0)			/* default always has 0 mask */
582  		return (mask);
583  
584  	if (ifp != NULL && ifp->int_ripv1_mask != HOST_MASK) {
585  		/*
586  		 * If the target network is that of the associated interface
587  		 * on which it arrived, then use the netmask of the interface.
588  		 */
589  		if (on_net(addr, ifp->int_net, ifp->int_std_mask))
590  			mask = ifp->int_ripv1_mask;
591  
592  	} else {
593  		/*
594  		 * Examine all interfaces, and if it the target seems
595  		 * to have the same network number of an interface, use the
596  		 * netmask of that interface.  If there is more than one
597  		 * such interface, prefer the interface with the longest
598  		 * match.
599  		 */
600  		for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
601  			if (on_net(addr, ifp->int_std_net, ifp->int_std_mask) &&
602  			    ifp->int_ripv1_mask > mask &&
603  			    ifp->int_ripv1_mask != HOST_MASK)
604  				mask = ifp->int_ripv1_mask;
605  		}
606  
607  	}
608  
609  	if (mask == 0) {
610  		/*
611  		 * Check to see if the user has supplied an applicable
612  		 * netmask as a ripv1_mask option in /etc/gateways.
613  		 */
614  		for (r1p = r1nets; r1p != NULL; r1p = r1p->r1net_next) {
615  			/*
616  			 * If the address is is on a matching network
617  			 * and we haven't already found a longer match,
618  			 * use the matching netmask.
619  			 */
620  			if (on_net(addr, r1p->r1net_net, r1p->r1net_match) &&
621  			    r1p->r1net_mask > mask)
622  				mask = r1p->r1net_mask;
623  		}
624  
625  		/* Otherwise, make the classic A/B/C guess. */
626  		if (mask == 0)
627  			mask = std_mask(addr);
628  	}
629  
630  	return (mask);
631  }
632  
633  
634  in_addr_t
ripv1_mask_host(in_addr_t addr,const struct interface * ifp)635  ripv1_mask_host(in_addr_t addr,		/* in network byte order */
636      const struct interface *ifp)	/* as seen on this interface */
637  {
638  	in_addr_t mask = ripv1_mask_net(addr, ifp);
639  
640  
641  	/*
642  	 * If the computed netmask does not mask all of the set bits
643  	 * in the address, then assume it is a host address
644  	 */
645  	if ((ntohl(addr) & ~mask) != 0)
646  		mask = HOST_MASK;
647  	return (mask);
648  }
649  
650  
651  /* See if a IP address looks reasonable as a destination */
652  boolean_t			/* _B_FALSE=bad _B_TRUE=good */
check_dst(in_addr_t addr)653  check_dst(in_addr_t addr)
654  {
655  	addr = ntohl(addr);
656  
657  	if (IN_CLASSA(addr)) {
658  		if (addr == 0)
659  			return (_B_TRUE);	/* default */
660  
661  		addr >>= IN_CLASSA_NSHIFT;
662  		return (addr != 0 && addr != IN_LOOPBACKNET);
663  	}
664  
665  	/* Must not allow destination to be link local address. */
666  	if (IN_LINKLOCAL(addr))
667  		return (_B_FALSE);
668  
669  	if (IN_CLASSB(addr) || IN_CLASSC(addr))
670  		return (_B_TRUE);
671  
672  	if (IN_CLASSD(addr))
673  		return (_B_FALSE);
674  
675  	return (_B_TRUE);
676  
677  }
678  
679  /*
680   * Find an existing interface which has the given parameters, but don't
681   * return the interface with name "name" if "name" is specified.
682   */
683  struct interface *
check_dup(const char * name,in_addr_t addr,in_addr_t dstaddr,in_addr_t mask,uint64_t if_flags,boolean_t allowdups)684  check_dup(const char *name,	/* Don't return this interface */
685      in_addr_t addr,	/* IP address, so network byte order */
686      in_addr_t dstaddr,	/* ditto */
687      in_addr_t mask,	/* mask, so host byte order */
688      uint64_t if_flags,	/* set IFF_POINTOPOINT to ignore local int_addr */
689      boolean_t allowdups)	/* set true to include duplicates */
690  {
691  	struct interface *best_ifp = NULL;
692  	struct interface *ifp;
693  	in_addr_t dstaddr_h = ntohl(dstaddr);
694  	int best_pref = 0;
695  	int pref;
696  
697  	for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
698  		/* This interface, not a duplicate. */
699  		if (name != NULL && strcmp(name, ifp->int_name) == 0)
700  			continue;
701  
702  		/*
703  		 * Find an interface which isn't already a duplicate to
704  		 * avoid cyclical duplication.  (i.e. qfe0:1 is a duplicate
705  		 * of qfe0, and qfe0 is a duplicate of qfe0:1.  That would
706  		 * be bad)
707  		 */
708  		if (!allowdups && (ifp->int_state & IS_DUP))
709  			continue;
710  
711  		if (ifp->int_mask != mask)
712  			continue;
713  
714  		if (!IS_IFF_UP(ifp->int_if_flags))
715  			continue;
716  
717  		/*
718  		 * The local address can only be shared with a point-to-point
719  		 * link.
720  		 */
721  		if ((ifp->int_addr == addr &&
722  		    ((if_flags|ifp->int_if_flags) & IFF_POINTOPOINT) == 0) ||
723  		    on_net(ifp->int_dstaddr, dstaddr_h, mask)) {
724  			pref = 0;
725  			if (!(ifp->int_state & IS_ALIAS))
726  				pref++;
727  			if (!IS_RIP_OUT_OFF(ifp->int_state))
728  				pref += 2;
729  			if (IS_IFF_ROUTING(ifp->int_if_flags))
730  				pref += 4;
731  			if (pref > best_pref) {
732  				best_pref = pref;
733  				best_ifp = ifp;
734  			}
735  		}
736  	}
737  	return (best_ifp);
738  }
739  
740  
741  /*
742   * See that a remote gateway is reachable.
743   *	Note that the answer can change as real interfaces come and go.
744   */
745  boolean_t			/* _B_FALSE=bad _B_TRUE=good */
check_remote(struct interface * ifp)746  check_remote(struct interface *ifp)
747  {
748  	struct rt_entry *rt;
749  
750  	/* do not worry about other kinds */
751  	if (!(ifp->int_state & IS_REMOTE))
752  		return (_B_TRUE);
753  
754  	rt = rtfind(ifp->int_addr);
755  	if (rt != NULL &&
756  	    rt->rt_ifp != NULL &&
757  	    on_net(ifp->int_addr, rt->rt_ifp->int_net, rt->rt_ifp->int_mask)) {
758  		return (_B_TRUE);
759  	}
760  
761  	/*
762  	 * the gateway cannot be reached directly from one of our
763  	 * interfaces
764  	 */
765  	if (!(ifp->int_state & IS_BROKE)) {
766  		msglog("unreachable gateway %s in "PATH_GATEWAYS,
767  		    naddr_ntoa(ifp->int_addr));
768  		if_bad(ifp, _B_FALSE);
769  	}
770  	return (_B_FALSE);
771  }
772  
773  /* Delete an interface. */
774  static void
ifdel(struct interface * ifp)775  ifdel(struct interface *ifp)
776  {
777  	struct rewire_data wire;
778  	boolean_t resurrected;
779  	struct physical_interface *phyi;
780  
781  	trace_if("Del", ifp);
782  
783  	ifp->int_state |= IS_BROKE;
784  
785  	/* unlink the interface */
786  	link_out(ifp, offsetof(struct interface, int_link));
787  	hash_unlink(&ahash_tbl, ifp);
788  	hash_unlink(&nhash_tbl, ifp);
789  	if (ifp->int_if_flags & IFF_BROADCAST)
790  		hash_unlink(&bhash_tbl, ifp);
791  
792  	/* Remove from list of interfaces with this ifIndex */
793  	if ((phyi = ifp->int_phys) != NULL) {
794  		link_out(ifp, offsetof(struct interface, int_ilist));
795  		if (phyi->phyi_interface == NULL) {
796  			hash_unlink(&ihash_tbl, phyi);
797  			free(phyi);
798  		}
799  	}
800  
801  	/*
802  	 * If this is a lead interface, then check first for
803  	 * duplicates of this interface with an eye towards promoting
804  	 * one of them.
805  	 */
806  	resurrected = _B_FALSE;
807  	if (!(ifp->int_state & IS_DUP) &&
808  	    (wire.if_new = check_dup(ifp->int_name, ifp->int_addr,
809  	    ifp->int_dstaddr, ifp->int_mask, ifp->int_if_flags,
810  	    _B_TRUE)) != NULL &&
811  	    !IS_IFF_QUIET(wire.if_new->int_if_flags)) {
812  
813  		trace_act("promoting duplicate %s in place of %s",
814  		    wire.if_new->int_name, ifp->int_name);
815  
816  		/* Rewire routes with the replacement interface */
817  		wire.if_old = ifp;
818  		wire.metric_delta = wire.if_new->int_metric - ifp->int_metric;
819  		(void) rn_walktree(rhead, walk_rewire, &wire);
820  		kern_rewire_ifp(wire.if_old, wire.if_new);
821  		if_rewire_rdisc(wire.if_old, wire.if_new);
822  
823  		/* Mark the replacement as being no longer a duplicate */
824  		wire.if_new->int_state &= ~IS_DUP;
825  		tot_interfaces++;
826  		if (!IS_RIP_OFF(wire.if_new->int_state))
827  			rip_interfaces++;
828  		if (!IS_RIP_OUT_OFF(wire.if_new->int_state))
829  			ripout_interfaces++;
830  		if (IS_IFF_ROUTING(wire.if_new->int_if_flags))
831  			fwd_interfaces++;
832  
833  		set_rdisc_mg(wire.if_new, 1);
834  		rip_mcast_on(wire.if_new);
835  
836  		/* We came out ok; no need to clobber routes over this. */
837  		resurrected = _B_TRUE;
838  	}
839  
840  	rip_mcast_off(ifp);
841  	if (rip_sock_interface == ifp)
842  		rip_sock_interface = NULL;
843  
844  	set_rdisc_mg(ifp, 0);
845  
846  	/*
847  	 * Note that duplicates are not counted in the total number of
848  	 * interfaces.
849  	 */
850  	if (!(ifp->int_state & IS_DUP) && !IS_IFF_QUIET(ifp->int_if_flags)) {
851  		tot_interfaces--;
852  		if (!IS_RIP_OFF(ifp->int_state))
853  			rip_interfaces--;
854  		if (!IS_RIP_OUT_OFF(ifp->int_state))
855  			ripout_interfaces--;
856  		if (IS_IFF_ROUTING(ifp->int_if_flags))
857  			fwd_interfaces--;
858  	}
859  
860  	if (!resurrected) {
861  		/*
862  		 * Zap all routes associated with this interface.
863  		 * Assume routes just using gateways beyond this interface
864  		 * will timeout naturally, and have probably already died.
865  		 */
866  		(void) rn_walktree(rhead, walk_bad, ifp);
867  		kern_flush_ifp(ifp);
868  
869  		if_bad_rdisc(ifp);
870  	}
871  
872  	free(ifp);
873  }
874  
875  
876  /* Mark an interface ill. */
877  void
if_sick(struct interface * ifp,boolean_t recurse)878  if_sick(struct interface *ifp, boolean_t recurse)
879  {
880  	struct interface *ifp1;
881  
882  	if (0 == (ifp->int_state & (IS_SICK | IS_BROKE))) {
883  		ifp->int_state |= IS_SICK;
884  		ifp->int_act_time = NEVER;
885  		trace_if("Chg", ifp);
886  
887  		LIM_SEC(ifscan_timer, now.tv_sec+CHECK_BAD_INTERVAL);
888  		if (recurse && ifp->int_phys != NULL) {
889  			/* If an interface is sick, so are its aliases. */
890  			for (ifp1 = ifp->int_phys->phyi_interface;
891  			    ifp1 != NULL; ifp1 = ifp1->int_ilist.hl_next) {
892  				if (ifp1 != ifp)
893  					if_sick(ifp1, _B_FALSE);
894  			}
895  		}
896  	}
897  }
898  
899  
900  /* Mark an interface dead. */
901  static void
if_bad(struct interface * ifp,boolean_t recurse)902  if_bad(struct interface *ifp, boolean_t recurse)
903  {
904  	struct interface *ifp1;
905  	struct rewire_data wire;
906  
907  	if (ifp->int_state & IS_BROKE)
908  		return;
909  
910  	LIM_SEC(ifscan_timer, now.tv_sec+CHECK_BAD_INTERVAL);
911  
912  	ifp->int_state |= (IS_BROKE | IS_SICK);
913  	ifp->int_act_time = NEVER;
914  	ifp->int_query_time = NEVER;
915  	/* Note: don't reset the stats timestamp here */
916  
917  	trace_if("Chg", ifp);
918  
919  	if (recurse && ifp->int_phys != NULL) {
920  		/* If an interface is bad, so are its aliases. */
921  		for (ifp1 = ifp->int_phys->phyi_interface;
922  		    ifp1 != NULL; ifp1 = ifp1->int_ilist.hl_next) {
923  			if (ifp1 != ifp)
924  				if_bad(ifp1, _B_FALSE);
925  		}
926  	}
927  
928  	/* If we can find a replacement, then pick it up. */
929  	if (!(ifp->int_state & IS_DUP) &&
930  	    (wire.if_new = check_dup(ifp->int_name, ifp->int_addr,
931  	    ifp->int_dstaddr, ifp->int_mask, ifp->int_if_flags,
932  	    _B_TRUE)) != NULL &&
933  	    !IS_IFF_QUIET(wire.if_new->int_if_flags)) {
934  		trace_act("promoting duplicate %s in place of %s",
935  		    wire.if_new->int_name, ifp->int_name);
936  		wire.if_old = ifp;
937  		wire.metric_delta = wire.if_new->int_metric - ifp->int_metric;
938  		(void) rn_walktree(rhead, walk_rewire, &wire);
939  		if_rewire_rdisc(wire.if_old, wire.if_new);
940  
941  		/* The broken guy becomes the duplicate */
942  		wire.if_new->int_state &= ~IS_DUP;
943  		set_rdisc_mg(ifp, 0);
944  		rip_mcast_off(ifp);
945  		ifp->int_state |= IS_DUP;
946  
947  		/* join the mcast groups for the replacement */
948  		set_rdisc_mg(wire.if_new, 1);
949  		rip_mcast_on(wire.if_new);
950  
951  		if (rip_sock_interface == ifp)
952  			rip_sock_interface = NULL;
953  	} else {
954  		(void) rn_walktree(rhead, walk_bad, ifp);
955  		if_bad_rdisc(ifp);
956  	}
957  }
958  
959  
960  /* Mark an interface alive */
961  void
if_ok(struct interface * ifp,const char * type,boolean_t recurse)962  if_ok(struct interface *ifp, const char *type, boolean_t recurse)
963  {
964  	struct interface *ifp1;
965  	boolean_t wasbroken = _B_FALSE;
966  
967  	if (ifp->int_state & IS_BROKE) {
968  		writelog(LOG_WARNING, "%sinterface %s to %s restored",
969  		    type, ifp->int_name, naddr_ntoa(ifp->int_dstaddr));
970  		ifp->int_state &= ~(IS_BROKE | IS_SICK);
971  		wasbroken = _B_TRUE;
972  	} else if (ifp->int_state & IS_SICK) {
973  		trace_act("%sinterface %s to %s working better",
974  		    type, ifp->int_name, naddr_ntoa(ifp->int_dstaddr));
975  		ifp->int_state &= ~IS_SICK;
976  	}
977  
978  	if (recurse && ifp->int_phys != NULL && IS_IFF_UP(ifp->int_if_flags)) {
979  		ifp->int_phys->phyi_data.ts = 0;
980  
981  		/* Also mark all aliases of this interface as ok */
982  		for (ifp1 = ifp->int_phys->phyi_interface;
983  		    ifp1 != NULL; ifp1 = ifp1->int_ilist.hl_next) {
984  			if (ifp1 != ifp)
985  				if_ok(ifp1, type, _B_FALSE);
986  		}
987  	}
988  
989  	if (wasbroken) {
990  		if (!(ifp->int_state & IS_DUP))
991  			if_ok_rdisc(ifp);
992  
993  		if (ifp->int_state & IS_REMOTE)
994  			(void) addrouteforif(ifp);
995  	}
996  }
997  
998  boolean_t
remote_address_ok(struct interface * ifp,in_addr_t addr)999  remote_address_ok(struct interface *ifp, in_addr_t addr)
1000  {
1001  	if (ifp->int_if_flags & IFF_POINTOPOINT) {
1002  		if (addr == ifp->int_dstaddr)
1003  			return (_B_TRUE);
1004  	} else if (on_net(addr, ifp->int_net, ifp->int_mask)) {
1005  		return (_B_TRUE);
1006  	}
1007  	return (_B_FALSE);
1008  }
1009  
1010  /*
1011   * Find the network interfaces which have configured themselves.
1012   *	This must be done regularly, if only for extra addresses
1013   *	that come and go on interfaces.
1014   */
1015  void
ifscan(void)1016  ifscan(void)
1017  {
1018  	uint_t complaints = 0;
1019  	static uint_t prev_complaints = 0;
1020  #define	COMP_BADADDR	0x001
1021  #define	COMP_NODST	0x002
1022  #define	COMP_NOBADDR	0x004
1023  #define	COMP_NOMASK	0x008
1024  #define	COMP_BAD_METRIC	0x010
1025  #define	COMP_NETMASK	0x020
1026  #define	COMP_NO_INDEX	0x040
1027  #define	COMP_BAD_FLAGS	0x080
1028  #define	COMP_NO_KSTATS	0x100
1029  #define	COMP_IPFORWARD	0x200
1030  
1031  	struct interface ifs, *ifp, *ifp1;
1032  	struct rt_entry *rt;
1033  	size_t needed;
1034  	static size_t lastneeded = 0;
1035  	char *buf;
1036  	static char *lastbuf = NULL;
1037  	int32_t in, ierr, out, oerr;
1038  	struct intnet *intnetp;
1039  	int sock;
1040  	struct lifnum lifn;
1041  	struct lifconf lifc;
1042  	struct lifreq *lifrp, *lifrp_lim;
1043  	struct sockaddr_in *sinp;
1044  	in_addr_t haddr;
1045  	static in_addr_t myaddr = 0;
1046  	uint32_t ifindex;
1047  	struct phyi_data newstats;
1048  	struct physical_interface *phyi;
1049  
1050  	last_ifscan = now;
1051  	ifscan_timer.tv_sec = now.tv_sec +
1052  	    (supplier || tot_interfaces != 1 ?
1053  	    CHECK_ACT_INTERVAL : CHECK_QUIET_INTERVAL);
1054  
1055  	/* mark all interfaces so we can get rid of those that disappear */
1056  	for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next)
1057  		ifp->int_state &= ~IS_CHECKED;
1058  
1059  	/* Fetch the size of the current interface list */
1060  	if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
1061  		BADERR(_B_TRUE, "ifscan: socket(SOCK_DGRAM)");
1062  	lifn.lifn_family = AF_INET;	/* Only count IPv4 interfaces */
1063  	/*
1064  	 * Include IFF_NOXMIT interfaces.  Such interfaces are exluded
1065  	 * from protocol operations, but their inclusion in the
1066  	 * internal table enables us to know when packets arrive on
1067  	 * such interfaces.
1068  	 */
1069  	lifn.lifn_flags = LIFC_NOXMIT;
1070  calculate_lifc_len:
1071  	if (ioctl(sock, SIOCGLIFNUM, &lifn) == -1) {
1072  		BADERR(_B_TRUE, "ifscan: ioctl(SIOCGLIFNUM)");
1073  	}
1074  
1075  	/*
1076  	 * When calculating the buffer size needed, add a small number
1077  	 * of interfaces to those we counted.  We do this to capture
1078  	 * the interface status of potential interfaces which may have
1079  	 * been plumbed between the SIOCGLIFNUM and the SIOCGLIFCONF.
1080  	 * Try to reuse the buffer we already have to avoid heap
1081  	 * thrash.
1082  	 */
1083  	needed = (lifn.lifn_count + 4) * sizeof (struct lifreq);
1084  	if (needed > lastneeded || needed < lastneeded/2) {
1085  		if (lastbuf != NULL)
1086  			free(lastbuf);
1087  		if ((buf = malloc(needed)) == NULL) {
1088  			lastbuf = NULL;
1089  			msglog("ifscan: malloc: %s", rip_strerror(errno));
1090  			return;
1091  		}
1092  	} else {
1093  		buf = lastbuf;
1094  	}
1095  	lastbuf = buf;
1096  	lastneeded = needed;
1097  
1098  	/* Get the list */
1099  	lifc.lifc_family = AF_INET;	/* We only need IPv4 interfaces */
1100  	lifc.lifc_flags = LIFC_NOXMIT;
1101  	lifc.lifc_len = needed;
1102  	lifc.lifc_buf = buf;
1103  	if (ioctl(sock, SIOCGLIFCONF, &lifc) == -1) {
1104  		/*
1105  		 * IP returns EINVAL if the lifc_len we passed in is
1106  		 * too small.  If that's the case, we need to go back
1107  		 * and recalculate it.
1108  		 */
1109  		if (errno == EINVAL)
1110  			goto calculate_lifc_len;
1111  		BADERR(_B_TRUE, "ifscan: ioctl(SIOCGLIFCONF)");
1112  	}
1113  
1114  	/*
1115  	 * If the returned lifc_len is within one lifreq of the
1116  	 * requested ammount, we may have used a buffer which
1117  	 * was too small to hold all of the interfaces.  In that
1118  	 * case go back and recalculate needed.
1119  	 */
1120  	if (lifc.lifc_len >= needed - sizeof (struct lifreq))
1121  		goto calculate_lifc_len;
1122  
1123  	lifrp = lifc.lifc_req;
1124  	lifrp_lim = lifrp + lifc.lifc_len / sizeof (*lifrp);
1125  	for (; lifrp < lifrp_lim; lifrp++) {
1126  
1127  		(void) memset(&ifs, 0, sizeof (ifs));
1128  
1129  		(void) strlcpy(ifs.int_name, lifrp->lifr_name,
1130  		    sizeof (ifs.int_name));
1131  
1132  		/* SIOCGLIFCONF fills in the lifr_addr of each lifreq */
1133  		ifs.int_addr = ((struct sockaddr_in *)&lifrp->lifr_addr)->
1134  		    sin_addr.s_addr;
1135  
1136  		if (ioctl(sock, SIOCGLIFFLAGS, lifrp) == -1) {
1137  			if (!(prev_complaints & COMP_BAD_FLAGS))
1138  				writelog(LOG_NOTICE,
1139  				    "unable to get interface flags for %s: %s",
1140  				    ifs.int_name, rip_strerror(errno));
1141  			complaints |= COMP_BAD_FLAGS;
1142  			ifs.int_if_flags = 0;
1143  		} else {
1144  			ifs.int_if_flags = lifrp->lifr_flags;
1145  		}
1146  
1147  		if (IN_CLASSD(ntohl(ifs.int_addr)) ||
1148  		    (ntohl(ifs.int_addr) & IN_CLASSA_NET) == 0) {
1149  			if (IS_IFF_UP(ifs.int_if_flags)) {
1150  				if (!(prev_complaints & COMP_BADADDR))
1151  					writelog(LOG_NOTICE,
1152  					    "%s has a bad address %s",
1153  					    ifs.int_name,
1154  					    naddr_ntoa(ifs.int_addr));
1155  				complaints |= COMP_BADADDR;
1156  			}
1157  			continue;
1158  		}
1159  
1160  		/* Ignore interface with IPv4 link local address. */
1161  		if (IN_LINKLOCAL(ntohl(ifs.int_addr)))
1162  			continue;
1163  
1164  		/* Get the interface index. */
1165  		if (ioctl(sock, SIOCGLIFINDEX, lifrp) == -1) {
1166  			ifindex = 0;
1167  			ifs.int_if_flags &= ~IFF_UP;
1168  			if (!(prev_complaints & COMP_NO_INDEX))
1169  				writelog(LOG_NOTICE, "%s has no ifIndex: %s",
1170  				    ifs.int_name, rip_strerror(errno));
1171  			complaints |= COMP_NO_INDEX;
1172  		} else {
1173  			ifindex = lifrp->lifr_index;
1174  		}
1175  
1176  		/*
1177  		 * Get the destination address for point-to-point
1178  		 * interfaces.
1179  		 */
1180  		if (ifs.int_if_flags & IFF_POINTOPOINT) {
1181  			sinp = (struct sockaddr_in *)&lifrp->lifr_dstaddr;
1182  			if (ioctl(sock, SIOCGLIFDSTADDR, lifrp) == -1) {
1183  				if (IS_IFF_UP(ifs.int_if_flags)) {
1184  					if (!(prev_complaints & COMP_NODST))
1185  						writelog(LOG_NOTICE,
1186  						    "%s has no destination "
1187  						    "address : %s",
1188  						    ifs.int_name,
1189  						    rip_strerror(errno));
1190  					complaints |= COMP_NODST;
1191  				}
1192  				continue;
1193  			}
1194  			ifs.int_net = ntohl(sinp->sin_addr.s_addr);
1195  			if (IN_CLASSD(ntohl(ifs.int_net)) ||
1196  			    (ifs.int_net != 0 &&
1197  			    (ifs.int_net & IN_CLASSA_NET) == 0)) {
1198  				if (IS_IFF_UP(ifs.int_if_flags)) {
1199  					if (!(prev_complaints & COMP_NODST))
1200  						writelog(LOG_NOTICE,
1201  						    "%s has a bad "
1202  						    "destination address %s",
1203  						    ifs.int_name,
1204  						    naddr_ntoa(ifs.int_net));
1205  					complaints |= COMP_NODST;
1206  				}
1207  				continue;
1208  			}
1209  			ifs.int_dstaddr = sinp->sin_addr.s_addr;
1210  		}
1211  
1212  		/* Get the subnet mask */
1213  		sinp = (struct sockaddr_in *)&lifrp->lifr_addr;
1214  		if (ioctl(sock, SIOCGLIFNETMASK, lifrp) == -1) {
1215  			if (IS_IFF_UP(ifs.int_if_flags)) {
1216  				if (!(prev_complaints & COMP_NOMASK))
1217  					writelog(LOG_NOTICE,
1218  					    "%s has no netmask: %s",
1219  					    ifs.int_name, rip_strerror(errno));
1220  				complaints |= COMP_NOMASK;
1221  			}
1222  			continue;
1223  		}
1224  		if (sinp->sin_addr.s_addr == INADDR_ANY) {
1225  			if (!(ifs.int_if_flags &
1226  			    (IFF_POINTOPOINT|IFF_LOOPBACK))) {
1227  				if (IS_IFF_UP(ifs.int_if_flags)) {
1228  					if (!(prev_complaints & COMP_NOMASK))
1229  						writelog(LOG_NOTICE,
1230  						    "%s has all-zero netmask",
1231  						    ifs.int_name);
1232  					complaints |= COMP_NOMASK;
1233  				}
1234  				continue;
1235  			}
1236  			ifs.int_mask = IP_HOST_MASK;
1237  		} else {
1238  			ifs.int_mask = ntohl(sinp->sin_addr.s_addr);
1239  		}
1240  
1241  		/*
1242  		 * Get the broadcast address on broadcast capable
1243  		 * interfaces.
1244  		 */
1245  		if (ifs.int_if_flags & IFF_BROADCAST) {
1246  			if (ioctl(sock, SIOCGLIFBRDADDR, lifrp) == -1) {
1247  				if (IS_IFF_UP(ifs.int_if_flags)) {
1248  					if (!(prev_complaints & COMP_NOBADDR))
1249  						writelog(LOG_NOTICE,
1250  						    "%s has no broadcast "
1251  						    "address: %s",
1252  						    ifs.int_name,
1253  						    rip_strerror(errno));
1254  					complaints |= COMP_NOBADDR;
1255  				}
1256  				continue;
1257  			}
1258  			haddr = ntohl(sinp->sin_addr.s_addr);
1259  			if (IN_CLASSD(haddr) ||
1260  			    (haddr & IN_CLASSA_NET) == 0) {
1261  				if (IS_IFF_UP(ifs.int_if_flags)) {
1262  					if (!(prev_complaints & COMP_NOBADDR))
1263  						writelog(LOG_NOTICE,
1264  						    "%s has a bad broadcast "
1265  						    "address %s",
1266  						    ifs.int_name,
1267  						    naddr_ntoa(haddr));
1268  					complaints |= COMP_NOBADDR;
1269  				}
1270  				continue;
1271  			}
1272  		}
1273  		ifs.int_brdaddr = sinp->sin_addr.s_addr;
1274  
1275  		/* Get interface metric, if possible. */
1276  		if (ioctl(sock, SIOCGLIFMETRIC, lifrp) == -1) {
1277  			if (IS_IFF_UP(ifs.int_if_flags)) {
1278  				if (!(prev_complaints & COMP_BAD_METRIC))
1279  					writelog(LOG_NOTICE,
1280  					    "%s has no metric: %s",
1281  					    ifs.int_name, rip_strerror(errno));
1282  				complaints |= COMP_BAD_METRIC;
1283  			}
1284  		} else {
1285  			ifs.int_metric = lifrp->lifr_metric;
1286  			if (ifs.int_metric > HOPCNT_INFINITY) {
1287  				if (IS_IFF_UP(ifs.int_if_flags)) {
1288  					if (!(prev_complaints &
1289  					    COMP_BAD_METRIC))
1290  						writelog(LOG_NOTICE,
1291  						    "%s has a metric of %d, "
1292  						    "defaulting to %d",
1293  						    ifs.int_name,
1294  						    ifs.int_metric,
1295  						    HOPCNT_INFINITY);
1296  					complaints |= COMP_BAD_METRIC;
1297  				}
1298  				ifs.int_metric = HOPCNT_INFINITY;
1299  			}
1300  		}
1301  
1302  		ifs.int_state |= IS_CHECKED;
1303  		ifs.int_query_time = NEVER;
1304  
1305  		/*
1306  		 * If this is an alias, then mark it appropriately.
1307  		 * Do not output RIP or Router-Discovery packets via
1308  		 * aliases.
1309  		 */
1310  		if (strchr(ifs.int_name, ':') != NULL)
1311  			ifs.int_state |= IS_ALIAS;
1312  
1313  		if (ifs.int_if_flags & IFF_LOOPBACK) {
1314  			ifs.int_state |= IS_PASSIVE | IS_NO_RIP | IS_NO_RDISC;
1315  			ifs.int_dstaddr = ifs.int_addr;
1316  			ifs.int_mask = HOST_MASK;
1317  			ifs.int_ripv1_mask = HOST_MASK;
1318  			ifs.int_std_mask = std_mask(ifs.int_dstaddr);
1319  			ifs.int_net = ntohl(ifs.int_dstaddr);
1320  			if (!foundloopback) {
1321  				foundloopback = _B_TRUE;
1322  				loopaddr = ifs.int_addr;
1323  				loop_rts.rts_gate = loopaddr;
1324  				loop_rts.rts_router = loopaddr;
1325  			}
1326  
1327  		} else if (ifs.int_if_flags & IFF_POINTOPOINT) {
1328  			ifs.int_ripv1_mask = ifs.int_mask;
1329  			ifs.int_mask = HOST_MASK;
1330  			ifs.int_std_mask = std_mask(ifs.int_dstaddr);
1331  
1332  		} else {
1333  			ifs.int_dstaddr = ifs.int_addr;
1334  			ifs.int_ripv1_mask = ifs.int_mask;
1335  			ifs.int_std_mask = std_mask(ifs.int_addr);
1336  			ifs.int_net = ntohl(ifs.int_addr) & ifs.int_mask;
1337  			if (ifs.int_mask != ifs.int_std_mask)
1338  				ifs.int_state |= IS_SUBNET;
1339  		}
1340  		ifs.int_std_net = ifs.int_net & ifs.int_std_mask;
1341  		ifs.int_std_addr = htonl(ifs.int_std_net);
1342  
1343  		/*
1344  		 * If this interface duplicates another, mark it
1345  		 * appropriately so that we don't generate duplicate
1346  		 * packets.
1347  		 */
1348  		ifp = check_dup(ifs.int_name, ifs.int_addr, ifs.int_dstaddr,
1349  		    ifs.int_mask, ifs.int_if_flags, _B_FALSE);
1350  		if (ifp != NULL) {
1351  			trace_misc("%s (%s%s%s) is a duplicate of %s (%s%s%s)",
1352  			    ifs.int_name,
1353  			    addrname(ifs.int_addr, ifs.int_mask, 1),
1354  			    ((ifs.int_if_flags & IFF_POINTOPOINT) ?
1355  			    "-->" : ""),
1356  			    ((ifs.int_if_flags & IFF_POINTOPOINT) ?
1357  			    naddr_ntoa(ifs.int_dstaddr) : ""),
1358  			    ifp->int_name,
1359  			    addrname(ifp->int_addr, ifp->int_mask, 1),
1360  			    ((ifp->int_if_flags & IFF_POINTOPOINT) ?
1361  			    "-->" : ""),
1362  			    ((ifp->int_if_flags & IFF_POINTOPOINT) ?
1363  			    naddr_ntoa(ifp->int_dstaddr) : ""));
1364  			ifs.int_state |= IS_DUP;
1365  		} else {
1366  			ifs.int_state &= ~IS_DUP;
1367  		}
1368  
1369  		/*
1370  		 * See if this is a familiar interface.
1371  		 * If so, stop worrying about it if it is the same.
1372  		 * Start it over if it now is to somewhere else, as happens
1373  		 * frequently with PPP and SLIP, or if its forwarding
1374  		 * status has changed.
1375  		 */
1376  		ifp = ifwithname(ifs.int_name);
1377  		if (ifp != NULL) {
1378  			ifp->int_state |= IS_CHECKED;
1379  			ifp->int_state = (ifp->int_state & ~IS_DUP) |
1380  			    (ifs.int_state & IS_DUP);
1381  
1382  			if ((ifp->int_phys == NULL && ifindex != 0) ||
1383  			    (ifp->int_phys != NULL &&
1384  			    ifp->int_phys->phyi_index != ifindex) ||
1385  			    0 != ((ifp->int_if_flags ^ ifs.int_if_flags)
1386  			    & (IFF_BROADCAST | IFF_LOOPBACK |
1387  			    IFF_POINTOPOINT | IFF_MULTICAST |
1388  			    IFF_ROUTER | IFF_NORTEXCH | IFF_NOXMIT)) ||
1389  			    ifp->int_addr != ifs.int_addr ||
1390  			    ifp->int_brdaddr != ifs.int_brdaddr ||
1391  			    ifp->int_dstaddr != ifs.int_dstaddr ||
1392  			    ifp->int_mask != ifs.int_mask ||
1393  			    ifp->int_metric != ifs.int_metric) {
1394  				/*
1395  				 * Forget old information about
1396  				 * a changed interface.
1397  				 */
1398  				trace_act("interface %s has changed",
1399  				    ifp->int_name);
1400  				ifdel(ifp);
1401  				ifp = NULL;
1402  			}
1403  		}
1404  
1405  		if (ifp != NULL) {
1406  			/* note interfaces that have been turned off */
1407  			if (!IS_IFF_UP(ifs.int_if_flags)) {
1408  				if (IS_IFF_UP(ifp->int_if_flags)) {
1409  					writelog(LOG_WARNING,
1410  					    "interface %s to %s turned off",
1411  					    ifp->int_name,
1412  					    naddr_ntoa(ifp->int_dstaddr));
1413  					if_bad(ifp, _B_FALSE);
1414  					ifp->int_if_flags &= ~IFF_UP;
1415  				} else if (ifp->int_phys != NULL &&
1416  				    now.tv_sec > (ifp->int_phys->phyi_data.ts +
1417  				    CHECK_BAD_INTERVAL)) {
1418  					trace_act("interface %s has been off"
1419  					    " %ld seconds; forget it",
1420  					    ifp->int_name,
1421  					    now.tv_sec -
1422  					    ifp->int_phys->phyi_data.ts);
1423  					ifdel(ifp);
1424  				}
1425  				continue;
1426  			}
1427  			/* or that were off and are now ok */
1428  			if (!IS_IFF_UP(ifp->int_if_flags)) {
1429  				ifp->int_if_flags |= IFF_UP;
1430  				if_ok(ifp, "", _B_FALSE);
1431  			}
1432  
1433  			/*
1434  			 * If it has been long enough,
1435  			 * see if the interface is broken.
1436  			 */
1437  			if ((phyi = ifp->int_phys) == NULL ||
1438  			    now.tv_sec < phyi->phyi_data.ts +
1439  			    CHECK_BAD_INTERVAL)
1440  				continue;
1441  
1442  			(void) memset(&newstats, 0, sizeof (newstats));
1443  			if (get_if_kstats(ifp, &newstats) == -1) {
1444  				if (!(prev_complaints & COMP_NO_KSTATS))
1445  					writelog(LOG_WARNING,
1446  					    "unable to obtain kstats for %s",
1447  					    phyi->phyi_name);
1448  				complaints |= COMP_NO_KSTATS;
1449  			}
1450  
1451  			/*
1452  			 * If the interface just awoke, restart the counters.
1453  			 */
1454  			if (phyi->phyi_data.ts == 0) {
1455  				phyi->phyi_data = newstats;
1456  				continue;
1457  			}
1458  
1459  			in = newstats.ipackets - phyi->phyi_data.ipackets;
1460  			ierr = newstats.ierrors - phyi->phyi_data.ierrors;
1461  			out = newstats.opackets - phyi->phyi_data.opackets;
1462  			oerr = newstats.oerrors - phyi->phyi_data.oerrors;
1463  			phyi->phyi_data = newstats;
1464  
1465  			/*
1466  			 * Withhold judgment when the short error counters
1467  			 * wrap, the interface is reset, or if there are
1468  			 * no kstats.
1469  			 */
1470  			if (ierr < 0 || in < 0 || oerr < 0 || out < 0 ||
1471  			    newstats.ts == 0) {
1472  				LIM_SEC(ifscan_timer,
1473  				    now.tv_sec + CHECK_BAD_INTERVAL);
1474  				continue;
1475  			}
1476  
1477  			/* Withhold judgement when there is no traffic */
1478  			if (in == 0 && out == 0 && ierr == 0 && oerr == 0)
1479  				continue;
1480  
1481  			/*
1482  			 * It is bad if at least 25% of input or output on
1483  			 * an interface results in errors.  Require
1484  			 * presistent problems before marking it dead.
1485  			 */
1486  			if ((ierr > 0 && ierr >= in/4) ||
1487  			    (oerr > 0 && oerr >= out/4)) {
1488  				if (!(ifp->int_state & IS_SICK)) {
1489  					trace_act("interface %s to %s"
1490  					    " sick: in=%d ierr=%d"
1491  					    " out=%d oerr=%d",
1492  					    ifp->int_name,
1493  					    naddr_ntoa(ifp->int_dstaddr),
1494  					    in, ierr, out, oerr);
1495  					if_sick(ifp, _B_TRUE);
1496  					continue;
1497  				}
1498  				if (!(ifp->int_state & IS_BROKE)) {
1499  					writelog(LOG_WARNING,
1500  					    "interface %s to %s broken:"
1501  					    " in=%d ierr=%d out=%d oerr=%d",
1502  					    ifp->int_name,
1503  					    naddr_ntoa(ifp->int_dstaddr),
1504  					    in, ierr, out, oerr);
1505  					if_bad(ifp, _B_TRUE);
1506  				}
1507  				continue;
1508  			}
1509  
1510  			/* otherwise, it is active and healthy */
1511  			ifp->int_act_time = now.tv_sec;
1512  			if_ok(ifp, "", _B_TRUE);
1513  			continue;
1514  		}
1515  
1516  		/*
1517  		 * This is a new interface.
1518  		 * If it is dead, forget it.
1519  		 */
1520  		if (!IS_IFF_UP(ifs.int_if_flags))
1521  			continue;
1522  
1523  		if (0 == (ifs.int_if_flags & (IFF_POINTOPOINT |
1524  		    IFF_BROADCAST | IFF_LOOPBACK)) &&
1525  		    !(ifs.int_state & IS_PASSIVE)) {
1526  			if (!(prev_complaints & COMP_BAD_FLAGS))
1527  				trace_act("%s is neither broadcast, "
1528  				    "point-to-point, nor loopback",
1529  				    ifs.int_name);
1530  			complaints |= COMP_BAD_FLAGS;
1531  			if (!(ifs.int_if_flags & IFF_MULTICAST))
1532  				ifs.int_state |= IS_NO_RDISC;
1533  		}
1534  
1535  
1536  		/*
1537  		 * It is new and ok.   Add it to the list of interfaces
1538  		 */
1539  		ifp = rtmalloc(sizeof (*ifp), "ifscan ifp");
1540  		(void) memcpy(ifp, &ifs, sizeof (*ifp));
1541  		get_parms(ifp);
1542  		if_link(ifp, ifindex);
1543  		trace_if("Add", ifp);
1544  
1545  		if (ifp->int_phys != NULL &&
1546  		    get_if_kstats(ifp, &ifp->int_phys->phyi_data) == -1) {
1547  			if (!(prev_complaints & COMP_NO_KSTATS))
1548  				writelog(LOG_NOTICE,
1549  				    "unable to obtain kstats for %s",
1550  				    ifp->int_phys->phyi_name);
1551  			complaints |= COMP_NO_KSTATS;
1552  		}
1553  
1554  		/* Detect interfaces that have conflicting netmasks. */
1555  		if (!(ifp->int_if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK))) {
1556  			for (ifp1 = ifnet; ifp1 != NULL;
1557  			    ifp1 = ifp1->int_next) {
1558  				if (ifp1->int_mask == ifp->int_mask)
1559  					continue;
1560  
1561  				/*
1562  				 * we don't care about point-to-point
1563  				 * or loopback aliases
1564  				 */
1565  				if (ifp1->int_if_flags &
1566  				    (IFF_POINTOPOINT|IFF_LOOPBACK)) {
1567  					continue;
1568  				}
1569  
1570  				/* ignore aliases on the same network */
1571  				if (ifp->int_phys == ifp1->int_phys)
1572  					continue;
1573  
1574  				if (on_net(ifp->int_addr,
1575  				    ifp1->int_net, ifp1->int_mask) ||
1576  				    on_net(ifp1->int_addr,
1577  				    ifp->int_net, ifp->int_mask)) {
1578  					writelog(LOG_INFO,
1579  					    "possible netmask problem"
1580  					    " between %s:%s and %s:%s",
1581  					    ifp->int_name,
1582  					    addrname(htonl(ifp->int_net),
1583  					    ifp->int_mask, 1),
1584  					    ifp1->int_name,
1585  					    addrname(htonl(ifp1->int_net),
1586  					    ifp1->int_mask, 1));
1587  					complaints |= COMP_NETMASK;
1588  				}
1589  			}
1590  		}
1591  
1592  		if (!(ifp->int_state & IS_DUP) &&
1593  		    !IS_IFF_QUIET(ifp->int_if_flags)) {
1594  			/* Count the # of directly connected networks. */
1595  			tot_interfaces++;
1596  			if (!IS_RIP_OFF(ifp->int_state))
1597  				rip_interfaces++;
1598  			if (!IS_RIP_OUT_OFF(ifp->int_state))
1599  				ripout_interfaces++;
1600  			if (IS_IFF_ROUTING(ifp->int_if_flags))
1601  				fwd_interfaces++;
1602  
1603  			if_ok_rdisc(ifp);
1604  			rip_on(ifp);
1605  		}
1606  	}
1607  
1608  	(void) close(sock);
1609  
1610  	/*
1611  	 * If we are multi-homed and have at least two interfaces that
1612  	 * are able to forward, then output RIP by default.
1613  	 */
1614  	if (!supplier_set)
1615  		set_supplier();
1616  
1617  	/*
1618  	 * If we are multi-homed, optionally advertise a route to
1619  	 * our main address.
1620  	 */
1621  	if (advertise_mhome || (tot_interfaces > 1 && mhome)) {
1622  		/* lookup myaddr if we haven't done so already */
1623  		if (myaddr == 0) {
1624  			char myname[MAXHOSTNAMELEN+1];
1625  
1626  			/*
1627  			 * If we are unable to resolve our hostname, don't
1628  			 * bother trying again.
1629  			 */
1630  			if (gethostname(myname, MAXHOSTNAMELEN) == -1) {
1631  				msglog("gethostname: %s", rip_strerror(errno));
1632  				advertise_mhome = _B_FALSE;
1633  				mhome = _B_FALSE;
1634  			} else if (gethost(myname, &myaddr) == 0) {
1635  				writelog(LOG_WARNING,
1636  				    "unable to resolve local hostname %s",
1637  				    myname);
1638  				advertise_mhome = _B_FALSE;
1639  				mhome = _B_FALSE;
1640  			}
1641  		}
1642  		if (myaddr != 0 &&
1643  		    (ifp = ifwithaddr(myaddr, _B_FALSE, _B_FALSE)) != NULL &&
1644  		    foundloopback) {
1645  			advertise_mhome = _B_TRUE;
1646  			rt = rtget(myaddr, HOST_MASK);
1647  			if (rt != NULL) {
1648  				if (rt->rt_ifp != ifp ||
1649  				    rt->rt_router != loopaddr) {
1650  					rtdelete(rt);
1651  					rt = NULL;
1652  				} else {
1653  					loop_rts.rts_ifp = ifp;
1654  					loop_rts.rts_metric = 0;
1655  					loop_rts.rts_time = rt->rt_time;
1656  					loop_rts.rts_origin = RO_LOOPBCK;
1657  					rtchange(rt, rt->rt_state | RS_MHOME,
1658  					    &loop_rts, NULL);
1659  				}
1660  			}
1661  			if (rt == NULL) {
1662  				loop_rts.rts_ifp = ifp;
1663  				loop_rts.rts_metric = 0;
1664  				loop_rts.rts_origin = RO_LOOPBCK;
1665  				rtadd(myaddr, HOST_MASK, RS_MHOME, &loop_rts);
1666  			}
1667  		}
1668  	}
1669  
1670  	for (ifp = ifnet; ifp != NULL; ifp = ifp1) {
1671  		ifp1 = ifp->int_next;	/* because we may delete it */
1672  
1673  		/* Forget any interfaces that have disappeared. */
1674  		if (!(ifp->int_state & (IS_CHECKED | IS_REMOTE))) {
1675  			trace_act("interface %s has disappeared",
1676  			    ifp->int_name);
1677  			ifdel(ifp);
1678  			continue;
1679  		}
1680  
1681  		if ((ifp->int_state & IS_BROKE) &&
1682  		    !(ifp->int_state & IS_PASSIVE))
1683  			LIM_SEC(ifscan_timer, now.tv_sec+CHECK_BAD_INTERVAL);
1684  
1685  		/*
1686  		 * If we ever have a RIPv1 interface, assume we always will.
1687  		 * It might come back if it ever goes away.
1688  		 */
1689  		if (!(ifp->int_state & (IS_NO_RIPV1_OUT | IS_DUP)) &&
1690  		    should_supply(ifp))
1691  			have_ripv1_out = _B_TRUE;
1692  		if (!(ifp->int_state & IS_NO_RIPV1_IN))
1693  			have_ripv1_in = _B_TRUE;
1694  	}
1695  
1696  	for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
1697  		/*
1698  		 * Ensure there is always a network route for interfaces,
1699  		 * after any dead interfaces have been deleted, which
1700  		 * might affect routes for point-to-point links.
1701  		 */
1702  		if (addrouteforif(ifp) == 0)
1703  			continue;
1704  
1705  		/*
1706  		 * Add routes to the local end of point-to-point interfaces
1707  		 * using loopback.
1708  		 */
1709  		if ((ifp->int_if_flags & IFF_POINTOPOINT) &&
1710  		    !(ifp->int_state & IS_REMOTE) && foundloopback) {
1711  			/*
1712  			 * Delete any routes to the network address through
1713  			 * foreign routers. Remove even static routes.
1714  			 */
1715  			del_static(ifp->int_addr, HOST_MASK, 0, ifp, 0);
1716  			rt = rtget(ifp->int_addr, HOST_MASK);
1717  			if (rt != NULL && rt->rt_router != loopaddr) {
1718  				rtdelete(rt);
1719  				rt = NULL;
1720  			}
1721  			if (rt != NULL) {
1722  				if (!(rt->rt_state & RS_LOCAL) ||
1723  				    rt->rt_metric > ifp->int_metric) {
1724  					ifp1 = ifp;
1725  				} else {
1726  					ifp1 = rt->rt_ifp;
1727  				}
1728  				loop_rts.rts_ifp = ifp1;
1729  				loop_rts.rts_metric = 0;
1730  				loop_rts.rts_time = rt->rt_time;
1731  				loop_rts.rts_origin = RO_LOOPBCK;
1732  				rtchange(rt, ((rt->rt_state & ~RS_NET_SYN) |
1733  				    (RS_IF|RS_LOCAL)), &loop_rts, 0);
1734  			} else {
1735  				loop_rts.rts_ifp = ifp;
1736  				loop_rts.rts_metric = 0;
1737  				loop_rts.rts_origin = RO_LOOPBCK;
1738  				rtadd(ifp->int_addr, HOST_MASK,
1739  				    (RS_IF | RS_LOCAL), &loop_rts);
1740  			}
1741  		}
1742  	}
1743  
1744  	/* add the authority routes */
1745  	for (intnetp = intnets; intnetp != NULL;
1746  	    intnetp = intnetp->intnet_next) {
1747  		rt = rtget(intnetp->intnet_addr, intnetp->intnet_mask);
1748  		if (rt != NULL &&
1749  		    !(rt->rt_state & RS_NO_NET_SYN) &&
1750  		    !(rt->rt_state & RS_NET_INT)) {
1751  			rtdelete(rt);
1752  			rt = NULL;
1753  		}
1754  		if (rt == NULL) {
1755  			loop_rts.rts_ifp = NULL;
1756  			loop_rts.rts_metric = intnetp->intnet_metric-1;
1757  			loop_rts.rts_origin = RO_LOOPBCK;
1758  			rtadd(intnetp->intnet_addr, intnetp->intnet_mask,
1759  			    RS_NET_SYN | RS_NET_INT, &loop_rts);
1760  		}
1761  	}
1762  
1763  	prev_complaints = complaints;
1764  }
1765  
1766  
1767  static void
check_net_syn(struct interface * ifp)1768  check_net_syn(struct interface *ifp)
1769  {
1770  	struct rt_entry *rt;
1771  	struct rt_spare new;
1772  
1773  	/*
1774  	 * Turn on the need to automatically synthesize a network route
1775  	 * for this interface only if we are running RIPv1 on some other
1776  	 * interface that is on a different class-A,B,or C network.
1777  	 */
1778  	if (have_ripv1_out || have_ripv1_in) {
1779  		ifp->int_state |= IS_NEED_NET_SYN;
1780  		rt = rtget(ifp->int_std_addr, ifp->int_std_mask);
1781  		if (rt != NULL &&
1782  		    0 == (rt->rt_state & RS_NO_NET_SYN) &&
1783  		    (!(rt->rt_state & RS_NET_SYN) ||
1784  		    rt->rt_metric > ifp->int_metric)) {
1785  			rtdelete(rt);
1786  			rt = NULL;
1787  		}
1788  		if (rt == NULL) {
1789  			(void) memset(&new, 0, sizeof (new));
1790  			new.rts_ifp = ifp;
1791  			new.rts_gate = ifp->int_addr;
1792  			new.rts_router = ifp->int_addr;
1793  			new.rts_metric = ifp->int_metric;
1794  			new.rts_origin = RO_NET_SYN;
1795  			rtadd(ifp->int_std_addr, ifp->int_std_mask,
1796  			    RS_NET_SYN, &new);
1797  		}
1798  
1799  	} else {
1800  		ifp->int_state &= ~IS_NEED_NET_SYN;
1801  
1802  		rt = rtget(ifp->int_std_addr, ifp->int_std_mask);
1803  		if (rt != NULL &&
1804  		    (rt->rt_state & RS_NET_SYN) &&
1805  		    rt->rt_ifp == ifp)
1806  			rtbad_sub(rt, NULL);
1807  	}
1808  }
1809  
1810  
1811  /*
1812   * Add route for interface if not currently installed.
1813   * Create route to other end if a point-to-point link,
1814   * otherwise a route to this (sub)network.
1815   */
1816  static boolean_t			/* _B_FALSE=bad interface */
addrouteforif(struct interface * ifp)1817  addrouteforif(struct interface *ifp)
1818  {
1819  	struct rt_entry *rt;
1820  	struct rt_spare new;
1821  	in_addr_t dst;
1822  	uint16_t rt_newstate = RS_IF;
1823  
1824  
1825  	/* skip sick interfaces */
1826  	if (ifp->int_state & IS_BROKE)
1827  		return (_B_FALSE);
1828  
1829  	/*
1830  	 * don't install routes for duplicate interfaces, or
1831  	 * unnumbered point-to-point interfaces.
1832  	 */
1833  	if ((ifp->int_state & IS_DUP) ||
1834  	    ((ifp->int_if_flags & IFF_POINTOPOINT) && ifp->int_dstaddr == 0))
1835  		return (_B_TRUE);
1836  
1837  	/*
1838  	 * If the interface on a subnet, then install a RIPv1 route to
1839  	 * the network as well (unless it is sick).
1840  	 */
1841  	if (ifp->int_state & IS_SUBNET)
1842  		check_net_syn(ifp);
1843  
1844  	dst = (0 != (ifp->int_if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) ?
1845  	    ifp->int_dstaddr : htonl(ifp->int_net));
1846  
1847  	(void) memset(&new, 0, sizeof (new));
1848  	new.rts_ifp = ifp;
1849  	new.rts_router = ifp->int_addr;
1850  	new.rts_gate = ifp->int_addr;
1851  	new.rts_metric = ifp->int_metric;
1852  	new.rts_time = now.tv_sec;
1853  	if (ifp->int_if_flags & IFF_POINTOPOINT)
1854  		new.rts_origin = RO_PTOPT;
1855  	else if (ifp->int_if_flags & IFF_LOOPBACK)
1856  		new.rts_origin = RO_LOOPBCK;
1857  	else
1858  		new.rts_origin = RO_IF;
1859  
1860  	/*
1861  	 * If we are going to send packets to the gateway,
1862  	 * it must be reachable using our physical interfaces
1863  	 */
1864  	if ((ifp->int_state & IS_REMOTE) &&
1865  	    !(ifp->int_state & IS_EXTERNAL) &&
1866  	    !check_remote(ifp))
1867  		return (_B_FALSE);
1868  
1869  	/*
1870  	 * We are finished if the correct main interface route exists.
1871  	 * The right route must be for the right interface, not synthesized
1872  	 * from a subnet, be a "gateway" or not as appropriate, and so forth.
1873  	 */
1874  	del_static(dst, ifp->int_mask, 0, ifp, 0);
1875  	rt = rtget(dst, ifp->int_mask);
1876  	if (!IS_IFF_ROUTING(ifp->int_if_flags))
1877  		rt_newstate |= RS_NOPROPAGATE;
1878  	if (rt != NULL) {
1879  		if ((rt->rt_ifp != ifp || rt->rt_router != ifp->int_addr) &&
1880  		    (rt->rt_ifp == NULL ||
1881  		    (rt->rt_ifp->int_state & IS_BROKE))) {
1882  			rtdelete(rt);
1883  			rt = NULL;
1884  		} else {
1885  			rtchange(rt, ((rt->rt_state | rt_newstate) &
1886  			    ~(RS_NET_SYN | RS_LOCAL)), &new, 0);
1887  		}
1888  	}
1889  	if (rt == NULL) {
1890  		if (ifp->int_transitions++ > 0)
1891  			trace_act("re-installing interface %s;"
1892  			    " went up %d times",
1893  			    ifp->int_name, ifp->int_transitions);
1894  
1895  		rtadd(dst, ifp->int_mask, rt_newstate, &new);
1896  	}
1897  
1898  	return (_B_TRUE);
1899  }
1900  
1901  /*
1902   * Obtains the named kstat, and places its value in *value.  It
1903   * returns 0 for success, -1 for failure.
1904   */
1905  static int
kstat_named_value(kstat_t * ksp,char * name,uint32_t * value)1906  kstat_named_value(kstat_t *ksp, char *name, uint32_t *value)
1907  {
1908  	kstat_named_t *knp;
1909  
1910  	if (ksp == NULL)
1911  		return (-1);
1912  
1913  	if ((knp = kstat_data_lookup(ksp, name)) == NULL) {
1914  		return (-1);
1915  	} else if (knp->data_type != KSTAT_DATA_UINT32) {
1916  		return (-1);
1917  	} else {
1918  		*value = knp->value.ui32;
1919  		return (0);
1920  	}
1921  }
1922  
1923  static int
get_if_kstats(struct interface * ifp,struct phyi_data * newdata)1924  get_if_kstats(struct interface *ifp, struct phyi_data *newdata)
1925  {
1926  	struct physical_interface *phyi = ifp->int_phys;
1927  	kstat_ctl_t *kc;
1928  	kstat_t *ksp;
1929  
1930  	/* We did this recently; don't do it again. */
1931  	if (phyi->phyi_data.ts == now.tv_sec) {
1932  		if (newdata != &phyi->phyi_data)
1933  			*newdata = phyi->phyi_data;
1934  		return (0);
1935  	}
1936  
1937  	if ((kc = kstat_open()) == NULL)
1938  		return (-1);
1939  
1940  	/*
1941  	 * First we try to query the "link" kstats in case the link is renamed.
1942  	 * If that fails, fallback to legacy ktats for those non-GLDv3 links.
1943  	 */
1944  	if (((ksp = kstat_lookup(kc, "link", 0, phyi->phyi_name)) == NULL) &&
1945  	    ((ksp = kstat_lookup(kc, NULL, -1, phyi->phyi_name)) == NULL)) {
1946  		(void) kstat_close(kc);
1947  		return (-1);
1948  	}
1949  
1950  	if (kstat_read(kc, ksp, NULL) == -1) {
1951  		(void) kstat_close(kc);
1952  		return (-1);
1953  	}
1954  
1955  	if ((kstat_named_value(ksp, "ipackets", &newdata->ipackets) == -1) ||
1956  	    (kstat_named_value(ksp, "opackets",	&newdata->opackets) == -1)) {
1957  		newdata->ts = 0;
1958  		(void) kstat_close(kc);
1959  		return (-1);
1960  	}
1961  
1962  	/* The loopback interface does not keep track of errors */
1963  	if (!(ifp->int_if_flags & IFF_LOOPBACK)) {
1964  		if ((kstat_named_value(ksp, "ierrors",
1965  		    &newdata->ierrors) == -1) ||
1966  		    (kstat_named_value(ksp, "oerrors",
1967  		    &newdata->oerrors) == -1)) {
1968  			newdata->ts = 0;
1969  			(void) kstat_close(kc);
1970  			return (-1);
1971  		}
1972  	}
1973  
1974  	newdata->ts = now.tv_sec;
1975  	(void) kstat_close(kc);
1976  	return (0);
1977  }
1978  
1979  /*
1980   * Returns true if we should supply routes to other systems.  If the
1981   * user has forced us to be a supplier (by the command line) or if we
1982   * have more than one forwarding interface and this is one of the
1983   * forwarding interfaces, then behave as a RIP supplier (supply rdisc
1984   * advertisements and RIP responses).
1985   */
1986  boolean_t
should_supply(struct interface * ifp)1987  should_supply(struct interface *ifp)
1988  {
1989  	if (ifp != NULL && !IS_IFF_ROUTING(ifp->int_if_flags))
1990  		return (_B_FALSE);
1991  	return ((supplier_set && supplier) ||
1992  	    (!supplier_set && fwd_interfaces > 1));
1993  }
1994