18732Ssam #ifndef lint 2*12610Smo static char sccsid[] = "@(#)htable.c 4.4 (Berkeley) 05/20/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> 1212227Ssam #include <netdb.h> 1312227Ssam #include <sys/socket.h> 1412227Ssam 159246Ssam #include "htable.h" /* includes <sys/types.h> */ 168732Ssam 179246Ssam #include <netinet/in.h> 188732Ssam 1912227Ssam #define INTERNET 10 /* gag */ 2012227Ssam 21*12610Smo #define DATELINES 3 /* these lines usually contain the date */ 22*12610Smo 239246Ssam FILE *hf; /* hosts file */ 249246Ssam FILE *gf; /* gateways file */ 259246Ssam FILE *nf; /* networks file */ 269246Ssam 278732Ssam main(argc, argv) 288732Ssam int argc; 298732Ssam char *argv[]; 308732Ssam { 318732Ssam if (argc > 2) { 328732Ssam fprintf(stderr, "usage: %s [ input-file ]\n", 338732Ssam argv[0]); 348732Ssam exit(1); 358732Ssam } 368732Ssam infile = "(stdin)"; 378732Ssam if (argc == 2) { 388732Ssam infile = argv[1]; 398732Ssam if (freopen(infile, "r", stdin) == NULL) { 408732Ssam perror(infile); 418732Ssam exit(1); 428732Ssam } 438732Ssam } 448732Ssam hf = fopen("hosts", "w"); 458732Ssam if (hf == NULL) { 468732Ssam perror("hosts"); 478732Ssam exit(1); 488732Ssam } 499246Ssam copylocal(hf, "localhosts"); 509246Ssam gf = fopen("gateways", "w"); 519246Ssam if (gf == NULL) { 528732Ssam perror("gateways"); 538732Ssam exit(1); 548732Ssam } 559246Ssam copylocal(gf, "localgateways"); 569246Ssam nf = fopen("networks", "w"); 579246Ssam if (nf == NULL) { 589246Ssam perror("networks"); 599246Ssam exit(1); 609246Ssam } 619246Ssam copylocal(nf, "localnetworks"); 62*12610Smo copycomments(stdin, hf, DATELINES); 638732Ssam exit(yyparse()); 648732Ssam } 658732Ssam 668732Ssam struct name * 678732Ssam newname(str) 688732Ssam char *str; 698732Ssam { 708732Ssam char *p; 718732Ssam struct name *nm; 728732Ssam 738732Ssam p = malloc(strlen(str) + 1); 748732Ssam strcpy(p, str); 759246Ssam nm = (struct name *)malloc(sizeof (struct name)); 768732Ssam nm->name_val = p; 778732Ssam nm->name_link = NONAME; 788732Ssam return (nm); 798732Ssam } 808732Ssam 818732Ssam char * 828732Ssam lower(str) 838732Ssam char *str; 848732Ssam { 858732Ssam register char *cp = str; 868732Ssam 878732Ssam while (*cp) { 888732Ssam if (isupper(*cp)) 898732Ssam *cp = tolower(*cp); 908732Ssam cp++; 918732Ssam } 928732Ssam return (str); 938732Ssam } 948732Ssam 958732Ssam do_entry(keyword, addrlist, namelist, cputype, opsys, protos) 968732Ssam int keyword; 978732Ssam struct addr *addrlist; 988732Ssam struct name *namelist, *cputype, *opsys, *protos; 998732Ssam { 1008732Ssam register struct addr *al, *al2; 1019246Ssam register struct name *nl; 10212227Ssam struct addr *inetal; 10312227Ssam int count; 1048732Ssam 1058732Ssam switch (keyword) { 1068732Ssam 1078732Ssam case KW_NET: 1089246Ssam nl = namelist; 1099246Ssam if (nl == NONAME) { 1109246Ssam fprintf(stderr, "htable: net"); 1119246Ssam putnet(stderr, addrlist->addr_val); 1129246Ssam fprintf(stderr, " missing names.\n"); 1139246Ssam break; 1149246Ssam } 1159246Ssam fprintf(nf, "%-16.16s", lower(nl->name_val)); 1169246Ssam al2 = addrlist; 1179246Ssam while (al = al2) { 1189246Ssam char *cp; 1198732Ssam 1209246Ssam putnet(nf, al->addr_val); 1219246Ssam cp = "\t%s"; 1229246Ssam while (nl = nl->name_link) { 1239246Ssam fprintf(nf, cp, lower(nl->name_val)); 1249246Ssam cp = " %s"; 1259246Ssam } 1269246Ssam putc('\n', nf); 1279246Ssam al2 = al->addr_link; 1289246Ssam free((char *)al); 1299246Ssam } 1309246Ssam goto alreadyfree; 1319246Ssam 1328732Ssam case KW_GATEWAY: 13312227Ssam /* 13412227Ssam * Kludge here: take only gateways directly connected to 13512227Ssam * the Internet. Should really calculate closure on 13612227Ssam * connectivity matrix to identify gateways to all networks 13712227Ssam * described in data base, but that's real work. 13812227Ssam */ 13912227Ssam /* locate Internet address, if one */ 14012227Ssam for (al = addrlist; al; al = al->addr_link) 14112227Ssam if (inet_netof(al->addr_val) == INTERNET) 14212227Ssam break; 14312227Ssam if (al == NULL) 14412227Ssam break; 14512227Ssam inetal = al; 14612227Ssam for (count = 0, al = al->addr_link; al; al = al->addr_link) { 14712227Ssam register int net; 14812227Ssam register struct netent *np; 1499246Ssam 15012227Ssam if (al == inetal) 15112227Ssam continue; 1529246Ssam /* suppress duplicates -- not optimal */ 15312227Ssam net = inet_netof(al->addr_val); 1549246Ssam if (checkgateway(net)) 1559246Ssam break; 15612227Ssam count++; 1579246Ssam fprintf(gf, "net "); 15812227Ssam np = getnetbyaddr(net, AF_INET); 15912227Ssam if (np) 16012227Ssam fprintf(gf, "%s", np->n_name); 16112227Ssam else 16212227Ssam putnet(gf, net); 1639246Ssam /* this is a kludge */ 16412227Ssam fprintf(gf, " gateway %s metric 1 passive\n", 1659246Ssam lower(namelist->name_val)); 16612227Ssam savegateway(net); 16712227Ssam } 16812227Ssam if (count > 0) { 16912227Ssam putaddr(hf, inetal->addr_val); 1709246Ssam fprintf(hf, "%s\t# gateway\n", 1719246Ssam lower(namelist->name_val)); 1729246Ssam } 1738732Ssam break; 1748732Ssam 1758732Ssam case KW_HOST: 1769246Ssam al2 = addrlist; 1779246Ssam while (al = al2) { 1789246Ssam if (inet_netof(al->addr_val) != LOCALNET) { 1799246Ssam char *cp; 1809246Ssam 1819246Ssam putaddr(hf, al->addr_val); 1829246Ssam cp = "%s"; 1839246Ssam for (nl = namelist; nl; nl = nl->name_link) { 1849246Ssam fprintf(hf, cp, lower(nl->name_val)); 1859246Ssam cp = " %s"; 1869246Ssam } 1878732Ssam putc('\n', hf); 1888732Ssam } 1898732Ssam al2 = al->addr_link; 1909246Ssam free((char *)al); 1918732Ssam } 1929246Ssam goto alreadyfree; 1938732Ssam 1948732Ssam default: 1958732Ssam fprintf(stderr, "Unknown keyword: %d.\n", keyword); 1968732Ssam } 1979246Ssam al2 = addrlist; 1989246Ssam while (al = al2) 1999246Ssam al2 = al->addr_link, free((char *)al); 2009246Ssam alreadyfree: 2019246Ssam freenames(namelist); 2029246Ssam freenames(protos); 2038732Ssam } 2048732Ssam 2059246Ssam copylocal(f, filename) 2069246Ssam FILE *f; 2079246Ssam char *filename; 2088732Ssam { 2098732Ssam register FILE *lhf; 2108732Ssam register cc; 2118732Ssam char buf[BUFSIZ]; 2129246Ssam extern int errno; 2138732Ssam 2149246Ssam lhf = fopen(filename, "r"); 2158732Ssam if (lhf == NULL) { 2169246Ssam if (errno != ENOENT) { 2179246Ssam perror(filename); 2189246Ssam exit(1); 2199246Ssam } 2209246Ssam fprintf(stderr, "Warning, no %s file.\n", filename); 2218732Ssam return; 2228732Ssam } 2238732Ssam while (cc = fread(buf, 1, sizeof(buf), lhf)) 2249246Ssam fwrite(buf, 1, cc, f); 2258732Ssam fclose(lhf); 2268732Ssam } 2279246Ssam 228*12610Smo copycomments(in, out, ccount) 229*12610Smo FILE *in, *out; 230*12610Smo int ccount; 231*12610Smo { 232*12610Smo char buf[BUFSIZ]; 233*12610Smo int length; 234*12610Smo int count; 235*12610Smo char *fgets(); 236*12610Smo 237*12610Smo for (count=0; count < ccount; count++) { 238*12610Smo if ((fgets(buf, sizeof(buf), in) == NULL) || (buf[0] != ';')) 239*12610Smo return; 240*12610Smo buf[0] = '#'; 241*12610Smo fputs(buf, out); 242*12610Smo } 243*12610Smo return; 244*12610Smo } 2459246Ssam #define UC(b) (((int)(b))&0xff) 2469246Ssam 2479246Ssam putnet(f, v) 2489246Ssam FILE *f; 2499246Ssam u_long v; 2509246Ssam { 2519246Ssam register char *a = (char *)&v; 2529246Ssam 2539246Ssam if (UC(a[0]&0x80) == 0) 2549246Ssam fprintf(f, "%d", UC(a[0])); 2559246Ssam else if ((UC(a[0])&0x40) == 0) 2569246Ssam fprintf(f, "%d.%d", UC(a[0]), UC(a[1])); 2579246Ssam else 2589246Ssam fprintf(f, "%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2])); 2599246Ssam } 2609246Ssam 2619246Ssam putaddr(f, v) 2629246Ssam FILE *f; 2639246Ssam u_long v; 2649246Ssam { 2659246Ssam register char *a = (char *)&v; 2669246Ssam char buf[32]; 2679246Ssam 2689246Ssam sprintf(buf,"%d.%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3])); 2699246Ssam fprintf(f, "%-16.16s", buf); 2709246Ssam } 2719246Ssam 2729246Ssam freenames(list) 2739246Ssam struct name *list; 2749246Ssam { 2759246Ssam register struct name *nl, *nl2; 2769246Ssam 2779246Ssam nl2 = list; 2789246Ssam while (nl = nl2) { 2799246Ssam nl2 = nl->name_link; 2809246Ssam free(nl->name_val); 2819246Ssam free((char *)nl); 2829246Ssam } 2839246Ssam } 2849246Ssam struct gateway { 2859246Ssam struct gateway *g_link; 2869246Ssam int g_net; 2879246Ssam }; 2889246Ssam 2899246Ssam struct gateway *gateways = 0; 2909246Ssam 2919246Ssam checkgateway(net) 2929246Ssam register int net; 2939246Ssam { 2949246Ssam register struct gateway *gp; 2959246Ssam 2969246Ssam for (gp = gateways; gp; gp = gp->g_link) 2979246Ssam if (gp->g_net == net) 2989246Ssam return (1); 2999246Ssam return (0); 3009246Ssam } 3019246Ssam 3029246Ssam savegateway(net) 3039246Ssam int net; 3049246Ssam { 3059246Ssam register struct gateway *gp; 3069246Ssam 3079246Ssam gp = (struct gateway *)malloc(sizeof (struct gateway)); 3089246Ssam if (gp == 0) { 3099246Ssam fprintf(stderr, "htable: out of memory\n"); 3109246Ssam exit(1); 3119246Ssam } 3129246Ssam gp->g_link = gateways; 3139246Ssam gp->g_net = net; 3149246Ssam gateways = gp; 3159246Ssam } 3169246Ssam 317