X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/1c15e88899094343f75aeba04122cd96a96b428e..ad7871609881e73855d0b04da49b486cd93efca7:/usr/src/sbin/XNSrouted/startup.c diff --git a/usr/src/sbin/XNSrouted/startup.c b/usr/src/sbin/XNSrouted/startup.c index aa99968030..bcb5615ff6 100644 --- a/usr/src/sbin/XNSrouted/startup.c +++ b/usr/src/sbin/XNSrouted/startup.c @@ -1,37 +1,57 @@ /* - * Copyright (c) 1985 The Regents of the University of California. - * All rights reserved. + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. * * This file includes significant work done at Cornell University by * Bill Nesheim. That work included by permission. * - * Redistribution and use in source and binary forms are permitted - * provided that: (1) source distributions retain this entire copyright - * notice and comment, and (2) distributions including binaries display - * the following acknowledgement: ``This product includes software - * developed by the University of California, Berkeley and its contributors'' - * in the documentation or other materials provided with the distribution - * and in all advertising materials mentioning features or use of this - * software. Neither the name of the University nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #ifndef lint -static char sccsid[] = "@(#)startup.c 5.9 (Berkeley) 6/1/90"; +static char sccsid[] = "@(#)startup.c 8.1 (Berkeley) 6/5/93"; #endif /* not lint */ /* * Routing Table Management Daemon */ #include "defs.h" + +#include #include +#include + #include +#include + #include -#include +#include struct interface *ifnet; int lookforinterfaces = 1; @@ -41,6 +61,48 @@ int externalinterfaces = 0; /* # of remote and local interfaces */ char ether_broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +void +quit(s) + char *s; +{ + extern int errno; + int sverrno = errno; + + (void) fprintf(stderr, "route: "); + if (s) + (void) fprintf(stderr, "%s: ", s); + (void) fprintf(stderr, "%s\n", strerror(sverrno)); + exit(1); + /* NOTREACHED */ +} + +struct rt_addrinfo info; +/* Sleazy use of local variables throughout file, warning!!!! */ +#define netmask info.rti_info[RTAX_NETMASK] +#define ifaaddr info.rti_info[RTAX_IFA] +#define brdaddr info.rti_info[RTAX_BRD] + +#define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) +#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) + +void +rt_xaddrs(cp, cplim, rtinfo) + register caddr_t cp, cplim; + register struct rt_addrinfo *rtinfo; +{ + register struct sockaddr *sa; + register int i; + + bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info)); + for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { + if ((rtinfo->rti_addrs & (1 << i)) == 0) + continue; + rtinfo->rti_info[i] = sa = (struct sockaddr *)cp; + ADVANCE(cp, sa); + } +} + /* * Find the network interfaces which have configured themselves. * If the interface is present but not yet up (for example an @@ -50,62 +112,73 @@ char ether_broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ifinit() { struct interface ifs, *ifp; - int s; - struct ifconf ifc; - char buf[BUFSIZ], *cp, *cplim; - struct ifreq ifreq, *ifr; + size_t needed; + int mib[6], no_nsaddr = 0, flags = 0; + char *buf, *cplim, *cp; + register struct if_msghdr *ifm; + register struct ifa_msghdr *ifam; + struct sockaddr_dl *sdl; u_long i; - if ((s = socket(AF_NS, SOCK_DGRAM, 0)) < 0) { - syslog(LOG_ERR, "socket: %m"); - exit(1); - } - ifc.ifc_len = sizeof (buf); - ifc.ifc_buf = buf; - if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { - syslog(LOG_ERR, "ioctl (get interface configuration)"); - close(s); - exit(1); - } - ifr = ifc.ifc_req; + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = AF_NS; + mib[4] = NET_RT_IFLIST; + mib[5] = 0; + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + quit("route-sysctl-estimate"); + if ((buf = malloc(needed)) == NULL) + quit("malloc"); + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) lookforinterfaces = 0; -#ifdef RTM_ADD -#define max(a, b) (a > b ? a : b) -#define size(p) max((p).sa_len, sizeof(p)) -#else -#define size(p) (sizeof (p)) -#endif - cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */ - for (cp = buf; cp < cplim; - cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) { - bzero((char *)&ifs, sizeof(ifs)); - ifs.int_addr = ifr->ifr_addr; - ifreq = *ifr; - if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { - syslog(LOG_ERR, "ioctl (get interface flags)"); - continue; - } - ifs.int_flags = ifreq.ifr_flags | IFF_INTERFACE; - if ((ifs.int_flags & IFF_UP) == 0 || - ifr->ifr_addr.sa_family == AF_UNSPEC) { - lookforinterfaces = 1; + cplim = buf + needed; + for (cp = buf; cp < cplim; cp += ifm->ifm_msglen) { + ifm = (struct if_msghdr *)cp; + if (ifm->ifm_type == RTM_IFINFO) { + bzero(&ifs, sizeof(ifs)); + ifs.int_flags = flags = ifm->ifm_flags | IFF_INTERFACE; + if ((flags & IFF_UP) == 0 || no_nsaddr) + lookforinterfaces = 1; + sdl = (struct sockaddr_dl *) (ifm + 1); + sdl->sdl_data[sdl->sdl_nlen] = 0; + no_nsaddr = 1; + continue; + } + if (ifm->ifm_type != RTM_NEWADDR) + quit("ifinit: out of sync"); + if ((flags & IFF_UP) == 0) + continue; + ifam = (struct ifa_msghdr *)ifm; + info.rti_addrs = ifam->ifam_addrs; + rt_xaddrs((char *)(ifam + 1), cp + ifam->ifam_msglen, &info); + if (ifaaddr == 0) { + syslog(LOG_ERR, "%s: (get addr)", sdl->sdl_data); continue; } + ifs.int_addr = *ifaaddr; if (ifs.int_addr.sa_family != AF_NS) continue; - if (ifs.int_flags & IFF_POINTOPOINT) { - if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) { - syslog(LOG_ERR, "ioctl (get dstaddr): %m"); - continue; + no_nsaddr = 0; + if (ifs.int_flags & IFF_POINTOPOINT) { + if (brdaddr == 0) { + syslog(LOG_ERR, "%s: (get dstaddr)", + sdl->sdl_data); + continue; + } + if (brdaddr->sa_family == AF_UNSPEC) { + lookforinterfaces = 1; + continue; } - ifs.int_dstaddr = ifreq.ifr_dstaddr; + ifs.int_dstaddr = *brdaddr; } - if (ifs.int_flags & IFF_BROADCAST) { - if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { - syslog(LOG_ERR, "ioctl (get broadaddr: %m"); - continue; - } - ifs.int_broadaddr = ifreq.ifr_broadaddr; + if (ifs.int_flags & IFF_BROADCAST) { + if (brdaddr == 0) { + syslog(LOG_ERR, "%s: (get broadaddr)", + sdl->sdl_data); + continue; + } + ifs.int_dstaddr = *brdaddr; } /* * already known to us? @@ -118,11 +191,13 @@ ifinit() if_ifwithaddr(&ifs.int_addr))) continue; /* no one cares about software loopback interfaces */ - if (strncmp(ifr->ifr_name,"lo", 2)==0) + if (ifs.int_flags & IFF_LOOPBACK) continue; - ifp = (struct interface *)malloc(sizeof (struct interface)); + ifp = (struct interface *) + malloc(sdl->sdl_nlen + 1 + sizeof(ifs)); if (ifp == 0) { - syslog(LOG_ERR,"XNSrouted: out of memory\n"); + syslog(LOG_ERR, "XNSrouted: out of memory\n"); + lookforinterfaces = 1; break; } *ifp = ifs; @@ -143,13 +218,9 @@ ifinit() */ if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0) supplier = 1; - ifp->int_name = malloc(strlen(ifr->ifr_name) + 1); - if (ifp->int_name == 0) { - syslog(LOG_ERR,"XNSrouted: out of memory\n"); - exit(1); - } - strcpy(ifp->int_name, ifr->ifr_name); - ifp->int_metric = 0; + ifp->int_name = (char *)(ifp + 1); + strcpy(ifp->int_name, sdl->sdl_data); + ifp->int_metric = ifam->ifam_metric; ifp->int_next = ifnet; ifnet = ifp; traceinit(ifp); @@ -157,7 +228,7 @@ ifinit() } if (externalinterfaces > 1 && supplier < 0) supplier = 1; - close(s); + free(buf); } addrouteforif(ifp)