config.c revision 1.5 1 1.5 thorpej /* $NetBSD: config.c,v 1.5 1995/10/09 03:51:37 thorpej 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
13 1.1 brezak #include "defs.h"
14 1.1 brezak
15 1.1 brezak
16 1.1 brezak /*
17 1.1 brezak * Query the kernel to find network interfaces that are multicast-capable
18 1.1 brezak * and install them in the uvifs array.
19 1.1 brezak */
20 1.1 brezak void config_vifs_from_kernel()
21 1.1 brezak {
22 1.1 brezak struct ifreq ifbuf[32];
23 1.4 mycroft struct ifreq *ifrp, *ifend;
24 1.1 brezak struct ifconf ifc;
25 1.1 brezak register struct uvif *v;
26 1.1 brezak register vifi_t vifi;
27 1.4 mycroft int n;
28 1.4 mycroft u_int32_t addr, mask, subnet;
29 1.1 brezak short flags;
30 1.1 brezak
31 1.1 brezak ifc.ifc_buf = (char *)ifbuf;
32 1.1 brezak ifc.ifc_len = sizeof(ifbuf);
33 1.1 brezak if (ioctl(udp_socket, SIOCGIFCONF, (char *)&ifc) < 0)
34 1.1 brezak log(LOG_ERR, errno, "ioctl SIOCGIFCONF");
35 1.1 brezak
36 1.1 brezak ifrp = (struct ifreq *)ifbuf;
37 1.1 brezak ifend = (struct ifreq *)((char *)ifbuf + ifc.ifc_len);
38 1.1 brezak /*
39 1.1 brezak * Loop through all of the interfaces.
40 1.1 brezak */
41 1.1 brezak for (; ifrp < ifend; ifrp = (struct ifreq *)((char *)ifrp + n)) {
42 1.1 brezak struct ifreq ifr;
43 1.1 brezak #if BSD >= 199006
44 1.1 brezak n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
45 1.1 brezak if (n < sizeof(*ifrp))
46 1.1 brezak n = sizeof(*ifrp);
47 1.1 brezak #else
48 1.1 brezak n = sizeof(*ifrp);
49 1.1 brezak #endif
50 1.1 brezak /*
51 1.1 brezak * Ignore any interface for an address family other than IP.
52 1.1 brezak */
53 1.1 brezak if (ifrp->ifr_addr.sa_family != AF_INET)
54 1.1 brezak continue;
55 1.1 brezak
56 1.4 mycroft addr = ((struct sockaddr_in *)&ifrp->ifr_addr)->sin_addr.s_addr;
57 1.4 mycroft
58 1.1 brezak /*
59 1.1 brezak * Need a template to preserve address info that is
60 1.1 brezak * used below to locate the next entry. (Otherwise,
61 1.1 brezak * SIOCGIFFLAGS stomps over it because the requests
62 1.1 brezak * are returned in a union.)
63 1.1 brezak */
64 1.1 brezak bcopy(ifrp->ifr_name, ifr.ifr_name, sizeof(ifr.ifr_name));
65 1.1 brezak
66 1.1 brezak /*
67 1.1 brezak * Ignore loopback interfaces and interfaces that do not support
68 1.1 brezak * multicast.
69 1.1 brezak */
70 1.1 brezak if (ioctl(udp_socket, SIOCGIFFLAGS, (char *)&ifr) < 0)
71 1.1 brezak log(LOG_ERR, errno, "ioctl SIOCGIFFLAGS for %s", ifr.ifr_name);
72 1.1 brezak flags = ifr.ifr_flags;
73 1.1 brezak if ((flags & (IFF_LOOPBACK|IFF_MULTICAST)) != IFF_MULTICAST) continue;
74 1.1 brezak
75 1.1 brezak /*
76 1.1 brezak * Ignore any interface whose address and mask do not define a
77 1.1 brezak * valid subnet number, or whose address is of the form {subnet,0}
78 1.1 brezak * or {subnet,-1}.
79 1.1 brezak */
80 1.1 brezak if (ioctl(udp_socket, SIOCGIFNETMASK, (char *)&ifr) < 0)
81 1.1 brezak log(LOG_ERR, errno, "ioctl SIOCGIFNETMASK for %s", ifr.ifr_name);
82 1.1 brezak mask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
83 1.1 brezak subnet = addr & mask;
84 1.1 brezak if (!inet_valid_subnet(subnet, mask) ||
85 1.1 brezak addr == subnet ||
86 1.1 brezak addr == (subnet | ~mask)) {
87 1.1 brezak log(LOG_WARNING, 0,
88 1.4 mycroft "ignoring %s, has invalid address (%s) and/or mask (%s)",
89 1.4 mycroft ifr.ifr_name, inet_fmt(addr, s1), inet_fmt(mask, s2));
90 1.1 brezak continue;
91 1.1 brezak }
92 1.1 brezak
93 1.1 brezak /*
94 1.1 brezak * Ignore any interface that is connected to the same subnet as
95 1.1 brezak * one already installed in the uvifs array.
96 1.1 brezak */
97 1.1 brezak for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
98 1.1 brezak if ((addr & v->uv_subnetmask) == v->uv_subnet ||
99 1.1 brezak (v->uv_subnet & mask) == subnet) {
100 1.1 brezak log(LOG_WARNING, 0, "ignoring %s, same subnet as %s",
101 1.1 brezak ifr.ifr_name, v->uv_name);
102 1.1 brezak break;
103 1.1 brezak }
104 1.1 brezak }
105 1.1 brezak if (vifi != numvifs) continue;
106 1.1 brezak
107 1.1 brezak /*
108 1.1 brezak * If there is room in the uvifs array, install this interface.
109 1.1 brezak */
110 1.1 brezak if (numvifs == MAXVIFS) {
111 1.1 brezak log(LOG_WARNING, 0, "too many vifs, ignoring %s", ifr.ifr_name);
112 1.1 brezak continue;
113 1.1 brezak }
114 1.1 brezak v = &uvifs[numvifs];
115 1.1 brezak v->uv_flags = 0;
116 1.1 brezak v->uv_metric = DEFAULT_METRIC;
117 1.4 mycroft v->uv_rate_limit = DEFAULT_PHY_RATE_LIMIT;
118 1.1 brezak v->uv_threshold = DEFAULT_THRESHOLD;
119 1.1 brezak v->uv_lcl_addr = addr;
120 1.1 brezak v->uv_rmt_addr = 0;
121 1.1 brezak v->uv_subnet = subnet;
122 1.1 brezak v->uv_subnetmask = mask;
123 1.1 brezak v->uv_subnetbcast = subnet | ~mask;
124 1.1 brezak strncpy(v->uv_name, ifr.ifr_name, IFNAMSIZ);
125 1.1 brezak v->uv_groups = NULL;
126 1.1 brezak v->uv_neighbors = NULL;
127 1.4 mycroft v->uv_acl = NULL;
128 1.4 mycroft v->uv_addrs = NULL;
129 1.1 brezak
130 1.4 mycroft log(LOG_INFO,0,"installing %s (%s on subnet %s) as vif #%u - rate=%d",
131 1.1 brezak v->uv_name, inet_fmt(addr, s1), inet_fmts(subnet, mask, s2),
132 1.4 mycroft numvifs, v->uv_rate_limit);
133 1.1 brezak
134 1.1 brezak ++numvifs;
135 1.1 brezak
136 1.1 brezak /*
137 1.1 brezak * If the interface is not yet up, set the vifs_down flag to
138 1.1 brezak * remind us to check again later.
139 1.1 brezak */
140 1.1 brezak if (!(flags & IFF_UP)) {
141 1.1 brezak v->uv_flags |= VIFF_DOWN;
142 1.1 brezak vifs_down = TRUE;
143 1.1 brezak }
144 1.1 brezak }
145 1.1 brezak }
146