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