18732Ssam #ifndef lint 2*12227Ssam static char sccsid[] = "@(#)htable.c 4.3 (Berkeley) 05/04/83"; 38732Ssam #endif 48732Ssam 58732Ssam /* 68732Ssam * htable - convert NIC host table into a UNIX format. 78732Ssam * NIC format is described in RFC 810, 1 March 1982. 88732Ssam */ 98732Ssam #include <stdio.h> 108732Ssam #include <ctype.h> 119246Ssam #include <errno.h> 12*12227Ssam #include <netdb.h> 13*12227Ssam #include <sys/socket.h> 14*12227Ssam 159246Ssam #include "htable.h" /* includes <sys/types.h> */ 168732Ssam 179246Ssam #include <netinet/in.h> 188732Ssam 19*12227Ssam #define INTERNET 10 /* gag */ 20*12227Ssam 219246Ssam FILE *hf; /* hosts file */ 229246Ssam FILE *gf; /* gateways file */ 239246Ssam FILE *nf; /* networks file */ 249246Ssam 258732Ssam main(argc, argv) 268732Ssam int argc; 278732Ssam char *argv[]; 288732Ssam { 298732Ssam if (argc > 2) { 308732Ssam fprintf(stderr, "usage: %s [ input-file ]\n", 318732Ssam argv[0]); 328732Ssam exit(1); 338732Ssam } 348732Ssam infile = "(stdin)"; 358732Ssam if (argc == 2) { 368732Ssam infile = argv[1]; 378732Ssam if (freopen(infile, "r", stdin) == NULL) { 388732Ssam perror(infile); 398732Ssam exit(1); 408732Ssam } 418732Ssam } 428732Ssam hf = fopen("hosts", "w"); 438732Ssam if (hf == NULL) { 448732Ssam perror("hosts"); 458732Ssam exit(1); 468732Ssam } 479246Ssam copylocal(hf, "localhosts"); 489246Ssam gf = fopen("gateways", "w"); 499246Ssam if (gf == NULL) { 508732Ssam perror("gateways"); 518732Ssam exit(1); 528732Ssam } 539246Ssam copylocal(gf, "localgateways"); 549246Ssam nf = fopen("networks", "w"); 559246Ssam if (nf == NULL) { 569246Ssam perror("networks"); 579246Ssam exit(1); 589246Ssam } 599246Ssam copylocal(nf, "localnetworks"); 608732Ssam exit(yyparse()); 618732Ssam } 628732Ssam 638732Ssam struct name * 648732Ssam newname(str) 658732Ssam char *str; 668732Ssam { 678732Ssam char *p; 688732Ssam struct name *nm; 698732Ssam 708732Ssam p = malloc(strlen(str) + 1); 718732Ssam strcpy(p, str); 729246Ssam nm = (struct name *)malloc(sizeof (struct name)); 738732Ssam nm->name_val = p; 748732Ssam nm->name_link = NONAME; 758732Ssam return (nm); 768732Ssam } 778732Ssam 788732Ssam char * 798732Ssam lower(str) 808732Ssam char *str; 818732Ssam { 828732Ssam register char *cp = str; 838732Ssam 848732Ssam while (*cp) { 858732Ssam if (isupper(*cp)) 868732Ssam *cp = tolower(*cp); 878732Ssam cp++; 888732Ssam } 898732Ssam return (str); 908732Ssam } 918732Ssam 928732Ssam do_entry(keyword, addrlist, namelist, cputype, opsys, protos) 938732Ssam int keyword; 948732Ssam struct addr *addrlist; 958732Ssam struct name *namelist, *cputype, *opsys, *protos; 968732Ssam { 978732Ssam register struct addr *al, *al2; 989246Ssam register struct name *nl; 99*12227Ssam struct addr *inetal; 100*12227Ssam int count; 1018732Ssam 1028732Ssam switch (keyword) { 1038732Ssam 1048732Ssam case KW_NET: 1059246Ssam nl = namelist; 1069246Ssam if (nl == NONAME) { 1079246Ssam fprintf(stderr, "htable: net"); 1089246Ssam putnet(stderr, addrlist->addr_val); 1099246Ssam fprintf(stderr, " missing names.\n"); 1109246Ssam break; 1119246Ssam } 1129246Ssam fprintf(nf, "%-16.16s", lower(nl->name_val)); 1139246Ssam al2 = addrlist; 1149246Ssam while (al = al2) { 1159246Ssam char *cp; 1168732Ssam 1179246Ssam putnet(nf, al->addr_val); 1189246Ssam cp = "\t%s"; 1199246Ssam while (nl = nl->name_link) { 1209246Ssam fprintf(nf, cp, lower(nl->name_val)); 1219246Ssam cp = " %s"; 1229246Ssam } 1239246Ssam putc('\n', nf); 1249246Ssam al2 = al->addr_link; 1259246Ssam free((char *)al); 1269246Ssam } 1279246Ssam goto alreadyfree; 1289246Ssam 1298732Ssam case KW_GATEWAY: 130*12227Ssam /* 131*12227Ssam * Kludge here: take only gateways directly connected to 132*12227Ssam * the Internet. Should really calculate closure on 133*12227Ssam * connectivity matrix to identify gateways to all networks 134*12227Ssam * described in data base, but that's real work. 135*12227Ssam */ 136*12227Ssam /* locate Internet address, if one */ 137*12227Ssam for (al = addrlist; al; al = al->addr_link) 138*12227Ssam if (inet_netof(al->addr_val) == INTERNET) 139*12227Ssam break; 140*12227Ssam if (al == NULL) 141*12227Ssam break; 142*12227Ssam inetal = al; 143*12227Ssam for (count = 0, al = al->addr_link; al; al = al->addr_link) { 144*12227Ssam register int net; 145*12227Ssam register struct netent *np; 1469246Ssam 147*12227Ssam if (al == inetal) 148*12227Ssam continue; 1499246Ssam /* suppress duplicates -- not optimal */ 150*12227Ssam net = inet_netof(al->addr_val); 1519246Ssam if (checkgateway(net)) 1529246Ssam break; 153*12227Ssam count++; 1549246Ssam fprintf(gf, "net "); 155*12227Ssam np = getnetbyaddr(net, AF_INET); 156*12227Ssam if (np) 157*12227Ssam fprintf(gf, "%s", np->n_name); 158*12227Ssam else 159*12227Ssam putnet(gf, net); 1609246Ssam /* this is a kludge */ 161*12227Ssam fprintf(gf, " gateway %s metric 1 passive\n", 1629246Ssam lower(namelist->name_val)); 163*12227Ssam savegateway(net); 164*12227Ssam } 165*12227Ssam if (count > 0) { 166*12227Ssam putaddr(hf, inetal->addr_val); 1679246Ssam fprintf(hf, "%s\t# gateway\n", 1689246Ssam lower(namelist->name_val)); 1699246Ssam } 1708732Ssam break; 1718732Ssam 1728732Ssam case KW_HOST: 1739246Ssam al2 = addrlist; 1749246Ssam while (al = al2) { 1759246Ssam if (inet_netof(al->addr_val) != LOCALNET) { 1769246Ssam char *cp; 1779246Ssam 1789246Ssam putaddr(hf, al->addr_val); 1799246Ssam cp = "%s"; 1809246Ssam for (nl = namelist; nl; nl = nl->name_link) { 1819246Ssam fprintf(hf, cp, lower(nl->name_val)); 1829246Ssam cp = " %s"; 1839246Ssam } 1848732Ssam putc('\n', hf); 1858732Ssam } 1868732Ssam al2 = al->addr_link; 1879246Ssam free((char *)al); 1888732Ssam } 1899246Ssam goto alreadyfree; 1908732Ssam 1918732Ssam default: 1928732Ssam fprintf(stderr, "Unknown keyword: %d.\n", keyword); 1938732Ssam } 1949246Ssam al2 = addrlist; 1959246Ssam while (al = al2) 1969246Ssam al2 = al->addr_link, free((char *)al); 1979246Ssam alreadyfree: 1989246Ssam freenames(namelist); 1999246Ssam freenames(protos); 2008732Ssam } 2018732Ssam 2029246Ssam copylocal(f, filename) 2039246Ssam FILE *f; 2049246Ssam char *filename; 2058732Ssam { 2068732Ssam register FILE *lhf; 2078732Ssam register cc; 2088732Ssam char buf[BUFSIZ]; 2099246Ssam extern int errno; 2108732Ssam 2119246Ssam lhf = fopen(filename, "r"); 2128732Ssam if (lhf == NULL) { 2139246Ssam if (errno != ENOENT) { 2149246Ssam perror(filename); 2159246Ssam exit(1); 2169246Ssam } 2179246Ssam fprintf(stderr, "Warning, no %s file.\n", filename); 2188732Ssam return; 2198732Ssam } 2208732Ssam while (cc = fread(buf, 1, sizeof(buf), lhf)) 2219246Ssam fwrite(buf, 1, cc, f); 2228732Ssam fclose(lhf); 2238732Ssam } 2249246Ssam 2259246Ssam #define UC(b) (((int)(b))&0xff) 2269246Ssam 2279246Ssam putnet(f, v) 2289246Ssam FILE *f; 2299246Ssam u_long v; 2309246Ssam { 2319246Ssam register char *a = (char *)&v; 2329246Ssam 2339246Ssam if (UC(a[0]&0x80) == 0) 2349246Ssam fprintf(f, "%d", UC(a[0])); 2359246Ssam else if ((UC(a[0])&0x40) == 0) 2369246Ssam fprintf(f, "%d.%d", UC(a[0]), UC(a[1])); 2379246Ssam else 2389246Ssam fprintf(f, "%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2])); 2399246Ssam } 2409246Ssam 2419246Ssam putaddr(f, v) 2429246Ssam FILE *f; 2439246Ssam u_long v; 2449246Ssam { 2459246Ssam register char *a = (char *)&v; 2469246Ssam char buf[32]; 2479246Ssam 2489246Ssam sprintf(buf,"%d.%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3])); 2499246Ssam fprintf(f, "%-16.16s", buf); 2509246Ssam } 2519246Ssam 2529246Ssam freenames(list) 2539246Ssam struct name *list; 2549246Ssam { 2559246Ssam register struct name *nl, *nl2; 2569246Ssam 2579246Ssam nl2 = list; 2589246Ssam while (nl = nl2) { 2599246Ssam nl2 = nl->name_link; 2609246Ssam free(nl->name_val); 2619246Ssam free((char *)nl); 2629246Ssam } 2639246Ssam } 2649246Ssam struct gateway { 2659246Ssam struct gateway *g_link; 2669246Ssam int g_net; 2679246Ssam }; 2689246Ssam 2699246Ssam struct gateway *gateways = 0; 2709246Ssam 2719246Ssam checkgateway(net) 2729246Ssam register int net; 2739246Ssam { 2749246Ssam register struct gateway *gp; 2759246Ssam 2769246Ssam for (gp = gateways; gp; gp = gp->g_link) 2779246Ssam if (gp->g_net == net) 2789246Ssam return (1); 2799246Ssam return (0); 2809246Ssam } 2819246Ssam 2829246Ssam savegateway(net) 2839246Ssam int net; 2849246Ssam { 2859246Ssam register struct gateway *gp; 2869246Ssam 2879246Ssam gp = (struct gateway *)malloc(sizeof (struct gateway)); 2889246Ssam if (gp == 0) { 2899246Ssam fprintf(stderr, "htable: out of memory\n"); 2909246Ssam exit(1); 2919246Ssam } 2929246Ssam gp->g_link = gateways; 2939246Ssam gp->g_net = net; 2949246Ssam gateways = gp; 2959246Ssam } 2969246Ssam 297