config.c revision 1.1 1 1.1 brezak /*
2 1.1 brezak * The mrouted program is covered by the license in the accompanying file
3 1.1 brezak * named "LICENSE". Use of the mrouted program represents acceptance of
4 1.1 brezak * the terms and conditions listed in that file.
5 1.1 brezak *
6 1.1 brezak * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
7 1.1 brezak * Leland Stanford Junior University.
8 1.1 brezak *
9 1.1 brezak *
10 1.1 brezak * from: Id: config.c,v 1.3 1993/05/30 01:36:38 deering Exp
11 1.1 brezak * $Id: config.c,v 1.1 1994/01/11 20:15:48 brezak Exp $
12 1.1 brezak */
13 1.1 brezak
14 1.1 brezak #ifndef lint
15 1.1 brezak static char rcsid[] = "$Id: config.c,v 1.1 1994/01/11 20:15:48 brezak Exp $";
16 1.1 brezak #endif
17 1.1 brezak
18 1.1 brezak #include "defs.h"
19 1.1 brezak
20 1.1 brezak
21 1.1 brezak char *configfilename = _PATH_MROUTED_CONF;
22 1.1 brezak
23 1.1 brezak
24 1.1 brezak /*
25 1.1 brezak * Forward declarations.
26 1.1 brezak */
27 1.1 brezak static char *next_word();
28 1.1 brezak
29 1.1 brezak
30 1.1 brezak /*
31 1.1 brezak * Query the kernel to find network interfaces that are multicast-capable
32 1.1 brezak * and install them in the uvifs array.
33 1.1 brezak */
34 1.1 brezak void config_vifs_from_kernel()
35 1.1 brezak {
36 1.1 brezak struct ifreq ifbuf[32];
37 1.1 brezak struct ifreq *ifrp, *ifend, *mp;
38 1.1 brezak struct ifconf ifc;
39 1.1 brezak register struct uvif *v;
40 1.1 brezak register vifi_t vifi;
41 1.1 brezak int i, n;
42 1.1 brezak u_long addr, mask, subnet;
43 1.1 brezak short flags;
44 1.1 brezak
45 1.1 brezak ifc.ifc_buf = (char *)ifbuf;
46 1.1 brezak ifc.ifc_len = sizeof(ifbuf);
47 1.1 brezak if (ioctl(udp_socket, SIOCGIFCONF, (char *)&ifc) < 0)
48 1.1 brezak log(LOG_ERR, errno, "ioctl SIOCGIFCONF");
49 1.1 brezak
50 1.1 brezak ifrp = (struct ifreq *)ifbuf;
51 1.1 brezak ifend = (struct ifreq *)((char *)ifbuf + ifc.ifc_len);
52 1.1 brezak /*
53 1.1 brezak * Loop through all of the interfaces.
54 1.1 brezak */
55 1.1 brezak for (; ifrp < ifend; ifrp = (struct ifreq *)((char *)ifrp + n)) {
56 1.1 brezak struct ifreq ifr;
57 1.1 brezak #if BSD >= 199006
58 1.1 brezak n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
59 1.1 brezak if (n < sizeof(*ifrp))
60 1.1 brezak n = sizeof(*ifrp);
61 1.1 brezak #else
62 1.1 brezak n = sizeof(*ifrp);
63 1.1 brezak #endif
64 1.1 brezak /*
65 1.1 brezak * Ignore any interface for an address family other than IP.
66 1.1 brezak */
67 1.1 brezak addr = ((struct sockaddr_in *)&ifrp->ifr_addr)->sin_addr.s_addr;
68 1.1 brezak if (ifrp->ifr_addr.sa_family != AF_INET)
69 1.1 brezak continue;
70 1.1 brezak
71 1.1 brezak /*
72 1.1 brezak * Need a template to preserve address info that is
73 1.1 brezak * used below to locate the next entry. (Otherwise,
74 1.1 brezak * SIOCGIFFLAGS stomps over it because the requests
75 1.1 brezak * are returned in a union.)
76 1.1 brezak */
77 1.1 brezak bcopy(ifrp->ifr_name, ifr.ifr_name, sizeof(ifr.ifr_name));
78 1.1 brezak
79 1.1 brezak /*
80 1.1 brezak * Ignore loopback interfaces and interfaces that do not support
81 1.1 brezak * multicast.
82 1.1 brezak */
83 1.1 brezak if (ioctl(udp_socket, SIOCGIFFLAGS, (char *)&ifr) < 0)
84 1.1 brezak log(LOG_ERR, errno, "ioctl SIOCGIFFLAGS for %s", ifr.ifr_name);
85 1.1 brezak flags = ifr.ifr_flags;
86 1.1 brezak if ((flags & (IFF_LOOPBACK|IFF_MULTICAST)) != IFF_MULTICAST) continue;
87 1.1 brezak
88 1.1 brezak /*
89 1.1 brezak * Ignore any interface whose address and mask do not define a
90 1.1 brezak * valid subnet number, or whose address is of the form {subnet,0}
91 1.1 brezak * or {subnet,-1}.
92 1.1 brezak */
93 1.1 brezak if (ioctl(udp_socket, SIOCGIFNETMASK, (char *)&ifr) < 0)
94 1.1 brezak log(LOG_ERR, errno, "ioctl SIOCGIFNETMASK for %s", ifr.ifr_name);
95 1.1 brezak mask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
96 1.1 brezak subnet = addr & mask;
97 1.1 brezak if (!inet_valid_subnet(subnet, mask) ||
98 1.1 brezak addr == subnet ||
99 1.1 brezak addr == (subnet | ~mask)) {
100 1.1 brezak log(LOG_WARNING, 0,
101 1.1 brezak "ignoring %s, has invalid address (%s) and/or mask (%08x)",
102 1.1 brezak ifr.ifr_name, inet_fmt(addr, s1), ntohl(mask));
103 1.1 brezak continue;
104 1.1 brezak }
105 1.1 brezak
106 1.1 brezak /*
107 1.1 brezak * Ignore any interface that is connected to the same subnet as
108 1.1 brezak * one already installed in the uvifs array.
109 1.1 brezak */
110 1.1 brezak for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
111 1.1 brezak if ((addr & v->uv_subnetmask) == v->uv_subnet ||
112 1.1 brezak (v->uv_subnet & mask) == subnet) {
113 1.1 brezak log(LOG_WARNING, 0, "ignoring %s, same subnet as %s",
114 1.1 brezak ifr.ifr_name, v->uv_name);
115 1.1 brezak break;
116 1.1 brezak }
117 1.1 brezak }
118 1.1 brezak if (vifi != numvifs) continue;
119 1.1 brezak
120 1.1 brezak /*
121 1.1 brezak * If there is room in the uvifs array, install this interface.
122 1.1 brezak */
123 1.1 brezak if (numvifs == MAXVIFS) {
124 1.1 brezak log(LOG_WARNING, 0, "too many vifs, ignoring %s", ifr.ifr_name);
125 1.1 brezak continue;
126 1.1 brezak }
127 1.1 brezak v = &uvifs[numvifs];
128 1.1 brezak v->uv_flags = 0;
129 1.1 brezak v->uv_metric = DEFAULT_METRIC;
130 1.1 brezak v->uv_threshold = DEFAULT_THRESHOLD;
131 1.1 brezak v->uv_lcl_addr = addr;
132 1.1 brezak v->uv_rmt_addr = 0;
133 1.1 brezak v->uv_subnet = subnet;
134 1.1 brezak v->uv_subnetmask = mask;
135 1.1 brezak v->uv_subnetbcast = subnet | ~mask;
136 1.1 brezak strncpy(v->uv_name, ifr.ifr_name, IFNAMSIZ);
137 1.1 brezak v->uv_groups = NULL;
138 1.1 brezak v->uv_neighbors = NULL;
139 1.1 brezak
140 1.1 brezak log(LOG_INFO, 0, "installing %s (%s on subnet %s) as vif #%u",
141 1.1 brezak v->uv_name, inet_fmt(addr, s1), inet_fmts(subnet, mask, s2),
142 1.1 brezak numvifs);
143 1.1 brezak
144 1.1 brezak ++numvifs;
145 1.1 brezak
146 1.1 brezak /*
147 1.1 brezak * If the interface is not yet up, set the vifs_down flag to
148 1.1 brezak * remind us to check again later.
149 1.1 brezak */
150 1.1 brezak if (!(flags & IFF_UP)) {
151 1.1 brezak v->uv_flags |= VIFF_DOWN;
152 1.1 brezak vifs_down = TRUE;
153 1.1 brezak }
154 1.1 brezak }
155 1.1 brezak }
156 1.1 brezak
157 1.1 brezak static struct ifreq *
158 1.1 brezak ifconfaddr(ifcp, a)
159 1.1 brezak struct ifconf *ifcp;
160 1.1 brezak u_long a;
161 1.1 brezak {
162 1.1 brezak int n;
163 1.1 brezak struct ifreq *ifrp = (struct ifreq *)ifcp->ifc_buf;
164 1.1 brezak struct ifreq *ifend = (struct ifreq *)((char *)ifrp + ifcp->ifc_len);
165 1.1 brezak
166 1.1 brezak while (ifrp < ifend) {
167 1.1 brezak if (ifrp->ifr_addr.sa_family == AF_INET &&
168 1.1 brezak ((struct sockaddr_in *)&ifrp->ifr_addr)->sin_addr.s_addr == a)
169 1.1 brezak return (ifrp);
170 1.1 brezak #if BSD >= 199006
171 1.1 brezak n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
172 1.1 brezak if (n < sizeof(*ifrp))
173 1.1 brezak ++ifrp;
174 1.1 brezak else
175 1.1 brezak ifrp = (struct ifreq *)((char *)ifrp + n);
176 1.1 brezak #else
177 1.1 brezak ++ifrp;
178 1.1 brezak #endif
179 1.1 brezak }
180 1.1 brezak return (0);
181 1.1 brezak }
182 1.1 brezak /*
183 1.1 brezak * Read the config file to learn about tunnel vifs and
184 1.1 brezak * non-default phyint parameters.
185 1.1 brezak */
186 1.1 brezak void config_vifs_from_file()
187 1.1 brezak {
188 1.1 brezak FILE *f;
189 1.1 brezak char linebuf[100];
190 1.1 brezak char *w, *s, c;
191 1.1 brezak u_long lcl_addr, rmt_addr;
192 1.1 brezak struct ifconf ifc;
193 1.1 brezak struct ifreq *ifr;
194 1.1 brezak struct ifreq ffr;
195 1.1 brezak int i;
196 1.1 brezak u_int n;
197 1.1 brezak struct ifreq ifbuf[32];
198 1.1 brezak vifi_t vifi;
199 1.1 brezak struct uvif *v;
200 1.1 brezak
201 1.1 brezak f = fopen(configfilename, "r");
202 1.1 brezak if (f == NULL) {
203 1.1 brezak if (errno != ENOENT)
204 1.1 brezak log(LOG_WARNING, errno, "can't open %s", configfilename);
205 1.1 brezak return;
206 1.1 brezak }
207 1.1 brezak
208 1.1 brezak ifc.ifc_buf = (char *)ifbuf;
209 1.1 brezak ifc.ifc_len = sizeof(ifbuf);
210 1.1 brezak if (ioctl(udp_socket, SIOCGIFCONF, (char *)&ifc) < 0)
211 1.1 brezak log(LOG_ERR, errno, "ioctl SIOCGIFCONF");
212 1.1 brezak
213 1.1 brezak while (fgets(linebuf, sizeof(linebuf), f) != NULL) {
214 1.1 brezak
215 1.1 brezak s = linebuf;
216 1.1 brezak if (EQUAL((w = next_word(&s)), "")) {
217 1.1 brezak /*
218 1.1 brezak * blank or comment line; ignore
219 1.1 brezak */
220 1.1 brezak }
221 1.1 brezak
222 1.1 brezak else if (EQUAL(w, "phyint")) {
223 1.1 brezak /*
224 1.1 brezak * phyint <local-addr> [disable] [metric <m>] [threshold <t>]
225 1.1 brezak */
226 1.1 brezak
227 1.1 brezak /*
228 1.1 brezak * Parse the local address.
229 1.1 brezak */
230 1.1 brezak if (EQUAL((w = next_word(&s)), "")) {
231 1.1 brezak log(LOG_WARNING, 0,
232 1.1 brezak "missing phyint address in %s",
233 1.1 brezak configfilename);
234 1.1 brezak continue;
235 1.1 brezak }
236 1.1 brezak if ((lcl_addr = inet_parse(w)) == 0xffffffff ||
237 1.1 brezak !inet_valid_host(lcl_addr)) {
238 1.1 brezak log(LOG_WARNING, 0,
239 1.1 brezak "invalid phyint address '%s' in %s",
240 1.1 brezak w, configfilename);
241 1.1 brezak continue;
242 1.1 brezak }
243 1.1 brezak
244 1.1 brezak /*
245 1.1 brezak * Look up the vif with the specified local address.
246 1.1 brezak */
247 1.1 brezak for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
248 1.1 brezak if (!(v->uv_flags & VIFF_TUNNEL) &&
249 1.1 brezak lcl_addr == v->uv_lcl_addr) {
250 1.1 brezak break;
251 1.1 brezak }
252 1.1 brezak }
253 1.1 brezak if (vifi == numvifs) {
254 1.1 brezak log(LOG_WARNING, 0,
255 1.1 brezak "phyint %s in %s is not a configured interface",
256 1.1 brezak inet_fmt(lcl_addr, s1), configfilename);
257 1.1 brezak continue;
258 1.1 brezak }
259 1.1 brezak
260 1.1 brezak /*
261 1.1 brezak * Look for "disable", "metric" and "threshold" options.
262 1.1 brezak */
263 1.1 brezak while (!EQUAL((w = next_word(&s)), "")) {
264 1.1 brezak if (EQUAL(w, "disable")) {
265 1.1 brezak v->uv_flags |= VIFF_DISABLED;
266 1.1 brezak }
267 1.1 brezak else if (EQUAL(w, "metric")) {
268 1.1 brezak if(EQUAL((w = next_word(&s)), "")) {
269 1.1 brezak log(LOG_WARNING, 0,
270 1.1 brezak "missing metric for phyint %s in %s",
271 1.1 brezak inet_fmt(lcl_addr, s1), configfilename);
272 1.1 brezak w = "garbage";
273 1.1 brezak break;
274 1.1 brezak }
275 1.1 brezak if(sscanf(w, "%u%c", &n, &c) != 1 ||
276 1.1 brezak n < 1 || n >= UNREACHABLE ) {
277 1.1 brezak log(LOG_WARNING, 0,
278 1.1 brezak "invalid metric '%s' for phyint %s in %s",
279 1.1 brezak w, inet_fmt(lcl_addr, s1), configfilename);
280 1.1 brezak break;
281 1.1 brezak }
282 1.1 brezak v->uv_metric = n;
283 1.1 brezak }
284 1.1 brezak else if (EQUAL(w, "threshold")) {
285 1.1 brezak if(EQUAL((w = next_word(&s)), "")) {
286 1.1 brezak log(LOG_WARNING, 0,
287 1.1 brezak "missing threshold for phyint %s in %s",
288 1.1 brezak inet_fmt(lcl_addr, s1), configfilename);
289 1.1 brezak w = "garbage";
290 1.1 brezak break;
291 1.1 brezak }
292 1.1 brezak if(sscanf(w, "%u%c", &n, &c) != 1 ||
293 1.1 brezak n < 1 || n > 255 ) {
294 1.1 brezak log(LOG_WARNING, 0,
295 1.1 brezak "invalid threshold '%s' for phyint %s in %s",
296 1.1 brezak w, inet_fmt(lcl_addr, s1), configfilename);
297 1.1 brezak break;
298 1.1 brezak }
299 1.1 brezak v->uv_threshold = n;
300 1.1 brezak }
301 1.1 brezak else break;
302 1.1 brezak }
303 1.1 brezak if (!EQUAL(w, "")) continue;
304 1.1 brezak }
305 1.1 brezak
306 1.1 brezak else if (EQUAL(w, "tunnel")) {
307 1.1 brezak /*
308 1.1 brezak * tunnel <local-addr> <remote-addr> [srcrt] [metric <m>] [threshold <t>]
309 1.1 brezak */
310 1.1 brezak
311 1.1 brezak /*
312 1.1 brezak * Parse the local address.
313 1.1 brezak */
314 1.1 brezak if (EQUAL((w = next_word(&s)), "")) {
315 1.1 brezak log(LOG_WARNING, 0,
316 1.1 brezak "missing tunnel local address in %s",
317 1.1 brezak configfilename);
318 1.1 brezak continue;
319 1.1 brezak }
320 1.1 brezak if ((lcl_addr = inet_parse(w)) == 0xffffffff ||
321 1.1 brezak !inet_valid_host(lcl_addr)) {
322 1.1 brezak log(LOG_WARNING, 0,
323 1.1 brezak "invalid tunnel local address '%s' in %s",
324 1.1 brezak w, configfilename);
325 1.1 brezak continue;
326 1.1 brezak }
327 1.1 brezak
328 1.1 brezak /*
329 1.1 brezak * Make sure the local address is one of ours.
330 1.1 brezak */
331 1.1 brezak ifr = ifconfaddr(&ifc, lcl_addr);
332 1.1 brezak if (ifr == 0) {
333 1.1 brezak log(LOG_WARNING, 0,
334 1.1 brezak "tunnel local address %s in %s is not one of ours",
335 1.1 brezak inet_fmt(lcl_addr, s1), configfilename);
336 1.1 brezak continue;
337 1.1 brezak }
338 1.1 brezak
339 1.1 brezak /*
340 1.1 brezak * Make sure the local address doesn't name a loopback interface..
341 1.1 brezak */
342 1.1 brezak strncpy(ffr.ifr_name, ifr->ifr_name, IFNAMSIZ);
343 1.1 brezak if (ioctl(udp_socket, SIOCGIFFLAGS, (char *)&ffr) < 0) {
344 1.1 brezak log(LOG_ERR, errno,
345 1.1 brezak "ioctl SIOCGIFFLAGS for %s", ffr.ifr_name);
346 1.1 brezak }
347 1.1 brezak if (ffr.ifr_flags & IFF_LOOPBACK) {
348 1.1 brezak log(LOG_WARNING, 0,
349 1.1 brezak "tunnel local address %s in %s is a loopback interface",
350 1.1 brezak inet_fmt(lcl_addr, s1), configfilename);
351 1.1 brezak continue;
352 1.1 brezak }
353 1.1 brezak
354 1.1 brezak /*
355 1.1 brezak * Parse the remote address.
356 1.1 brezak */
357 1.1 brezak if (EQUAL((w = next_word(&s)), "")) {
358 1.1 brezak log(LOG_WARNING, 0,
359 1.1 brezak "missing tunnel remote address in %s",
360 1.1 brezak configfilename);
361 1.1 brezak continue;
362 1.1 brezak }
363 1.1 brezak if ((rmt_addr = inet_parse(w)) == 0xffffffff ||
364 1.1 brezak !inet_valid_host(rmt_addr)) {
365 1.1 brezak log(LOG_WARNING, 0,
366 1.1 brezak "invalid tunnel remote address %s in %s",
367 1.1 brezak w, configfilename);
368 1.1 brezak continue;
369 1.1 brezak }
370 1.1 brezak
371 1.1 brezak /*
372 1.1 brezak * Make sure the remote address is not one of ours.
373 1.1 brezak */
374 1.1 brezak if (ifconfaddr(&ifc, rmt_addr) != 0) {
375 1.1 brezak log(LOG_WARNING, 0,
376 1.1 brezak "tunnel remote address %s in %s is one of ours",
377 1.1 brezak inet_fmt(rmt_addr, s1), configfilename);
378 1.1 brezak continue;
379 1.1 brezak }
380 1.1 brezak
381 1.1 brezak /*
382 1.1 brezak * Make sure the remote address has not been used for another
383 1.1 brezak * tunnel and does not belong to a subnet to which we have direct
384 1.1 brezak * access on an enabled phyint.
385 1.1 brezak */
386 1.1 brezak for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
387 1.1 brezak if (v->uv_flags & VIFF_TUNNEL) {
388 1.1 brezak if (rmt_addr == v->uv_rmt_addr) {
389 1.1 brezak log(LOG_WARNING, 0,
390 1.1 brezak "duplicate tunnel remote address %s in %s",
391 1.1 brezak inet_fmt(rmt_addr, s1), configfilename);
392 1.1 brezak break;
393 1.1 brezak }
394 1.1 brezak }
395 1.1 brezak else if (!(v->uv_flags & VIFF_DISABLED)) {
396 1.1 brezak if ((rmt_addr & v->uv_subnetmask) == v->uv_subnet) {
397 1.1 brezak log(LOG_WARNING, 0,
398 1.1 brezak "unnecessary tunnel remote address %s in %s",
399 1.1 brezak inet_fmt(rmt_addr, s1), configfilename);
400 1.1 brezak break;
401 1.1 brezak }
402 1.1 brezak }
403 1.1 brezak }
404 1.1 brezak if (vifi != numvifs) continue;
405 1.1 brezak
406 1.1 brezak /*
407 1.1 brezak * OK, let's initialize a uvif structure for the tunnel.
408 1.1 brezak */
409 1.1 brezak if (numvifs == MAXVIFS) {
410 1.1 brezak log(LOG_WARNING, 0, "too many vifs, ignoring tunnel to %s",
411 1.1 brezak inet_fmt(rmt_addr, s1));
412 1.1 brezak continue;
413 1.1 brezak }
414 1.1 brezak v = &uvifs[numvifs];
415 1.1 brezak v->uv_flags = VIFF_TUNNEL;
416 1.1 brezak v->uv_metric = DEFAULT_METRIC;
417 1.1 brezak v->uv_threshold = DEFAULT_THRESHOLD;
418 1.1 brezak v->uv_lcl_addr = lcl_addr;
419 1.1 brezak v->uv_rmt_addr = rmt_addr;
420 1.1 brezak v->uv_subnet = 0;
421 1.1 brezak v->uv_subnetmask = 0;
422 1.1 brezak v->uv_subnetbcast = 0;
423 1.1 brezak strncpy(v->uv_name, ffr.ifr_name, IFNAMSIZ);
424 1.1 brezak v->uv_groups = NULL;
425 1.1 brezak v->uv_neighbors = NULL;
426 1.1 brezak
427 1.1 brezak /*
428 1.1 brezak * Look for "metric" and "threshold" options.
429 1.1 brezak */
430 1.1 brezak while (!EQUAL((w = next_word(&s)), "")) {
431 1.1 brezak if (EQUAL(w, "metric")) {
432 1.1 brezak if(EQUAL((w = next_word(&s)), "")) {
433 1.1 brezak log(LOG_WARNING, 0,
434 1.1 brezak "missing metric for tunnel to %s in %s",
435 1.1 brezak inet_fmt(rmt_addr, s1), configfilename);
436 1.1 brezak w = "garbage";
437 1.1 brezak break;
438 1.1 brezak }
439 1.1 brezak if(sscanf(w, "%u%c", &n, &c) != 1 ||
440 1.1 brezak n < 1 || n >= UNREACHABLE ) {
441 1.1 brezak log(LOG_WARNING, 0,
442 1.1 brezak "invalid metric '%s' for tunnel to %s in %s",
443 1.1 brezak w, inet_fmt(rmt_addr, s1), configfilename);
444 1.1 brezak break;
445 1.1 brezak }
446 1.1 brezak v->uv_metric = n;
447 1.1 brezak }
448 1.1 brezak else if (EQUAL(w, "threshold")) {
449 1.1 brezak if(EQUAL((w = next_word(&s)), "")) {
450 1.1 brezak log(LOG_WARNING, 0,
451 1.1 brezak "missing threshold for tunnel to %s in %s",
452 1.1 brezak inet_fmt(rmt_addr, s1), configfilename);
453 1.1 brezak w = "garbage";
454 1.1 brezak break;
455 1.1 brezak }
456 1.1 brezak if(sscanf(w, "%u%c", &n, &c) != 1 ||
457 1.1 brezak n < 1 || n > 255 ) {
458 1.1 brezak log(LOG_WARNING, 0,
459 1.1 brezak "invalid threshold '%s' for tunnel to %s in %s",
460 1.1 brezak w, inet_fmt(rmt_addr, s1), configfilename);
461 1.1 brezak break;
462 1.1 brezak }
463 1.1 brezak v->uv_threshold = n;
464 1.1 brezak }
465 1.1 brezak else if (EQUAL(w, "srcrt") || EQUAL(w, "sourceroute")) {
466 1.1 brezak v->uv_flags |= VIFF_SRCRT;
467 1.1 brezak }
468 1.1 brezak else break;
469 1.1 brezak }
470 1.1 brezak if (!EQUAL(w, "")) continue;
471 1.1 brezak
472 1.1 brezak log(LOG_INFO, 0,
473 1.1 brezak "installing %stunnel from %s to %s as vif #%u",
474 1.1 brezak v->uv_flags & VIFF_SRCRT? "srcrt " : "",
475 1.1 brezak inet_fmt(lcl_addr, s1), inet_fmt(rmt_addr, s2), numvifs);
476 1.1 brezak
477 1.1 brezak ++numvifs;
478 1.1 brezak
479 1.1 brezak if (!(ffr.ifr_flags & IFF_UP)) {
480 1.1 brezak v->uv_flags |= VIFF_DOWN;
481 1.1 brezak vifs_down = TRUE;
482 1.1 brezak }
483 1.1 brezak }
484 1.1 brezak
485 1.1 brezak else {
486 1.1 brezak log(LOG_WARNING, 0,
487 1.1 brezak "unknown command '%s' in %s", w, configfilename);
488 1.1 brezak }
489 1.1 brezak }
490 1.1 brezak
491 1.1 brezak close(f);
492 1.1 brezak }
493 1.1 brezak
494 1.1 brezak
495 1.1 brezak /*
496 1.1 brezak * Return a pointer to the next "word" in the string to which '*s' points,
497 1.1 brezak * lower-cased and null terminated, and advance '*s' to point beyond the word.
498 1.1 brezak * Words are separated by blanks and/or tabs, and the input string is
499 1.1 brezak * considered to terminate at a newline, '#' (comment), or null character.
500 1.1 brezak * If no words remain, a pointer to a null string ("") is returned.
501 1.1 brezak * Warning: This function clobbers the input string.
502 1.1 brezak */
503 1.1 brezak static char *next_word(s)
504 1.1 brezak char **s;
505 1.1 brezak {
506 1.1 brezak char *w;
507 1.1 brezak
508 1.1 brezak w = *s;
509 1.1 brezak while (*w == ' ' || *w == '\t')
510 1.1 brezak ++w;
511 1.1 brezak
512 1.1 brezak *s = w;
513 1.1 brezak for(;;) {
514 1.1 brezak switch (**s) {
515 1.1 brezak
516 1.1 brezak case ' ' :
517 1.1 brezak case '\t' : **s = '\0';
518 1.1 brezak ++*s;
519 1.1 brezak return (w);
520 1.1 brezak
521 1.1 brezak case '\n' :
522 1.1 brezak case '#' : **s = '\0';
523 1.1 brezak return (w);
524 1.1 brezak
525 1.1 brezak case '\0' : return (w);
526 1.1 brezak
527 1.1 brezak default : if (isascii(**s) && isupper(**s))
528 1.1 brezak **s = tolower(**s);
529 1.1 brezak ++*s;
530 1.1 brezak }
531 1.1 brezak }
532 1.1 brezak }
533