Annotation of XNU/bsd/net/tokensr.h, revision 1.1.1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.