#ifdef DRIVER_PRIVATE
#ifndef _TOKENSR_
#define _TOKENSR_
#include <sys/socket.h>
#include <net/tokendefs.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <objc/hashtable.h>
typedef struct {
int vunit;
int vflags;
int vmtu;
int vtokpri;
} vparms_t;
typedef struct {
unsigned long ipAddr;
sroute_t ri;
} srtable_t;
typedef enum {
SRB_OFF,
SRB_AR,
SRB_SR,
SRB_INVALID
} srbcast_t;
#ifdef GATEWAY
#define ARPTAB_BSIZ 16
#define ARPTAB_NB 37
#else
#define ARPTAB_BSIZ 9
#define ARPTAB_NB 19
#endif
extern struct arptab arptab[];
#define ARPTAB_HASH(a) \
((u_long)(a) % ARPTAB_NB)
#define ARPTAB_LOOK(at,addr,ifp) { \
register n; \
at = &arptab[ARPTAB_HASH(addr) * ARPTAB_BSIZ]; \
for (n = 0 ; n < ARPTAB_BSIZ ; n++,at++) \
if (at->at_iaddr.s_addr == addr && \
(!(ifp) || at->at_if == (ifp))) \
break; \
if (n >= ARPTAB_BSIZ) \
at = 0; \
}
static __inline__
void init_src_routing(NXHashTable **sourceRouteTable)
{
extern NXHashTablePrototype SRTablePrototype;
*sourceRouteTable = NXCreateHashTable(SRTablePrototype, 0, NULL);
}
static __inline__
sroute_t *find_sr(NXHashTable *sourceRouteTable, unsigned long idst)
{
srtable_t *sourceRouteEntry = NXHashGet(sourceRouteTable,
(const void *)&idst);
if (sourceRouteEntry) {
return &sourceRouteEntry->ri;
}
return NULL;
}
static __inline__
void add_sr(netif_t netif, NXHashTable *sourceRouteTable, unsigned long ipAddr,
sroute_t *rip, unsigned long srLimit)
{
srtable_t *sourceRouteEntry;
struct ifnet *ifp = (struct ifnet *)netif;
if ((rip->rc.len > 18)|| (rip->rc.len < 2) || (rip->rc.len & 1))
return;
sourceRouteEntry = NXHashGet(sourceRouteTable,&ipAddr);
if (sourceRouteEntry) {
bcopy(rip, &sourceRouteEntry->ri, rip->rc.len);
sourceRouteEntry->ri.rc.bcast = 0;
sourceRouteEntry->ri.rc.dir = ~sourceRouteEntry->ri.rc.dir;
return;
}
if (NXCountHashTable(sourceRouteTable) >= srLimit) {
BOOL dumpedOne = NO;
NXHashState state = NXInitHashState(sourceRouteTable);
while (NXNextHashState(sourceRouteTable, &state,
(void **)&sourceRouteEntry)) {
struct arptab *at;
ARPTAB_LOOK(at, sourceRouteEntry->ipAddr, ifp);
if (at == NULL) {
sourceRouteEntry =
NXHashRemove(sourceRouteTable,
(const void *)&sourceRouteEntry->ipAddr);
if (sourceRouteEntry) {
kfree(sourceRouteEntry,sizeof(srtable_t));
dumpedOne = YES;
break;
}
}
}
if (dumpedOne == NO) {
printf("add_sr: source route table overflow\n");
return;
}
}
sourceRouteEntry = (srtable_t *)kalloc(sizeof(srtable_t));
sourceRouteEntry->ipAddr = ipAddr;
bcopy(rip, &sourceRouteEntry->ri, rip->rc.len);
sourceRouteEntry->ri.rc.bcast = 0;
sourceRouteEntry->ri.rc.dir = ~sourceRouteEntry->ri.rc.dir;
sourceRouteEntry =
NXHashInsert(sourceRouteTable,(const void *)&sourceRouteEntry->ipAddr);
if (sourceRouteEntry)
kfree(sourceRouteEntry,sizeof(srtable_t));
}
static __inline__
void get_src_route(NXHashTable *sourceRouteTable, unsigned long idst,
unsigned char *da, tokenHeader_t *th)
{
sroute_t *sourceRoute;
if (da[0] & 0x80)
return;
sourceRoute = find_sr(sourceRouteTable, idst);
if (sourceRoute) {
bcopy(sourceRoute, &th->ri, sourceRoute->rc.len);
th->sa[0] |= TR_RII;
}
else
th->sa[0] &= ~TR_RII;
}
static __inline__
void save_src_route(netif_t netif, NXHashTable *sourceRouteTable,
unsigned long ipAddr, tokenHeader_t *th, unsigned long srLimit)
{
if ((th->sa[0] & TR_RII) && (th->ri.rc.len > 2))
add_sr(netif, sourceRouteTable, ipAddr, &th->ri, srLimit);
}
static __inline__
int get_ri_len(tokenHeader_t *th)
{
int ri_len = 0;
sroute_t *rif = (sroute_t *)&th->ri;
if (th->sa[0] & 0x80) {
ri_len = (int)rif->rc.len;
if ((ri_len & 1) || (ri_len < 2) || (ri_len > 18)) {
ri_len = -1;
}
}
return ri_len;
}
static __inline__
int get_8025_hdr_len(tokenHeader_t *th)
{
int ri_len;
ri_len = get_ri_len(th);
if (ri_len < 0)
return ri_len;
return ri_len + MAC_HDR_MIN;
}
static __inline__
int check_mac_bcast(tokenHeader_t *th)
{
if (th->da[0] & 0x80)
return 1; return 0;
}
static __inline__
void make_sr_bcast(tokenHeader_t *th, srbcast_t type)
{
if ((type == SRB_OFF) || (type >= SRB_INVALID)) {
th->sa[0] &= ~TR_RII;
return;
}
th->sa[0] |= TR_RII;
if (type == SRB_AR)
th->ri.rc.bcast = BI_AR_BCAST;
else
th->ri.rc.bcast = BI_SR_BCAST;
th->ri.rc.len = 2;
th->ri.rc.dir = 0;
th->ri.rc.longf = LF_BCAST;
th->ri.rc.rsrvd = 0;
}
static __inline__
void make_mac_reply(tokenHeader_t *th)
{
bcopy(th->sa, th->da, sizeof(th->da));
th->da[0] &= ~TR_RII;
if (th->sa[0] & TR_RII) {
th->ri.rc.dir = ~th->ri.rc.dir;
th->ri.rc.bcast = 0;
}
}
#endif
#endif