|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)htable.c 4.7 (Berkeley) 11/3/83"; ! 3: #endif ! 4: ! 5: /* ! 6: * htable - convert NIC host table into a UNIX format. ! 7: * NIC format is described in RFC 810, 1 March 1982. ! 8: */ ! 9: #include <stdio.h> ! 10: #include <ctype.h> ! 11: #include <errno.h> ! 12: #include <netdb.h> ! 13: ! 14: #include "htable.h" /* includes <sys/types.h> */ ! 15: ! 16: #include <sys/socket.h> ! 17: #include <netinet/in.h> ! 18: ! 19: #define DATELINES 3 /* these lines usually contain the date */ ! 20: #define MAXNETS 30 /* array size for local, connected nets */ ! 21: ! 22: FILE *hf; /* hosts file */ ! 23: FILE *gf; /* gateways file */ ! 24: FILE *nf; /* networks file */ ! 25: struct gateway *savegateway(), *gatewayto(); ! 26: ! 27: int connected_nets[MAXNETS]; ! 28: int nconnected; ! 29: int local_nets[MAXNETS]; ! 30: int nlocal; ! 31: char *myname; ! 32: ! 33: main(argc, argv) ! 34: int argc; ! 35: char *argv[]; ! 36: { ! 37: int errs; ! 38: ! 39: infile = "(stdin)"; ! 40: myname = argv[0]; ! 41: argc--; ! 42: argv++; ! 43: while (argc--) { ! 44: if (*argv[0] == '-') { ! 45: switch (argv[0][1]) { ! 46: case 'c': ! 47: nconnected = addlocal(argv[1], connected_nets); ! 48: argv++; ! 49: argc--; ! 50: break; ! 51: case 'l': ! 52: nlocal = addlocal(argv[1], local_nets); ! 53: argv++; ! 54: argc--; ! 55: break; ! 56: default: ! 57: usage(); ! 58: /*NOTREACHED*/ ! 59: } ! 60: } else { ! 61: infile = argv[0]; ! 62: if (freopen(infile, "r", stdin) == NULL) { ! 63: perror(infile); ! 64: exit(1); ! 65: } ! 66: } ! 67: argv++; ! 68: } ! 69: hf = fopen("hosts", "w"); ! 70: if (hf == NULL) { ! 71: perror("hosts"); ! 72: exit(1); ! 73: } ! 74: copylocal(hf, "localhosts"); ! 75: gf = fopen("gateways", "w"); ! 76: if (gf == NULL) { ! 77: perror("gateways"); ! 78: exit(1); ! 79: } ! 80: copygateways(gf, "localgateways"); ! 81: nf = fopen("networks", "w"); ! 82: if (nf == NULL) { ! 83: perror("networks"); ! 84: exit(1); ! 85: } ! 86: copylocal(nf, "localnetworks"); ! 87: copycomments(stdin, hf, DATELINES); ! 88: errs = yyparse(); ! 89: dogateways(); ! 90: exit(errs); ! 91: } ! 92: ! 93: usage() ! 94: { ! 95: fprintf(stderr, ! 96: "usage: %s [ -c connected-nets ] [-l local-nets ] [ input-file ]\n", ! 97: myname); ! 98: exit(1); ! 99: } ! 100: ! 101: /* ! 102: * Turn a comma-separated list of network names or numbers in dot notation ! 103: * (e.g. "arpanet, 128.32") into an array of net numbers. ! 104: */ ! 105: addlocal(arg, nets) ! 106: char *arg; ! 107: int *nets; ! 108: { ! 109: register char *p, c; ! 110: register int nfound = 0; ! 111: ! 112: do { ! 113: p = arg; ! 114: while (*p && *p != ',' && !isspace(*p)) ! 115: p++; ! 116: c = *p; ! 117: *p = 0; ! 118: while (*arg && isspace(*arg)) ! 119: arg++; ! 120: if (*arg == 0) ! 121: continue; ! 122: if (nfound == MAXNETS) { ! 123: fprintf(stderr, "%s: Too many networks in list\n", ! 124: myname); ! 125: return (nfound); ! 126: } ! 127: if (getnetaddr(arg, &nets[nfound])) ! 128: nfound++; ! 129: else { ! 130: fprintf(stderr, "%s: %s: unknown network\n", ! 131: myname, arg); ! 132: exit(1); ! 133: } ! 134: arg = p + 1; ! 135: } while (c); ! 136: return (nfound); ! 137: } ! 138: ! 139: struct name * ! 140: newname(str) ! 141: char *str; ! 142: { ! 143: char *p; ! 144: struct name *nm; ! 145: ! 146: p = malloc(strlen(str) + 1); ! 147: strcpy(p, str); ! 148: nm = (struct name *)malloc(sizeof (struct name)); ! 149: nm->name_val = p; ! 150: nm->name_link = NONAME; ! 151: return (nm); ! 152: } ! 153: ! 154: char * ! 155: lower(str) ! 156: char *str; ! 157: { ! 158: register char *cp = str; ! 159: ! 160: while (*cp) { ! 161: if (isupper(*cp)) ! 162: *cp = tolower(*cp); ! 163: cp++; ! 164: } ! 165: return (str); ! 166: } ! 167: ! 168: do_entry(keyword, addrlist, namelist, cputype, opsys, protos) ! 169: int keyword; ! 170: struct addr *addrlist; ! 171: struct name *namelist, *cputype, *opsys, *protos; ! 172: { ! 173: register struct addr *al, *al2; ! 174: register struct name *nl; ! 175: struct addr *connect_addr; ! 176: char *cp; ! 177: ! 178: switch (keyword) { ! 179: ! 180: case KW_NET: ! 181: nl = namelist; ! 182: if (nl == NONAME) { ! 183: fprintf(stderr, "htable: net"); ! 184: putnet(stderr, addrlist->addr_val); ! 185: fprintf(stderr, " missing names.\n"); ! 186: break; ! 187: } ! 188: fprintf(nf, "%-16.16s", lower(nl->name_val)); ! 189: al2 = addrlist; ! 190: while (al = al2) { ! 191: char *cp; ! 192: ! 193: putnet(nf, al->addr_val); ! 194: cp = "\t%s"; ! 195: while (nl = nl->name_link) { ! 196: fprintf(nf, cp, lower(nl->name_val)); ! 197: cp = " %s"; ! 198: } ! 199: putc('\n', nf); ! 200: al2 = al->addr_link; ! 201: free((char *)al); ! 202: } ! 203: break; ! 204: ! 205: case KW_GATEWAY: ! 206: /* locate locally connected address, if one */ ! 207: for (al = addrlist; al; al = al->addr_link) ! 208: if (connectedto(inet_netof(al->addr_val))) ! 209: break; ! 210: if (al == NULL) { ! 211: /* ! 212: * Not connected to known networks. Save for later. ! 213: */ ! 214: struct gateway *gw, *firstgw = (struct gateway *) NULL; ! 215: ! 216: for (al = addrlist; al; al = al->addr_link) { ! 217: register int net; ! 218: ! 219: net = inet_netof(al->addr_val); ! 220: gw = savegateway(namelist, net, ! 221: al->addr_val, 0); ! 222: if (firstgw == (struct gateway *) NULL) ! 223: firstgw = gw; ! 224: gw->g_firstent = firstgw; ! 225: } ! 226: freeaddrs(addrlist); ! 227: goto dontfree; ! 228: } ! 229: /* ! 230: * Connected to a known network. ! 231: * Mark this as the gateway to all other networks ! 232: * that are on the addrlist (unless we already have ! 233: * gateways to them). ! 234: */ ! 235: connect_addr = al; ! 236: for (al = addrlist; al; al = al->addr_link) { ! 237: register int net; ! 238: ! 239: if (al == connect_addr) ! 240: continue; ! 241: /* suppress duplicates -- not optimal */ ! 242: net = inet_netof(al->addr_val); ! 243: if (gatewayto(net)) ! 244: continue; ! 245: printgateway(net, namelist->name_val, 1); ! 246: (void) savegateway(namelist, net, al->addr_val, 1); ! 247: } ! 248: /* ! 249: * Put the gateway in the hosts file. ! 250: */ ! 251: putaddr(hf, connect_addr->addr_val); ! 252: cp = "%s"; ! 253: for (nl = namelist; nl; nl = nl->name_link) { ! 254: fprintf(hf, cp, lower(nl->name_val)); ! 255: cp = " %s"; ! 256: } ! 257: fprintf(hf, "\t# gateway\n"); ! 258: freeaddrs(addrlist); ! 259: goto dontfree; ! 260: ! 261: case KW_HOST: ! 262: al2 = addrlist; ! 263: while (al = al2) { ! 264: if (!local(inet_netof(al->addr_val))) { ! 265: char *cp; ! 266: ! 267: putaddr(hf, al->addr_val); ! 268: cp = "%s"; ! 269: for (nl = namelist; nl; nl = nl->name_link) { ! 270: fprintf(hf, cp, lower(nl->name_val)); ! 271: cp = " %s"; ! 272: } ! 273: putc('\n', hf); ! 274: } ! 275: al2 = al->addr_link; ! 276: free((char *)al); ! 277: } ! 278: break; ! 279: ! 280: default: ! 281: fprintf(stderr, "Unknown keyword: %d.\n", keyword); ! 282: } ! 283: freenames(namelist); ! 284: dontfree: ! 285: freenames(protos); ! 286: } ! 287: ! 288: printgateway(net, name, metric) ! 289: int net; ! 290: char *name; ! 291: int metric; ! 292: { ! 293: struct netent *np; ! 294: ! 295: fprintf(gf, "net "); ! 296: np = getnetbyaddr(net, AF_INET); ! 297: if (np) ! 298: fprintf(gf, "%s", np->n_name); ! 299: else ! 300: putnet(gf, net); ! 301: fprintf(gf, " gateway %s metric %d passive\n", ! 302: lower(name), metric); ! 303: } ! 304: ! 305: copylocal(f, filename) ! 306: FILE *f; ! 307: char *filename; ! 308: { ! 309: register FILE *lhf; ! 310: register cc; ! 311: char buf[BUFSIZ]; ! 312: extern int errno; ! 313: ! 314: lhf = fopen(filename, "r"); ! 315: if (lhf == NULL) { ! 316: if (errno != ENOENT) { ! 317: perror(filename); ! 318: exit(1); ! 319: } ! 320: fprintf(stderr, "Warning, no %s file.\n", filename); ! 321: return; ! 322: } ! 323: while (cc = fread(buf, 1, sizeof(buf), lhf)) ! 324: fwrite(buf, 1, cc, f); ! 325: fclose(lhf); ! 326: } ! 327: ! 328: copygateways(f, filename) ! 329: FILE *f; ! 330: char *filename; ! 331: { ! 332: register FILE *lhf; ! 333: register cc; ! 334: struct name *nl; ! 335: char type[80]; ! 336: char dname[80]; ! 337: char gname[80]; ! 338: char junk[80]; ! 339: u_long addr; ! 340: int net, metric; ! 341: extern int errno; ! 342: ! 343: lhf = fopen(filename, "r"); ! 344: if (lhf == NULL) { ! 345: if (errno != ENOENT) { ! 346: perror(filename); ! 347: exit(1); ! 348: } ! 349: fprintf(stderr, "Warning, no %s file.\n", filename); ! 350: return; ! 351: } ! 352: /* format: {net | host} XX gateway XX metric DD [passive]\n */ ! 353: #define readentry(fp) \ ! 354: fscanf((fp), "%s %s gateway %s metric %d %s\n", \ ! 355: type, dname, gname, &metric, junk) ! 356: while (readentry(lhf) != EOF) { ! 357: if (strcmp(type, "net")) ! 358: goto dumpit; ! 359: if (!getnetaddr(dname, &net)) ! 360: goto dumpit; ! 361: if (!gethostaddr(gname, &addr)) ! 362: goto dumpit; ! 363: nl = newname(gname); ! 364: (void) savegateway(nl, net, addr, metric); ! 365: dumpit: ! 366: fprintf(gf, "%s %s gateway %s metric %d %s\n", ! 367: type, dname, gname, metric, junk); ! 368: } ! 369: fclose(lhf); ! 370: } ! 371: ! 372: getnetaddr(name, addr) ! 373: char *name; ! 374: int *addr; ! 375: { ! 376: struct netent *np = getnetbyname(name); ! 377: int n; ! 378: ! 379: if (np == 0) { ! 380: *addr = inet_network(name); ! 381: return (*addr != -1); ! 382: } else { ! 383: if (np->n_addrtype != AF_INET) ! 384: return (0); ! 385: *addr = np->n_net; ! 386: return (1); ! 387: } ! 388: } ! 389: ! 390: gethostaddr(name, addr) ! 391: char *name; ! 392: u_long *addr; ! 393: { ! 394: struct hostent *hp; ! 395: ! 396: hp = gethostbyname(name); ! 397: if (hp) { ! 398: *addr = *(u_long *)(hp->h_addr); ! 399: return (1); ! 400: } ! 401: *addr = inet_addr(name); ! 402: return (*addr != -1); ! 403: } ! 404: ! 405: copycomments(in, out, ccount) ! 406: FILE *in, *out; ! 407: int ccount; ! 408: { ! 409: char buf[BUFSIZ]; ! 410: int length; ! 411: int count; ! 412: char *fgets(); ! 413: ! 414: for (count=0; count < ccount; count++) { ! 415: if ((fgets(buf, sizeof(buf), in) == NULL) || (buf[0] != ';')) ! 416: return; ! 417: buf[0] = '#'; ! 418: fputs(buf, out); ! 419: } ! 420: return; ! 421: } ! 422: #define UC(b) (((int)(b))&0xff) ! 423: ! 424: putnet(f, v) ! 425: FILE *f; ! 426: u_long v; ! 427: { ! 428: register char *a = (char *)&v; ! 429: ! 430: if (UC(a[0]&0x80) == 0) ! 431: fprintf(f, "%d", UC(a[0])); ! 432: else if ((UC(a[0])&0x40) == 0) ! 433: fprintf(f, "%d.%d", UC(a[0]), UC(a[1])); ! 434: else ! 435: fprintf(f, "%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2])); ! 436: } ! 437: ! 438: putaddr(f, v) ! 439: FILE *f; ! 440: u_long v; ! 441: { ! 442: register char *a = (char *)&v; ! 443: char buf[32]; ! 444: ! 445: sprintf(buf,"%d.%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3])); ! 446: fprintf(f, "%-16.16s", buf); ! 447: } ! 448: ! 449: freenames(list) ! 450: struct name *list; ! 451: { ! 452: register struct name *nl, *nl2; ! 453: ! 454: nl2 = list; ! 455: while (nl = nl2) { ! 456: nl2 = nl->name_link; ! 457: free(nl->name_val); ! 458: free((char *)nl); ! 459: } ! 460: } ! 461: ! 462: freeaddrs(list) ! 463: struct addr *list; ! 464: { ! 465: register struct addr *al, *al2; ! 466: ! 467: al2 = list; ! 468: while (al = al2) ! 469: al2 = al->addr_link, free((char *)al); ! 470: } ! 471: ! 472: struct gateway *gateways = 0; ! 473: struct gateway *lastgateway = 0; ! 474: ! 475: struct gateway * ! 476: gatewayto(net) ! 477: register int net; ! 478: { ! 479: register struct gateway *gp; ! 480: ! 481: for (gp = gateways; gp; gp = gp->g_link) ! 482: if ((gp->g_net == net) && (gp->g_metric > 0)) ! 483: return (gp); ! 484: return ((struct gateway *) NULL); ! 485: } ! 486: ! 487: struct gateway * ! 488: savegateway(namelist, net, addr, metric) ! 489: struct name *namelist; ! 490: u_long addr; ! 491: int net, metric; ! 492: { ! 493: register struct gateway *gp; ! 494: ! 495: gp = (struct gateway *)malloc(sizeof (struct gateway)); ! 496: if (gp == 0) { ! 497: fprintf(stderr, "htable: out of memory\n"); ! 498: exit(1); ! 499: } ! 500: gp->g_link = (struct gateway *) NULL; ! 501: if (lastgateway) ! 502: lastgateway->g_link = gp; ! 503: else ! 504: gateways = gp; ! 505: lastgateway = gp; ! 506: gp->g_name = namelist; ! 507: gp->g_net = net; ! 508: gp->g_addr = addr; ! 509: gp->g_metric = metric; ! 510: if (metric == 1) ! 511: gp->g_dst = gp; ! 512: } ! 513: ! 514: connectedto(net) ! 515: u_long net; ! 516: { ! 517: register i; ! 518: ! 519: for (i = 0; i < nconnected; i++) ! 520: if (connected_nets[i] == net) ! 521: return(1); ! 522: return(0); ! 523: } ! 524: ! 525: local(net) ! 526: u_long net; ! 527: { ! 528: register i; ! 529: ! 530: for (i = 0; i < nlocal; i++) ! 531: if (local_nets[i] == net) ! 532: return(1); ! 533: return(0); ! 534: } ! 535: ! 536: #define MAXHOPS 10 ! 537: ! 538: /* ! 539: * Go through list of gateways, finding connections for gateways ! 540: * that are not yet connected. ! 541: */ ! 542: dogateways() ! 543: { ! 544: register struct gateway *gp, *gw, *ggp; ! 545: register int hops, changed = 1; ! 546: struct name *nl; ! 547: char *cp; ! 548: ! 549: for (hops = 0; hops < MAXHOPS && changed; hops++, changed = 0) { ! 550: for (gp = gateways; gp; gp = gp->g_link) ! 551: if ((gp->g_metric == 0) && (gw = gatewayto(gp->g_net))) { ! 552: /* ! 553: * Found a new connection. ! 554: * For each other network that this gateway is on, ! 555: * add a new gateway to that network. ! 556: */ ! 557: changed = 1; ! 558: gp->g_dst = gw->g_dst; ! 559: gp->g_metric = gw->g_metric + 1; ! 560: for (ggp = gp->g_firstent; ggp->g_name == gp->g_name; ! 561: ggp = ggp->g_link) { ! 562: if (ggp == gp) ! 563: continue; ! 564: if (gatewayto(ggp->g_net)) ! 565: continue; ! 566: ggp->g_dst = gp->g_dst; ! 567: ggp->g_metric = gp->g_metric; ! 568: printgateway(ggp->g_net, ! 569: gw->g_dst->g_name->name_val, gp->g_metric); ! 570: } ! 571: /* ! 572: * Put the gateway in the hosts file, ! 573: * using the address for the connected net. ! 574: */ ! 575: putaddr(hf, gp->g_addr); ! 576: cp = "%s"; ! 577: for (nl = gp->g_name; nl; nl = nl->name_link) { ! 578: fprintf(hf, cp, lower(nl->name_val)); ! 579: cp = " %s"; ! 580: } ! 581: fprintf(hf, "\t# gateway\n"); ! 582: } ! 583: } ! 584: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.