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