|
|
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.