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