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