17c478bd9Sstevel@tonic-gate /* 2*982ec2c2SRishi Srivatsavai * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate * 57c478bd9Sstevel@tonic-gate * Copyright (c) 1983, 1993 67c478bd9Sstevel@tonic-gate * The Regents of the University of California. All rights reserved. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 97c478bd9Sstevel@tonic-gate * modification, are permitted provided that the following conditions 107c478bd9Sstevel@tonic-gate * are met: 117c478bd9Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 127c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 137c478bd9Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 147c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 157c478bd9Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 167c478bd9Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 177c478bd9Sstevel@tonic-gate * must display the following acknowledgment: 187c478bd9Sstevel@tonic-gate * This product includes software developed by the University of 197c478bd9Sstevel@tonic-gate * California, Berkeley and its contributors. 207c478bd9Sstevel@tonic-gate * 4. Neither the name of the University nor the names of its contributors 217c478bd9Sstevel@tonic-gate * may be used to endorse or promote products derived from this software 227c478bd9Sstevel@tonic-gate * without specific prior written permission. 237c478bd9Sstevel@tonic-gate * 247c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 257c478bd9Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 267c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 277c478bd9Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 287c478bd9Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 297c478bd9Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 307c478bd9Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 317c478bd9Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 327c478bd9Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 337c478bd9Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 347c478bd9Sstevel@tonic-gate * SUCH DAMAGE. 357c478bd9Sstevel@tonic-gate * 367c478bd9Sstevel@tonic-gate * $FreeBSD: src/sbin/routed/parms.c,v 1.9 2000/08/11 08:24:38 sheldonh Exp $ 377c478bd9Sstevel@tonic-gate */ 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate #include "defs.h" 407c478bd9Sstevel@tonic-gate #include "pathnames.h" 417c478bd9Sstevel@tonic-gate #include <sys/stat.h> 427c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 437c478bd9Sstevel@tonic-gate #include <ctype.h> 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate #define PARMS_MAXLINELEN 500 467c478bd9Sstevel@tonic-gate static struct parm *parms; 477c478bd9Sstevel@tonic-gate struct intnet *intnets; 487c478bd9Sstevel@tonic-gate struct r1net *r1nets; 497c478bd9Sstevel@tonic-gate struct tgate *tgates; 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate static void addroutefordefault(in_addr_t, in_addr_t, in_addr_t, 527c478bd9Sstevel@tonic-gate uint32_t, uint16_t); 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate /* use configured parameters */ 557c478bd9Sstevel@tonic-gate void 567c478bd9Sstevel@tonic-gate get_parms(struct interface *ifp) 577c478bd9Sstevel@tonic-gate { 587c478bd9Sstevel@tonic-gate static boolean_t warned_auth_in, warned_auth_out; 597c478bd9Sstevel@tonic-gate struct parm *parmp; 607c478bd9Sstevel@tonic-gate int i, num_passwds = 0; 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate if (ifp == NULL) 637c478bd9Sstevel@tonic-gate return; 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate /* get all relevant parameters */ 667c478bd9Sstevel@tonic-gate for (parmp = parms; parmp != NULL; parmp = parmp->parm_next) { 677c478bd9Sstevel@tonic-gate if (parmp->parm_name[0] == '\0' || 687c478bd9Sstevel@tonic-gate strcmp(ifp->int_name, parmp->parm_name) == 0 || 697c478bd9Sstevel@tonic-gate (parmp->parm_name[0] == '\n' && 707c478bd9Sstevel@tonic-gate on_net(ifp->int_addr, 717c478bd9Sstevel@tonic-gate parmp->parm_net, parmp->parm_mask))) { 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate /* 747c478bd9Sstevel@tonic-gate * This group of parameters is relevant, 757c478bd9Sstevel@tonic-gate * so get its settings 767c478bd9Sstevel@tonic-gate */ 777c478bd9Sstevel@tonic-gate ifp->int_state |= parmp->parm_int_state; 787c478bd9Sstevel@tonic-gate for (i = 0; i < MAX_AUTH_KEYS; i++) { 797c478bd9Sstevel@tonic-gate if (parmp->parm_auth[i].type == RIP_AUTH_NONE || 807c478bd9Sstevel@tonic-gate num_passwds >= MAX_AUTH_KEYS) 817c478bd9Sstevel@tonic-gate break; 827c478bd9Sstevel@tonic-gate ifp->int_auth[num_passwds++] = 837c478bd9Sstevel@tonic-gate parmp->parm_auth[i]; 847c478bd9Sstevel@tonic-gate } 857c478bd9Sstevel@tonic-gate if (parmp->parm_rdisc_pref != 0) 867c478bd9Sstevel@tonic-gate ifp->int_rdisc_pref = parmp->parm_rdisc_pref; 877c478bd9Sstevel@tonic-gate if (parmp->parm_rdisc_int != 0) 887c478bd9Sstevel@tonic-gate ifp->int_rdisc_int = parmp->parm_rdisc_int; 897c478bd9Sstevel@tonic-gate if (parmp->parm_d_metric != 0) 907c478bd9Sstevel@tonic-gate ifp->int_d_metric = parmp->parm_d_metric; 917c478bd9Sstevel@tonic-gate if (parmp->parm_ripout_addr != 0) 927c478bd9Sstevel@tonic-gate ifp->int_ripout_addr = parmp->parm_ripout_addr; 937c478bd9Sstevel@tonic-gate } 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate /* 977c478bd9Sstevel@tonic-gate * Set general defaults. 987c478bd9Sstevel@tonic-gate * 997c478bd9Sstevel@tonic-gate * Default poor-man's router discovery to a metric that will 1007c478bd9Sstevel@tonic-gate * be heard by old versions of `routed`. They ignored received 1017c478bd9Sstevel@tonic-gate * routes with metric 15. 1027c478bd9Sstevel@tonic-gate */ 1037c478bd9Sstevel@tonic-gate if ((ifp->int_state & IS_PM_RDISC) && ifp->int_d_metric == 0) 1047c478bd9Sstevel@tonic-gate ifp->int_d_metric = FAKE_METRIC; 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate if (ifp->int_rdisc_int == 0) 1077c478bd9Sstevel@tonic-gate ifp->int_rdisc_int = DEF_MAXADVERTISEINTERVAL; 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate if (!(ifp->int_if_flags & IFF_MULTICAST) && 1107c478bd9Sstevel@tonic-gate !(ifp->int_state & IS_REMOTE)) 1117c478bd9Sstevel@tonic-gate ifp->int_state |= IS_BCAST_RDISC; 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate if (ifp->int_if_flags & IFF_POINTOPOINT) { 1147c478bd9Sstevel@tonic-gate ifp->int_state |= IS_BCAST_RDISC; 1157c478bd9Sstevel@tonic-gate /* 1167c478bd9Sstevel@tonic-gate * By default, point-to-point links should be passive 1177c478bd9Sstevel@tonic-gate * about router-discovery for the sake of demand-dialing. 1187c478bd9Sstevel@tonic-gate */ 1197c478bd9Sstevel@tonic-gate if (!(ifp->int_state & GROUP_IS_SOL_OUT)) 1207c478bd9Sstevel@tonic-gate ifp->int_state |= IS_NO_SOL_OUT; 1217c478bd9Sstevel@tonic-gate if (!(ifp->int_state & GROUP_IS_ADV_OUT)) 1227c478bd9Sstevel@tonic-gate ifp->int_state |= IS_NO_ADV_OUT; 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate if (0 != (ifp->int_state & (IS_PASSIVE | IS_REMOTE))) 1267c478bd9Sstevel@tonic-gate ifp->int_state |= IS_NO_RDISC; 1277c478bd9Sstevel@tonic-gate if (ifp->int_state & IS_PASSIVE) 1287c478bd9Sstevel@tonic-gate ifp->int_state |= IS_NO_RIP; 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate if (!IS_RIP_IN_OFF(ifp->int_state) && 1317c478bd9Sstevel@tonic-gate ifp->int_auth[0].type != RIP_AUTH_NONE && 1327c478bd9Sstevel@tonic-gate !(ifp->int_state & IS_NO_RIPV1_IN) && !warned_auth_in) { 1337c478bd9Sstevel@tonic-gate writelog(LOG_WARNING, "RIPv1 input via %s" 1347c478bd9Sstevel@tonic-gate " will be accepted without authentication", 1357c478bd9Sstevel@tonic-gate ifp->int_name); 1367c478bd9Sstevel@tonic-gate warned_auth_in = _B_TRUE; 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate if (!IS_RIP_OUT_OFF(ifp->int_state) && 1397c478bd9Sstevel@tonic-gate ifp->int_auth[0].type != RIP_AUTH_NONE && 1407c478bd9Sstevel@tonic-gate !(ifp->int_state & IS_NO_RIPV1_OUT)) { 1417c478bd9Sstevel@tonic-gate if (!warned_auth_out) { 1427c478bd9Sstevel@tonic-gate writelog(LOG_WARNING, "RIPv1 output via %s" 1437c478bd9Sstevel@tonic-gate " will be sent without authentication", 1447c478bd9Sstevel@tonic-gate ifp->int_name); 1457c478bd9Sstevel@tonic-gate warned_auth_out = _B_TRUE; 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate /* 1507c478bd9Sstevel@tonic-gate * If not overriden by the rip_neighbor option, set the 1517c478bd9Sstevel@tonic-gate * default address to which RIP packets will be sent on 1527c478bd9Sstevel@tonic-gate * this interface. 1537c478bd9Sstevel@tonic-gate */ 1547c478bd9Sstevel@tonic-gate if (ifp->int_ripout_addr == 0) { 1557c478bd9Sstevel@tonic-gate if (ifp->int_state & IS_REMOTE) { 1567c478bd9Sstevel@tonic-gate /* 1577c478bd9Sstevel@tonic-gate * By definition we always send RIP packets to 1587c478bd9Sstevel@tonic-gate * the address assigned to a remote interface. 1597c478bd9Sstevel@tonic-gate */ 1607c478bd9Sstevel@tonic-gate ifp->int_ripout_addr = ifp->int_addr; 1617c478bd9Sstevel@tonic-gate } else if ((ifp->int_state & IS_NO_RIPV1_OUT) && 1627c478bd9Sstevel@tonic-gate (ifp->int_if_flags & IFF_MULTICAST) && 1637c478bd9Sstevel@tonic-gate !(ifp->int_state & IS_NO_RIP_MCAST)) { 1647c478bd9Sstevel@tonic-gate /* 1657c478bd9Sstevel@tonic-gate * If the interface is being used for RIPv2 1667c478bd9Sstevel@tonic-gate * and it supports multicast, and if the user 1677c478bd9Sstevel@tonic-gate * has not explicitely turned off multicast 1687c478bd9Sstevel@tonic-gate * RIP output, send to the all RIP routers 1697c478bd9Sstevel@tonic-gate * multicast address. 1707c478bd9Sstevel@tonic-gate */ 1717c478bd9Sstevel@tonic-gate ifp->int_ripout_addr = htonl(INADDR_RIP_GROUP); 1727c478bd9Sstevel@tonic-gate } else if (ifp->int_if_flags & IFF_POINTOPOINT) { 1737c478bd9Sstevel@tonic-gate /* 1747c478bd9Sstevel@tonic-gate * For point-to-point interfaces which don't 1757c478bd9Sstevel@tonic-gate * fall into the two categories above, just 1767c478bd9Sstevel@tonic-gate * send to the destination address of the 1777c478bd9Sstevel@tonic-gate * interface. 1787c478bd9Sstevel@tonic-gate */ 1797c478bd9Sstevel@tonic-gate ifp->int_ripout_addr = ifp->int_dstaddr; 1807c478bd9Sstevel@tonic-gate } else { 1817c478bd9Sstevel@tonic-gate /* Otherwise, use the broadcast address. */ 1827c478bd9Sstevel@tonic-gate ifp->int_ripout_addr = ifp->int_brdaddr; 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate /* 1897c478bd9Sstevel@tonic-gate * Read a list of gateways from /etc/gateways and add them to our tables. 1907c478bd9Sstevel@tonic-gate * 1917c478bd9Sstevel@tonic-gate * This file contains a list of "remote" gateways. That is usually 1927c478bd9Sstevel@tonic-gate * a gateway which we cannot immediately determine if it is present or 1937c478bd9Sstevel@tonic-gate * not as we can do for those provided by directly connected hardware. 1947c478bd9Sstevel@tonic-gate * 1957c478bd9Sstevel@tonic-gate * If a gateway is marked "passive" in the file, then we assume it 1967c478bd9Sstevel@tonic-gate * does not understand RIP and assume it is always present. Those 1977c478bd9Sstevel@tonic-gate * not marked passive are treated as if they were directly connected 1987c478bd9Sstevel@tonic-gate * and assumed to be broken if they do not send us advertisements. 1997c478bd9Sstevel@tonic-gate * All remote interfaces are added to our list, and those not marked 2007c478bd9Sstevel@tonic-gate * passive are sent routing updates. 2017c478bd9Sstevel@tonic-gate * 2027c478bd9Sstevel@tonic-gate * A passive interface can also be local, hardware interface exempt 2037c478bd9Sstevel@tonic-gate * from RIP. 2047c478bd9Sstevel@tonic-gate */ 2057c478bd9Sstevel@tonic-gate void 2067c478bd9Sstevel@tonic-gate gwkludge(void) 2077c478bd9Sstevel@tonic-gate { 2087c478bd9Sstevel@tonic-gate #define STR2(x) #x 2097c478bd9Sstevel@tonic-gate #define STR(x) STR2(x) 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate #define NETHOST_LEN 4 2127c478bd9Sstevel@tonic-gate #define DNAME_LEN MAXHOSTNAMELEN 2137c478bd9Sstevel@tonic-gate #define GNAME_LEN MAXHOSTNAMELEN 2147c478bd9Sstevel@tonic-gate #define QUAL_LEN 8 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate FILE *fp; 2177c478bd9Sstevel@tonic-gate char *p, *lptr; 2187c478bd9Sstevel@tonic-gate const char *cp; 2197c478bd9Sstevel@tonic-gate char lbuf[PARMS_MAXLINELEN], net_host[NETHOST_LEN + 1]; 2207c478bd9Sstevel@tonic-gate char dname[MAXHOSTNAMELEN + 1]; 2217c478bd9Sstevel@tonic-gate char gname[MAXHOSTNAMELEN + 1], qual[QUAL_LEN +1]; 2227c478bd9Sstevel@tonic-gate struct interface *ifp; 2237c478bd9Sstevel@tonic-gate uint32_t dst, netmask, gate; 2247c478bd9Sstevel@tonic-gate int n; 2257c478bd9Sstevel@tonic-gate uint32_t lnum; 2267c478bd9Sstevel@tonic-gate struct stat sb; 2277c478bd9Sstevel@tonic-gate uint32_t state, metric; 2287c478bd9Sstevel@tonic-gate boolean_t default_dst; 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate fp = fopen(PATH_GATEWAYS, "r"); 2327c478bd9Sstevel@tonic-gate if (fp == NULL) 2337c478bd9Sstevel@tonic-gate return; 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate if (0 > fstat(fileno(fp), &sb)) { 2367c478bd9Sstevel@tonic-gate msglog("fstat() failed: %s for "PATH_GATEWAYS, 2377c478bd9Sstevel@tonic-gate rip_strerror(errno)); 2387c478bd9Sstevel@tonic-gate (void) fclose(fp); 2397c478bd9Sstevel@tonic-gate return; 2407c478bd9Sstevel@tonic-gate } 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate for (lnum = 1; ; lnum++) { 2437c478bd9Sstevel@tonic-gate if (NULL == fgets(lbuf, sizeof (lbuf), fp)) 2447c478bd9Sstevel@tonic-gate break; 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate /* Eliminate the /n character at the end of the lbuf */ 2477c478bd9Sstevel@tonic-gate if (strlen(lbuf) > 0) 2487c478bd9Sstevel@tonic-gate lbuf[strlen(lbuf) - 1] = '\0'; 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate /* Move lptr to the first non-space character */ 2517c478bd9Sstevel@tonic-gate for (lptr = lbuf; isspace(*lptr); lptr++) 2527c478bd9Sstevel@tonic-gate ; 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate if (*lptr == '#' || *lptr == '\0') 2557c478bd9Sstevel@tonic-gate continue; 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate /* Move p to the end of the line */ 2587c478bd9Sstevel@tonic-gate p = lptr + strlen(lptr) - 1; 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate /* Skip all trailing spaces except escaped space */ 2617c478bd9Sstevel@tonic-gate while (p > lptr && (isspace(*p) && *(p-1) != '\\')) 2627c478bd9Sstevel@tonic-gate p--; 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate /* truncate the line to remove trailing spaces */ 2657c478bd9Sstevel@tonic-gate *++p = '\0'; 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate /* notice newfangled parameter lines */ 2687c478bd9Sstevel@tonic-gate if (strncasecmp("net", lptr, 3) != 0 && 2697c478bd9Sstevel@tonic-gate strncasecmp("host", lptr, 4) != 0) { 2707c478bd9Sstevel@tonic-gate cp = parse_parms(lptr, (sb.st_uid == 0 && 2717c478bd9Sstevel@tonic-gate !(sb.st_mode&(S_IRWXG|S_IRWXO)))); 2727c478bd9Sstevel@tonic-gate if (cp != 0) 2737c478bd9Sstevel@tonic-gate msglog("%s in line %u of "PATH_GATEWAYS, 2747c478bd9Sstevel@tonic-gate cp, lnum); 2757c478bd9Sstevel@tonic-gate continue; 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate /* 2797c478bd9Sstevel@tonic-gate * Processes lines of the follwoing format: 2807c478bd9Sstevel@tonic-gate * net|host <name>[/mask] gateway <Gname> metric <value> 2817c478bd9Sstevel@tonic-gate * passive|active|extern 2827c478bd9Sstevel@tonic-gate */ 2837c478bd9Sstevel@tonic-gate qual[0] = '\0'; 2847c478bd9Sstevel@tonic-gate n = sscanf(lptr, "%"STR(NETHOST_LEN)"s %"STR(DNAME_LEN) 2857c478bd9Sstevel@tonic-gate "[^ \t] gateway %"STR(GNAME_LEN)"[^ / \t] metric %u %" 2867c478bd9Sstevel@tonic-gate STR(QUAL_LEN)"s\n", net_host, dname, gname, &metric, qual); 2877c478bd9Sstevel@tonic-gate if (n != 4 && n != 5) { 2887c478bd9Sstevel@tonic-gate msglog("bad "PATH_GATEWAYS" entry \"%s\"; %d values", 2897c478bd9Sstevel@tonic-gate lptr, n); 2907c478bd9Sstevel@tonic-gate continue; 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate if (metric >= HOPCNT_INFINITY) { 2937c478bd9Sstevel@tonic-gate msglog("bad metric in "PATH_GATEWAYS" entry \"%s\"", 2947c478bd9Sstevel@tonic-gate lptr); 2957c478bd9Sstevel@tonic-gate continue; 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate default_dst = _B_FALSE; 2987c478bd9Sstevel@tonic-gate if (strcasecmp(net_host, "host") == 0) { 2997c478bd9Sstevel@tonic-gate if (!gethost(dname, &dst)) { 3007c478bd9Sstevel@tonic-gate msglog("bad host \"%s\" in "PATH_GATEWAYS 3017c478bd9Sstevel@tonic-gate " entry \"%s\"", dname, lptr); 3027c478bd9Sstevel@tonic-gate continue; 3037c478bd9Sstevel@tonic-gate } 3047c478bd9Sstevel@tonic-gate netmask = HOST_MASK; 3057c478bd9Sstevel@tonic-gate } else if (strcasecmp(net_host, "net") == 0) { 3067c478bd9Sstevel@tonic-gate if (!getnet(dname, &dst, &netmask)) { 3077c478bd9Sstevel@tonic-gate msglog("bad net \"%s\" in "PATH_GATEWAYS 3087c478bd9Sstevel@tonic-gate " entry \"%s\"", dname, lptr); 3097c478bd9Sstevel@tonic-gate continue; 3107c478bd9Sstevel@tonic-gate } 3117c478bd9Sstevel@tonic-gate default_dst = (dst == RIP_DEFAULT); 3127c478bd9Sstevel@tonic-gate dst = htonl(dst); /* make network # into IP address */ 3137c478bd9Sstevel@tonic-gate } else { 3147c478bd9Sstevel@tonic-gate msglog("bad \"%s\" in "PATH_GATEWAYS 3157c478bd9Sstevel@tonic-gate " entry \"%s\"", net_host, lptr); 3167c478bd9Sstevel@tonic-gate continue; 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate if (!gethost(gname, &gate)) { 3207c478bd9Sstevel@tonic-gate msglog("bad gateway \"%s\" in "PATH_GATEWAYS 3217c478bd9Sstevel@tonic-gate " entry \"%s\"", gname, lptr); 3227c478bd9Sstevel@tonic-gate continue; 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate if (strcasecmp(qual, "passive") == 0) { 3267c478bd9Sstevel@tonic-gate /* 3277c478bd9Sstevel@tonic-gate * Passive entries are not placed in our tables, 3287c478bd9Sstevel@tonic-gate * only the kernel's, so we don't copy all of the 3297c478bd9Sstevel@tonic-gate * external routing information within a net. 3307c478bd9Sstevel@tonic-gate * Internal machines should use the default 3317c478bd9Sstevel@tonic-gate * route to a suitable gateway (like us). 3327c478bd9Sstevel@tonic-gate */ 3337c478bd9Sstevel@tonic-gate state = IS_REMOTE | IS_PASSIVE; 3347c478bd9Sstevel@tonic-gate if (metric == 0) 3357c478bd9Sstevel@tonic-gate metric = 1; 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate } else if (strcasecmp(qual, "external") == 0) { 3387c478bd9Sstevel@tonic-gate /* 3397c478bd9Sstevel@tonic-gate * External entries are handled by other means 3407c478bd9Sstevel@tonic-gate * such as EGP, and are placed only in the daemon 3417c478bd9Sstevel@tonic-gate * tables to prevent overriding them with something 3427c478bd9Sstevel@tonic-gate * else. 3437c478bd9Sstevel@tonic-gate */ 3447c478bd9Sstevel@tonic-gate (void) strlcpy(qual, "external", sizeof (qual)); 3457c478bd9Sstevel@tonic-gate state = IS_REMOTE | IS_PASSIVE | IS_EXTERNAL; 3467c478bd9Sstevel@tonic-gate if (metric == 0) 3477c478bd9Sstevel@tonic-gate metric = 1; 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate } else if (strcasecmp(qual, "active") == 0 || 3507c478bd9Sstevel@tonic-gate qual[0] == '\0') { 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate if (default_dst) { 3537c478bd9Sstevel@tonic-gate msglog("bad net \"%s\" in "PATH_GATEWAYS 3547c478bd9Sstevel@tonic-gate " entry \"%s\"-- cannot be default", 3557c478bd9Sstevel@tonic-gate dname, lptr); 3567c478bd9Sstevel@tonic-gate continue; 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate if (metric != 0) { 3607c478bd9Sstevel@tonic-gate /* 3617c478bd9Sstevel@tonic-gate * Entries that are neither "passive" nor 3627c478bd9Sstevel@tonic-gate * "external" are "remote" and must behave 3637c478bd9Sstevel@tonic-gate * like physical interfaces. If they are not 3647c478bd9Sstevel@tonic-gate * heard from regularly, they are deleted. 3657c478bd9Sstevel@tonic-gate */ 3667c478bd9Sstevel@tonic-gate state = IS_REMOTE; 3677c478bd9Sstevel@tonic-gate } else { 3687c478bd9Sstevel@tonic-gate /* 3697c478bd9Sstevel@tonic-gate * "remote" entries with a metric of 0 3707c478bd9Sstevel@tonic-gate * are aliases for our own interfaces 3717c478bd9Sstevel@tonic-gate */ 3727c478bd9Sstevel@tonic-gate state = IS_REMOTE | IS_PASSIVE | IS_ALIAS; 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate } else { 3767c478bd9Sstevel@tonic-gate msglog("bad "PATH_GATEWAYS" entry \"%s\";" 3777c478bd9Sstevel@tonic-gate " unknown type %s", lptr, qual); 3787c478bd9Sstevel@tonic-gate continue; 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate if (0 != (state & (IS_PASSIVE | IS_REMOTE))) 3827c478bd9Sstevel@tonic-gate state |= IS_NO_RDISC; 3837c478bd9Sstevel@tonic-gate if (state & IS_PASSIVE) 3847c478bd9Sstevel@tonic-gate state |= IS_NO_RIP; 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate if (default_dst) { 3887c478bd9Sstevel@tonic-gate addroutefordefault(dst, gate, netmask, metric, 3897c478bd9Sstevel@tonic-gate ((state & IS_EXTERNAL)? RTS_EXTERNAL : 0)); 3907c478bd9Sstevel@tonic-gate continue; 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate ifp = check_dup(NULL, gate, dst, netmask, 0, _B_FALSE); 3947c478bd9Sstevel@tonic-gate if (ifp != NULL) { 3957c478bd9Sstevel@tonic-gate msglog("duplicate "PATH_GATEWAYS" entry \"%s\"", lptr); 3967c478bd9Sstevel@tonic-gate continue; 3977c478bd9Sstevel@tonic-gate } 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate ifp = rtmalloc(sizeof (*ifp), "gwkludge()"); 4007c478bd9Sstevel@tonic-gate (void) memset(ifp, 0, sizeof (*ifp)); 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate ifp->int_state = state; 4037c478bd9Sstevel@tonic-gate if (netmask == HOST_MASK) 4047c478bd9Sstevel@tonic-gate ifp->int_if_flags = IFF_POINTOPOINT | IFF_UP; 4057c478bd9Sstevel@tonic-gate else 4067c478bd9Sstevel@tonic-gate ifp->int_if_flags = IFF_UP; 4077c478bd9Sstevel@tonic-gate ifp->int_act_time = NEVER; 4087c478bd9Sstevel@tonic-gate ifp->int_addr = gate; 4097c478bd9Sstevel@tonic-gate ifp->int_dstaddr = dst; 4107c478bd9Sstevel@tonic-gate ifp->int_mask = netmask; 4117c478bd9Sstevel@tonic-gate ifp->int_ripv1_mask = netmask; 4127c478bd9Sstevel@tonic-gate ifp->int_std_mask = std_mask(gate); 4137c478bd9Sstevel@tonic-gate ifp->int_net = ntohl(dst); 4147c478bd9Sstevel@tonic-gate ifp->int_std_net = ifp->int_net & ifp->int_std_mask; 4157c478bd9Sstevel@tonic-gate ifp->int_std_addr = htonl(ifp->int_std_net); 4167c478bd9Sstevel@tonic-gate ifp->int_metric = metric; 4177c478bd9Sstevel@tonic-gate if (!(state & IS_EXTERNAL) && 4187c478bd9Sstevel@tonic-gate ifp->int_mask != ifp->int_std_mask) 4197c478bd9Sstevel@tonic-gate ifp->int_state |= IS_SUBNET; 4207c478bd9Sstevel@tonic-gate (void) snprintf(ifp->int_name, sizeof (ifp->int_name), 4217c478bd9Sstevel@tonic-gate "remote(%s)", gname); 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate if_link(ifp, 0); 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate (void) fclose(fp); 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate /* 4297c478bd9Sstevel@tonic-gate * After all of the parameter lines have been read, 4307c478bd9Sstevel@tonic-gate * apply them to any remote interfaces. 4317c478bd9Sstevel@tonic-gate */ 4327c478bd9Sstevel@tonic-gate for (ifp = ifnet; NULL != ifp; ifp = ifp->int_next) { 4337c478bd9Sstevel@tonic-gate get_parms(ifp); 4347c478bd9Sstevel@tonic-gate 4357c478bd9Sstevel@tonic-gate tot_interfaces++; 4367c478bd9Sstevel@tonic-gate if (!IS_RIP_OFF(ifp->int_state)) 4377c478bd9Sstevel@tonic-gate rip_interfaces++; 4387c478bd9Sstevel@tonic-gate if (!IS_RIP_OUT_OFF(ifp->int_state)) 4397c478bd9Sstevel@tonic-gate ripout_interfaces++; 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate trace_if("Add", ifp); 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate 4447c478bd9Sstevel@tonic-gate } 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate /* Parse password timestamp */ 4477c478bd9Sstevel@tonic-gate static char * 4487c478bd9Sstevel@tonic-gate parse_ts(time_t *tp, 4497c478bd9Sstevel@tonic-gate char **valp, 4507c478bd9Sstevel@tonic-gate char *val0, 4517c478bd9Sstevel@tonic-gate char *delimp, 4527c478bd9Sstevel@tonic-gate char *buf, 4537c478bd9Sstevel@tonic-gate uint_t bufsize) 4547c478bd9Sstevel@tonic-gate { 4557c478bd9Sstevel@tonic-gate struct tm tm; 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate if (0 > parse_quote(valp, "| ,", delimp, buf, bufsize) || 4587c478bd9Sstevel@tonic-gate buf[bufsize-1] != '\0' || buf[bufsize-2] != '\0') { 4597c478bd9Sstevel@tonic-gate (void) snprintf(buf, bufsize, "bad timestamp %.25s", val0); 4607c478bd9Sstevel@tonic-gate return (buf); 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate (void) strlcat(buf, "\n", bufsize); 4637c478bd9Sstevel@tonic-gate (void) memset(&tm, 0, sizeof (tm)); 4647c478bd9Sstevel@tonic-gate if (5 != sscanf(buf, "%u/%u/%u@%u:%u\n", 4657c478bd9Sstevel@tonic-gate (unsigned *)&tm.tm_year, (unsigned *)&tm.tm_mon, 4667c478bd9Sstevel@tonic-gate (unsigned *)&tm.tm_mday, (unsigned *)&tm.tm_hour, 4677c478bd9Sstevel@tonic-gate (unsigned *)&tm.tm_min) || 4687c478bd9Sstevel@tonic-gate tm.tm_mon < 1 || tm.tm_mon > 12 || 4697c478bd9Sstevel@tonic-gate tm.tm_mday < 1 || tm.tm_mday > 31) { 4707c478bd9Sstevel@tonic-gate (void) snprintf(buf, bufsize, "bad timestamp %.25s", val0); 4717c478bd9Sstevel@tonic-gate return (buf); 4727c478bd9Sstevel@tonic-gate } 4737c478bd9Sstevel@tonic-gate tm.tm_mon--; 4747c478bd9Sstevel@tonic-gate /* assume small years are in the 3rd millenium */ 4757c478bd9Sstevel@tonic-gate if (tm.tm_year <= 37) 4767c478bd9Sstevel@tonic-gate tm.tm_year += 100; 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate if (tm.tm_year >= 1900) 4797c478bd9Sstevel@tonic-gate tm.tm_year -= 1900; 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate if ((*tp = mktime(&tm)) == -1) { 4827c478bd9Sstevel@tonic-gate (void) snprintf(buf, bufsize, "bad timestamp %.25s", val0); 4837c478bd9Sstevel@tonic-gate return (buf); 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate return (NULL); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate 4907c478bd9Sstevel@tonic-gate /* 4917c478bd9Sstevel@tonic-gate * Get a password, key ID, and expiration date in the format 4927c478bd9Sstevel@tonic-gate * passwd|keyID|year/mon/day@hour:min|year/mon/day@hour:min 4937c478bd9Sstevel@tonic-gate * returns NULL or error message 4947c478bd9Sstevel@tonic-gate */ 4957c478bd9Sstevel@tonic-gate static const char * 4967c478bd9Sstevel@tonic-gate get_passwd(char *tgt, 4977c478bd9Sstevel@tonic-gate char *val, 4987c478bd9Sstevel@tonic-gate struct parm *parmp, 4997c478bd9Sstevel@tonic-gate uint16_t type, 5007c478bd9Sstevel@tonic-gate boolean_t safe) /* 1=from secure file */ 5017c478bd9Sstevel@tonic-gate { 5027c478bd9Sstevel@tonic-gate static char buf[80]; 5037c478bd9Sstevel@tonic-gate char *val0, *p, delim; 5047c478bd9Sstevel@tonic-gate struct auth k, *ap, *ap2; 5057c478bd9Sstevel@tonic-gate int i; 5067c478bd9Sstevel@tonic-gate ulong_t l; 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate 5097c478bd9Sstevel@tonic-gate if (!safe) 5107c478bd9Sstevel@tonic-gate return ("ignore unsafe password"); 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate for (ap = parmp->parm_auth, i = 0; ap->type != RIP_AUTH_NONE; 5137c478bd9Sstevel@tonic-gate i++, ap++) { 5147c478bd9Sstevel@tonic-gate if (i >= MAX_AUTH_KEYS) 5157c478bd9Sstevel@tonic-gate return ("too many passwords"); 5167c478bd9Sstevel@tonic-gate } 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate (void) memset(&k, 0, sizeof (k)); 5197c478bd9Sstevel@tonic-gate k.type = type; 5207c478bd9Sstevel@tonic-gate k.end = -1-DAY; 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate val0 = val; 5237c478bd9Sstevel@tonic-gate if (0 > parse_quote(&val, "| ,", &delim, 5247c478bd9Sstevel@tonic-gate (char *)k.key, sizeof (k.key))) 5257c478bd9Sstevel@tonic-gate return (tgt); 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate if (delim != '|') { 5287c478bd9Sstevel@tonic-gate if (type == RIP_AUTH_MD5) 5297c478bd9Sstevel@tonic-gate return ("missing Keyid"); 5307c478bd9Sstevel@tonic-gate } else { 5317c478bd9Sstevel@tonic-gate val0 = ++val; 5327c478bd9Sstevel@tonic-gate buf[sizeof (buf)-1] = '\0'; 5337c478bd9Sstevel@tonic-gate if (0 > parse_quote(&val, "| ,", &delim, buf, 5347c478bd9Sstevel@tonic-gate sizeof (buf)) || 5357c478bd9Sstevel@tonic-gate buf[sizeof (buf) - 1] != '\0' || 5367c478bd9Sstevel@tonic-gate (l = strtoul(buf, &p, 0)) > 255 || 5377c478bd9Sstevel@tonic-gate p == buf || *p != '\0') { 5387c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), 5397c478bd9Sstevel@tonic-gate "bad KeyID \"%.20s\"", val0); 5407c478bd9Sstevel@tonic-gate return (buf); 5417c478bd9Sstevel@tonic-gate } 5427c478bd9Sstevel@tonic-gate for (ap2 = parmp->parm_auth; ap2 < ap; ap2++) { 5437c478bd9Sstevel@tonic-gate if (ap2->keyid == l) { 5447c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), 5457c478bd9Sstevel@tonic-gate "duplicate KeyID \"%.20s\"", 5467c478bd9Sstevel@tonic-gate val0); 5477c478bd9Sstevel@tonic-gate return (buf); 5487c478bd9Sstevel@tonic-gate } 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate k.keyid = (int)l; 5517c478bd9Sstevel@tonic-gate 5527c478bd9Sstevel@tonic-gate if (delim == '|') { 5537c478bd9Sstevel@tonic-gate val0 = ++val; 5547c478bd9Sstevel@tonic-gate if (NULL != (p = parse_ts(&k.start, &val, val0, &delim, 5557c478bd9Sstevel@tonic-gate buf, sizeof (buf)))) 5567c478bd9Sstevel@tonic-gate return (p); 5577c478bd9Sstevel@tonic-gate if (delim != '|') 5587c478bd9Sstevel@tonic-gate return ("missing second timestamp"); 5597c478bd9Sstevel@tonic-gate val0 = ++val; 5607c478bd9Sstevel@tonic-gate if (NULL != (p = parse_ts(&k.end, &val, val0, &delim, 5617c478bd9Sstevel@tonic-gate buf, sizeof (buf)))) 5627c478bd9Sstevel@tonic-gate return (p); 5637c478bd9Sstevel@tonic-gate if ((ulong_t)k.start > (ulong_t)k.end) { 5647c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), 5657c478bd9Sstevel@tonic-gate "out of order timestamp %.30s", val0); 5667c478bd9Sstevel@tonic-gate return (buf); 5677c478bd9Sstevel@tonic-gate } 5687c478bd9Sstevel@tonic-gate } 5697c478bd9Sstevel@tonic-gate } 5707c478bd9Sstevel@tonic-gate if (delim != '\0') 5717c478bd9Sstevel@tonic-gate return (tgt); 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate (void) memmove(ap, &k, sizeof (*ap)); 5747c478bd9Sstevel@tonic-gate return (NULL); 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate static const char * 5797c478bd9Sstevel@tonic-gate bad_str(const char *estr) 5807c478bd9Sstevel@tonic-gate { 5817c478bd9Sstevel@tonic-gate static char buf[100+8]; 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), "bad \"%.100s\"", estr); 5847c478bd9Sstevel@tonic-gate return (buf); 5857c478bd9Sstevel@tonic-gate } 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate 5887c478bd9Sstevel@tonic-gate /* 5897c478bd9Sstevel@tonic-gate * Parse a set of parameters for an interface. 5907c478bd9Sstevel@tonic-gate * returns NULL or error message 5917c478bd9Sstevel@tonic-gate */ 5927c478bd9Sstevel@tonic-gate const char * 5937c478bd9Sstevel@tonic-gate parse_parms(char *line, 5947c478bd9Sstevel@tonic-gate boolean_t safe) /* 1=from secure file */ 5957c478bd9Sstevel@tonic-gate { 5967c478bd9Sstevel@tonic-gate #define PARS(str) (strcasecmp(tgt, str) == 0) 5977c478bd9Sstevel@tonic-gate #define PARSEQ(str) (strncasecmp(tgt, str"=", sizeof (str)) == 0) 5987c478bd9Sstevel@tonic-gate /* 5997c478bd9Sstevel@tonic-gate * This macro checks for conflicting configurations options 6007c478bd9Sstevel@tonic-gate * For eg one can set either the IS_NO_SOL_OUT flag bit or the IS_SOL_OUT flag 6017c478bd9Sstevel@tonic-gate * bit, but not both. 6027c478bd9Sstevel@tonic-gate */ 6037c478bd9Sstevel@tonic-gate #define CKF(g, b) {if (0 != (parm.parm_int_state & ((g) & ~(b)))) break; \ 6047c478bd9Sstevel@tonic-gate parm.parm_int_state |= (b); } 6057c478bd9Sstevel@tonic-gate struct parm parm; 6067c478bd9Sstevel@tonic-gate struct intnet *intnetp; 6077c478bd9Sstevel@tonic-gate struct r1net *r1netp; 6087c478bd9Sstevel@tonic-gate struct tgate *tg; 6097c478bd9Sstevel@tonic-gate uint32_t addr, mask; 6107c478bd9Sstevel@tonic-gate char delim, *val0 = 0, *tgt, *val, *p; 6117c478bd9Sstevel@tonic-gate const char *msg; 6127c478bd9Sstevel@tonic-gate char buf[PARMS_MAXLINELEN], buf2[PARMS_MAXLINELEN]; 6137c478bd9Sstevel@tonic-gate int i; 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate 6167c478bd9Sstevel@tonic-gate /* "subnet=x.y.z.u/mask[,metric]" must be alone on the line */ 6177c478bd9Sstevel@tonic-gate if (strncasecmp(line, "subnet=", sizeof ("subnet=") - 1) == 0 && 6187c478bd9Sstevel@tonic-gate *(val = &line[sizeof ("subnet=") -1 ]) != '\0') { 6197c478bd9Sstevel@tonic-gate if (0 > parse_quote(&val, ",", &delim, buf, sizeof (buf))) 6207c478bd9Sstevel@tonic-gate return (bad_str(line)); 6217c478bd9Sstevel@tonic-gate intnetp = rtmalloc(sizeof (*intnetp), 6227c478bd9Sstevel@tonic-gate "parse_parms subnet"); 6237c478bd9Sstevel@tonic-gate intnetp->intnet_metric = 1; 6247c478bd9Sstevel@tonic-gate if (delim == ',') { 6257c478bd9Sstevel@tonic-gate intnetp->intnet_metric = (int)strtol(val+1, &p, 0); 6267c478bd9Sstevel@tonic-gate if (*p != '\0' || intnetp->intnet_metric <= 0 || 6277c478bd9Sstevel@tonic-gate val+1 == p || 6287c478bd9Sstevel@tonic-gate intnetp->intnet_metric >= HOPCNT_INFINITY) { 6297c478bd9Sstevel@tonic-gate free(intnetp); 6307c478bd9Sstevel@tonic-gate return (bad_str(line)); 6317c478bd9Sstevel@tonic-gate } 6327c478bd9Sstevel@tonic-gate } 6337c478bd9Sstevel@tonic-gate if (!getnet(buf, &intnetp->intnet_addr, 6347c478bd9Sstevel@tonic-gate &intnetp->intnet_mask) || 6357c478bd9Sstevel@tonic-gate intnetp->intnet_mask == HOST_MASK || 6367c478bd9Sstevel@tonic-gate intnetp->intnet_addr == RIP_DEFAULT) { 6377c478bd9Sstevel@tonic-gate free(intnetp); 6387c478bd9Sstevel@tonic-gate return (bad_str(line)); 6397c478bd9Sstevel@tonic-gate } 6407c478bd9Sstevel@tonic-gate intnetp->intnet_addr = htonl(intnetp->intnet_addr); 6417c478bd9Sstevel@tonic-gate intnetp->intnet_next = intnets; 6427c478bd9Sstevel@tonic-gate intnets = intnetp; 6437c478bd9Sstevel@tonic-gate return (NULL); 6447c478bd9Sstevel@tonic-gate } 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate /* 6477c478bd9Sstevel@tonic-gate * "ripv1_mask=x.y.z.u/mask1,mask2" must be alone on the line. 6487c478bd9Sstevel@tonic-gate * This requires that x.y.z.u/mask1 be considered a subnet of 6497c478bd9Sstevel@tonic-gate * x.y.z.u/mask2, as if x.y.z.u/mask2 were a class-full network. 6507c478bd9Sstevel@tonic-gate */ 6517c478bd9Sstevel@tonic-gate if (!strncasecmp(line, "ripv1_mask=", sizeof ("ripv1_mask=") - 1) && 6527c478bd9Sstevel@tonic-gate *(val = &line[sizeof ("ripv1_mask=")-1]) != '\0') { 6537c478bd9Sstevel@tonic-gate if (0 > parse_quote(&val, ",", &delim, buf, sizeof (buf)) || 6547c478bd9Sstevel@tonic-gate delim == '\0') 6557c478bd9Sstevel@tonic-gate return (bad_str(line)); 6567c478bd9Sstevel@tonic-gate if ((i = (int)strtol(val+1, &p, 0)) <= 0 || i > 32 || 6577c478bd9Sstevel@tonic-gate *p != '\0') 6587c478bd9Sstevel@tonic-gate return (bad_str(line)); 6597c478bd9Sstevel@tonic-gate r1netp = rtmalloc(sizeof (*r1netp), "parse_parms ripv1_mask"); 6607c478bd9Sstevel@tonic-gate r1netp->r1net_mask = HOST_MASK << (32-i); 6617c478bd9Sstevel@tonic-gate if (!getnet(buf, &r1netp->r1net_net, &r1netp->r1net_match) || 6627c478bd9Sstevel@tonic-gate r1netp->r1net_net == RIP_DEFAULT || 6637c478bd9Sstevel@tonic-gate r1netp->r1net_mask > r1netp->r1net_match) { 6647c478bd9Sstevel@tonic-gate free(r1netp); 6657c478bd9Sstevel@tonic-gate return (bad_str(line)); 6667c478bd9Sstevel@tonic-gate } 6677c478bd9Sstevel@tonic-gate r1netp->r1net_next = r1nets; 6687c478bd9Sstevel@tonic-gate r1nets = r1netp; 6697c478bd9Sstevel@tonic-gate return (NULL); 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate (void) memset(&parm, 0, sizeof (parm)); 6737c478bd9Sstevel@tonic-gate /* 6747c478bd9Sstevel@tonic-gate * Support of the following for Solaris backward compatibility 6757c478bd9Sstevel@tonic-gate * norip <ifname> 6767c478bd9Sstevel@tonic-gate * noripin <ifname> 6777c478bd9Sstevel@tonic-gate * noripout <ifname> 6787c478bd9Sstevel@tonic-gate */ 6797c478bd9Sstevel@tonic-gate if (strncasecmp("norip", line, 5) == 0) { 6807c478bd9Sstevel@tonic-gate char cmd[64], ifname[64]; 6817c478bd9Sstevel@tonic-gate int n; 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate n = sscanf(line, "%63s %63s\n", cmd, ifname); 6847c478bd9Sstevel@tonic-gate if (n != 2) { 6857c478bd9Sstevel@tonic-gate /* Not enough parameters */ 6867c478bd9Sstevel@tonic-gate return (bad_str(line)); 6877c478bd9Sstevel@tonic-gate } 6887c478bd9Sstevel@tonic-gate 6897c478bd9Sstevel@tonic-gate /* 6907c478bd9Sstevel@tonic-gate * Get the interface name and turn on the appropriate 6917c478bd9Sstevel@tonic-gate * interface flags 6927c478bd9Sstevel@tonic-gate */ 6937c478bd9Sstevel@tonic-gate (void) strlcpy(parm.parm_name, ifname, sizeof (parm.parm_name)); 6947c478bd9Sstevel@tonic-gate if (strcasecmp("norip", cmd) == 0) { 6957c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_NO_RIP; 6967c478bd9Sstevel@tonic-gate } else if (strcasecmp("noripin", cmd) == 0) { 6977c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_NO_RIP_IN; 6987c478bd9Sstevel@tonic-gate } else if (strcasecmp("noripout", cmd) == 0) { 6997c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_NO_RIP_OUT; 7007c478bd9Sstevel@tonic-gate } else { 7017c478bd9Sstevel@tonic-gate /* Bad command */ 7027c478bd9Sstevel@tonic-gate return (bad_str(line)); 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate /* 7057c478bd9Sstevel@tonic-gate * Look for duplication, and if new, 7067c478bd9Sstevel@tonic-gate * link to the rest of the parm entries. 7077c478bd9Sstevel@tonic-gate */ 7087c478bd9Sstevel@tonic-gate return (insert_parm(&parm)); 7097c478bd9Sstevel@tonic-gate } 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate for (;;) { 7127c478bd9Sstevel@tonic-gate tgt = line + strspn(line, " ,\n\r"); 7137c478bd9Sstevel@tonic-gate if (*tgt == '\0' || *tgt == '#') 7147c478bd9Sstevel@tonic-gate break; 7157c478bd9Sstevel@tonic-gate line = tgt+strcspn(tgt, "= #,\n\r"); 7167c478bd9Sstevel@tonic-gate delim = *line; 7177c478bd9Sstevel@tonic-gate if (delim == '=') { 7187c478bd9Sstevel@tonic-gate val0 = ++line; 7197c478bd9Sstevel@tonic-gate if (0 > parse_quote(&line, " #,", &delim, 7207c478bd9Sstevel@tonic-gate buf, sizeof (buf))) 7217c478bd9Sstevel@tonic-gate return (bad_str(tgt)); 7227c478bd9Sstevel@tonic-gate } 7237c478bd9Sstevel@tonic-gate if (delim != '\0') { 7247c478bd9Sstevel@tonic-gate for (;;) { 7257c478bd9Sstevel@tonic-gate *line = '\0'; 7267c478bd9Sstevel@tonic-gate if (delim == '#') 7277c478bd9Sstevel@tonic-gate break; 7287c478bd9Sstevel@tonic-gate ++line; 7297c478bd9Sstevel@tonic-gate if (!isspace(delim) || 7307c478bd9Sstevel@tonic-gate ((delim = *line), !isspace(delim))) 7317c478bd9Sstevel@tonic-gate break; 7327c478bd9Sstevel@tonic-gate } 7337c478bd9Sstevel@tonic-gate } 7347c478bd9Sstevel@tonic-gate 7357c478bd9Sstevel@tonic-gate if (PARSEQ("if")) { 7367c478bd9Sstevel@tonic-gate if (parm.parm_name[0] != '\0' || 7377c478bd9Sstevel@tonic-gate strlen(buf) > IF_NAME_LEN) 7387c478bd9Sstevel@tonic-gate return (bad_str(tgt)); 7397c478bd9Sstevel@tonic-gate (void) strlcpy(parm.parm_name, buf, 7407c478bd9Sstevel@tonic-gate sizeof (parm.parm_name)); 7417c478bd9Sstevel@tonic-gate 7427c478bd9Sstevel@tonic-gate } else if (PARSEQ("addr")) { 7437c478bd9Sstevel@tonic-gate /* 7447c478bd9Sstevel@tonic-gate * This is a bad idea, because the address based 7457c478bd9Sstevel@tonic-gate * sets of parameters cannot be checked for 7467c478bd9Sstevel@tonic-gate * consistency with the interface name parameters. 7477c478bd9Sstevel@tonic-gate * The parm_net stuff is needed to allow several 7487c478bd9Sstevel@tonic-gate * -F settings. 7497c478bd9Sstevel@tonic-gate */ 7507c478bd9Sstevel@tonic-gate if (!getnet(val0, &addr, &mask) || 7517c478bd9Sstevel@tonic-gate parm.parm_name[0] != '\0') 7527c478bd9Sstevel@tonic-gate return (bad_str(tgt)); 7537c478bd9Sstevel@tonic-gate parm.parm_net = addr; 7547c478bd9Sstevel@tonic-gate parm.parm_mask = mask; 7557c478bd9Sstevel@tonic-gate parm.parm_name[0] = '\n'; 7567c478bd9Sstevel@tonic-gate 7577c478bd9Sstevel@tonic-gate } else if (PARSEQ("passwd")) { 7587c478bd9Sstevel@tonic-gate /* 7597c478bd9Sstevel@tonic-gate * since cleartext passwords are so weak allow 7607c478bd9Sstevel@tonic-gate * them anywhere 7617c478bd9Sstevel@tonic-gate */ 7627c478bd9Sstevel@tonic-gate msg = get_passwd(tgt, val0, &parm, RIP_AUTH_PW, 1); 7637c478bd9Sstevel@tonic-gate if (msg) { 7647c478bd9Sstevel@tonic-gate *val0 = '\0'; 7657c478bd9Sstevel@tonic-gate return (bad_str(msg)); 7667c478bd9Sstevel@tonic-gate } 7677c478bd9Sstevel@tonic-gate 7687c478bd9Sstevel@tonic-gate } else if (PARSEQ("md5_passwd")) { 7697c478bd9Sstevel@tonic-gate msg = get_passwd(tgt, val0, &parm, RIP_AUTH_MD5, safe); 7707c478bd9Sstevel@tonic-gate if (msg) { 7717c478bd9Sstevel@tonic-gate *val0 = '\0'; 7727c478bd9Sstevel@tonic-gate return (bad_str(msg)); 7737c478bd9Sstevel@tonic-gate } 7747c478bd9Sstevel@tonic-gate 7757c478bd9Sstevel@tonic-gate } else if (PARS("no_ag")) { 7767c478bd9Sstevel@tonic-gate parm.parm_int_state |= (IS_NO_AG | IS_NO_SUPER_AG); 7777c478bd9Sstevel@tonic-gate 7787c478bd9Sstevel@tonic-gate } else if (PARS("no_host")) { 7797c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_NO_HOST; 7807c478bd9Sstevel@tonic-gate 7817c478bd9Sstevel@tonic-gate } else if (PARS("no_super_ag")) { 7827c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_NO_SUPER_AG; 7837c478bd9Sstevel@tonic-gate 7847c478bd9Sstevel@tonic-gate } else if (PARS("no_ripv1_in")) { 7857c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_NO_RIPV1_IN; 7867c478bd9Sstevel@tonic-gate 7877c478bd9Sstevel@tonic-gate } else if (PARS("no_ripv2_in")) { 7887c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_NO_RIPV2_IN; 7897c478bd9Sstevel@tonic-gate 7907c478bd9Sstevel@tonic-gate } else if (PARS("ripv2_out")) { 7917c478bd9Sstevel@tonic-gate if (parm.parm_int_state & IS_NO_RIPV2_OUT) 7927c478bd9Sstevel@tonic-gate return (bad_str(tgt)); 7937c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_NO_RIPV1_OUT; 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate } else if (PARS("ripv2")) { 7967c478bd9Sstevel@tonic-gate if ((parm.parm_int_state & IS_NO_RIPV2_OUT) || 7977c478bd9Sstevel@tonic-gate (parm.parm_int_state & IS_NO_RIPV2_IN)) 7987c478bd9Sstevel@tonic-gate return (bad_str(tgt)); 7997c478bd9Sstevel@tonic-gate parm.parm_int_state |= (IS_NO_RIPV1_IN 8007c478bd9Sstevel@tonic-gate | IS_NO_RIPV1_OUT); 8017c478bd9Sstevel@tonic-gate 8027c478bd9Sstevel@tonic-gate } else if (PARS("no_rip")) { 8037c478bd9Sstevel@tonic-gate CKF(IS_PM_RDISC, IS_NO_RIP); 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate } else if (PARS("no_rip_mcast")) { 8067c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_NO_RIP_MCAST; 8077c478bd9Sstevel@tonic-gate 8087c478bd9Sstevel@tonic-gate } else if (PARS("no_rdisc")) { 8097c478bd9Sstevel@tonic-gate CKF((GROUP_IS_SOL_OUT|GROUP_IS_ADV_OUT), IS_NO_RDISC); 8107c478bd9Sstevel@tonic-gate 8117c478bd9Sstevel@tonic-gate } else if (PARS("no_solicit")) { 8127c478bd9Sstevel@tonic-gate CKF(GROUP_IS_SOL_OUT, IS_NO_SOL_OUT); 8137c478bd9Sstevel@tonic-gate 8147c478bd9Sstevel@tonic-gate } else if (PARS("send_solicit")) { 8157c478bd9Sstevel@tonic-gate CKF(GROUP_IS_SOL_OUT, IS_SOL_OUT); 8167c478bd9Sstevel@tonic-gate 8177c478bd9Sstevel@tonic-gate } else if (PARS("no_rdisc_adv")) { 8187c478bd9Sstevel@tonic-gate CKF(GROUP_IS_ADV_OUT, IS_NO_ADV_OUT); 8197c478bd9Sstevel@tonic-gate 8207c478bd9Sstevel@tonic-gate } else if (PARS("rdisc_adv")) { 8217c478bd9Sstevel@tonic-gate CKF(GROUP_IS_ADV_OUT, IS_ADV_OUT); 8227c478bd9Sstevel@tonic-gate 8237c478bd9Sstevel@tonic-gate } else if (PARS("bcast_rdisc")) { 8247c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_BCAST_RDISC; 8257c478bd9Sstevel@tonic-gate 8267c478bd9Sstevel@tonic-gate } else if (PARS("passive")) { 8277c478bd9Sstevel@tonic-gate CKF((GROUP_IS_SOL_OUT|GROUP_IS_ADV_OUT), IS_NO_RDISC); 8287c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_NO_RIP | IS_PASSIVE; 8297c478bd9Sstevel@tonic-gate 8307c478bd9Sstevel@tonic-gate } else if (PARSEQ("rdisc_pref")) { 8317c478bd9Sstevel@tonic-gate if (parm.parm_rdisc_pref != 0 || 8327c478bd9Sstevel@tonic-gate (parm.parm_rdisc_pref = (int)strtol(buf, &p, 0), 8337c478bd9Sstevel@tonic-gate *p != '\0') || (buf == p)) 8347c478bd9Sstevel@tonic-gate return (bad_str(tgt)); 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate } else if (PARS("pm_rdisc")) { 8377c478bd9Sstevel@tonic-gate if (IS_RIP_OUT_OFF(parm.parm_int_state)) 8387c478bd9Sstevel@tonic-gate return (bad_str(tgt)); 8397c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_PM_RDISC; 8407c478bd9Sstevel@tonic-gate 8417c478bd9Sstevel@tonic-gate } else if (PARSEQ("rdisc_interval")) { 8427c478bd9Sstevel@tonic-gate if (parm.parm_rdisc_int != 0 || 8437c478bd9Sstevel@tonic-gate (parm.parm_rdisc_int = (int)strtoul(buf, &p, 0), 8447c478bd9Sstevel@tonic-gate *p != '\0') || (buf == p) || 8457c478bd9Sstevel@tonic-gate parm.parm_rdisc_int < MIN_MAXADVERTISEINTERVAL || 8467c478bd9Sstevel@tonic-gate parm.parm_rdisc_int > MAX_MAXADVERTISEINTERVAL) 8477c478bd9Sstevel@tonic-gate return (bad_str(tgt)); 8487c478bd9Sstevel@tonic-gate 8497c478bd9Sstevel@tonic-gate } else if (PARSEQ("fake_default")) { 8507c478bd9Sstevel@tonic-gate if (parm.parm_d_metric != 0 || 8517c478bd9Sstevel@tonic-gate IS_RIP_OUT_OFF(parm.parm_int_state) || 8527c478bd9Sstevel@tonic-gate (parm.parm_d_metric = (int)strtoul(buf, &p, 0), 8537c478bd9Sstevel@tonic-gate *p != '\0') || (buf == p) || 8547c478bd9Sstevel@tonic-gate parm.parm_d_metric > HOPCNT_INFINITY-1) 8557c478bd9Sstevel@tonic-gate return (bad_str(tgt)); 8567c478bd9Sstevel@tonic-gate 8577c478bd9Sstevel@tonic-gate } else if (PARSEQ("trust_gateway")) { 8587c478bd9Sstevel@tonic-gate /* look for trust_gateway=x.y.z|net/mask|...) */ 8597c478bd9Sstevel@tonic-gate p = buf; 8607c478bd9Sstevel@tonic-gate if (0 > parse_quote(&p, "|", &delim, buf2, 8617c478bd9Sstevel@tonic-gate sizeof (buf2)) || !gethost(buf2, &addr)) 8627c478bd9Sstevel@tonic-gate return (bad_str(tgt)); 8637c478bd9Sstevel@tonic-gate tg = rtmalloc(sizeof (*tg), 8647c478bd9Sstevel@tonic-gate "parse_parms trust_gateway"); 8657c478bd9Sstevel@tonic-gate (void) memset(tg, 0, sizeof (*tg)); 8667c478bd9Sstevel@tonic-gate tg->tgate_addr = addr; 8677c478bd9Sstevel@tonic-gate i = 0; 8687c478bd9Sstevel@tonic-gate /* The default is to trust all routes. */ 8697c478bd9Sstevel@tonic-gate while (delim == '|') { 8707c478bd9Sstevel@tonic-gate p++; 8717c478bd9Sstevel@tonic-gate if (i >= MAX_TGATE_NETS || 8727c478bd9Sstevel@tonic-gate 0 > parse_quote(&p, "|", &delim, buf2, 8737c478bd9Sstevel@tonic-gate sizeof (buf2)) || 8747c478bd9Sstevel@tonic-gate !getnet(buf2, &tg->tgate_nets[i].net, 8757c478bd9Sstevel@tonic-gate &tg->tgate_nets[i].mask) || 8767c478bd9Sstevel@tonic-gate tg->tgate_nets[i].net == RIP_DEFAULT || 8777c478bd9Sstevel@tonic-gate tg->tgate_nets[i].mask == 0) { 8787c478bd9Sstevel@tonic-gate free(tg); 8797c478bd9Sstevel@tonic-gate return (bad_str(tgt)); 8807c478bd9Sstevel@tonic-gate } 8817c478bd9Sstevel@tonic-gate i++; 8827c478bd9Sstevel@tonic-gate } 8837c478bd9Sstevel@tonic-gate tg->tgate_next = tgates; 8847c478bd9Sstevel@tonic-gate tgates = tg; 8857c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_DISTRUST; 8867c478bd9Sstevel@tonic-gate 8877c478bd9Sstevel@tonic-gate } else if (PARS("redirect_ok")) { 8887c478bd9Sstevel@tonic-gate parm.parm_int_state |= IS_REDIRECT_OK; 8897c478bd9Sstevel@tonic-gate 8907c478bd9Sstevel@tonic-gate } else if (PARSEQ("rip_neighbor")) { 8917c478bd9Sstevel@tonic-gate if (parm.parm_name[0] == '\0' || 8927c478bd9Sstevel@tonic-gate gethost(buf, &parm.parm_ripout_addr) != 1) 8937c478bd9Sstevel@tonic-gate return (bad_str(tgt)); 8947c478bd9Sstevel@tonic-gate 8957c478bd9Sstevel@tonic-gate } else { 8967c478bd9Sstevel@tonic-gate return (bad_str(tgt)); /* error */ 8977c478bd9Sstevel@tonic-gate } 8987c478bd9Sstevel@tonic-gate } 8997c478bd9Sstevel@tonic-gate 9007c478bd9Sstevel@tonic-gate return (insert_parm(&parm)); 9017c478bd9Sstevel@tonic-gate #undef PARS 9027c478bd9Sstevel@tonic-gate #undef PARSEQ 9037c478bd9Sstevel@tonic-gate #undef CKF 9047c478bd9Sstevel@tonic-gate } 9057c478bd9Sstevel@tonic-gate 9067c478bd9Sstevel@tonic-gate 9077c478bd9Sstevel@tonic-gate /* 9087c478bd9Sstevel@tonic-gate * Insert parameter specifications into the parms list. Returns NULL if 9097c478bd9Sstevel@tonic-gate * successful, or an error message otherwise. 9107c478bd9Sstevel@tonic-gate */ 9117c478bd9Sstevel@tonic-gate const char * 9127c478bd9Sstevel@tonic-gate insert_parm(struct parm *new) 9137c478bd9Sstevel@tonic-gate { 9147c478bd9Sstevel@tonic-gate struct parm *parmp, **parmpp; 9157c478bd9Sstevel@tonic-gate int i, num_passwds; 9167c478bd9Sstevel@tonic-gate 9177c478bd9Sstevel@tonic-gate /* set implicit values */ 9187c478bd9Sstevel@tonic-gate if (new->parm_int_state & (IS_NO_ADV_IN|IS_NO_SOL_OUT)) 9197c478bd9Sstevel@tonic-gate new->parm_int_state |= IS_NO_ADV_IN|IS_NO_SOL_OUT; 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate for (i = num_passwds = 0; i < MAX_AUTH_KEYS; i++) { 9227c478bd9Sstevel@tonic-gate if (new->parm_auth[i].type != RIP_AUTH_NONE) 9237c478bd9Sstevel@tonic-gate num_passwds++; 9247c478bd9Sstevel@tonic-gate } 9257c478bd9Sstevel@tonic-gate 9267c478bd9Sstevel@tonic-gate /* compare with existing sets of parameters */ 9277c478bd9Sstevel@tonic-gate for (parmpp = &parms; (parmp = *parmpp) != 0; 9287c478bd9Sstevel@tonic-gate parmpp = &parmp->parm_next) { 9297c478bd9Sstevel@tonic-gate if (strcmp(new->parm_name, parmp->parm_name) != 0) 9307c478bd9Sstevel@tonic-gate continue; 9317c478bd9Sstevel@tonic-gate if (!on_net(htonl(parmp->parm_net), new->parm_net, 9327c478bd9Sstevel@tonic-gate new->parm_mask) && 9337c478bd9Sstevel@tonic-gate !on_net(htonl(new->parm_net), parmp->parm_net, 9347c478bd9Sstevel@tonic-gate parmp->parm_mask)) 9357c478bd9Sstevel@tonic-gate continue; 9367c478bd9Sstevel@tonic-gate 9377c478bd9Sstevel@tonic-gate for (i = 0; i < MAX_AUTH_KEYS; i++) { 9387c478bd9Sstevel@tonic-gate if (parmp->parm_auth[i].type != RIP_AUTH_NONE) 9397c478bd9Sstevel@tonic-gate num_passwds++; 9407c478bd9Sstevel@tonic-gate } 9417c478bd9Sstevel@tonic-gate if (num_passwds > MAX_AUTH_KEYS) 9427c478bd9Sstevel@tonic-gate return ("too many conflicting passwords"); 9437c478bd9Sstevel@tonic-gate 9447c478bd9Sstevel@tonic-gate if ((0 != (new->parm_int_state & GROUP_IS_SOL_OUT) && 9457c478bd9Sstevel@tonic-gate 0 != (parmp->parm_int_state & GROUP_IS_SOL_OUT) && 9467c478bd9Sstevel@tonic-gate 0 != ((new->parm_int_state ^ parmp->parm_int_state) && 9477c478bd9Sstevel@tonic-gate GROUP_IS_SOL_OUT)) || 9487c478bd9Sstevel@tonic-gate (0 != (new->parm_int_state & GROUP_IS_ADV_OUT) && 9497c478bd9Sstevel@tonic-gate 0 != (parmp->parm_int_state & GROUP_IS_ADV_OUT) && 9507c478bd9Sstevel@tonic-gate 0 != ((new->parm_int_state ^ parmp->parm_int_state) && 9517c478bd9Sstevel@tonic-gate GROUP_IS_ADV_OUT)) || 9527c478bd9Sstevel@tonic-gate (new->parm_rdisc_pref != 0 && 9537c478bd9Sstevel@tonic-gate parmp->parm_rdisc_pref != 0 && 9547c478bd9Sstevel@tonic-gate new->parm_rdisc_pref != parmp->parm_rdisc_pref) || 9557c478bd9Sstevel@tonic-gate (new->parm_rdisc_int != 0 && 9567c478bd9Sstevel@tonic-gate parmp->parm_rdisc_int != 0 && 9577c478bd9Sstevel@tonic-gate new->parm_rdisc_int != parmp->parm_rdisc_int)) { 9587c478bd9Sstevel@tonic-gate return ("conflicting, duplicate router discovery" 9597c478bd9Sstevel@tonic-gate " parameters"); 9607c478bd9Sstevel@tonic-gate 9617c478bd9Sstevel@tonic-gate } 9627c478bd9Sstevel@tonic-gate 9637c478bd9Sstevel@tonic-gate if (new->parm_d_metric != 0 && parmp->parm_d_metric != 0 && 9647c478bd9Sstevel@tonic-gate new->parm_d_metric != parmp->parm_d_metric) { 9657c478bd9Sstevel@tonic-gate return ("conflicting, duplicate poor man's router" 9667c478bd9Sstevel@tonic-gate " discovery or fake default metric"); 9677c478bd9Sstevel@tonic-gate } 9687c478bd9Sstevel@tonic-gate } 9697c478bd9Sstevel@tonic-gate 9707c478bd9Sstevel@tonic-gate /* 9717c478bd9Sstevel@tonic-gate * link new entry on the list so that when the entries are scanned, 9727c478bd9Sstevel@tonic-gate * they affect the result in the order the operator specified. 9737c478bd9Sstevel@tonic-gate */ 9747c478bd9Sstevel@tonic-gate parmp = rtmalloc(sizeof (*parmp), "insert_parm"); 9757c478bd9Sstevel@tonic-gate (void) memcpy(parmp, new, sizeof (*parmp)); 9767c478bd9Sstevel@tonic-gate *parmpp = parmp; 9777c478bd9Sstevel@tonic-gate 9787c478bd9Sstevel@tonic-gate return (NULL); 9797c478bd9Sstevel@tonic-gate } 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate int /* 0=bad */ 9827c478bd9Sstevel@tonic-gate gethost(char *name, in_addr_t *addrp) 9837c478bd9Sstevel@tonic-gate { 9847c478bd9Sstevel@tonic-gate struct hostent *hp; 9857c478bd9Sstevel@tonic-gate struct in_addr in; 9867c478bd9Sstevel@tonic-gate 9877c478bd9Sstevel@tonic-gate 9887c478bd9Sstevel@tonic-gate /* 9897c478bd9Sstevel@tonic-gate * Try for a number first. This avoids hitting the name 9907c478bd9Sstevel@tonic-gate * server which might be sick because routing is. 9917c478bd9Sstevel@tonic-gate */ 9927c478bd9Sstevel@tonic-gate if ((in.s_addr = inet_addr(name)) != (in_addr_t)-1) { 9937c478bd9Sstevel@tonic-gate /* 9947c478bd9Sstevel@tonic-gate * get a good number, but check that it makes some 9957c478bd9Sstevel@tonic-gate * sense. 9967c478bd9Sstevel@tonic-gate */ 9977c478bd9Sstevel@tonic-gate if ((ntohl(in.s_addr) >> 24) == 0 || 9987c478bd9Sstevel@tonic-gate (ntohl(in.s_addr) >> 24) == 0xff) 9997c478bd9Sstevel@tonic-gate return (0); 10007c478bd9Sstevel@tonic-gate *addrp = in.s_addr; 10017c478bd9Sstevel@tonic-gate return (1); 10027c478bd9Sstevel@tonic-gate } 10037c478bd9Sstevel@tonic-gate 10047c478bd9Sstevel@tonic-gate hp = gethostbyname(name); 10057c478bd9Sstevel@tonic-gate if (hp != NULL) { 10067c478bd9Sstevel@tonic-gate (void) memcpy(addrp, hp->h_addr, sizeof (*addrp)); 10077c478bd9Sstevel@tonic-gate return (1); 10087c478bd9Sstevel@tonic-gate } 10097c478bd9Sstevel@tonic-gate 10107c478bd9Sstevel@tonic-gate return (0); 10117c478bd9Sstevel@tonic-gate } 10127c478bd9Sstevel@tonic-gate 10137c478bd9Sstevel@tonic-gate 10147c478bd9Sstevel@tonic-gate static void 10157c478bd9Sstevel@tonic-gate addroutefordefault(in_addr_t dst, in_addr_t gate, in_addr_t mask, 10167c478bd9Sstevel@tonic-gate uint32_t metric, uint16_t rts_flags) 10177c478bd9Sstevel@tonic-gate { 10187c478bd9Sstevel@tonic-gate struct rt_spare new; 10197c478bd9Sstevel@tonic-gate struct interface *ifp; 10207c478bd9Sstevel@tonic-gate uint16_t rt_newstate = RS_STATIC; 10217c478bd9Sstevel@tonic-gate 10227c478bd9Sstevel@tonic-gate 10237c478bd9Sstevel@tonic-gate ifp = iflookup(gate); 10247c478bd9Sstevel@tonic-gate if (ifp == NULL) { 10257c478bd9Sstevel@tonic-gate msglog("unreachable gateway %s in "PATH_GATEWAYS, 10267c478bd9Sstevel@tonic-gate naddr_ntoa(gate)); 10277c478bd9Sstevel@tonic-gate return; 10287c478bd9Sstevel@tonic-gate } 10297c478bd9Sstevel@tonic-gate 10307c478bd9Sstevel@tonic-gate trace_misc("addroutefordefault: found interface %s", ifp->int_name); 10317c478bd9Sstevel@tonic-gate 10327c478bd9Sstevel@tonic-gate (void) memset(&new, 0, sizeof (new)); 10337c478bd9Sstevel@tonic-gate new.rts_ifp = ifp; 10347c478bd9Sstevel@tonic-gate new.rts_router = gate; 10357c478bd9Sstevel@tonic-gate new.rts_gate = gate; 10367c478bd9Sstevel@tonic-gate new.rts_metric = metric; 10377c478bd9Sstevel@tonic-gate new.rts_time = now.tv_sec; 10387c478bd9Sstevel@tonic-gate new.rts_flags = rts_flags; 10397c478bd9Sstevel@tonic-gate new.rts_origin = RO_FILE; 10407c478bd9Sstevel@tonic-gate 10417c478bd9Sstevel@tonic-gate input_route(dst, mask, &new, NULL, rt_newstate); 10427c478bd9Sstevel@tonic-gate } 1043