|
|
1.1 root 1: /*
2: * Hyperchannel routing program
3: *
4: * Copyright (c) 1983, Tektronix Inc.
5: * All Rights Reserved
6: *
7: */
8:
9: static char rcsid[] = "$Header: hyr_main.c,v 2.3 84/05/04 12:15:59 steveg Exp $$Locker: $";
10:
11: #include <stdio.h>
12: #include <sys/types.h>
13: #include <sys/socket.h>
14: #include <sys/ioctl.h>
15:
16: #include <netinet/in.h>
17: #include <net/if.h>
18:
19: #include <vaxif/if_hy.h>
20: #include <ctype.h>
21: #define MAIN
22: #include "hyr_sym.h"
23:
24: struct hy_route hy_route;
25: struct hy_route ker_hy_route;
26: int comp_flag = 0;
27: int set_flag = 0;
28: int print_flag = 0;
29: int dump_flag = 0;
30: int debug_flag = 0;
31: int lexdebug;
32: int lex_error;
33: int maxgate = 0;
34: char *progname = "hyroute";
35: char *devname = "hy0";
36:
37: /*
38: * hash a hyperchannel address into the table
39: * return NULL if table is full or entry not found and adding a new one
40: */
41: struct hyr_hash *
42: rhash(key, new, r)
43: u_long key;
44: int new;
45: register struct hy_route *r;
46: {
47: register struct hyr_hash *rh;
48: register struct hyr_hash *ret = NULL;
49: int n = HYRHASH(key);
50:
51: if (debug_flag)
52: printf("%s hashing key %6x initial %d ", new? "new": "old", key, n);
53: rh = &r->hyr_hash[n];
54: n = 0;
55: while (rh->hyr_key != key) {
56: if ((rh->hyr_flags & HYR_INUSE) == 0) {
57: if (new)
58: ret = rh;
59: goto out;
60: }
61: if (n++ > HYRSIZE) {
62: goto out;
63: }
64: if (++rh >= &r->hyr_hash[HYRSIZE]) {
65: rh = &r->hyr_hash[0];
66: if (debug_flag) printf("|");
67: }
68: if (debug_flag) printf(".");
69: }
70: ret = rh;
71: out:
72: if (ret == NULL) {
73: if (new) {
74: fprintf(stderr, "%s: %s add_gates, hash table full\n", progname, devname);
75: exit(1);
76: }
77: }
78: if (debug_flag) {
79: if (ret == NULL)
80: printf(" returning NULL\n");
81: else
82: printf(" returning %d\n", ret - &r->hyr_hash[0]);
83: }
84: return(ret);
85: }
86:
87: /*
88: * add a direct entry to the hash table using the specified key,
89: * destination, control and access fields, and loopback flags.
90: */
91: add_direct(key, dst, ctl, access, flags, r)
92: u_long key;
93: unsigned dst;
94: unsigned ctl;
95: unsigned access;
96: unsigned flags;
97: register struct hy_route *r;
98: {
99: register struct hyr_hash *kh = rhash(key, 1, r);
100:
101: if ((kh->hyr_flags & HYR_INUSE) == 0) {
102: kh->hyr_flags = (HYR_INUSE | HYR_DIR);
103: kh->hyr_key = key;
104: kh->hyr_dst = dst;
105: kh->hyr_ctl = ctl;
106: kh->hyr_access = access;
107: if (flags & HS_LOOP)
108: kh->hyr_flags |= HYR_LOOP;
109: if (flags & HS_RLOOP)
110: kh->hyr_flags |= HYR_RLOOP;
111: return;
112: }
113: fprintf(stderr, "%s: %s add_direct, hash table full\n", progname, devname);
114: }
115:
116: /*
117: * compare function for the qsort in add_gates, see below
118: */
119: int
120: compare_gates(a, b)
121: unsigned *a, *b;
122: {
123: if (*a < *b)
124: return(-1);
125: else if (*a > *b)
126: return(1);
127: else
128: return(0);
129: }
130:
131: /*
132: * add a gatewayed entry to the hash table using the sicified array of
133: * gateway keys. reuse space so as to make the gateway table small as
134: * possible.
135: */
136: add_gates(key, numgates, gates, r)
137: u_long key;
138: unsigned numgates;
139: unsigned gates[256];
140: register struct hy_route *r;
141: {
142: register struct hyr_hash *kh = rhash(key, 1, r);
143: register struct hyr_hash *rh;
144: int i, j;
145:
146: for (i = 0; i < numgates; i++) {
147: rh = rhash(gates[i], 1, r);
148: gates[i] = rh - &r->hyr_hash[0];
149: }
150: qsort(gates, numgates, sizeof(unsigned), compare_gates);
151: /*
152: * loop through all existing hash table entries to find one that
153: * matches the currently requested list
154: */
155: for (rh = &r->hyr_hash[0]; rh < &r->hyr_hash[HYRSIZE]; rh++) {
156: if (rh->hyr_flags & HYR_GATE) {
157: if ((rh->hyr_egate - rh->hyr_pgate + 1) == numgates) {
158: for (i = 0, j = rh->hyr_pgate; i < numgates ; i++, j++) {
159: if (gates[i] != r->hyr_gateway[j])
160: goto skipit;
161: }
162: /*
163: * found a match, just use it
164: */
165: kh->hyr_flags = (HYR_INUSE | HYR_GATE);
166: kh->hyr_key = key;
167: kh->hyr_pgate = rh->hyr_pgate;
168: kh->hyr_egate = rh->hyr_egate;
169: kh->hyr_nextgate = rh->hyr_nextgate;
170: return;
171: }
172: }
173: skipit:
174: ;
175: }
176: /*
177: * didn't find anything, if there is room add a new entry
178: */
179: if (numgates + maxgate > 256) {
180: fprintf(stderr, "%s: %s add_gates, gateway table full\n", progname, devname);
181: exit(1);
182: }
183: kh->hyr_flags = (HYR_INUSE | HYR_GATE);
184: kh->hyr_key = key;
185: kh->hyr_pgate = maxgate;
186: kh->hyr_egate = maxgate + numgates - 1;
187: kh->hyr_nextgate = maxgate;
188: for (i = 0; i < numgates; i++, maxgate++)
189: r->hyr_gateway[maxgate] = gates[i];
190: }
191:
192: /*
193: * set the kernel table
194: */
195: settable(r)
196: struct hy_route *r;
197: {
198: int s;
199: struct hyrsetget sg;
200:
201: sg.hyrsg_ptr = r;
202: sg.hyrsg_len = sizeof(*r);
203: strncpy(sg.hyrsg_name, devname, sizeof(sg.hyrsg_name));
204:
205: if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
206: perror("socket create in settable");
207: exit(1);
208: }
209: if (ioctl(s, HYSETROUTE, (char *)&sg) < 0) {
210: perror("HYSETROUTE ioctl in settable");
211: exit(1);
212: }
213: if (close(s) < 0) {
214: perror("socket close in settable");
215: exit(1);
216: }
217: }
218:
219: /*
220: * get the kernel table
221: */
222: gettable(r)
223: struct hy_route *r;
224: {
225: int s;
226: struct hyrsetget sg;
227:
228: sg.hyrsg_ptr = r;
229: sg.hyrsg_len = sizeof(*r);
230: strncpy(sg.hyrsg_name, devname, sizeof(sg.hyrsg_name));
231:
232: if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
233: perror("socket create in gettable");
234: exit(1);
235: }
236: if (ioctl(s, HYGETROUTE, (char *)&sg) < 0) {
237: perror("HYGETROUTE ioctl in gettable");
238: exit(1);
239: }
240: if (close(s) < 0) {
241: perror("socket close in gettable");
242: exit(1);
243: }
244: }
245:
246:
247: /*
248: * print a somewhat readable version of the routine table
249: * that the kernel uses (mostly for debugging)
250: */
251: print_table(r)
252: register struct hy_route *r;
253: {
254: register struct hyr_hash *rh;
255: register int i;
256: extern char *ctime();
257:
258: if (r->hyr_lasttime != 0)
259: printf("table set time: %s", ctime(&r->hyr_lasttime));
260: else
261: printf("time not set\n");
262:
263: for (i = 0; i < HYRSIZE; i++) {
264: rh = &r->hyr_hash[i];
265: if (rh->hyr_flags & HYR_INUSE) {
266: printf("hash %d key %06x flags %x\n", i, rh->hyr_key, rh->hyr_flags);
267: if (rh->hyr_flags & HYR_DIR)
268: printf("\tdst %04x ctl %04x access %04x",
269: ntohs(rh->hyr_dst),
270: ntohs(rh->hyr_ctl),
271: ntohs(rh->hyr_access));
272: else if (rh->hyr_flags & HYR_GATE)
273: printf("\tpgate %d egate %d nextgate %d",
274: rh->hyr_pgate,
275: rh->hyr_egate,
276: rh->hyr_nextgate);
277: if (rh->hyr_flags & HYR_LOOP)
278: printf(" LOOP");
279: if (rh->hyr_flags & HYR_RLOOP)
280: printf(" REMLOOP");
281: printf("\n");
282: }
283: }
284:
285: for (i = 0; i < 256; i++) {
286: printf("gate[%d] = %d\n", i, r->hyr_gateway[i]);
287: if (r->hyr_gateway[i] == 0 && r->hyr_gateway[i+1] == 0)
288: break;
289: }
290: }
291:
292: /*
293: * comnpare two routing tables tom insure that they are the same
294: */
295: compare_table(r1, r2)
296: register struct hy_route *r1, *r2;
297: {
298: register struct hyr_hash *rh1, *rh2;
299: register int i;
300: int ndiffs = 0;
301:
302: for (i = 0; i < HYRSIZE; i++) {
303: rh1 = &r1->hyr_hash[i];
304: rh2 = &r2->hyr_hash[i];
305: if (rh1->hyr_flags != rh2->hyr_flags) {
306: fprintf(stderr, "%s: hash entry %d - flags differ (%x vs %x)\n", progname, i, rh1->hyr_flags, rh2->hyr_flags);
307: ndiffs++;
308: }
309: if ((rh1->hyr_flags & HYR_INUSE) && (rh1->hyr_flags & HYR_DIR)) {
310: if (rh1->hyr_dst != rh1->hyr_dst ||
311: rh1->hyr_ctl != rh1->hyr_ctl ||
312: rh1->hyr_access != rh1->hyr_access) {
313: fprintf(stderr, "%s: direct hash entry %d - fields differ\n", progname, i);
314: fprintf(stderr, "\tdst: %04x vs %04x\tctl: %04x vs %04x\taccess: %04x vs %04x\n",
315: ntohs(rh1->hyr_dst), ntohs(rh2->hyr_dst),
316: ntohs(rh1->hyr_ctl), ntohs(rh2->hyr_ctl),
317: ntohs(rh1->hyr_access), ntohs(rh2->hyr_access));
318: ndiffs++;
319: }
320: }
321: if ((rh1->hyr_flags & HYR_INUSE) && (rh1->hyr_flags & HYR_GATE)) {
322: if (rh1->hyr_pgate != rh1->hyr_pgate ||
323: rh1->hyr_egate != rh1->hyr_egate ||
324: rh1->hyr_nextgate < rh1->hyr_pgate ||
325: rh1->hyr_nextgate > rh1->hyr_egate ||
326: rh2->hyr_nextgate < rh2->hyr_pgate ||
327: rh2->hyr_nextgate > rh2->hyr_egate) {
328: fprintf(stderr, "%s: direct hash entry %d - fields differ\n", progname, i);
329: fprintf(stderr, "\tpgate: %04x vs %04x\tegate: %04x vs %04x\tnextgate: %04x vs %04x\n",
330: rh1->hyr_pgate, rh2->hyr_pgate,
331: rh1->hyr_egate, rh2->hyr_egate,
332: rh1->hyr_nextgate, rh2->hyr_nextgate);
333: ndiffs++;
334: }
335: }
336: }
337: for (i = 0; i < 256; i++) {
338: if (r1->hyr_gateway[i] != r2->hyr_gateway[i]) {
339: fprintf(stderr, "%s: gate[%d] = %d v2 %d\n", progname, i,
340: r1->hyr_gateway[i], r2->hyr_gateway[i]);
341: }
342: }
343: return(ndiffs);
344: }
345:
346: main(argc, argv)
347: int argc;
348: char *argv[];
349: {
350: char *filename = NULL; /* input file name (default stdin) */
351: char *cp;
352:
353: if (argc)
354: progname = argv[0];
355: else
356: progname = "hyroute";
357:
358: argc--; argv++;
359: while (argc) {
360: if (argv[0][0] == '-' && argv[0][1] != '\0') {
361: cp = &argv[0][0];
362: switch(*++cp) {
363:
364: case 's': /* set the kernel table */
365: set_flag++;
366: break;
367:
368: case 'd': /* print the kernel table */
369: dump_flag++;
370: break;
371:
372: case 'p': /* print symbol table */
373: print_flag++;
374: break;
375:
376: case 'c': /* compare with kernel table */
377: comp_flag++;
378: break;
379:
380: case 'l': /* check the parser */
381: lexdebug++;
382: break;
383:
384: default:
385: fprintf(stderr, "%s: unrecognized switch -%c\n", progname, *cp);
386: exit(1);
387: }
388: } else if (devname == NULL) {
389: devname = argv[0];
390: } else if (filename == NULL) {
391: filename = argv[0];
392: } else {
393: fprintf(stderr, "%s: extra arguments starting with %s\n", progname, argv[0]);
394: exit(1);
395: }
396: argc--; argv++;
397: }
398:
399: if (filename != NULL || set_flag || comp_flag)
400: readin(filename, &hy_route);
401:
402: if (print_flag)
403: symtab_print();
404:
405: if (set_flag)
406: settable(&hy_route);
407:
408: if (dump_flag) {
409: if (filename == NULL) {
410: gettable(&ker_hy_route);
411: print_table(&ker_hy_route);
412: } else {
413: print_table(&hy_route);
414: }
415: }
416:
417: if (comp_flag) {
418: gettable(&ker_hy_route);
419: compare_table(&hy_route, &ker_hy_route);
420: }
421: }
422:
423: /*
424: * read in the control file named filename into structure r
425: */
426: readin(filename, r)
427: char *filename;
428: register struct hy_route *r;
429: {
430: register char *cp;
431: register struct sym *s;
432: unsigned gates[256];
433: char buf[512];
434: unsigned i;
435: extern FILE *yyin;
436:
437: if (filename == NULL || *filename == '\0' || strcmp(filename, "-") == 0) {
438: yyin = stdin;
439: } else {
440: yyin = fopen(filename, "r");
441: if (yyin == NULL) {
442: perror(filename);
443: exit(1);
444: }
445: }
446:
447: maxgate = 0;
448: bzero((char *)r, sizeof(*r));
449:
450: lex_error = 0;
451: yylex();
452: if (lex_error) {
453: fprintf(stderr, "hyroute: syntax errors, aborting operation\n");
454: exit(1);
455: }
456:
457: for (s = sym_head; s != NULL; s = s->sym_next) {
458: if (s->sym_flags & HS_DIR) {
459: add_direct(inet_lnaof(s->sym_inaddr), s->sym_dst, s->sym_ctl, s->sym_access, s->sym_flags, r);
460: } else if (s->sym_flags & HS_INDIR) {
461: for (i = 0; i < s->sym_ngate; i++)
462: gates[i] = inet_lnaof(s->sym_gate[i]->sym_inaddr);
463: add_gates(inet_lnaof(s->sym_inaddr), s->sym_ngate, gates, r);
464: }
465: }
466: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.