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

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

unix.superglobalmegacorp.com

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