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