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