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