static char sccsid
[] = "@(#)hyr_main.c 4.2 (Berkeley) 7/8/83";
static char origsccsid
[] = "@(#)hyr_main.c 2.1 Hyperchannel Routing Daemon 82/11/29";
struct hyroute ker_hy_route
;
char *progname
= "hy-route";
* hash a hyperchannel address into the table
* return NULL if table is full or entry not found and adding a new one
register struct hyroute
*r
;
register struct hy_hash
*rh
= &r
->hyr_hash
[HYRHASH(key
)];
while (rh
->hyr_key
!= key
) {
if ((rh
->hyr_flags
& HYR_INUSE
) == 0)
if (rh
++ >= &r
->hyr_hash
[HYRSIZE
])
* add a direct entry to the hash table using the specified key,
* destination, control and access fields, return 0 if successful
add_direct(key
, dst
, ctl
, access
, r
)
register struct hyroute
*r
;
register struct hy_hash
*kh
= rhash(key
, 1, r
);
if ((kh
->hyr_flags
& HYR_INUSE
) == 0) {
kh
->hyr_flags
= (HYR_INUSE
| HYR_DIR
);
* compare function for the qsort in add_gates, see below
* add a gatewayed entry to the hash table using the sicified array of
* gateway keys. reuse space so as to make the gateway table small as
* possible. return 0 if successful
add_gates(key
, numgates
, gates
, r
)
register struct hyroute
*r
;
register struct hy_hash
*kh
= rhash(key
, 1, r
);
register struct hy_hash
*rh
;
for (i
= 0; i
< numgates
; i
++) {
rh
= rhash(gates
[i
], 1, r
);
gates
[i
] = rh
- &r
->hyr_hash
[0];
qsort(gates
, numgates
, sizeof(unsigned), compare_gates
);
* loop through all existing hash table entries to find one that
* matches the currently requested list
for (rh
= &r
->hyr_hash
[0]; rh
< &r
->hyr_hash
[HYRSIZE
]; rh
++) {
if (rh
->hyr_flags
& HYR_GATE
) {
if ((rh
->hyr_egate
- rh
->hyr_pgate
+ 1) == numgates
) {
for (i
= 0, j
= rh
->hyr_pgate
; i
< numgates
; i
++, j
++) {
if (gates
[i
] != r
->hyr_gateway
[j
])
* found a match, just use it
kh
->hyr_flags
= (HYR_INUSE
| HYR_GATE
);
kh
->hyr_pgate
= rh
->hyr_pgate
;
kh
->hyr_egate
= rh
->hyr_egate
;
kh
->hyr_nextgate
= rh
->hyr_nextgate
;
* didn't find anything, if there is room add a new entry
if (numgates
+ maxgate
> 256)
kh
->hyr_flags
= (HYR_INUSE
| HYR_GATE
);
kh
->hyr_egate
= maxgate
+ numgates
- 1;
kh
->hyr_nextgate
= maxgate
;
for (i
= 0; i
< numgates
; i
++, maxgate
++)
r
->hyr_gateway
[maxgate
] = gates
[i
];
if ((fd
= open("/dev/hy", 0)) < 0) {
perror("/dev/hy open in settable");
if (ioctl(fd
, HYSETROUTE
, (char *)r
) < 0) {
perror("/dev/hy HYSETROUTE ioctl in settable");
perror("/dev/hy close in settable");
if ((fd
= open("/dev/hy", 0)) < 0) {
perror("/dev/hy open in gettable");
if (ioctl(fd
, HYGETROUTE
, (char *)r
) < 0) {
perror("/dev/hy HYGETROUTE ioctl in gettable");
perror("/dev/hy close in gettable");
* print a somewhat readable version of the routine table
* that the kernel uses (mostly for debugging)
register struct hyroute
*r
;
register struct hy_hash
*rh
;
if (r
->hyr_lasttime
.tv_sec
)
printf("table set time: %s", ctime(&r
->hyr_lasttime
.tv_sec
));
printf("time not set\n");
for (i
= 0; i
< HYRSIZE
; i
++) {
if (rh
->hyr_flags
& HYR_INUSE
) {
printf("hash %d key %04x flags %x\n", i
, rh
->hyr_key
, rh
->hyr_flags
);
if (rh
->hyr_flags
& HYR_DIR
)
printf("\tdst %04x ctl %04x access %04x\n",
else if (rh
->hyr_flags
& HYR_GATE
)
printf("\tpgate %d egate %d nextgate %d\n",
for (i
= 0; i
< 256; i
++) {
printf("gate[%d] = %d\n", i
, r
->hyr_gateway
[i
]);
if (r
->hyr_gateway
[i
] == 0 && r
->hyr_gateway
[i
+1] == 0)
* comnpare teo routing tables tom insure that they are the same
register struct hyroute
*r1
, *r2
;
register struct hy_hash
*rh1
, *rh2
;
for (i
= 0; i
< HYRSIZE
; i
++) {
if (rh1
->hyr_flags
!= rh2
->hyr_flags
) {
fprintf(stderr
, "%s: hash entry %d - flags differ (%x vs %x)\n", progname
, i
, rh1
->hyr_flags
, rh2
->hyr_flags
);
} else if ((rh1
->hyr_flags
& HYR_INUSE
) && (rh1
->hyr_flags
& HYR_DIR
)) {
if (rh1
->hyr_dst
!= rh1
->hyr_dst
||
rh1
->hyr_ctl
!= rh1
->hyr_ctl
||
rh1
->hyr_access
!= rh1
->hyr_access
) {
fprintf(stderr
, "%s: direct hash entry %d - fields differ\n", progname
, i
);
fprintf(stderr
, "\tdst: %04x vs %04x\tctl: %04x vs %04x\taccess: %04x vs %04x\n",
ntohs(rh1
->hyr_dst
), ntohs(rh2
->hyr_dst
),
ntohs(rh1
->hyr_ctl
), ntohs(rh2
->hyr_ctl
),
ntohs(rh1
->hyr_access
), ntohs(rh2
->hyr_access
));
} else if ((rh1
->hyr_flags
& HYR_INUSE
) && (rh1
->hyr_flags
& HYR_GATE
)) {
if (rh1
->hyr_pgate
!= rh1
->hyr_pgate
||
rh1
->hyr_egate
!= rh1
->hyr_egate
||
rh1
->hyr_nextgate
< rh1
->hyr_pgate
||
rh1
->hyr_nextgate
> rh1
->hyr_egate
||
rh2
->hyr_nextgate
< rh2
->hyr_pgate
||
rh2
->hyr_nextgate
> rh2
->hyr_egate
) {
fprintf(stderr
, "%s: direct hash entry %d - fields differ\n", progname
, i
);
fprintf(stderr
, "\tpgate: %04x vs %04x\tegate: %04x vs %04x\tnextgate: %04x vs %04x\n",
rh1
->hyr_pgate
, rh2
->hyr_pgate
,
rh1
->hyr_egate
, rh2
->hyr_egate
,
rh1
->hyr_nextgate
, rh2
->hyr_nextgate
);
for (i
= 0; i
< 256; i
++) {
if (r1
->hyr_gateway
[i
] != r2
->hyr_gateway
[i
]) {
fprintf(stderr
, "%s: gate[%d] = %d v2 %d\n", progname
, i
,
r1
->hyr_gateway
[i
], r2
->hyr_gateway
[i
]);
char *filename
= NULL
; /* input file name (default stdin) */
if (argv
[0][0] == '-' && argv
[0][1] != '\0') {
case 's': /* set the kernel table */
case 'd': /* dump the kernel table */
case 'p': /* print symbol table */
case 'c': /* compare with kernel table */
case 'l': /* check the parser */
fprintf(stderr
, "%s: unrecognized switch -%c\n", progname
, *cp
);
} else if (filename
== NULL
) {
fprintf(stderr
, "%s: extra arguments starting with %s\n", progname
, argv
[0]);
if (filename
!= NULL
|| sflag
|| cflag
)
readin(filename
, &hy_route
);
print_table(filename
== NULL
? &ker_hy_route
: &hy_route
);
compare_table(&hy_route
, &ker_hy_route
);
* read in the control file named filename into structure r
register struct hyroute
*r
;
if (filename
== NULL
|| *filename
== '\0' || strcmp(filename
, "-") == 0) {
yyin
= fopen(filename
, "r");
bzero((char *)r
, sizeof(*r
));
fprintf(stderr
, "hyroute: syntax errors, aborting operation\n");
for (s
= sym_head
; s
!= NULL
; s
= s
->s_next
) {
if (s
->s_flags
& HS_DIR
) {
add_direct(inet_lnaof(s
->s_fulladdr
), s
->s_dst
, s
->s_ctl
, s
->s_access
, r
);
} else if (s
->s_flags
& HS_INDIR
) {
for (i
= 0; i
< s
->s_ngate
; i
++)
gates
[i
] = inet_lnaof(s
->s_gate
[i
]->s_fulladdr
);
add_gates(inet_lnaof(s
->s_fulladdr
), s
->s_ngate
, gates
, r
);