xref: /openbsd-src/usr.sbin/mrouted/config.c (revision df69c215c7c66baf660f3f65414fd34796c96152)
1a17240f2Sderaadt /*	$NetBSD: config.c,v 1.6 1995/12/10 10:06:58 mycroft Exp $	*/
2df930be7Sderaadt 
3df930be7Sderaadt /*
4df930be7Sderaadt  * The mrouted program is covered by the license in the accompanying file
5df930be7Sderaadt  * named "LICENSE".  Use of the mrouted program represents acceptance of
6df930be7Sderaadt  * the terms and conditions listed in that file.
7df930be7Sderaadt  *
8df930be7Sderaadt  * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
9df930be7Sderaadt  * Leland Stanford Junior University.
10df930be7Sderaadt  */
11df930be7Sderaadt 
12df930be7Sderaadt #include "defs.h"
13873be588Sitojun #include <net/if.h>
14873be588Sitojun #include <ifaddrs.h>
15df930be7Sderaadt 
16df930be7Sderaadt 
17df930be7Sderaadt /*
18df930be7Sderaadt  * Query the kernel to find network interfaces that are multicast-capable
19df930be7Sderaadt  * and install them in the uvifs array.
20df930be7Sderaadt  */
21a17240f2Sderaadt void
config_vifs_from_kernel(void)22873be588Sitojun config_vifs_from_kernel(void)
23df930be7Sderaadt {
24873be588Sitojun     struct ifaddrs *ifa, *ifap;
25873be588Sitojun     struct uvif *v;
26873be588Sitojun     vifi_t vifi;
27df930be7Sderaadt     u_int32_t addr, mask, subnet;
28df930be7Sderaadt     short flags;
29df930be7Sderaadt 
30*df69c215Sderaadt     if (getifaddrs(&ifap) == -1)
3140443a2fSmillert 	logit(LOG_ERR, errno, "getifaddrs");
32df930be7Sderaadt 
33873be588Sitojun     for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
34df930be7Sderaadt 	/*
35df930be7Sderaadt 	 * Ignore any interface for an address family other than IP.
36df930be7Sderaadt 	 */
37873be588Sitojun 	if (ifa->ifa_addr->sa_family != AF_INET)
38df930be7Sderaadt 	    continue;
39df930be7Sderaadt 
40873be588Sitojun 	addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
41df930be7Sderaadt 
42df930be7Sderaadt 	/*
43df930be7Sderaadt 	 * Ignore loopback interfaces and interfaces that do not support
44df930be7Sderaadt 	 * multicast.
45df930be7Sderaadt 	 */
46873be588Sitojun 	flags = ifa->ifa_flags;
47873be588Sitojun 	if ((flags & (IFF_LOOPBACK|IFF_MULTICAST)) != IFF_MULTICAST)
48873be588Sitojun 	    continue;
49df930be7Sderaadt 
50df930be7Sderaadt 	/*
51df930be7Sderaadt 	 * Ignore any interface whose address and mask do not define a
52df930be7Sderaadt 	 * valid subnet number, or whose address is of the form {subnet,0}
53df930be7Sderaadt 	 * or {subnet,-1}.
54df930be7Sderaadt 	 */
55873be588Sitojun 	mask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr.s_addr;
56df930be7Sderaadt 	subnet = addr & mask;
57df930be7Sderaadt 	if (!inet_valid_subnet(subnet, mask) ||
58df930be7Sderaadt 	    addr == subnet ||
59df930be7Sderaadt 	    addr == (subnet | ~mask)) {
6040443a2fSmillert 	    logit(LOG_WARNING, 0,
61df930be7Sderaadt 		"ignoring %s, has invalid address (%s) and/or mask (%s)",
62873be588Sitojun 		ifa->ifa_name, inet_fmt(addr, s1), inet_fmt(mask, s2));
63df930be7Sderaadt 	    continue;
64df930be7Sderaadt 	}
65df930be7Sderaadt 
66df930be7Sderaadt 	/*
67df930be7Sderaadt 	 * Ignore any interface that is connected to the same subnet as
68df930be7Sderaadt 	 * one already installed in the uvifs array.
69df930be7Sderaadt 	 */
70df930be7Sderaadt 	for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
71df930be7Sderaadt 	    if ((addr & v->uv_subnetmask) == v->uv_subnet ||
72df930be7Sderaadt 		(v->uv_subnet & mask) == subnet) {
7340443a2fSmillert 		logit(LOG_WARNING, 0, "ignoring %s, same subnet as %s",
74873be588Sitojun 		    ifa->ifa_name, v->uv_name);
75df930be7Sderaadt 		break;
76df930be7Sderaadt 	    }
77df930be7Sderaadt 	}
78873be588Sitojun 	if (vifi != numvifs)
79873be588Sitojun 	    continue;
80df930be7Sderaadt 
81df930be7Sderaadt 	/*
82df930be7Sderaadt 	 * If there is room in the uvifs array, install this interface.
83df930be7Sderaadt 	 */
84df930be7Sderaadt 	if (numvifs == MAXVIFS) {
8540443a2fSmillert 	    logit(LOG_WARNING, 0, "too many vifs, ignoring %s", ifa->ifa_name);
86df930be7Sderaadt 	    continue;
87df930be7Sderaadt 	}
88df930be7Sderaadt 	v  = &uvifs[numvifs];
89df930be7Sderaadt 	v->uv_flags       = 0;
90df930be7Sderaadt 	v->uv_metric      = DEFAULT_METRIC;
91df930be7Sderaadt 	v->uv_rate_limit  = DEFAULT_PHY_RATE_LIMIT;
92df930be7Sderaadt 	v->uv_threshold   = DEFAULT_THRESHOLD;
93df930be7Sderaadt 	v->uv_lcl_addr    = addr;
94df930be7Sderaadt 	v->uv_rmt_addr    = 0;
95df930be7Sderaadt 	v->uv_subnet      = subnet;
96df930be7Sderaadt 	v->uv_subnetmask  = mask;
97df930be7Sderaadt 	v->uv_subnetbcast = subnet | ~mask;
98873be588Sitojun 	strlcpy(v->uv_name, ifa->ifa_name, sizeof(v->uv_name));
99df930be7Sderaadt 	v->uv_groups      = NULL;
100df930be7Sderaadt 	v->uv_neighbors   = NULL;
101df930be7Sderaadt 	v->uv_acl         = NULL;
102df930be7Sderaadt 	v->uv_addrs	  = NULL;
103df930be7Sderaadt 
10440443a2fSmillert 	logit(LOG_INFO,0,"installing %s (%s on subnet %s) as vif #%u - rate=%d",
105df930be7Sderaadt 	    v->uv_name, inet_fmt(addr, s1), inet_fmts(subnet, mask, s2),
106df930be7Sderaadt 	    numvifs, v->uv_rate_limit);
107df930be7Sderaadt 
108df930be7Sderaadt 	++numvifs;
109df930be7Sderaadt 
110df930be7Sderaadt 	/*
111df930be7Sderaadt 	 * If the interface is not yet up, set the vifs_down flag to
112df930be7Sderaadt 	 * remind us to check again later.
113df930be7Sderaadt 	 */
114df930be7Sderaadt 	if (!(flags & IFF_UP)) {
115df930be7Sderaadt 	    v->uv_flags |= VIFF_DOWN;
116df930be7Sderaadt 	    vifs_down = TRUE;
117df930be7Sderaadt 	}
118df930be7Sderaadt     }
119873be588Sitojun 
120873be588Sitojun     freeifaddrs(ifap);
121df930be7Sderaadt }
122