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