|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)startup.c 4.4 (Berkeley) 5/25/83"; ! 3: #endif ! 4: ! 5: /* ! 6: * Routing Table Management Daemon ! 7: */ ! 8: #include "defs.h" ! 9: #include <net/if.h> ! 10: #include <nlist.h> ! 11: ! 12: struct interface *ifnet; ! 13: int kmem = -1; ! 14: int lookforinterfaces = 1; ! 15: int performnlist = 1; ! 16: int externalinterfaces = 0; /* # of remote and local interfaces */ ! 17: ! 18: struct nlist nl[] = { ! 19: #define N_IFNET 0 ! 20: { "_ifnet" }, ! 21: { "" }, ! 22: }; ! 23: ! 24: /* ! 25: * Changes: ! 26: * . from Usenet: mask out internal flags when setting ! 27: * IFF_INTERFACE flag. ! 28: */ ! 29: /* ! 30: * Probe the kernel through /dev/kmem to find the network ! 31: * interfaces which have configured themselves. If the ! 32: * interface is present but not yet up (for example an ! 33: * ARPANET IMP), set the lookforinterfaces flag so we'll ! 34: * come back later and look again. ! 35: */ ! 36: ifinit() ! 37: { ! 38: struct interface *ifp; ! 39: struct ifnet ifs, *next; ! 40: char name[32], *cp, *index(); ! 41: ! 42: if (performnlist) { ! 43: nlist("/vmunix", nl); ! 44: if (nl[N_IFNET].n_value == 0) { ! 45: printf("ifnet: not in namelist\n"); ! 46: goto bad; ! 47: } ! 48: performnlist = 0; ! 49: } ! 50: if (kmem < 0) { ! 51: kmem = open("/dev/kmem", 0); ! 52: if (kmem < 0) { ! 53: perror("/dev/kmem"); ! 54: goto bad; ! 55: } ! 56: } ! 57: if (lseek(kmem, (long)nl[N_IFNET].n_value, 0) == -1 || ! 58: read(kmem, (char *)&next, sizeof (next)) != sizeof (next)) { ! 59: printf("ifnet: error reading kmem\n"); ! 60: goto bad; ! 61: } ! 62: lookforinterfaces = 0; ! 63: while (next) { ! 64: if (lseek(kmem, (long)next, 0) == -1 || ! 65: read(kmem, (char *)&ifs, sizeof (ifs)) != sizeof (ifs)) { ! 66: perror("read"); ! 67: goto bad; ! 68: } ! 69: next = ifs.if_next; ! 70: if ((ifs.if_flags & IFF_UP) == 0) { ! 71: lookforinterfaces = 1; ! 72: continue; ! 73: } ! 74: /* already known to us? */ ! 75: if (if_ifwithaddr(&ifs.if_addr)) ! 76: continue; ! 77: /* argh, this'll have to change sometime */ ! 78: if (ifs.if_addr.sa_family != AF_INET) ! 79: continue; ! 80: /* no one cares about software loopback interfaces */ ! 81: if (ifs.if_net == LOOPBACKNET) ! 82: continue; ! 83: ifp = (struct interface *)malloc(sizeof (struct interface)); ! 84: if (ifp == 0) { ! 85: printf("routed: out of memory\n"); ! 86: break; ! 87: } ! 88: /* ! 89: * Count the # of directly connected networks ! 90: * and point to point links which aren't looped ! 91: * back to ourself. This is used below to ! 92: * decide if we should be a routing ``supplier''. ! 93: */ ! 94: if ((ifs.if_flags & IFF_POINTOPOINT) == 0 || ! 95: if_ifwithaddr(&ifs.if_dstaddr) == 0) ! 96: externalinterfaces++; ! 97: lseek(kmem, ifs.if_name, 0); ! 98: read(kmem, name, sizeof (name)); ! 99: name[sizeof (name) - 1] = '\0'; ! 100: cp = index(name, '\0'); ! 101: *cp++ = ifs.if_unit + '0'; ! 102: *cp = '\0'; ! 103: ifp->int_name = malloc(strlen(name) + 1); ! 104: if (ifp->int_name == 0) { ! 105: fprintf(stderr, "routed: ifinit: out of memory\n"); ! 106: goto bad; /* ??? */ ! 107: } ! 108: strcpy(ifp->int_name, name); ! 109: ifp->int_addr = ifs.if_addr; ! 110: ifp->int_flags = (ifs.if_flags & 0x1f)| IFF_INTERFACE; ! 111: /* this works because broadaddr overlaps dstaddr */ ! 112: ifp->int_broadaddr = ifs.if_broadaddr; ! 113: ifp->int_net = ifs.if_net; ! 114: ifp->int_metric = 0; ! 115: ifp->int_next = ifnet; ! 116: ifnet = ifp; ! 117: traceinit(ifp); ! 118: addrouteforif(ifp); ! 119: } ! 120: if (externalinterfaces > 1 && supplier < 0) ! 121: supplier = 1; ! 122: return; ! 123: bad: ! 124: sleep(60); ! 125: close(kmem), close(s); ! 126: execv("/etc/routed", argv0); ! 127: _exit(0177); ! 128: } ! 129: ! 130: addrouteforif(ifp) ! 131: struct interface *ifp; ! 132: { ! 133: struct sockaddr_in net; ! 134: struct sockaddr *dst; ! 135: int state, metric; ! 136: struct rt_entry *rt; ! 137: ! 138: if (ifp->int_flags & IFF_POINTOPOINT) ! 139: dst = &ifp->int_dstaddr; ! 140: else { ! 141: bzero((char *)&net, sizeof (net)); ! 142: net.sin_family = AF_INET; ! 143: net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY); ! 144: dst = (struct sockaddr *)&net; ! 145: } ! 146: rt = rtlookup(dst); ! 147: rtadd(dst, &ifp->int_addr, ifp->int_metric, ! 148: ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE)); ! 149: if (rt) ! 150: rtdelete(rt); ! 151: } ! 152: ! 153: /* ! 154: * As a concession to the ARPANET we read a list of gateways ! 155: * from /etc/gateways and add them to our tables. This file ! 156: * exists at each ARPANET gateway and indicates a set of ``remote'' ! 157: * gateways (i.e. a gateway which we can't immediately determine ! 158: * if it's present or not as we can do for those directly connected ! 159: * at the hardware level). If a gateway is marked ``passive'' ! 160: * in the file, then we assume it doesn't have a routing process ! 161: * of our design and simply assume it's always present. Those ! 162: * not marked passive are treated as if they were directly ! 163: * connected -- they're added into the interface list so we'll ! 164: * send them routing updates. ! 165: */ ! 166: gwkludge() ! 167: { ! 168: struct sockaddr_in dst, gate; ! 169: FILE *fp; ! 170: char *type, *dname, *gname, *qual, buf[BUFSIZ]; ! 171: struct interface *ifp; ! 172: int metric; ! 173: ! 174: fp = fopen("/etc/gateways", "r"); ! 175: if (fp == NULL) ! 176: return; ! 177: qual = buf; ! 178: dname = buf + 64; ! 179: gname = buf + ((BUFSIZ - 64) / 3); ! 180: type = buf + (((BUFSIZ - 64) * 2) / 3); ! 181: bzero((char *)&dst, sizeof (dst)); ! 182: bzero((char *)&gate, sizeof (gate)); ! 183: /* format: {net | host} XX gateway XX metric DD [passive]\n */ ! 184: #define readentry(fp) \ ! 185: fscanf((fp), "%s %s gateway %s metric %d %s\n", \ ! 186: type, dname, gname, &metric, qual) ! 187: for (;;) { ! 188: if (readentry(fp) == EOF) ! 189: break; ! 190: if (!getnetorhostname(type, dname, &dst)) ! 191: continue; ! 192: if (!gethostnameornumber(gname, &gate)) ! 193: continue; ! 194: ifp = (struct interface *)malloc(sizeof (*ifp)); ! 195: bzero((char *)ifp, sizeof (*ifp)); ! 196: ifp->int_flags = IFF_REMOTE; ! 197: /* can't identify broadcast capability */ ! 198: ifp->int_net = inet_netof(dst.sin_addr); ! 199: if (strcmp(type, "host") == 0) { ! 200: ifp->int_flags |= IFF_POINTOPOINT; ! 201: ifp->int_dstaddr = *((struct sockaddr *)&dst); ! 202: } ! 203: if (strcmp(qual, "passive") == 0) ! 204: ifp->int_flags |= IFF_PASSIVE; ! 205: else ! 206: /* assume no duplicate entries */ ! 207: externalinterfaces++; ! 208: ifp->int_addr = *((struct sockaddr *)&gate); ! 209: ifp->int_metric = metric; ! 210: ifp->int_next = ifnet; ! 211: ifnet = ifp; ! 212: addrouteforif(ifp); ! 213: } ! 214: fclose(fp); ! 215: } ! 216: ! 217: getnetorhostname(type, name, sin) ! 218: char *type, *name; ! 219: struct sockaddr_in *sin; ! 220: { ! 221: ! 222: if (strcmp(type, "net") == 0) { ! 223: struct netent *np = getnetbyname(name); ! 224: int n; ! 225: ! 226: if (np == 0) ! 227: n = inet_network(name); ! 228: else { ! 229: if (np->n_addrtype != AF_INET) ! 230: return (0); ! 231: n = np->n_net; ! 232: } ! 233: sin->sin_family = AF_INET; ! 234: sin->sin_addr = inet_makeaddr(n, INADDR_ANY); ! 235: return (1); ! 236: } ! 237: if (strcmp(type, "host") == 0) { ! 238: struct hostent *hp = gethostbyname(name); ! 239: ! 240: if (hp == 0) ! 241: sin->sin_addr.s_addr = inet_addr(name); ! 242: else { ! 243: if (hp->h_addrtype != AF_INET) ! 244: return (0); ! 245: bcopy(hp->h_addr, &sin->sin_addr, hp->h_length); ! 246: } ! 247: sin->sin_family = AF_INET; ! 248: return (1); ! 249: } ! 250: return (0); ! 251: } ! 252: ! 253: gethostnameornumber(name, sin) ! 254: char *name; ! 255: struct sockaddr_in *sin; ! 256: { ! 257: struct hostent *hp; ! 258: ! 259: hp = gethostbyname(name); ! 260: if (hp) { ! 261: bcopy(hp->h_addr, &sin->sin_addr, hp->h_length); ! 262: sin->sin_family = hp->h_addrtype; ! 263: return (1); ! 264: } ! 265: sin->sin_addr.s_addr = inet_addr(name); ! 266: sin->sin_family = AF_INET; ! 267: return (sin->sin_addr.s_addr != -1); ! 268: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.