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