Home | History | Annotate | Line # | Download | only in routed
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