1: /* 2: * Copyright (c) 1985 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * Includes material written at Cornell University by Bill Nesheim, 7: * by permission of the author. 8: */ 9: 10: 11: #ifndef lint 12: static char sccsid[] = "@(#)startup.c 5.5 (Berkeley) 2/14/86"; 13: #endif not lint 14: 15: /* 16: * Routing Table Management Daemon 17: */ 18: #include "defs.h" 19: #include <sys/ioctl.h> 20: #include <net/if.h> 21: #include <nlist.h> 22: #include <syslog.h> 23: 24: struct interface *ifnet; 25: int lookforinterfaces = 1; 26: int performnlist = 1; 27: int gateway = 0; 28: int externalinterfaces = 0; /* # of remote and local interfaces */ 29: char ether_broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 30: 31: 32: /* 33: * Find the network interfaces which have configured themselves. 34: * If the interface is present but not yet up (for example an 35: * ARPANET IMP), set the lookforinterfaces flag so we'll 36: * come back later and look again. 37: */ 38: ifinit() 39: { 40: struct interface ifs, *ifp; 41: int s, n; 42: struct ifconf ifc; 43: char buf[(sizeof (struct ifreq ) * 20)]; 44: struct ifreq ifreq, *ifr; 45: u_long i; 46: 47: if ((s = socket(AF_NS, SOCK_DGRAM, 0)) < 0) { 48: syslog(LOG_ERR, "socket: %m"); 49: exit(1); 50: } 51: ifc.ifc_len = sizeof (buf); 52: ifc.ifc_buf = buf; 53: if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { 54: syslog(LOG_ERR, "ioctl (get interface configuration)"); 55: close(s); 56: return (0); 57: } 58: ifr = ifc.ifc_req; 59: lookforinterfaces = 0; 60: for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifr++) { 61: bzero((char *)&ifs, sizeof(ifs)); 62: ifs.int_addr = ifr->ifr_addr; 63: ifreq = *ifr; 64: if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { 65: syslog(LOG_ERR, "ioctl (get interface flags)"); 66: continue; 67: } 68: ifs.int_flags = ifreq.ifr_flags | IFF_INTERFACE; 69: if ((ifs.int_flags & IFF_UP) == 0 || 70: ifr->ifr_addr.sa_family == AF_UNSPEC) { 71: lookforinterfaces = 1; 72: continue; 73: } 74: if (ifs.int_addr.sa_family != AF_NS) 75: continue; 76: if (ifs.int_flags & IFF_POINTOPOINT) { 77: if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) { 78: syslog(LOG_ERR, "ioctl (get dstaddr): %m"); 79: continue; 80: } 81: ifs.int_dstaddr = ifreq.ifr_dstaddr; 82: } 83: if (ifs.int_flags & IFF_BROADCAST) { 84: if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { 85: syslog(LOG_ERR, "ioctl (get broadaddr: %m"); 86: continue; 87: } 88: ifs.int_broadaddr = ifreq.ifr_broadaddr; 89: } 90: /* 91: * already known to us? 92: * what makes a POINTOPOINT if unique is its dst addr, 93: * NOT its source address 94: */ 95: if ( ((ifs.int_flags & IFF_POINTOPOINT) && 96: if_ifwithdstaddr(&ifs.int_dstaddr)) || 97: ( ((ifs.int_flags & IFF_POINTOPOINT) == 0) && 98: if_ifwithaddr(&ifs.int_addr))) 99: continue; 100: /* no one cares about software loopback interfaces */ 101: if (strncmp(ifr->ifr_name,"lo", 2)==0) 102: continue; 103: ifp = (struct interface *)malloc(sizeof (struct interface)); 104: if (ifp == 0) { 105: syslog(LOG_ERR,"XNSrouted: out of memory\n"); 106: break; 107: } 108: *ifp = ifs; 109: /* 110: * Count the # of directly connected networks 111: * and point to point links which aren't looped 112: * back to ourself. This is used below to 113: * decide if we should be a routing ``supplier''. 114: */ 115: if ((ifs.int_flags & IFF_POINTOPOINT) == 0 || 116: if_ifwithaddr(&ifs.int_dstaddr) == 0) 117: externalinterfaces++; 118: /* 119: * If we have a point-to-point link, we want to act 120: * as a supplier even if it's our only interface, 121: * as that's the only way our peer on the other end 122: * can tell that the link is up. 123: */ 124: if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0) 125: supplier = 1; 126: ifp->int_name = malloc(strlen(ifr->ifr_name) + 1); 127: if (ifp->int_name == 0) { 128: syslog(LOG_ERR,"XNSrouted: out of memory\n"); 129: goto bad; /* ??? */ 130: } 131: strcpy(ifp->int_name, ifr->ifr_name); 132: ifp->int_metric = 0; 133: ifp->int_next = ifnet; 134: ifnet = ifp; 135: traceinit(ifp); 136: addrouteforif(ifp); 137: } 138: if (externalinterfaces > 1 && supplier < 0) 139: supplier = 1; 140: close(s); 141: return; 142: bad: 143: sleep(60); 144: close(s); 145: sleep(60); 146: execv("/etc/XNSrouted", argv0); 147: _exit(0177); 148: } 149: 150: addrouteforif(ifp) 151: struct interface *ifp; 152: { 153: struct sockaddr_ns net; 154: struct sockaddr *dst; 155: int state, metric; 156: struct rt_entry *rt; 157: 158: if (ifp->int_flags & IFF_POINTOPOINT) { 159: int (*match)(); 160: register struct interface *ifp2 = ifnet; 161: register struct interface *ifprev = ifnet; 162: 163: dst = &ifp->int_dstaddr; 164: 165: /* Search for interfaces with the same net */ 166: ifp->int_sq.n = ifp->int_sq.p = &(ifp->int_sq); 167: match = afswitch[dst->sa_family].af_netmatch; 168: if (match) 169: for (ifp2 = ifnet; ifp2; ifp2 =ifp2->int_next) { 170: if (ifp->int_flags & IFF_POINTOPOINT == 0) 171: continue; 172: if ((*match)(&ifp2->int_dstaddr,&ifp->int_dstaddr)) { 173: insque(&ifp2->int_sq,&ifp->int_sq); 174: break; 175: } 176: } 177: } else { 178: dst = &ifp->int_broadaddr; 179: } 180: rt = rtlookup(dst); 181: if (rt) 182: rtdelete(rt); 183: if (tracing) 184: fprintf(stderr, "Adding route to interface %s\n", ifp->int_name); 185: if (ifp->int_transitions++ > 0) 186: syslog(LOG_ERR, "re-installing interface %s", ifp->int_name); 187: rtadd(dst, &ifp->int_addr, ifp->int_metric, 188: ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE)); 189: }