parms.c revision 1.3 1 1.3 christos /* $NetBSD: parms.c,v 1.3 1996/09/24 16:24:17 christos Exp $ */
2 1.2 thorpej
3 1.1 thorpej /*
4 1.1 thorpej * Copyright (c) 1983, 1993
5 1.1 thorpej * The Regents of the University of California. All rights reserved.
6 1.1 thorpej *
7 1.1 thorpej * Redistribution and use in source and binary forms, with or without
8 1.1 thorpej * modification, are permitted provided that the following conditions
9 1.1 thorpej * are met:
10 1.1 thorpej * 1. Redistributions of source code must retain the above copyright
11 1.1 thorpej * notice, this list of conditions and the following disclaimer.
12 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 thorpej * notice, this list of conditions and the following disclaimer in the
14 1.1 thorpej * documentation and/or other materials provided with the distribution.
15 1.1 thorpej * 3. All advertising materials mentioning features or use of this software
16 1.1 thorpej * must display the following acknowledgement:
17 1.1 thorpej * This product includes software developed by the University of
18 1.1 thorpej * California, Berkeley and its contributors.
19 1.1 thorpej * 4. Neither the name of the University nor the names of its contributors
20 1.1 thorpej * may be used to endorse or promote products derived from this software
21 1.1 thorpej * without specific prior written permission.
22 1.1 thorpej *
23 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 1.1 thorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 1.1 thorpej * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 1.1 thorpej * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 1.1 thorpej * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 1.1 thorpej * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 1.1 thorpej * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 1.1 thorpej * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 1.1 thorpej * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 1.1 thorpej * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 1.1 thorpej * SUCH DAMAGE.
34 1.1 thorpej */
35 1.1 thorpej
36 1.3 christos #if !defined(lint) && !defined(sgi) && !defined(__NetBSD__)
37 1.1 thorpej static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93";
38 1.3 christos #elif defined(__NetBSD__)
39 1.3 christos static char rcsid[] = "$NetBSD: parms.c,v 1.3 1996/09/24 16:24:17 christos Exp $";
40 1.2 thorpej #endif
41 1.1 thorpej
42 1.1 thorpej #include "defs.h"
43 1.1 thorpej #include "pathnames.h"
44 1.1 thorpej
45 1.1 thorpej
46 1.1 thorpej struct parm *parms;
47 1.1 thorpej struct intnet *intnets;
48 1.1 thorpej
49 1.1 thorpej
50 1.1 thorpej /* use configured parameters
51 1.1 thorpej */
52 1.1 thorpej void
53 1.1 thorpej get_parms(struct interface *ifp)
54 1.1 thorpej {
55 1.1 thorpej struct parm *parmp;
56 1.1 thorpej
57 1.1 thorpej /* get all relevant parameters
58 1.1 thorpej */
59 1.1 thorpej for (parmp = parms; parmp != 0; parmp = parmp->parm_next) {
60 1.1 thorpej if ((parmp->parm_name[0] == '\0'
61 1.1 thorpej && on_net(ifp->int_addr,
62 1.1 thorpej parmp->parm_addr_h, parmp->parm_mask))
63 1.1 thorpej || (parmp->parm_name[0] != '\0'
64 1.1 thorpej && !strcmp(ifp->int_name, parmp->parm_name))) {
65 1.1 thorpej /* this group of parameters is relevant,
66 1.1 thorpej * so get its settings
67 1.1 thorpej */
68 1.1 thorpej ifp->int_state |= parmp->parm_int_state;
69 1.1 thorpej if (parmp->parm_passwd[0] != '\0')
70 1.1 thorpej bcopy(parmp->parm_passwd, ifp->int_passwd,
71 1.1 thorpej sizeof(ifp->int_passwd));
72 1.1 thorpej if (parmp->parm_rdisc_pref != 0)
73 1.1 thorpej ifp->int_rdisc_pref = parmp->parm_rdisc_pref;
74 1.1 thorpej if (parmp->parm_rdisc_int != 0)
75 1.1 thorpej ifp->int_rdisc_int = parmp->parm_rdisc_int;
76 1.1 thorpej if (parmp->parm_d_metric != 0)
77 1.1 thorpej ifp->int_d_metric = parmp->parm_d_metric;
78 1.1 thorpej }
79 1.1 thorpej }
80 1.1 thorpej /* default poor-man's router discovery to a metric that will
81 1.1 thorpej * be heard by old versions of routed.
82 1.1 thorpej */
83 1.1 thorpej if ((ifp->int_state & IS_PM_RDISC)
84 1.1 thorpej && ifp->int_d_metric == 0)
85 1.1 thorpej ifp->int_d_metric = HOPCNT_INFINITY-2;
86 1.1 thorpej
87 1.1 thorpej if (IS_RIP_IN_OFF(ifp->int_state))
88 1.1 thorpej ifp->int_state |= IS_NO_RIP_OUT;
89 1.1 thorpej
90 1.1 thorpej if (ifp->int_rdisc_int == 0)
91 1.1 thorpej ifp->int_rdisc_int = DefMaxAdvertiseInterval;
92 1.1 thorpej
93 1.1 thorpej if (!(ifp->int_if_flags & IFF_MULTICAST)
94 1.1 thorpej && !(ifp->int_if_flags & IFF_POINTOPOINT))
95 1.1 thorpej ifp->int_state |= IS_NO_RIPV2_OUT;
96 1.1 thorpej
97 1.1 thorpej if (!(ifp->int_if_flags & IFF_MULTICAST))
98 1.1 thorpej ifp->int_state |= IS_BCAST_RDISC;
99 1.1 thorpej
100 1.1 thorpej if (ifp->int_if_flags & IFF_POINTOPOINT) {
101 1.1 thorpej ifp->int_state |= IS_BCAST_RDISC;
102 1.1 thorpej /* By default, point-to-point links should be passive
103 1.1 thorpej * about router-discovery for the sake of demand-dialing.
104 1.1 thorpej */
105 1.1 thorpej if (0 == (ifp->int_state & GROUP_IS_SOL))
106 1.1 thorpej ifp->int_state |= IS_NO_SOL_OUT;
107 1.1 thorpej if (0 == (ifp->int_state & GROUP_IS_ADV))
108 1.1 thorpej ifp->int_state |= IS_NO_ADV_OUT;
109 1.1 thorpej }
110 1.1 thorpej
111 1.1 thorpej if (0 != (ifp->int_state & (IS_PASSIVE | IS_REMOTE)))
112 1.1 thorpej ifp->int_state |= IS_NO_RDISC;
113 1.1 thorpej if (ifp->int_state & IS_PASSIVE)
114 1.1 thorpej ifp->int_state |= (IS_NO_RIP | IS_NO_RDISC);
115 1.3 christos if ((ifp->int_state & (IS_NO_RIP | IS_NO_RDISC))
116 1.3 christos == (IS_NO_RIP|IS_NO_RDISC))
117 1.1 thorpej ifp->int_state |= IS_PASSIVE;
118 1.1 thorpej }
119 1.1 thorpej
120 1.1 thorpej
121 1.1 thorpej /* Read a list of gateways from /etc/gateways and add them to our tables.
122 1.1 thorpej *
123 1.1 thorpej * This file contains a list of "remote" gateways. That is usually
124 1.1 thorpej * a gateway which we cannot immediately determine if it is present or
125 1.1 thorpej * not as we can do for those provided by directly connected hardware.
126 1.1 thorpej *
127 1.1 thorpej * If a gateway is marked "passive" in the file, then we assume it
128 1.1 thorpej * does not understand RIP and assume it is always present. Those
129 1.1 thorpej * not marked passive are treated as if they were directly connected
130 1.1 thorpej * and assumed to be broken if they do not send us advertisements.
131 1.1 thorpej * All remote interfaces are added to our list, and those not marked
132 1.1 thorpej * passive are sent routing updates.
133 1.1 thorpej *
134 1.1 thorpej * A passive interface can also be local, hardware interface exempt
135 1.1 thorpej * from RIP.
136 1.1 thorpej */
137 1.1 thorpej void
138 1.1 thorpej gwkludge(void)
139 1.1 thorpej {
140 1.1 thorpej FILE *fp;
141 1.1 thorpej char *p, *lptr;
142 1.1 thorpej char lbuf[200], net_host[5], dname[64+1+64+1], gname[64+1], qual[9];
143 1.1 thorpej struct interface *ifp;
144 1.1 thorpej naddr dst, netmask, gate;
145 1.1 thorpej int metric, n;
146 1.1 thorpej u_int state;
147 1.1 thorpej char *type;
148 1.1 thorpej struct parm *parmp;
149 1.1 thorpej
150 1.1 thorpej
151 1.1 thorpej fp = fopen(_PATH_GATEWAYS, "r");
152 1.1 thorpej if (fp == 0)
153 1.1 thorpej return;
154 1.1 thorpej
155 1.1 thorpej for (;;) {
156 1.1 thorpej if (0 == fgets(lbuf, sizeof(lbuf)-1, fp))
157 1.1 thorpej break;
158 1.1 thorpej lptr = lbuf;
159 1.1 thorpej while (*lptr == ' ')
160 1.1 thorpej lptr++;
161 1.1 thorpej if (*lptr == '\n' /* ignore null and comment lines */
162 1.1 thorpej || *lptr == '#')
163 1.1 thorpej continue;
164 1.1 thorpej p = lptr+strlen(lptr)-1;
165 1.1 thorpej while (*p == '\n'
166 1.1 thorpej || *p == ' ')
167 1.1 thorpej *p-- = '\0';
168 1.1 thorpej
169 1.1 thorpej /* notice newfangled parameter lines
170 1.1 thorpej */
171 1.1 thorpej if (strncasecmp("net", lptr, 3)
172 1.1 thorpej && strncasecmp("host", lptr, 4)) {
173 1.1 thorpej p = parse_parms(lptr);
174 1.1 thorpej if (p != 0) {
175 1.1 thorpej if (strcmp(p,lptr))
176 1.1 thorpej msglog("bad \"%s\" in "_PATH_GATEWAYS
177 1.1 thorpej " entry \"%s\"", lptr, p);
178 1.1 thorpej else
179 1.1 thorpej msglog("bad \"%s\" in "_PATH_GATEWAYS,
180 1.1 thorpej lptr);
181 1.1 thorpej }
182 1.1 thorpej continue;
183 1.1 thorpej }
184 1.1 thorpej
185 1.1 thorpej /* {net | host} XX[/M] XX gateway XX metric DD [passive | external]\n */
186 1.1 thorpej n = sscanf(lptr, "%4s %129[^ \t] gateway"
187 1.1 thorpej " %64[^ / \t] metric %d %8s\n",
188 1.1 thorpej net_host, dname, gname, &metric, qual);
189 1.1 thorpej if (n != 5) {
190 1.1 thorpej msglog("bad "_PATH_GATEWAYS" entry \"%s\"", lptr);
191 1.1 thorpej continue;
192 1.1 thorpej }
193 1.1 thorpej if (metric < 0 || metric >= HOPCNT_INFINITY) {
194 1.1 thorpej msglog("bad metric in "_PATH_GATEWAYS" entry \"%s\"",
195 1.1 thorpej lptr);
196 1.1 thorpej continue;
197 1.1 thorpej }
198 1.1 thorpej if (!strcmp(net_host, "host")) {
199 1.1 thorpej if (!gethost(dname, &dst)) {
200 1.1 thorpej msglog("bad host \"%s\" in "_PATH_GATEWAYS
201 1.1 thorpej " entry \"%s\"", dname, lptr);
202 1.1 thorpej continue;
203 1.1 thorpej }
204 1.1 thorpej netmask = HOST_MASK;
205 1.1 thorpej } else if (!strcmp(net_host, "net")) {
206 1.1 thorpej if (!getnet(dname, &dst, &netmask)) {
207 1.1 thorpej msglog("bad net \"%s\" in "_PATH_GATEWAYS
208 1.1 thorpej " entry \"%s\"", dname, lptr);
209 1.1 thorpej continue;
210 1.1 thorpej }
211 1.1 thorpej } else {
212 1.1 thorpej msglog("bad \"%s\" in "_PATH_GATEWAYS
213 1.1 thorpej " entry \"%s\"", lptr);
214 1.1 thorpej continue;
215 1.1 thorpej }
216 1.1 thorpej
217 1.1 thorpej if (!gethost(gname, &gate)) {
218 1.1 thorpej msglog("bad gateway \"%s\" in "_PATH_GATEWAYS
219 1.1 thorpej " entry \"%s\"", gname, lptr);
220 1.1 thorpej continue;
221 1.1 thorpej }
222 1.1 thorpej
223 1.1 thorpej if (strcmp(qual, type = "passive") == 0) {
224 1.1 thorpej /* Passive entries are not placed in our tables,
225 1.1 thorpej * only the kernel's, so we don't copy all of the
226 1.1 thorpej * external routing information within a net.
227 1.1 thorpej * Internal machines should use the default
228 1.1 thorpej * route to a suitable gateway (like us).
229 1.1 thorpej */
230 1.1 thorpej state = IS_REMOTE | IS_PASSIVE;
231 1.1 thorpej if (metric == 0)
232 1.1 thorpej metric = 1;
233 1.1 thorpej
234 1.1 thorpej } else if (strcmp(qual, type = "external") == 0) {
235 1.1 thorpej /* External entries are handled by other means
236 1.1 thorpej * such as EGP, and are placed only in the daemon
237 1.1 thorpej * tables to prevent overriding them with something
238 1.1 thorpej * else.
239 1.1 thorpej */
240 1.1 thorpej state = IS_REMOTE | IS_PASSIVE | IS_EXTERNAL;
241 1.1 thorpej if (metric == 0)
242 1.1 thorpej metric = 1;
243 1.1 thorpej
244 1.1 thorpej } else if (qual[0] == '\0') {
245 1.1 thorpej if (metric != 0) {
246 1.1 thorpej /* Entries that are neither "passive" nor
247 1.1 thorpej * "external" are "remote" and must behave
248 1.1 thorpej * like physical interfaces. If they are not
249 1.1 thorpej * heard from regularly, they are deleted.
250 1.1 thorpej */
251 1.1 thorpej state = IS_REMOTE;
252 1.1 thorpej type = "remote";
253 1.1 thorpej } else {
254 1.1 thorpej /* "remote" entries with a metric of 0
255 1.1 thorpej * are aliases for our own interfaces
256 1.1 thorpej */
257 1.1 thorpej state = IS_REMOTE | IS_PASSIVE;
258 1.1 thorpej type = "alias";
259 1.1 thorpej }
260 1.1 thorpej
261 1.1 thorpej } else {
262 1.1 thorpej msglog("bad "_PATH_GATEWAYS" entry \"%s\"", lptr);
263 1.1 thorpej continue;
264 1.1 thorpej }
265 1.1 thorpej
266 1.1 thorpej /* Remember to advertise the corresponding logical network.
267 1.1 thorpej */
268 1.1 thorpej if (!(state & IS_EXTERNAL)
269 1.1 thorpej && netmask != std_mask(dst))
270 1.1 thorpej state |= IS_SUBNET;
271 1.1 thorpej
272 1.1 thorpej if (0 != (state & (IS_PASSIVE | IS_REMOTE)))
273 1.1 thorpej state |= IS_NO_RDISC;
274 1.1 thorpej if (state & IS_PASSIVE)
275 1.1 thorpej state |= (IS_NO_RIP | IS_NO_RDISC);
276 1.3 christos if ((state & (IS_NO_RIP | IS_NO_RDISC))
277 1.3 christos == (IS_NO_RIP|IS_NO_RDISC))
278 1.1 thorpej state |= IS_PASSIVE;
279 1.1 thorpej
280 1.1 thorpej parmp = (struct parm*)malloc(sizeof(*parmp));
281 1.1 thorpej bzero(parmp, sizeof(*parmp));
282 1.1 thorpej parmp->parm_next = parms;
283 1.1 thorpej parms = parmp;
284 1.1 thorpej parmp->parm_addr_h = ntohl(dst);
285 1.1 thorpej parmp->parm_mask = -1;
286 1.1 thorpej parmp->parm_d_metric = 0;
287 1.1 thorpej parmp->parm_int_state = state;
288 1.1 thorpej
289 1.1 thorpej /* See if this new interface duplicates an existing
290 1.1 thorpej * interface.
291 1.1 thorpej */
292 1.1 thorpej for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) {
293 1.1 thorpej if (ifp->int_mask == netmask
294 1.1 thorpej && ((ifp->int_addr == dst
295 1.1 thorpej && netmask != HOST_MASK)
296 1.1 thorpej || (ifp->int_dstaddr == dst
297 1.1 thorpej && netmask == HOST_MASK)))
298 1.1 thorpej break;
299 1.1 thorpej }
300 1.1 thorpej if (ifp != 0) {
301 1.1 thorpej /* Let one of our real interfaces be marked passive.
302 1.1 thorpej */
303 1.1 thorpej if ((state & IS_PASSIVE) && !(state & IS_EXTERNAL)) {
304 1.1 thorpej ifp->int_state |= state;
305 1.1 thorpej } else {
306 1.1 thorpej msglog("%s is duplicated in "_PATH_GATEWAYS
307 1.1 thorpej " by %s",
308 1.1 thorpej ifp->int_name, lptr);
309 1.1 thorpej }
310 1.1 thorpej continue;
311 1.1 thorpej }
312 1.1 thorpej
313 1.1 thorpej tot_interfaces++;
314 1.1 thorpej
315 1.1 thorpej ifp = (struct interface *)malloc(sizeof(*ifp));
316 1.1 thorpej bzero(ifp, sizeof(*ifp));
317 1.1 thorpej if (ifnet != 0) {
318 1.1 thorpej ifp->int_next = ifnet;
319 1.1 thorpej ifnet->int_prev = ifp;
320 1.1 thorpej }
321 1.1 thorpej ifnet = ifp;
322 1.1 thorpej
323 1.1 thorpej ifp->int_state = state;
324 1.1 thorpej ifp->int_net = ntohl(dst) & netmask;
325 1.1 thorpej ifp->int_mask = netmask;
326 1.1 thorpej if (netmask == HOST_MASK)
327 1.1 thorpej ifp->int_if_flags |= IFF_POINTOPOINT;
328 1.1 thorpej ifp->int_dstaddr = dst;
329 1.1 thorpej ifp->int_addr = gate;
330 1.1 thorpej ifp->int_metric = metric;
331 1.1 thorpej (void)sprintf(ifp->int_name, "%s-%s", type, naddr_ntoa(dst));
332 1.1 thorpej ifp->int_index = -1;
333 1.1 thorpej
334 1.1 thorpej get_parms(ifp);
335 1.1 thorpej
336 1.1 thorpej trace_if("Add", ifp);
337 1.1 thorpej }
338 1.1 thorpej }
339 1.1 thorpej
340 1.1 thorpej
341 1.1 thorpej /* parse a set of parameters for an interface
342 1.1 thorpej */
343 1.1 thorpej char * /* 0 or error message */
344 1.1 thorpej parse_parms(char *line)
345 1.1 thorpej {
346 1.1 thorpej #define PARS(str) (0 == (tgt = str, strcasecmp(tok, tgt)))
347 1.1 thorpej #define PARSE(str) (0 == (tgt = str, strncasecmp(tok, str "=", sizeof(str))))
348 1.1 thorpej #define CKF(g,b) {if (0 != (parm.parm_int_state & ((g) & ~(b)))) break; \
349 1.1 thorpej parm.parm_int_state |= (b);}
350 1.1 thorpej #define DELIMS " ,\t\n"
351 1.1 thorpej struct parm parm;
352 1.1 thorpej struct intnet *intnetp;
353 1.1 thorpej char *tok, *tgt, *p;
354 1.1 thorpej
355 1.1 thorpej
356 1.1 thorpej /* "subnet=x.y.z.u/mask" must be alone on the line */
357 1.1 thorpej if (!strncasecmp("subnet=",line,7)) {
358 1.1 thorpej intnetp = (struct intnet*)malloc(sizeof(*intnetp));
359 1.1 thorpej intnetp->intnet_metric = 1;
360 1.2 thorpej if ((p = strrchr(line,','))) {
361 1.1 thorpej *p++ = '\0';
362 1.1 thorpej intnetp->intnet_metric = (int)strtol(p,&p,0);
363 1.1 thorpej if (*p != '\0'
364 1.1 thorpej || intnetp->intnet_metric <= 0
365 1.1 thorpej || intnetp->intnet_metric >= HOPCNT_INFINITY)
366 1.1 thorpej return line;
367 1.1 thorpej }
368 1.1 thorpej if (!getnet(&line[7], &intnetp->intnet_addr,
369 1.1 thorpej &intnetp->intnet_mask)
370 1.1 thorpej || intnetp->intnet_mask == HOST_MASK
371 1.1 thorpej || intnetp->intnet_addr == RIP_DEFAULT) {
372 1.1 thorpej free(intnetp);
373 1.1 thorpej return line;
374 1.1 thorpej }
375 1.1 thorpej intnetp->intnet_next = intnets;
376 1.1 thorpej intnets = intnetp;
377 1.1 thorpej return 0;
378 1.1 thorpej }
379 1.1 thorpej
380 1.1 thorpej bzero(&parm, sizeof(parm));
381 1.1 thorpej
382 1.1 thorpej tgt = "null";
383 1.1 thorpej for (tok = strtok(line, DELIMS);
384 1.1 thorpej tok != 0 && tok[0] != '\0';
385 1.1 thorpej tgt = 0, tok = strtok(0,DELIMS)) {
386 1.1 thorpej if (PARSE("if")) {
387 1.1 thorpej if (parm.parm_name[0] != '\0'
388 1.1 thorpej || tok[3] == '\0'
389 1.1 thorpej || strlen(tok) > IFNAMSIZ+3)
390 1.1 thorpej break;
391 1.1 thorpej strcpy(parm.parm_name, tok+3);
392 1.1 thorpej
393 1.1 thorpej } else if (PARSE("passwd")) {
394 1.1 thorpej if (tok[7] == '\0'
395 1.1 thorpej || strlen(tok) > RIP_AUTH_PW_LEN+7)
396 1.1 thorpej break;
397 1.1 thorpej strcpy(parm.parm_passwd, tok+7);
398 1.1 thorpej
399 1.1 thorpej } else if (PARS("no_ag")) {
400 1.1 thorpej parm.parm_int_state |= (IS_NO_AG | IS_NO_SUPER_AG);
401 1.1 thorpej
402 1.1 thorpej } else if (PARS("no_super_ag")) {
403 1.1 thorpej parm.parm_int_state |= IS_NO_SUPER_AG;
404 1.1 thorpej
405 1.1 thorpej } else if (PARS("no_ripv1_in")) {
406 1.1 thorpej parm.parm_int_state |= IS_NO_RIPV1_IN;
407 1.1 thorpej
408 1.1 thorpej } else if (PARS("no_ripv2_in")) {
409 1.1 thorpej parm.parm_int_state |= IS_NO_RIPV2_IN;
410 1.1 thorpej
411 1.1 thorpej } else if (PARS("ripv2_out")) {
412 1.1 thorpej if (parm.parm_int_state & IS_NO_RIPV2_OUT)
413 1.1 thorpej break;
414 1.1 thorpej parm.parm_int_state |= IS_NO_RIPV1_OUT;
415 1.1 thorpej
416 1.1 thorpej } else if (PARS("no_rip")) {
417 1.1 thorpej parm.parm_int_state |= IS_NO_RIP;
418 1.1 thorpej
419 1.1 thorpej } else if (PARS("no_rdisc")) {
420 1.1 thorpej CKF((GROUP_IS_SOL|GROUP_IS_ADV), IS_NO_RDISC);
421 1.1 thorpej
422 1.1 thorpej } else if (PARS("no_solicit")) {
423 1.1 thorpej CKF(GROUP_IS_SOL, IS_NO_SOL_OUT);
424 1.1 thorpej
425 1.1 thorpej } else if (PARS("send_solicit")) {
426 1.1 thorpej CKF(GROUP_IS_SOL, IS_SOL_OUT);
427 1.1 thorpej
428 1.1 thorpej } else if (PARS("no_rdisc_adv")) {
429 1.1 thorpej CKF(GROUP_IS_ADV, IS_NO_ADV_OUT);
430 1.1 thorpej
431 1.1 thorpej } else if (PARS("rdisc_adv")) {
432 1.1 thorpej CKF(GROUP_IS_ADV, IS_ADV_OUT);
433 1.1 thorpej
434 1.1 thorpej } else if (PARS("bcast_rdisc")) {
435 1.1 thorpej parm.parm_int_state |= IS_BCAST_RDISC;
436 1.1 thorpej
437 1.1 thorpej } else if (PARS("passive")) {
438 1.1 thorpej CKF((GROUP_IS_SOL|GROUP_IS_ADV), IS_NO_RDISC);
439 1.1 thorpej parm.parm_int_state |= IS_NO_RIP;
440 1.1 thorpej
441 1.1 thorpej } else if (PARSE("rdisc_pref")) {
442 1.1 thorpej if (parm.parm_rdisc_pref != 0
443 1.1 thorpej || tok[11] == '\0'
444 1.1 thorpej || (parm.parm_rdisc_pref = (int)strtol(&tok[11],
445 1.1 thorpej &p,0),
446 1.1 thorpej *p != '\0'))
447 1.1 thorpej break;
448 1.1 thorpej
449 1.1 thorpej } else if (PARS("pm_rdisc")) {
450 1.1 thorpej parm.parm_int_state |= IS_PM_RDISC;
451 1.1 thorpej
452 1.1 thorpej } else if (PARSE("rdisc_interval")) {
453 1.1 thorpej if (parm.parm_rdisc_int != 0
454 1.1 thorpej || tok[15] == '\0'
455 1.1 thorpej || (parm.parm_rdisc_int = (int)strtol(&tok[15],
456 1.1 thorpej &p,0),
457 1.1 thorpej *p != '\0')
458 1.1 thorpej || parm.parm_rdisc_int < MinMaxAdvertiseInterval
459 1.1 thorpej || parm.parm_rdisc_int > MaxMaxAdvertiseInterval)
460 1.1 thorpej break;
461 1.1 thorpej
462 1.1 thorpej } else if (PARSE("fake_default")) {
463 1.1 thorpej if (parm.parm_d_metric != 0
464 1.1 thorpej || tok[13] == '\0'
465 1.1 thorpej || (parm.parm_d_metric=(int)strtol(&tok[13],&p,0),
466 1.1 thorpej *p != '\0')
467 1.1 thorpej || parm.parm_d_metric > HOPCNT_INFINITY-1)
468 1.1 thorpej break;
469 1.1 thorpej
470 1.1 thorpej } else {
471 1.1 thorpej tgt = tok;
472 1.1 thorpej break;
473 1.1 thorpej }
474 1.1 thorpej }
475 1.1 thorpej if (tgt != 0)
476 1.1 thorpej return tgt;
477 1.1 thorpej
478 1.1 thorpej return check_parms(&parm);
479 1.1 thorpej #undef DELIMS
480 1.1 thorpej #undef PARS
481 1.1 thorpej #undef PARSE
482 1.1 thorpej }
483 1.1 thorpej
484 1.1 thorpej
485 1.1 thorpej /* check for duplicate parameter specifications */
486 1.1 thorpej char * /* 0 or error message */
487 1.1 thorpej check_parms(struct parm *new)
488 1.1 thorpej {
489 1.1 thorpej struct parm *parmp;
490 1.1 thorpej
491 1.1 thorpej
492 1.3 christos /* set implicit values
493 1.3 christos */
494 1.3 christos if (!supplier && supplier_set)
495 1.3 christos new->parm_int_state |= (IS_NO_RIPV1_OUT
496 1.3 christos | IS_NO_RIPV2_OUT
497 1.3 christos | IS_NO_ADV_OUT);
498 1.3 christos if (new->parm_int_state & IS_NO_ADV_IN)
499 1.3 christos new->parm_int_state |= IS_NO_SOL_OUT;
500 1.3 christos
501 1.3 christos if ((new->parm_int_state & (IS_NO_RIP | IS_NO_RDISC))
502 1.3 christos == (IS_NO_RIP | IS_NO_RDISC))
503 1.3 christos new->parm_int_state |= IS_PASSIVE;
504 1.3 christos
505 1.3 christos /* compare with existing sets of parameters
506 1.3 christos */
507 1.1 thorpej for (parmp = parms; parmp != 0; parmp = parmp->parm_next) {
508 1.1 thorpej if (strcmp(new->parm_name, parmp->parm_name))
509 1.1 thorpej continue;
510 1.1 thorpej if (!on_net(htonl(parmp->parm_addr_h),
511 1.1 thorpej new->parm_addr_h, new->parm_mask)
512 1.1 thorpej && !on_net(htonl(new->parm_addr_h),
513 1.1 thorpej parmp->parm_addr_h, parmp->parm_mask))
514 1.1 thorpej continue;
515 1.1 thorpej
516 1.1 thorpej if (strcmp(parmp->parm_passwd, new->parm_passwd)
517 1.1 thorpej || (0 != (new->parm_int_state & GROUP_IS_SOL)
518 1.1 thorpej && 0 != (parmp->parm_int_state & GROUP_IS_SOL)
519 1.1 thorpej && 0 != ((new->parm_int_state ^ parmp->parm_int_state)
520 1.1 thorpej && GROUP_IS_SOL))
521 1.1 thorpej || (0 != (new->parm_int_state & GROUP_IS_ADV)
522 1.1 thorpej && 0 != (parmp->parm_int_state & GROUP_IS_ADV)
523 1.1 thorpej && 0 != ((new->parm_int_state ^ parmp->parm_int_state)
524 1.1 thorpej && GROUP_IS_ADV))
525 1.1 thorpej || (new->parm_rdisc_pref != 0
526 1.1 thorpej && parmp->parm_rdisc_pref != 0
527 1.1 thorpej && new->parm_rdisc_pref != parmp->parm_rdisc_pref)
528 1.1 thorpej || (new->parm_rdisc_int != 0
529 1.1 thorpej && parmp->parm_rdisc_int != 0
530 1.1 thorpej && new->parm_rdisc_int != parmp->parm_rdisc_int)
531 1.1 thorpej || (new->parm_d_metric != 0
532 1.1 thorpej && parmp->parm_d_metric != 0
533 1.1 thorpej && new->parm_d_metric != parmp->parm_d_metric))
534 1.1 thorpej return "duplicate";
535 1.1 thorpej }
536 1.1 thorpej
537 1.1 thorpej parmp = (struct parm*)malloc(sizeof(*parmp));
538 1.1 thorpej bcopy(new, parmp, sizeof(*parmp));
539 1.1 thorpej parmp->parm_next = parms;
540 1.1 thorpej parms = parmp;
541 1.1 thorpej
542 1.1 thorpej return 0;
543 1.1 thorpej }
544 1.1 thorpej
545 1.1 thorpej
546 1.1 thorpej /* get a network number as a name or a number, with an optional "/xx"
547 1.1 thorpej * netmask.
548 1.1 thorpej */
549 1.1 thorpej int /* 0=bad */
550 1.1 thorpej getnet(char *name,
551 1.1 thorpej naddr *addrp, /* host byte order */
552 1.1 thorpej naddr *maskp)
553 1.1 thorpej {
554 1.1 thorpej int i;
555 1.1 thorpej struct netent *np;
556 1.1 thorpej naddr mask;
557 1.1 thorpej struct in_addr in;
558 1.1 thorpej char hname[MAXHOSTNAMELEN+1];
559 1.1 thorpej char *mname, *p;
560 1.1 thorpej
561 1.1 thorpej
562 1.1 thorpej /* Detect and separate "1.2.3.4/24"
563 1.1 thorpej */
564 1.1 thorpej if (0 != (mname = rindex(name,'/'))) {
565 1.1 thorpej i = (int)(mname - name);
566 1.1 thorpej if (i > sizeof(hname)-1) /* name too long */
567 1.1 thorpej return 0;
568 1.1 thorpej bcopy(name, hname, i);
569 1.1 thorpej hname[i] = '\0';
570 1.1 thorpej mname++;
571 1.1 thorpej name = hname;
572 1.1 thorpej }
573 1.1 thorpej
574 1.1 thorpej np = getnetbyname(name);
575 1.1 thorpej if (np != 0) {
576 1.1 thorpej in.s_addr = (naddr)np->n_net;
577 1.1 thorpej } else if (inet_aton(name, &in) == 1) {
578 1.1 thorpej HTONL(in.s_addr);
579 1.1 thorpej } else {
580 1.1 thorpej return 0;
581 1.1 thorpej }
582 1.1 thorpej
583 1.1 thorpej if (mname == 0) {
584 1.1 thorpej /* we cannot use the interfaces here because we have not
585 1.1 thorpej * looked at them yet.
586 1.1 thorpej */
587 1.1 thorpej mask = std_mask(in.s_addr);
588 1.1 thorpej if ((~mask & ntohl(in.s_addr)) != 0)
589 1.1 thorpej mask = HOST_MASK;
590 1.1 thorpej } else {
591 1.1 thorpej mask = (naddr)strtoul(mname, &p, 0);
592 1.1 thorpej if (*p != '\0' || mask > 32)
593 1.1 thorpej return 0;
594 1.1 thorpej mask = HOST_MASK << (32-mask);
595 1.1 thorpej }
596 1.1 thorpej if (mask != 0 && in.s_addr == RIP_DEFAULT)
597 1.1 thorpej return 0;
598 1.1 thorpej if ((~mask & ntohl(in.s_addr)) != 0)
599 1.1 thorpej return 0;
600 1.1 thorpej
601 1.1 thorpej *addrp = in.s_addr;
602 1.1 thorpej *maskp = mask;
603 1.1 thorpej return 1;
604 1.1 thorpej }
605 1.1 thorpej
606 1.1 thorpej
607 1.1 thorpej int /* 0=bad */
608 1.1 thorpej gethost(char *name,
609 1.1 thorpej naddr *addrp)
610 1.1 thorpej {
611 1.1 thorpej struct hostent *hp;
612 1.1 thorpej struct in_addr in;
613 1.1 thorpej
614 1.1 thorpej
615 1.1 thorpej /* Try for a number first, even in IRIX where gethostbyname()
616 1.1 thorpej * is smart. This avoids hitting the name server which
617 1.1 thorpej * might be sick because routing is.
618 1.1 thorpej */
619 1.1 thorpej if (inet_aton(name, &in) == 1) {
620 1.1 thorpej *addrp = in.s_addr;
621 1.1 thorpej return 1;
622 1.1 thorpej }
623 1.1 thorpej
624 1.1 thorpej hp = gethostbyname(name);
625 1.1 thorpej if (hp) {
626 1.1 thorpej bcopy(hp->h_addr, addrp, sizeof(*addrp));
627 1.1 thorpej return 1;
628 1.1 thorpej }
629 1.1 thorpej
630 1.1 thorpej return 0;
631 1.1 thorpej }
632