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: }

Defined functions

addlocal defined in line 117; used 2 times
connectedto defined in line 529; used 2 times
copycomments defined in line 417; used 1 times
  • in line 99
copygateways defined in line 338; used 1 times
  • in line 92
copylocal defined in line 315; used 2 times
do_entry defined in line 180; used 5 times
dogateways defined in line 557; used 1 times
freeaddrs defined in line 476; used 2 times
freenames defined in line 463; used 2 times
gatewayto defined in line 489; used 4 times
gethostaddr defined in line 402; used 1 times
getnetaddr defined in line 384; used 2 times
local defined in line 540; used 1 times
lower defined in line 166; used 6 times
main defined in line 45; never used
newname defined in line 151; used 2 times
printgateway defined in line 298; used 2 times
putaddr defined in line 452; used 3 times
putnet defined in line 440; used 3 times
savegateway defined in line 501; used 4 times
usage defined in line 105; used 1 times
  • in line 69

Defined variables

connected_nets defined in line 39; used 2 times
copyright defined in line 8; never used
gateways defined in line 486; used 3 times
lastgateway defined in line 487; used 3 times
local_nets defined in line 41; used 2 times
myname defined in line 43; used 4 times
nconnected defined in line 40; used 2 times
nlocal defined in line 42; used 2 times
sccsid defined in line 14; never used

Defined macros

DATELINES defined in line 31; used 1 times
  • in line 99
MAXHOPS defined in line 551; used 1 times
MAXNETS defined in line 32; used 3 times
UC defined in line 434; used 9 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2759
Valid CSS Valid XHTML 1.0 Strict