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