startup.c revision 11820
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 * 3811820Sjulian * $Id: startup.c,v 1.3 1995/10/11 18:57:30 jhay 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> 5311820Sjulian 5411820Sjulian#include <net/if.h> 5511820Sjulian#include <net/if_dl.h> 5611820Sjulian 5711820Sjulian#include <nlist.h> 5811820Sjulian#include <stdlib.h> 5911820Sjulian 6011820Sjulianstruct interface *ifnet; 6111820Sjulianint lookforinterfaces = 1; 6211820Sjulianint performnlist = 1; 6311820Sjulianint gateway = 0; 6411820Sjulianint externalinterfaces = 0; /* # of remote and local interfaces */ 6511820Sjulianchar ether_broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 6611820Sjulian 6711820Sjulian 6811820Sjulianvoid 6911820Sjulianquit(s) 7011820Sjulian char *s; 7111820Sjulian{ 7211820Sjulian extern int errno; 7311820Sjulian int sverrno = errno; 7411820Sjulian 7511820Sjulian (void) fprintf(stderr, "IPXroute: "); 7611820Sjulian if (s) 7711820Sjulian (void) fprintf(stderr, "%s: ", s); 7811820Sjulian (void) fprintf(stderr, "%s\n", strerror(sverrno)); 7911820Sjulian exit(1); 8011820Sjulian /* NOTREACHED */ 8111820Sjulian} 8211820Sjulian 8311820Sjulianstruct rt_addrinfo info; 8411820Sjulian/* Sleazy use of local variables throughout file, warning!!!! */ 8511820Sjulian#define netmask info.rti_info[RTAX_NETMASK] 8611820Sjulian#define ifaaddr info.rti_info[RTAX_IFA] 8711820Sjulian#define brdaddr info.rti_info[RTAX_BRD] 8811820Sjulian 8911820Sjulian#define ROUNDUP(a) \ 9011820Sjulian ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 9111820Sjulian#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) 9211820Sjulian 9311820Sjulianvoid 9411820Sjulianrt_xaddrs(cp, cplim, rtinfo) 9511820Sjulian register caddr_t cp, cplim; 9611820Sjulian register struct rt_addrinfo *rtinfo; 9711820Sjulian{ 9811820Sjulian register struct sockaddr *sa; 9911820Sjulian register int i; 10011820Sjulian 10111820Sjulian bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info)); 10211820Sjulian for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { 10311820Sjulian if ((rtinfo->rti_addrs & (1 << i)) == 0) 10411820Sjulian continue; 10511820Sjulian rtinfo->rti_info[i] = sa = (struct sockaddr *)cp; 10611820Sjulian ADVANCE(cp, sa); 10711820Sjulian } 10811820Sjulian} 10911820Sjulian 11011820Sjulian/* 11111820Sjulian * Find the network interfaces which have configured themselves. 11211820Sjulian * If the interface is present but not yet up (for example an 11311820Sjulian * ARPANET IMP), set the lookforinterfaces flag so we'll 11411820Sjulian * come back later and look again. 11511820Sjulian */ 11611820Sjulianvoid 11711820Sjulianifinit(void) 11811820Sjulian{ 11911820Sjulian struct interface ifs, *ifp; 12011820Sjulian size_t needed; 12111820Sjulian int mib[6], no_ipxaddr = 0, flags = 0; 12211820Sjulian char *buf, *cplim, *cp; 12311820Sjulian register struct if_msghdr *ifm; 12411820Sjulian register struct ifa_msghdr *ifam; 12511820Sjulian struct sockaddr_dl *sdl = 0; 12611820Sjulian 12711820Sjulian mib[0] = CTL_NET; 12811820Sjulian mib[1] = PF_ROUTE; 12911820Sjulian mib[2] = 0; 13011820Sjulian mib[3] = AF_IPX; 13111820Sjulian mib[4] = NET_RT_IFLIST; 13211820Sjulian mib[5] = 0; 13311820Sjulian if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) 13411820Sjulian quit("route-sysctl-estimate"); 13511820Sjulian if ((buf = malloc(needed)) == NULL) 13611820Sjulian quit("malloc"); 13711820Sjulian if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) 13811820Sjulian lookforinterfaces = 0; 13911820Sjulian cplim = buf + needed; 14011820Sjulian for (cp = buf; cp < cplim; cp += ifm->ifm_msglen) { 14111820Sjulian ifm = (struct if_msghdr *)cp; 14211820Sjulian if (ifm->ifm_type == RTM_IFINFO) { 14311820Sjulian bzero(&ifs, sizeof(ifs)); 14411820Sjulian ifs.int_flags = flags = ifm->ifm_flags | IFF_INTERFACE; 14511820Sjulian if ((flags & IFF_UP) == 0 || no_ipxaddr) 14611820Sjulian lookforinterfaces = 1; 14711820Sjulian sdl = (struct sockaddr_dl *) (ifm + 1); 14811820Sjulian sdl->sdl_data[sdl->sdl_nlen] = 0; 14911820Sjulian no_ipxaddr = 1; 15011820Sjulian continue; 15111820Sjulian } 15211820Sjulian if (ifm->ifm_type != RTM_NEWADDR) 15311820Sjulian quit("ifinit: out of sync"); 15411820Sjulian if ((flags & IFF_UP) == 0) 15511820Sjulian continue; 15611820Sjulian ifam = (struct ifa_msghdr *)ifm; 15711820Sjulian info.rti_addrs = ifam->ifam_addrs; 15811820Sjulian rt_xaddrs((char *)(ifam + 1), cp + ifam->ifam_msglen, &info); 15911820Sjulian if (ifaaddr == 0) { 16011820Sjulian syslog(LOG_ERR, "%s: (get addr)", sdl->sdl_data); 16111820Sjulian continue; 16211820Sjulian } 16311820Sjulian ifs.int_addr = *ifaaddr; 16411820Sjulian if (ifs.int_addr.sa_family != AF_IPX) 16511820Sjulian continue; 16611820Sjulian no_ipxaddr = 0; 16711820Sjulian if (ifs.int_flags & IFF_POINTOPOINT) { 16811820Sjulian if (brdaddr == 0) { 16911820Sjulian syslog(LOG_ERR, "%s: (get dstaddr)", 17011820Sjulian sdl->sdl_data); 17111820Sjulian continue; 17211820Sjulian } 17311820Sjulian if (brdaddr->sa_family == AF_UNSPEC) { 17411820Sjulian lookforinterfaces = 1; 17511820Sjulian continue; 17611820Sjulian } 17711820Sjulian ifs.int_dstaddr = *brdaddr; 17811820Sjulian } 17911820Sjulian if (ifs.int_flags & IFF_BROADCAST) { 18011820Sjulian if (brdaddr == 0) { 18111820Sjulian syslog(LOG_ERR, "%s: (get broadaddr)", 18211820Sjulian sdl->sdl_data); 18311820Sjulian continue; 18411820Sjulian } 18511820Sjulian ifs.int_dstaddr = *brdaddr; 18611820Sjulian } 18711820Sjulian /* 18811820Sjulian * already known to us? 18911820Sjulian * what makes a POINTOPOINT if unique is its dst addr, 19011820Sjulian * NOT its source address 19111820Sjulian */ 19211820Sjulian if ( ((ifs.int_flags & IFF_POINTOPOINT) && 19311820Sjulian if_ifwithdstaddr(&ifs.int_dstaddr)) || 19411820Sjulian ( ((ifs.int_flags & IFF_POINTOPOINT) == 0) && 19511820Sjulian if_ifwithaddr(&ifs.int_addr))) 19611820Sjulian continue; 19711820Sjulian /* no one cares about software loopback interfaces */ 19811820Sjulian if (ifs.int_flags & IFF_LOOPBACK) 19911820Sjulian continue; 20011820Sjulian ifp = (struct interface *) 20111820Sjulian malloc(sdl->sdl_nlen + 1 + sizeof(ifs)); 20211820Sjulian if (ifp == 0) { 20311820Sjulian syslog(LOG_ERR, "IPXrouted: out of memory\n"); 20411820Sjulian lookforinterfaces = 1; 20511820Sjulian break; 20611820Sjulian } 20711820Sjulian *ifp = ifs; 20811820Sjulian /* 20911820Sjulian * Count the # of directly connected networks 21011820Sjulian * and point to point links which aren't looped 21111820Sjulian * back to ourself. This is used below to 21211820Sjulian * decide if we should be a routing ``supplier''. 21311820Sjulian */ 21411820Sjulian if ((ifs.int_flags & IFF_POINTOPOINT) == 0 || 21511820Sjulian if_ifwithaddr(&ifs.int_dstaddr) == 0) 21611820Sjulian externalinterfaces++; 21711820Sjulian /* 21811820Sjulian * If we have a point-to-point link, we want to act 21911820Sjulian * as a supplier even if it's our only interface, 22011820Sjulian * as that's the only way our peer on the other end 22111820Sjulian * can tell that the link is up. 22211820Sjulian */ 22311820Sjulian if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0) 22411820Sjulian supplier = 1; 22511820Sjulian ifp->int_name = (char *)(ifp + 1); 22611820Sjulian strcpy(ifp->int_name, sdl->sdl_data); 22711820Sjulian 22811820Sjulian ifp->int_metric = ifam->ifam_metric; 22911820Sjulian ifp->int_next = ifnet; 23011820Sjulian ifnet = ifp; 23111820Sjulian traceinit(ifp); 23211820Sjulian addrouteforif(ifp); 23311820Sjulian } 23411820Sjulian if (externalinterfaces > 1 && supplier < 0) 23511820Sjulian supplier = 1; 23611820Sjulian free(buf); 23711820Sjulian} 23811820Sjulian 23911820Sjulianvoid 24011820Sjulianaddrouteforif(ifp) 24111820Sjulian struct interface *ifp; 24211820Sjulian{ 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 { 26511820Sjulian dst = &ifp->int_broadaddr; 26611820Sjulian } 26711820Sjulian rt = rtlookup(dst); 26811820Sjulian if (rt) 26911820Sjulian rtdelete(rt); 27011820Sjulian if (tracing) 27111820Sjulian fprintf(stderr, "Adding route to interface %s\n", ifp->int_name); 27211820Sjulian if (ifp->int_transitions++ > 0) 27311820Sjulian syslog(LOG_ERR, "re-installing interface %s", ifp->int_name); 27411820Sjulian rtadd(dst, &ifp->int_addr, ifp->int_metric, 0, 27511820Sjulian ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE)); 27611820Sjulian} 27711820Sjulian 278