startup.c revision 43713
111820Sjulian/* 211820Sjulian * Copyright (c) 1985, 1993 311820Sjulian * The Regents of the University of California. All rights reserved. 411820Sjulian * 511820Sjulian * Copyright (c) 1995 John Hay. All rights reserved. 611820Sjulian * 711820Sjulian * This file includes significant work done at Cornell University by 811820Sjulian * Bill Nesheim. That work included by permission. 911820Sjulian * 1011820Sjulian * Redistribution and use in source and binary forms, with or without 1111820Sjulian * modification, are permitted provided that the following conditions 1211820Sjulian * are met: 1311820Sjulian * 1. Redistributions of source code must retain the above copyright 1411820Sjulian * notice, this list of conditions and the following disclaimer. 1511820Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1611820Sjulian * notice, this list of conditions and the following disclaimer in the 1711820Sjulian * documentation and/or other materials provided with the distribution. 1811820Sjulian * 3. All advertising materials mentioning features or use of this software 1911820Sjulian * must display the following acknowledgement: 2011820Sjulian * This product includes software developed by the University of 2111820Sjulian * California, Berkeley and its contributors. 2211820Sjulian * 4. Neither the name of the University nor the names of its contributors 2311820Sjulian * may be used to endorse or promote products derived from this software 2411820Sjulian * without specific prior written permission. 2511820Sjulian * 2611820Sjulian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2711820Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2811820Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2911820Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3011820Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3111820Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3211820Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3311820Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3411820Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3511820Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3611820Sjulian * SUCH DAMAGE. 3711820Sjulian * 3843713Sjhay * $Id: startup.c,v 1.6 1997/02/22 16:01:01 peter Exp $ 3911820Sjulian */ 4011820Sjulian 4111820Sjulian#ifndef lint 4211820Sjulianstatic char sccsid[] = "@(#)startup.c 8.1 (Berkeley) 6/5/93"; 4311820Sjulian#endif /* not lint */ 4411820Sjulian 4511820Sjulian/* 4611820Sjulian * Routing Table Management Daemon 4711820Sjulian */ 4811820Sjulian#include "defs.h" 4911820Sjulian 5011820Sjulian#include <sys/param.h> 5111820Sjulian#include <sys/ioctl.h> 5211820Sjulian#include <sys/sysctl.h> 5320287Swollman#include <sys/time.h> 5411820Sjulian 5511820Sjulian#include <net/if.h> 5611820Sjulian#include <net/if_dl.h> 5711820Sjulian 5811820Sjulian#include <nlist.h> 5911820Sjulian#include <stdlib.h> 6011820Sjulian 6111820Sjulianstruct interface *ifnet; 6211820Sjulianint lookforinterfaces = 1; 6311820Sjulianint performnlist = 1; 6411820Sjulianint gateway = 0; 6511820Sjulianint externalinterfaces = 0; /* # of remote and local interfaces */ 6611820Sjulian 6711820Sjulianvoid 6811820Sjulianquit(s) 6911820Sjulian char *s; 7011820Sjulian{ 7111820Sjulian extern int errno; 7211820Sjulian int sverrno = errno; 7311820Sjulian 7411820Sjulian (void) fprintf(stderr, "IPXroute: "); 7511820Sjulian if (s) 7611820Sjulian (void) fprintf(stderr, "%s: ", s); 7711820Sjulian (void) fprintf(stderr, "%s\n", strerror(sverrno)); 7811820Sjulian exit(1); 7911820Sjulian /* NOTREACHED */ 8011820Sjulian} 8111820Sjulian 8211820Sjulianstruct rt_addrinfo info; 8311820Sjulian/* Sleazy use of local variables throughout file, warning!!!! */ 8411820Sjulian#define netmask info.rti_info[RTAX_NETMASK] 8511820Sjulian#define ifaaddr info.rti_info[RTAX_IFA] 8611820Sjulian#define brdaddr info.rti_info[RTAX_BRD] 8711820Sjulian 8811820Sjulian#define ROUNDUP(a) \ 8911820Sjulian ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 9011820Sjulian#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) 9111820Sjulian 9211820Sjulianvoid 9311820Sjulianrt_xaddrs(cp, cplim, rtinfo) 9411820Sjulian register caddr_t cp, cplim; 9511820Sjulian register struct rt_addrinfo *rtinfo; 9611820Sjulian{ 9711820Sjulian register struct sockaddr *sa; 9811820Sjulian register int i; 9911820Sjulian 10011820Sjulian bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info)); 10111820Sjulian for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { 10211820Sjulian if ((rtinfo->rti_addrs & (1 << i)) == 0) 10311820Sjulian continue; 10411820Sjulian rtinfo->rti_info[i] = sa = (struct sockaddr *)cp; 10511820Sjulian ADVANCE(cp, sa); 10611820Sjulian } 10711820Sjulian} 10811820Sjulian 10911820Sjulian/* 11011820Sjulian * Find the network interfaces which have configured themselves. 11111820Sjulian * If the interface is present but not yet up (for example an 11211820Sjulian * ARPANET IMP), set the lookforinterfaces flag so we'll 11311820Sjulian * come back later and look again. 11411820Sjulian */ 11511820Sjulianvoid 11611820Sjulianifinit(void) 11711820Sjulian{ 11811820Sjulian struct interface ifs, *ifp; 11911820Sjulian size_t needed; 12011820Sjulian int mib[6], no_ipxaddr = 0, flags = 0; 12111820Sjulian char *buf, *cplim, *cp; 12211820Sjulian register struct if_msghdr *ifm; 12311820Sjulian register struct ifa_msghdr *ifam; 12411820Sjulian struct sockaddr_dl *sdl = 0; 12511820Sjulian 12611820Sjulian mib[0] = CTL_NET; 12711820Sjulian mib[1] = PF_ROUTE; 12811820Sjulian mib[2] = 0; 12911820Sjulian mib[3] = AF_IPX; 13011820Sjulian mib[4] = NET_RT_IFLIST; 13111820Sjulian mib[5] = 0; 13211820Sjulian if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) 13311820Sjulian quit("route-sysctl-estimate"); 13411820Sjulian if ((buf = malloc(needed)) == NULL) 13511820Sjulian quit("malloc"); 13611820Sjulian if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) 13711820Sjulian lookforinterfaces = 0; 13811820Sjulian cplim = buf + needed; 13911820Sjulian for (cp = buf; cp < cplim; cp += ifm->ifm_msglen) { 14011820Sjulian ifm = (struct if_msghdr *)cp; 14111820Sjulian if (ifm->ifm_type == RTM_IFINFO) { 14211820Sjulian bzero(&ifs, sizeof(ifs)); 14311820Sjulian ifs.int_flags = flags = ifm->ifm_flags | IFF_INTERFACE; 14411820Sjulian if ((flags & IFF_UP) == 0 || no_ipxaddr) 14511820Sjulian lookforinterfaces = 1; 14611820Sjulian sdl = (struct sockaddr_dl *) (ifm + 1); 14711820Sjulian sdl->sdl_data[sdl->sdl_nlen] = 0; 14811820Sjulian no_ipxaddr = 1; 14911820Sjulian continue; 15011820Sjulian } 15111820Sjulian if (ifm->ifm_type != RTM_NEWADDR) 15211820Sjulian quit("ifinit: out of sync"); 15311820Sjulian if ((flags & IFF_UP) == 0) 15411820Sjulian continue; 15511820Sjulian ifam = (struct ifa_msghdr *)ifm; 15611820Sjulian info.rti_addrs = ifam->ifam_addrs; 15711820Sjulian rt_xaddrs((char *)(ifam + 1), cp + ifam->ifam_msglen, &info); 15811820Sjulian if (ifaaddr == 0) { 15911820Sjulian syslog(LOG_ERR, "%s: (get addr)", sdl->sdl_data); 16011820Sjulian continue; 16111820Sjulian } 16211820Sjulian ifs.int_addr = *ifaaddr; 16311820Sjulian if (ifs.int_addr.sa_family != AF_IPX) 16411820Sjulian continue; 16511820Sjulian no_ipxaddr = 0; 16611820Sjulian if (ifs.int_flags & IFF_POINTOPOINT) { 16711820Sjulian if (brdaddr == 0) { 16811820Sjulian syslog(LOG_ERR, "%s: (get dstaddr)", 16911820Sjulian sdl->sdl_data); 17011820Sjulian continue; 17111820Sjulian } 17211820Sjulian if (brdaddr->sa_family == AF_UNSPEC) { 17311820Sjulian lookforinterfaces = 1; 17411820Sjulian continue; 17511820Sjulian } 17611820Sjulian ifs.int_dstaddr = *brdaddr; 17711820Sjulian } 17811820Sjulian if (ifs.int_flags & IFF_BROADCAST) { 17911820Sjulian if (brdaddr == 0) { 18011820Sjulian syslog(LOG_ERR, "%s: (get broadaddr)", 18111820Sjulian sdl->sdl_data); 18211820Sjulian continue; 18311820Sjulian } 18411820Sjulian ifs.int_dstaddr = *brdaddr; 18511820Sjulian } 18643713Sjhay if (ifs.int_flags & IFF_LOOPBACK) { 18743713Sjhay ifs.int_dstaddr = ifs.int_addr; 18843713Sjhay } 18911820Sjulian /* 19011820Sjulian * already known to us? 19111820Sjulian * what makes a POINTOPOINT if unique is its dst addr, 19211820Sjulian * NOT its source address 19311820Sjulian */ 19411820Sjulian if ( ((ifs.int_flags & IFF_POINTOPOINT) && 19511820Sjulian if_ifwithdstaddr(&ifs.int_dstaddr)) || 19611820Sjulian ( ((ifs.int_flags & IFF_POINTOPOINT) == 0) && 19711820Sjulian if_ifwithaddr(&ifs.int_addr))) 19811820Sjulian continue; 19911820Sjulian ifp = (struct interface *) 20011820Sjulian malloc(sdl->sdl_nlen + 1 + sizeof(ifs)); 20111820Sjulian if (ifp == 0) { 20211820Sjulian syslog(LOG_ERR, "IPXrouted: out of memory\n"); 20311820Sjulian lookforinterfaces = 1; 20411820Sjulian break; 20511820Sjulian } 20611820Sjulian *ifp = ifs; 20711820Sjulian /* 20811820Sjulian * Count the # of directly connected networks 20911820Sjulian * and point to point links which aren't looped 21011820Sjulian * back to ourself. This is used below to 21111820Sjulian * decide if we should be a routing ``supplier''. 21211820Sjulian */ 21311820Sjulian if ((ifs.int_flags & IFF_POINTOPOINT) == 0 || 21411820Sjulian if_ifwithaddr(&ifs.int_dstaddr) == 0) 21511820Sjulian externalinterfaces++; 21611820Sjulian /* 21711820Sjulian * If we have a point-to-point link, we want to act 21811820Sjulian * as a supplier even if it's our only interface, 21911820Sjulian * as that's the only way our peer on the other end 22011820Sjulian * can tell that the link is up. 22111820Sjulian */ 22211820Sjulian if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0) 22311820Sjulian supplier = 1; 22411820Sjulian ifp->int_name = (char *)(ifp + 1); 22511820Sjulian strcpy(ifp->int_name, sdl->sdl_data); 22611820Sjulian 22711820Sjulian ifp->int_metric = ifam->ifam_metric; 22811820Sjulian ifp->int_next = ifnet; 22911820Sjulian ifnet = ifp; 23011820Sjulian traceinit(ifp); 23111820Sjulian addrouteforif(ifp); 23211820Sjulian } 23311820Sjulian if (externalinterfaces > 1 && supplier < 0) 23411820Sjulian supplier = 1; 23511820Sjulian free(buf); 23611820Sjulian} 23711820Sjulian 23811820Sjulianvoid 23911820Sjulianaddrouteforif(ifp) 24011820Sjulian struct interface *ifp; 24111820Sjulian{ 24214165Sjulian struct sockaddr_ipx net; 24311820Sjulian struct sockaddr *dst; 24411820Sjulian struct rt_entry *rt; 24511820Sjulian 24611820Sjulian if (ifp->int_flags & IFF_POINTOPOINT) { 24711820Sjulian int (*match)(); 24811820Sjulian register struct interface *ifp2 = ifnet; 24911820Sjulian 25011820Sjulian dst = &ifp->int_dstaddr; 25111820Sjulian 25211820Sjulian /* Search for interfaces with the same net */ 25311820Sjulian ifp->int_sq.n = ifp->int_sq.p = &(ifp->int_sq); 25411820Sjulian match = afswitch[dst->sa_family].af_netmatch; 25511820Sjulian if (match) 25611820Sjulian for (ifp2 = ifnet; ifp2; ifp2 =ifp2->int_next) { 25711820Sjulian if (ifp->int_flags & IFF_POINTOPOINT == 0) 25811820Sjulian continue; 25911820Sjulian if ((*match)(&ifp2->int_dstaddr,&ifp->int_dstaddr)) { 26011820Sjulian insque(&ifp2->int_sq,&ifp->int_sq); 26111820Sjulian break; 26211820Sjulian } 26311820Sjulian } 26411820Sjulian } else { 26514165Sjulian bzero(&net, sizeof(net)); 26614165Sjulian net.sipx_family = AF_IPX; 26714165Sjulian net.sipx_len = sizeof (net); 26814165Sjulian net.sipx_addr.x_net = satoipx_addr(ifp->int_broadaddr).x_net; 26914165Sjulian dst = (struct sockaddr *)&net; 27011820Sjulian } 27111820Sjulian rt = rtlookup(dst); 27211820Sjulian if (rt) 27311820Sjulian rtdelete(rt); 27411820Sjulian if (tracing) 27511820Sjulian fprintf(stderr, "Adding route to interface %s\n", ifp->int_name); 27611820Sjulian if (ifp->int_transitions++ > 0) 27711820Sjulian syslog(LOG_ERR, "re-installing interface %s", ifp->int_name); 27811820Sjulian rtadd(dst, &ifp->int_addr, ifp->int_metric, 0, 27911820Sjulian ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE)); 28011820Sjulian} 28111820Sjulian 282