|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* Copyright (c) 1993 NeXT Computer, Inc. All rights reserved. ! 23: * ! 24: * tokensr.h - Token-ring IEEE 802.5 source routing utility functions. ! 25: * ! 26: * We currently make these functions static inlines. These should ! 27: * be considered for movement to a library and made public (after ! 28: * sanitizing API). ! 29: * ! 30: * HISTORY ! 31: * ! 32: * 22-Jul-94 John Immordino (jimmord) at NeXT ! 33: * Converted static array of source routes to a hash table. ! 34: * Loosely coupled hash table entries to arp table entries, ie. ! 35: * when hash table is full, delete the first entry for which there ! 36: * is no arp entry before inserting the next source route. ! 37: * ! 38: * 26-Apr-94 John Immordino (jimmord) at NeXT ! 39: * Cleaned up. Fixed byte-swap problems, converted all addresses to ! 40: * character arrays, etc. ! 41: * ! 42: * 07-Apr-93 Joel Greenblatt at NeXT ! 43: * Created ! 44: * ! 45: */ ! 46: ! 47: #ifdef DRIVER_PRIVATE ! 48: ! 49: #ifndef _TOKENSR_ ! 50: #define _TOKENSR_ ! 51: ! 52: #include <sys/socket.h> ! 53: #include <net/tokendefs.h> ! 54: #include <net/if.h> ! 55: #include <net/if_arp.h> ! 56: #include <netinet/in.h> ! 57: #include <netinet/if_ether.h> ! 58: #include <objc/hashtable.h> /* Not an Obj-C header */ ! 59: ! 60: /* ! 61: * Virtual driver parameters ! 62: * Used by if_vtrXX modules ! 63: */ ! 64: typedef struct { ! 65: int vunit; ! 66: int vflags; ! 67: int vmtu; ! 68: int vtokpri; ! 69: } vparms_t; ! 70: ! 71: ! 72: /* ! 73: * Source routing table entry ! 74: * Note: ipAddr must be the first element in order for our hash table ! 75: * code to work properly. ! 76: */ ! 77: typedef struct { ! 78: unsigned long ipAddr; /* IP address of this entry - */ ! 79: /* needed for our temporary */ ! 80: /* arp table lookup scheme */ ! 81: sroute_t ri; /* routing information field */ ! 82: } srtable_t; ! 83: ! 84: ! 85: /* ! 86: * Encoded source-routing broadcast type (used as parameter to ! 87: * source routing routines). ! 88: */ ! 89: typedef enum { ! 90: SRB_OFF, /* no source-route broadcast */ ! 91: SRB_AR, /* all-routes broadcast */ ! 92: SRB_SR, /* single-route broadcast */ ! 93: SRB_INVALID /* invalid entry */ ! 94: } srbcast_t; ! 95: ! 96: /* ! 97: * ARP code taken from bsd/netinet/if_ether.c. Need this in order ! 98: * to perform lookups of IP addresses to determine which source route ! 99: * entry to remove from the table. The first source route entry without ! 100: * a corresponding ARP entry will be removed. ! 101: */ ! 102: #ifdef GATEWAY ! 103: #define ARPTAB_BSIZ 16 /* bucket size */ ! 104: #define ARPTAB_NB 37 /* number of buckets */ ! 105: #else ! 106: #define ARPTAB_BSIZ 9 /* bucket size */ ! 107: #define ARPTAB_NB 19 /* number of buckets */ ! 108: #endif ! 109: ! 110: extern struct arptab arptab[]; ! 111: ! 112: #define ARPTAB_HASH(a) \ ! 113: ((u_long)(a) % ARPTAB_NB) ! 114: ! 115: /* ! 116: * Change to permit multiple heterogenous interfaces to co-exist. ! 117: */ ! 118: #define ARPTAB_LOOK(at,addr,ifp) { \ ! 119: register n; \ ! 120: at = &arptab[ARPTAB_HASH(addr) * ARPTAB_BSIZ]; \ ! 121: for (n = 0 ; n < ARPTAB_BSIZ ; n++,at++) \ ! 122: if (at->at_iaddr.s_addr == addr && \ ! 123: (!(ifp) || at->at_if == (ifp))) \ ! 124: break; \ ! 125: if (n >= ARPTAB_BSIZ) \ ! 126: at = 0; \ ! 127: } ! 128: ! 129: ! 130: /* ! 131: * Initialize callers source routing table. ! 132: */ ! 133: static __inline__ ! 134: void init_src_routing(NXHashTable **sourceRouteTable) ! 135: { ! 136: extern NXHashTablePrototype SRTablePrototype; ! 137: *sourceRouteTable = NXCreateHashTable(SRTablePrototype, 0, NULL); ! 138: } ! 139: ! 140: /* ! 141: * Search for a source route (given a destination address). ! 142: */ ! 143: static __inline__ ! 144: sroute_t *find_sr(NXHashTable *sourceRouteTable, unsigned long idst) ! 145: { ! 146: srtable_t *sourceRouteEntry = NXHashGet(sourceRouteTable, ! 147: (const void *)&idst); ! 148: if (sourceRouteEntry) { ! 149: return &sourceRouteEntry->ri; ! 150: } ! 151: return NULL; ! 152: } ! 153: ! 154: /* ! 155: * Add an entry to the callers source routing table. ! 156: */ ! 157: static __inline__ ! 158: void add_sr(netif_t netif, NXHashTable *sourceRouteTable, unsigned long ipAddr, ! 159: sroute_t *rip, unsigned long srLimit) ! 160: { ! 161: srtable_t *sourceRouteEntry; ! 162: struct ifnet *ifp = (struct ifnet *)netif; ! 163: ! 164: if ((rip->rc.len > 18)|| (rip->rc.len < 2) || (rip->rc.len & 1)) ! 165: return; ! 166: ! 167: /* ! 168: * See if the entry is already in the table ! 169: */ ! 170: sourceRouteEntry = NXHashGet(sourceRouteTable,&ipAddr); ! 171: if (sourceRouteEntry) { ! 172: bcopy(rip, &sourceRouteEntry->ri, rip->rc.len); ! 173: sourceRouteEntry->ri.rc.bcast = 0; /* make non-bcast */ ! 174: sourceRouteEntry->ri.rc.dir = ~sourceRouteEntry->ri.rc.dir; ! 175: return; ! 176: } ! 177: ! 178: /* ! 179: * See if there's room in the table for another entry. ! 180: */ ! 181: if (NXCountHashTable(sourceRouteTable) >= srLimit) { ! 182: BOOL dumpedOne = NO; ! 183: NXHashState state = NXInitHashState(sourceRouteTable); ! 184: ! 185: /* ! 186: * Need to delete an entry. ! 187: */ ! 188: while (NXNextHashState(sourceRouteTable, &state, ! 189: (void **)&sourceRouteEntry)) { ! 190: ! 191: struct arptab *at; ! 192: ! 193: /* ! 194: * Look for an entry without a corresponding entry in the ! 195: * arp table. ! 196: */ ! 197: ARPTAB_LOOK(at, sourceRouteEntry->ipAddr, ifp); ! 198: if (at == NULL) { ! 199: /* ! 200: * Found one - try to remove it ! 201: */ ! 202: sourceRouteEntry = ! 203: NXHashRemove(sourceRouteTable, ! 204: (const void *)&sourceRouteEntry->ipAddr); ! 205: if (sourceRouteEntry) { ! 206: kfree(sourceRouteEntry,sizeof(srtable_t)); ! 207: dumpedOne = YES; ! 208: break; ! 209: } ! 210: } ! 211: } ! 212: if (dumpedOne == NO) { ! 213: printf("add_sr: source route table overflow\n"); ! 214: return; ! 215: } ! 216: } ! 217: ! 218: sourceRouteEntry = (srtable_t *)kalloc(sizeof(srtable_t)); ! 219: ! 220: sourceRouteEntry->ipAddr = ipAddr; ! 221: bcopy(rip, &sourceRouteEntry->ri, rip->rc.len); ! 222: sourceRouteEntry->ri.rc.bcast = 0; /* make non-bcast */ ! 223: sourceRouteEntry->ri.rc.dir = ~sourceRouteEntry->ri.rc.dir; ! 224: ! 225: sourceRouteEntry = ! 226: NXHashInsert(sourceRouteTable,(const void *)&sourceRouteEntry->ipAddr); ! 227: if (sourceRouteEntry) /* shouldn't happen */ ! 228: kfree(sourceRouteEntry,sizeof(srtable_t)); ! 229: } ! 230: ! 231: /* ! 232: * Find & return the source route to the callers address. ! 233: */ ! 234: static __inline__ ! 235: void get_src_route(NXHashTable *sourceRouteTable, unsigned long idst, ! 236: unsigned char *da, tokenHeader_t *th) ! 237: { ! 238: sroute_t *sourceRoute; ! 239: ! 240: if (da[0] & 0x80) ! 241: return; /* don't handle group addresses */ ! 242: ! 243: /* ! 244: * Find source route in srtable and copy to caller's ! 245: * tokenHeader_t (or turn off sri bit). ! 246: */ ! 247: sourceRoute = find_sr(sourceRouteTable, idst); ! 248: if (sourceRoute) { ! 249: bcopy(sourceRoute, &th->ri, sourceRoute->rc.len); ! 250: th->sa[0] |= TR_RII; ! 251: } ! 252: else ! 253: th->sa[0] &= ~TR_RII; /* turn off source routing bit */ ! 254: } ! 255: ! 256: /* ! 257: * Save the source route in the callers MAC header. ! 258: */ ! 259: static __inline__ ! 260: void save_src_route(netif_t netif, NXHashTable *sourceRouteTable, ! 261: unsigned long ipAddr, tokenHeader_t *th, unsigned long srLimit) ! 262: { ! 263: /* ! 264: * If frame has a routing field > 2 then save it (i.e. it's been ! 265: * thru at least one bridge). ! 266: */ ! 267: if ((th->sa[0] & TR_RII) && (th->ri.rc.len > 2)) ! 268: add_sr(netif, sourceRouteTable, ipAddr, &th->ri, srLimit); ! 269: } ! 270: ! 271: ! 272: /* ! 273: * Returns length of the source routing field in callers MAC header. ! 274: * Returns -1 if the header is invalid. ! 275: */ ! 276: static __inline__ ! 277: int get_ri_len(tokenHeader_t *th) ! 278: { ! 279: int ri_len = 0; ! 280: sroute_t *rif = (sroute_t *)&th->ri; ! 281: ! 282: if (th->sa[0] & 0x80) { ! 283: ri_len = (int)rif->rc.len; ! 284: if ((ri_len & 1) || (ri_len < 2) || (ri_len > 18)) { ! 285: ri_len = -1; ! 286: } ! 287: } ! 288: return ri_len; ! 289: } ! 290: ! 291: /* ! 292: * Returns the length of an 802.5 MAC header (including routing field). ! 293: */ ! 294: static __inline__ ! 295: int get_8025_hdr_len(tokenHeader_t *th) ! 296: { ! 297: int ri_len; ! 298: ! 299: ri_len = get_ri_len(th); ! 300: if (ri_len < 0) ! 301: return ri_len; // bad header ! 302: ! 303: return ri_len + MAC_HDR_MIN; ! 304: } ! 305: ! 306: /* ! 307: * Returns 1 if mac address is any type of broadcast, zero otherwise. ! 308: */ ! 309: static __inline__ ! 310: int check_mac_bcast(tokenHeader_t *th) ! 311: { ! 312: if (th->da[0] & 0x80) ! 313: return 1; // group address (I/G bit) ! 314: return 0; ! 315: } ! 316: ! 317: /* ! 318: * Build a broadcast routing field in the callers MAC header. ! 319: */ ! 320: static __inline__ ! 321: void make_sr_bcast(tokenHeader_t *th, srbcast_t type) ! 322: { ! 323: if ((type == SRB_OFF) || (type >= SRB_INVALID)) { ! 324: th->sa[0] &= ~TR_RII; ! 325: return; ! 326: } ! 327: ! 328: th->sa[0] |= TR_RII; /* turn on rii bit to ind. src rtng field */ ! 329: ! 330: /* ! 331: * Build the routing control field for the requested ! 332: * broadcast type. ! 333: */ ! 334: if (type == SRB_AR) ! 335: th->ri.rc.bcast = BI_AR_BCAST; ! 336: else ! 337: th->ri.rc.bcast = BI_SR_BCAST; ! 338: ! 339: th->ri.rc.len = 2; ! 340: th->ri.rc.dir = 0; ! 341: th->ri.rc.longf = LF_BCAST; ! 342: th->ri.rc.rsrvd = 0; ! 343: } ! 344: ! 345: /* ! 346: * Make the callers MAC header a reply to sender. ! 347: */ ! 348: static __inline__ ! 349: void make_mac_reply(tokenHeader_t *th) ! 350: { ! 351: ! 352: /* ! 353: * Copy source address to destination address. Turn off RII bit in ! 354: * the destination address. ! 355: */ ! 356: bcopy(th->sa, th->da, sizeof(th->da)); ! 357: th->da[0] &= ~TR_RII; ! 358: ! 359: /* ! 360: * Convert the source routing field to a reply (flip direction ! 361: * bit & turn off broadcast bits). ! 362: */ ! 363: if (th->sa[0] & TR_RII) { ! 364: th->ri.rc.dir = ~th->ri.rc.dir; ! 365: th->ri.rc.bcast = 0; ! 366: } ! 367: } ! 368: ! 369: ! 370: #endif /* _TOKENSR_ */ ! 371: ! 372: #endif /* DRIVER_PRIVATE */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.