|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This file includes significant work done at Cornell University by ! 6: * Bill Nesheim. That work included by permission. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted ! 9: * provided that: (1) source distributions retain this entire copyright ! 10: * notice and comment, and (2) distributions including binaries display ! 11: * the following acknowledgement: ``This product includes software ! 12: * developed by the University of California, Berkeley and its contributors'' ! 13: * in the documentation or other materials provided with the distribution ! 14: * and in all advertising materials mentioning features or use of this ! 15: * software. Neither the name of the University nor the names of its ! 16: * contributors may be used to endorse or promote products derived ! 17: * from this software without specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: static char sccsid[] = "@(#)startup.c 5.9 (Berkeley) 6/1/90"; ! 25: #endif /* not lint */ ! 26: ! 27: /* ! 28: * Routing Table Management Daemon ! 29: */ ! 30: #include "defs.h" ! 31: #include <sys/ioctl.h> ! 32: #include <net/if.h> ! 33: #include <nlist.h> ! 34: #include <syslog.h> ! 35: ! 36: struct interface *ifnet; ! 37: int lookforinterfaces = 1; ! 38: int performnlist = 1; ! 39: int gateway = 0; ! 40: int externalinterfaces = 0; /* # of remote and local interfaces */ ! 41: char ether_broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ! 42: ! 43: ! 44: /* ! 45: * Find the network interfaces which have configured themselves. ! 46: * If the interface is present but not yet up (for example an ! 47: * ARPANET IMP), set the lookforinterfaces flag so we'll ! 48: * come back later and look again. ! 49: */ ! 50: ifinit() ! 51: { ! 52: struct interface ifs, *ifp; ! 53: int s; ! 54: struct ifconf ifc; ! 55: char buf[BUFSIZ], *cp, *cplim; ! 56: struct ifreq ifreq, *ifr; ! 57: u_long i; ! 58: ! 59: if ((s = socket(AF_NS, SOCK_DGRAM, 0)) < 0) { ! 60: syslog(LOG_ERR, "socket: %m"); ! 61: exit(1); ! 62: } ! 63: ifc.ifc_len = sizeof (buf); ! 64: ifc.ifc_buf = buf; ! 65: if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { ! 66: syslog(LOG_ERR, "ioctl (get interface configuration)"); ! 67: close(s); ! 68: exit(1); ! 69: } ! 70: ifr = ifc.ifc_req; ! 71: lookforinterfaces = 0; ! 72: #ifdef RTM_ADD ! 73: #define max(a, b) (a > b ? a : b) ! 74: #define size(p) max((p).sa_len, sizeof(p)) ! 75: #else ! 76: #define size(p) (sizeof (p)) ! 77: #endif ! 78: cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */ ! 79: for (cp = buf; cp < cplim; ! 80: cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) { ! 81: bzero((char *)&ifs, sizeof(ifs)); ! 82: ifs.int_addr = ifr->ifr_addr; ! 83: ifreq = *ifr; ! 84: if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { ! 85: syslog(LOG_ERR, "ioctl (get interface flags)"); ! 86: continue; ! 87: } ! 88: ifs.int_flags = ifreq.ifr_flags | IFF_INTERFACE; ! 89: if ((ifs.int_flags & IFF_UP) == 0 || ! 90: ifr->ifr_addr.sa_family == AF_UNSPEC) { ! 91: lookforinterfaces = 1; ! 92: continue; ! 93: } ! 94: if (ifs.int_addr.sa_family != AF_NS) ! 95: continue; ! 96: if (ifs.int_flags & IFF_POINTOPOINT) { ! 97: if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) { ! 98: syslog(LOG_ERR, "ioctl (get dstaddr): %m"); ! 99: continue; ! 100: } ! 101: ifs.int_dstaddr = ifreq.ifr_dstaddr; ! 102: } ! 103: if (ifs.int_flags & IFF_BROADCAST) { ! 104: if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { ! 105: syslog(LOG_ERR, "ioctl (get broadaddr: %m"); ! 106: continue; ! 107: } ! 108: ifs.int_broadaddr = ifreq.ifr_broadaddr; ! 109: } ! 110: /* ! 111: * already known to us? ! 112: * what makes a POINTOPOINT if unique is its dst addr, ! 113: * NOT its source address ! 114: */ ! 115: if ( ((ifs.int_flags & IFF_POINTOPOINT) && ! 116: if_ifwithdstaddr(&ifs.int_dstaddr)) || ! 117: ( ((ifs.int_flags & IFF_POINTOPOINT) == 0) && ! 118: if_ifwithaddr(&ifs.int_addr))) ! 119: continue; ! 120: /* no one cares about software loopback interfaces */ ! 121: if (strncmp(ifr->ifr_name,"lo", 2)==0) ! 122: continue; ! 123: ifp = (struct interface *)malloc(sizeof (struct interface)); ! 124: if (ifp == 0) { ! 125: syslog(LOG_ERR,"XNSrouted: out of memory\n"); ! 126: break; ! 127: } ! 128: *ifp = ifs; ! 129: /* ! 130: * Count the # of directly connected networks ! 131: * and point to point links which aren't looped ! 132: * back to ourself. This is used below to ! 133: * decide if we should be a routing ``supplier''. ! 134: */ ! 135: if ((ifs.int_flags & IFF_POINTOPOINT) == 0 || ! 136: if_ifwithaddr(&ifs.int_dstaddr) == 0) ! 137: externalinterfaces++; ! 138: /* ! 139: * If we have a point-to-point link, we want to act ! 140: * as a supplier even if it's our only interface, ! 141: * as that's the only way our peer on the other end ! 142: * can tell that the link is up. ! 143: */ ! 144: if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0) ! 145: supplier = 1; ! 146: ifp->int_name = malloc(strlen(ifr->ifr_name) + 1); ! 147: if (ifp->int_name == 0) { ! 148: syslog(LOG_ERR,"XNSrouted: out of memory\n"); ! 149: exit(1); ! 150: } ! 151: strcpy(ifp->int_name, ifr->ifr_name); ! 152: ifp->int_metric = 0; ! 153: ifp->int_next = ifnet; ! 154: ifnet = ifp; ! 155: traceinit(ifp); ! 156: addrouteforif(ifp); ! 157: } ! 158: if (externalinterfaces > 1 && supplier < 0) ! 159: supplier = 1; ! 160: close(s); ! 161: } ! 162: ! 163: addrouteforif(ifp) ! 164: struct interface *ifp; ! 165: { ! 166: struct sockaddr_ns net; ! 167: struct sockaddr *dst; ! 168: int state, metric; ! 169: struct rt_entry *rt; ! 170: ! 171: if (ifp->int_flags & IFF_POINTOPOINT) { ! 172: int (*match)(); ! 173: register struct interface *ifp2 = ifnet; ! 174: register struct interface *ifprev = ifnet; ! 175: ! 176: dst = &ifp->int_dstaddr; ! 177: ! 178: /* Search for interfaces with the same net */ ! 179: ifp->int_sq.n = ifp->int_sq.p = &(ifp->int_sq); ! 180: match = afswitch[dst->sa_family].af_netmatch; ! 181: if (match) ! 182: for (ifp2 = ifnet; ifp2; ifp2 =ifp2->int_next) { ! 183: if (ifp->int_flags & IFF_POINTOPOINT == 0) ! 184: continue; ! 185: if ((*match)(&ifp2->int_dstaddr,&ifp->int_dstaddr)) { ! 186: insque(&ifp2->int_sq,&ifp->int_sq); ! 187: break; ! 188: } ! 189: } ! 190: } else { ! 191: dst = &ifp->int_broadaddr; ! 192: } ! 193: rt = rtlookup(dst); ! 194: if (rt) ! 195: rtdelete(rt); ! 196: if (tracing) ! 197: fprintf(stderr, "Adding route to interface %s\n", ifp->int_name); ! 198: if (ifp->int_transitions++ > 0) ! 199: syslog(LOG_ERR, "re-installing interface %s", ifp->int_name); ! 200: rtadd(dst, &ifp->int_addr, ifp->int_metric, ! 201: ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE)); ! 202: } ! 203:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.