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