]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/tokensr.h
xnu-123.5.tar.gz
[apple/xnu.git] / bsd / net / tokensr.h
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 */