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: #if defined(DOSCCS) && !defined(lint)
   8: char copyright[] =
   9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: 
  12: static char sccsid[] = "@(#)htable.c	5.5.1 (2.11BSD GTE) 1/1/94";
  13: #endif
  14: 
  15: /*
  16:  * htable - convert NIC host table into a UNIX format.
  17:  * NIC format is described in RFC 810, 1 March 1982.
  18:  */
  19: 
  20: #include <stdio.h>
  21: #include <ctype.h>
  22: #include <errno.h>
  23: #include <netdb.h>
  24: 
  25: #include "htable.h"     /* includes <sys/types.h> */
  26: 
  27: #include <sys/socket.h>
  28: #include <netinet/in.h>
  29: #include <arpa/inet.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: u_long connected_nets[MAXNETS];
  40: int nconnected;
  41: u_long 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 u_long 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 u_long 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(cputype);
 296:     freenames(opsys);
 297:     freenames(protos);
 298: }
 299: 
 300: printgateway(net, name, metric)
 301:     u_long net;
 302:     char *name;
 303:     int metric;
 304: {
 305:     struct netent *np;
 306: 
 307:     fprintf(gf, "net ");
 308:     np = getnetbyaddr(net, AF_INET);
 309:     if (np)
 310:         fprintf(gf, "%s", np->n_name);
 311:     else
 312:         putnet(gf, net);
 313:     fprintf(gf, " gateway %s metric %d passive\n",
 314:         lower(name), metric);
 315: }
 316: 
 317: copylocal(f, filename)
 318:     FILE *f;
 319:     char *filename;
 320: {
 321:     register FILE *lhf;
 322:     register cc;
 323:     char buf[BUFSIZ];
 324:     extern int errno;
 325: 
 326:     lhf = fopen(filename, "r");
 327:     if (lhf == NULL) {
 328:         if (errno != ENOENT) {
 329:             perror(filename);
 330:             exit(1);
 331:         }
 332:         fprintf(stderr, "Warning, no %s file.\n", filename);
 333:         return;
 334:     }
 335:     while (cc = fread(buf, 1, sizeof(buf), lhf))
 336:         fwrite(buf, 1, cc, f);
 337:     fclose(lhf);
 338: }
 339: 
 340: copygateways(f, filename)
 341:     FILE *f;
 342:     char *filename;
 343: {
 344:     register FILE *lhf;
 345:     struct name *nl;
 346:     char type[80];
 347:     char dname[80];
 348:     char gname[80];
 349:     char junk[80];
 350:     char buf[500];
 351:     u_long addr, net;
 352:     int metric;
 353:     extern int errno;
 354: 
 355:     lhf = fopen(filename, "r");
 356:     if (lhf == NULL) {
 357:         if (errno != ENOENT) {
 358:             perror(filename);
 359:             exit(1);
 360:         }
 361:         fprintf(stderr, "Warning, no %s file.\n", filename);
 362:         return;
 363:     }
 364:     /* format: {net | host} XX gateway XX metric DD [passive]\n */
 365:     for (;;) {
 366:         junk[0] = 0;
 367:         if (fgets(buf, sizeof(buf), lhf) == (char *)NULL)
 368:             break;
 369:         fputs(buf, gf);
 370:         if (buf[0] == '#' ||
 371:             sscanf(buf, "%s %s gateway %s metric %d %s",
 372:             type, dname, gname, &metric, junk) < 5)
 373:             continue;
 374:         if (strcmp(type, "net"))
 375:             continue;
 376:         if (!getnetaddr(dname, &net))
 377:             continue;
 378:         if (!gethostaddr(gname, &addr))
 379:             continue;
 380:         nl = newname(gname);
 381:         (void) savegateway(nl, net, addr, metric);
 382:     }
 383:     fclose(lhf);
 384: }
 385: 
 386: getnetaddr(name, addr)
 387:     char *name;
 388:     u_long *addr;
 389: {
 390:     struct netent *np = getnetbyname(name);
 391:     int n;
 392: 
 393:     if (np == 0) {
 394:         *addr = inet_network(name);
 395:         return (*addr != -1);
 396:     } else {
 397:         if (np->n_addrtype != AF_INET)
 398:             return (0);
 399:         *addr = np->n_net;
 400:         return (1);
 401:     }
 402: }
 403: 
 404: gethostaddr(name, addr)
 405:     char *name;
 406:     u_long *addr;
 407: {
 408:     struct hostent *hp;
 409: 
 410:     hp = gethostbyname(name);
 411:     if (hp) {
 412:         *addr = *(u_long *)(hp->h_addr);
 413:         return (1);
 414:     }
 415:     *addr = inet_addr(name);
 416:     return (*addr != -1);
 417: }
 418: 
 419: copycomments(in, out, ccount)
 420:     FILE *in, *out;
 421:     int ccount;
 422: {
 423:     char buf[BUFSIZ];
 424:     int length;
 425:     int count;
 426:     char *fgets();
 427: 
 428:     for (count=0; count < ccount; count++) {
 429:         if ((fgets(buf, sizeof(buf), in) == NULL) || (buf[0] != ';'))
 430:             return;
 431:         buf[0] = '#';
 432:         fputs(buf, out);
 433:     }
 434:     return;
 435: }
 436: #define UC(b)   (((int)(b))&0xff)
 437: 
 438: /*
 439:  * Print network number in internet-standard dot notation;
 440:  * v is in host byte order.
 441:  */
 442: putnet(f, v)
 443:     FILE *f;
 444:     register u_long v;
 445: {
 446:     if (v < 128)
 447:         fprintf(f, "%d", (int)v);
 448:     else if (v < 65536)
 449:         fprintf(f, "%d.%d", UC(v >> 8), UC(v));
 450:     else
 451:         fprintf(f, "%d.%d.%d", UC(v >> 16), UC(v >> 8), UC(v));
 452: }
 453: 
 454: putaddr(f, v)
 455:     FILE *f;
 456:     u_long v;
 457: {
 458:     register char *a = (char *)&v;
 459:     char buf[32];
 460: 
 461:     sprintf(buf,"%d.%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]));
 462:     fprintf(f, "%-16.16s", buf);
 463: }
 464: 
 465: freenames(list)
 466:     struct name *list;
 467: {
 468:     register struct name *nl, *nl2;
 469: 
 470:     nl2 = list;
 471:     while (nl = nl2) {
 472:         nl2 = nl->name_link;
 473:         free(nl->name_val);
 474:         free((char *)nl);
 475:     }
 476: }
 477: 
 478: freeaddrs(list)
 479:     struct addr *list;
 480: {
 481:     register struct addr *al, *al2;
 482: 
 483:     al2 = list;
 484:     while (al = al2)
 485:         al2 = al->addr_link, free((char *)al);
 486: }
 487: 
 488: struct gateway *gateways = 0;
 489: struct gateway *lastgateway = 0;
 490: 
 491: struct gateway *
 492: gatewayto(net)
 493:     register u_long net;
 494: {
 495:     register struct gateway *gp;
 496: 
 497:     for (gp = gateways; gp; gp = gp->g_link)
 498:         if ((gp->g_net == net) && (gp->g_metric > 0))
 499:             return (gp);
 500:     return ((struct gateway *) NULL);
 501: }
 502: 
 503: struct gateway *
 504: savegateway(namelist, net, addr, metric)
 505:     struct name *namelist;
 506:     u_long addr, net;
 507:     int metric;
 508: {
 509:     register struct gateway *gp;
 510: 
 511:     gp = (struct gateway *)malloc(sizeof (struct gateway));
 512:     if (gp == 0) {
 513:         fprintf(stderr, "htable: out of memory\n");
 514:         exit(1);
 515:     }
 516:     gp->g_link = (struct gateway *) NULL;
 517:     if (lastgateway)
 518:         lastgateway->g_link = gp;
 519:     else
 520:         gateways = gp;
 521:     lastgateway = gp;
 522:     gp->g_name = namelist;
 523:     gp->g_net = net;
 524:     gp->g_addr = addr;
 525:     gp->g_metric = metric;
 526:     if (metric == 1)
 527:         gp->g_dst = gp;
 528:     return (gp);
 529: }
 530: 
 531: connectedto(net)
 532:     u_long net;
 533: {
 534:     register i;
 535: 
 536:     for (i = 0; i < nconnected; i++)
 537:         if (connected_nets[i] == net)
 538:             return(1);
 539:     return(0);
 540: }
 541: 
 542: local(net)
 543:     u_long net;
 544: {
 545:     register i;
 546: 
 547:     for (i = 0; i < nlocal; i++)
 548:         if (local_nets[i] == net)
 549:             return(1);
 550:     return(0);
 551: }
 552: 
 553: #define MAXHOPS 10
 554: 
 555: /*
 556:  * Go through list of gateways, finding connections for gateways
 557:  * that are not yet connected.
 558:  */
 559: dogateways()
 560: {
 561:     register struct gateway *gp, *gw, *ggp;
 562:     register int hops, changed = 1;
 563:     struct name *nl;
 564:     char *cp;
 565: 
 566:     for (hops = 0; hops < MAXHOPS && changed; hops++, changed = 0) {
 567:         for (gp = gateways; gp; gp = gp->g_link)
 568:         if ((gp->g_metric == 0) && (gw = gatewayto(gp->g_net))) {
 569:             /*
 570: 		     * Found a new connection.
 571: 		     * For each other network that this gateway is on,
 572: 		     * add a new gateway to that network.
 573: 		     */
 574:             changed = 1;
 575:             gp->g_dst = gw->g_dst;
 576:             gp->g_metric = gw->g_metric + 1;
 577:             for (ggp = gp->g_firstent; ggp->g_name == gp->g_name;
 578:             ggp = ggp->g_link) {
 579:                 if (ggp == gp)
 580:                 continue;
 581:                 if (gatewayto(ggp->g_net))
 582:                 continue;
 583:                 ggp->g_dst = gp->g_dst;
 584:                 ggp->g_metric = gp->g_metric;
 585:                 printgateway(ggp->g_net,
 586:                     gw->g_dst->g_name->name_val, gp->g_metric);
 587:             }
 588:             /*
 589: 		     * Put the gateway in the hosts file,
 590: 		     * using the address for the connected net.
 591: 		     */
 592:             putaddr(hf, gp->g_addr);
 593:             cp = "%s";
 594:             for (nl = gp->g_name; nl; nl = nl->name_link) {
 595:                 fprintf(hf, cp, lower(nl->name_val));
 596:                 cp = " %s";
 597:             }
 598:             fprintf(hf, "\t# gateway\n");
 599:         }
 600:     }
 601: }

Defined functions

addlocal defined in line 117; used 2 times
connectedto defined in line 531; used 2 times
copycomments defined in line 419; used 1 times
  • in line 99
copygateways defined in line 340; used 1 times
  • in line 92
copylocal defined in line 317; used 2 times
do_entry defined in line 180; used 5 times
dogateways defined in line 559; used 1 times
freeaddrs defined in line 478; used 2 times
freenames defined in line 465; used 4 times
gatewayto defined in line 491; used 4 times
gethostaddr defined in line 404; used 1 times
getnetaddr defined in line 386; used 2 times
local defined in line 542; 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 300; used 2 times
putaddr defined in line 454; used 3 times
putnet defined in line 442; used 3 times
savegateway defined in line 503; 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 488; used 3 times
lastgateway defined in line 489; 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 12; never used

Defined macros

DATELINES defined in line 31; used 1 times
  • in line 99
MAXHOPS defined in line 553; used 1 times
MAXNETS defined in line 32; used 3 times
UC defined in line 436; used 9 times
Last modified: 1994-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5245
Valid CSS Valid XHTML 1.0 Strict