]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/dlil.h
5a34f2823a487d9d2e39a329c2528a822a7648e3
[apple/xnu.git] / bsd / net / dlil.h
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * Copyright (c) 1999 Apple Computer, Inc.
27 *
28 * Data Link Inteface Layer
29 * Author: Ted Walker
30 */
31
32
33 #ifndef DLIL_H
34 #define DLIL_H
35 #include <sys/appleapiopts.h>
36
37 #if __STDC__
38
39 struct ifnet;
40 struct mbuf;
41 struct ether_header;
42
43 #endif
44
45
46 #ifdef __APPLE_API_UNSTABLE
47 #define DLIL_LAST_FILTER -1
48 #define DLIL_NULL_FILTER -2
49
50 #define DLIL_WAIT_FOR_FREE -2
51
52 #define DLIL_BLUEBOX 1
53
54
55
56 #include <net/if.h>
57 #include <net/if_var.h>
58 #include <sys/kern_event.h>
59
60 enum {
61 BPF_TAP_DISABLE,
62 BPF_TAP_INPUT,
63 BPF_TAP_OUTPUT,
64 BPF_TAP_INPUT_OUTPUT
65 };
66
67
68 struct dl_tag_attr_str {
69 u_long dl_tag;
70 short if_flags;
71 short if_unit;
72 u_long if_family;
73 u_long protocol_family;
74 };
75
76
77 struct dlil_pr_flt_str {
78 caddr_t cookie;
79
80 int (*filter_dl_input)(caddr_t cookie,
81 struct mbuf **m,
82 char **frame_header,
83 struct ifnet **ifp);
84
85
86 int (*filter_dl_output)(caddr_t cookie,
87 struct mbuf **m,
88 struct ifnet **ifp,
89 struct sockaddr **dest,
90 char *dest_linkaddr,
91 char *frame_type);
92
93 int (*filter_dl_event)(caddr_t cookie,
94 struct kern_event_msg *event_msg);
95
96 int (*filter_dl_ioctl)(caddr_t cookie,
97 struct ifnet *ifp,
98 u_long ioctl_cmd,
99 caddr_t ioctl_arg);
100
101 int (*filter_detach)(caddr_t cookie);
102 u_long reserved[2];
103 };
104
105 struct dlil_if_flt_str {
106 caddr_t cookie;
107 int (*filter_if_input)(caddr_t cookie,
108 struct ifnet **ifnet_ptr,
109 struct mbuf **mbuf_ptr,
110 char **frame_ptr);
111
112 int (*filter_if_event)(caddr_t cookie,
113 struct ifnet **ifnet_ptr,
114 struct kern_event_msg **event_msg_ptr);
115
116 int (*filter_if_output)(caddr_t cookie,
117 struct ifnet **ifnet_ptr,
118 struct mbuf **mbuf_ptr);
119
120
121 int (*filter_if_ioctl)(caddr_t cookie,
122 struct ifnet *ifnet_ptr,
123 u_long ioctl_code_ptr,
124 caddr_t ioctl_arg_ptr);
125
126 int (*filter_if_free)(caddr_t cookie,
127 struct ifnet *ifnet_ptr);
128
129 int (*filter_detach)(caddr_t cookie);
130 u_long reserved[2];
131 };
132
133
134 #define DLIL_PR_FILTER 1
135 #define DLIL_IF_FILTER 2
136
137
138
139 typedef int (*dl_input_func)(struct mbuf *m, char *frame_header,
140 struct ifnet *ifp, u_long dl_tag, int sync_ok);
141 typedef int (*dl_pre_output_func)(struct ifnet *ifp,
142 struct mbuf **m,
143 struct sockaddr *dest,
144 caddr_t route_entry,
145 char *frame_type,
146 char *dst_addr,
147 u_long dl_tag);
148
149 typedef int (*dl_event_func)(struct kern_event_msg *event,
150 u_long dl_tag);
151
152 typedef int (*dl_offer_func)(struct mbuf *m, char *frame_header);
153 typedef int (*dl_ioctl_func)(u_long dl_tag,
154 struct ifnet *ifp,
155 u_long ioctl_cmd,
156 caddr_t ioctl_arg);
157
158
159
160 #ifdef __APPLE_API_PRIVATE
161 struct dlil_filterq_entry {
162 TAILQ_ENTRY(dlil_filterq_entry) que;
163 u_long filter_id;
164 int type;
165 union {
166 struct dlil_if_flt_str if_filter;
167 struct dlil_pr_flt_str pr_filter;
168 } variants;
169 };
170 #else
171 struct dlil_filterq_entry;
172 #endif /* __APPLE_API_PRIVATE */
173
174 TAILQ_HEAD(dlil_filterq_head, dlil_filterq_entry);
175
176
177 struct if_proto {
178 TAILQ_ENTRY(if_proto) next;
179 u_long dl_tag;
180 struct dlil_filterq_head pr_flt_head;
181 struct ifnet *ifp;
182 dl_input_func dl_input;
183 dl_pre_output_func dl_pre_output;
184 dl_event_func dl_event;
185 dl_offer_func dl_offer;
186 dl_ioctl_func dl_ioctl;
187 u_long protocol_family;
188 u_long reserved[4];
189
190 };
191
192 #ifdef __APPLE_API_PRIVATE
193 TAILQ_HEAD(dlil_proto_head, if_proto);
194
195 struct dlil_tag_list_entry {
196 TAILQ_ENTRY(dlil_tag_list_entry) next;
197 struct ifnet *ifp;
198 u_long dl_tag;
199 };
200 #endif /* __APPLE_API_PRIVATE */
201
202
203 #ifdef __APPLE_API_OBSOLETE
204 /* Obsolete types */
205 #define DLIL_DESC_RAW 1
206 #define DLIL_DESC_802_2 2
207 #define DLIL_DESC_802_2_SNAP 3
208 /*
209 * DLIL_DESC_RAW - obsolete type, data in variants.bitmask or native_type
210 * if variants.bitmask.proto_id_length, native_type in host
211 * byte order.
212 * DLIL_DESC_802_2 - obsolete, data in variants.desc_802_2
213 * DLIL_DESC_802_2_SNAP - obsolete, data in variants.desc_802_2_SNAP
214 * protocol field in host byte order
215 */
216 #endif /* __APPLE_API_OBSOLETE */
217
218 /* Ehernet specific types */
219 #define DLIL_DESC_ETYPE2 4
220 #define DLIL_DESC_SAP 5
221 #define DLIL_DESC_SNAP 6
222 /*
223 * DLIL_DESC_ETYPE2 - native_type must point to 2 byte ethernet raw protocol,
224 * variants.native_type_length must be set to 2
225 * DLIL_DESC_SAP - native_type must point to 3 byte SAP protocol
226 * variants.native_type_length must be set to 3
227 * DLIL_DESC_SNAP - native_type must point to 5 byte SNAP protocol
228 * variants.native_type_length must be set to 5
229 *
230 * All protocols must be in Network byte order.
231 *
232 * Future interface families may define more protocol types they know about.
233 * The type implies the offset and context of the protocol data at native_type.
234 * The length of the protocol data specified at native_type must be set in
235 * variants.native_type_length.
236 */
237
238 struct dlil_demux_desc {
239 TAILQ_ENTRY(dlil_demux_desc) next;
240
241 int type;
242 u_char *native_type;
243
244 union {
245 /* Structs in this union are obsolete. They exist for binary compatability only */
246 /* Only the native_type_length is used */
247 struct {
248 u_long proto_id_length; /* IN LONGWORDS!!! */
249 u_char *proto_id; /* No longer supported by Ethernet family */
250 u_char *proto_id_mask;
251 } bitmask;
252
253 struct {
254 u_char dsap;
255 u_char ssap;
256 u_char control_code;
257 u_char pad;
258 } desc_802_2;
259
260 struct {
261 u_char dsap; /* Ignored, assumed to be 0xAA */
262 u_char ssap; /* Ignored, assumed to be 0xAA */
263 u_char control_code; /* Ignored, assumed to be 0x03 */
264 u_char org[3];
265 u_short protocol_type; /* In host byte order */
266 } desc_802_2_SNAP;
267
268 /* Length of data pointed to by native_type, must be set correctly */
269 u_int32_t native_type_length;
270 } variants;
271 };
272
273 TAILQ_HEAD(ddesc_head_str, dlil_demux_desc);
274
275
276 struct dlil_proto_reg_str {
277 struct ddesc_head_str demux_desc_head;
278 u_long interface_family;
279 u_long protocol_family;
280 short unit_number;
281 int default_proto; /* 0 or 1 */
282 dl_input_func input;
283 dl_pre_output_func pre_output;
284 dl_event_func event;
285 dl_offer_func offer;
286 dl_ioctl_func ioctl;
287 u_long reserved[4];
288 };
289
290
291 int dlil_attach_interface_filter(struct ifnet *ifnet_ptr,
292 struct dlil_if_flt_str *interface_filter,
293 u_long *filter_id,
294 int insertion_point);
295
296 int
297 dlil_input(struct ifnet *ifp, struct mbuf *m_head, struct mbuf *m_tail);
298
299 int
300 dlil_output(u_long dl_tag,
301 struct mbuf *m,
302 caddr_t route,
303 struct sockaddr *dest,
304 int raw);
305
306
307 int
308 dlil_ioctl(u_long proto_family,
309 struct ifnet *ifp,
310 u_long ioctl_code,
311 caddr_t ioctl_arg);
312
313 int
314 dlil_attach_protocol(struct dlil_proto_reg_str *proto,
315 u_long *dl_tag);
316
317 int
318 dlil_detach_protocol(u_long dl_tag);
319
320 int
321 dlil_if_attach(struct ifnet *ifp);
322
323 int
324 dlil_attach_protocol_filter(u_long dl_tag,
325 struct dlil_pr_flt_str *proto_filter,
326 u_long *filter_id,
327 int insertion_point);
328 int
329 dlil_detach_filter(u_long filter_id);
330
331 struct dlil_ifmod_reg_str {
332 int (*add_if)(struct ifnet *ifp);
333 int (*del_if)(struct ifnet *ifp);
334 int (*add_proto)(struct ddesc_head_str *demux_desc_head,
335 struct if_proto *proto, u_long dl_tag);
336 int (*del_proto)(struct if_proto *proto, u_long dl_tag);
337 int (*ifmod_ioctl)(struct ifnet *ifp, u_long ioctl_cmd, caddr_t data);
338 int (*shutdown)();
339 int (*init_if)(struct ifnet *ifp);
340 u_long reserved[3];
341 };
342
343
344 int dlil_reg_if_modules(u_long interface_family,
345 struct dlil_ifmod_reg_str *ifmod_reg);
346
347 int
348 dlil_inject_if_input(struct mbuf *m, char *frame_header, u_long from_id);
349
350 int
351 dlil_inject_pr_input(struct mbuf *m, char *frame_header, u_long from_id);
352
353 int
354 dlil_inject_pr_output(struct mbuf *m,
355 struct sockaddr *dest,
356 int raw,
357 char *frame_type,
358 char *dst_linkaddr,
359 u_long from_id);
360
361 int
362 dlil_inject_if_output(struct mbuf *m, u_long from_id);
363
364 int
365 dlil_find_dltag(u_long if_family, short unit, u_long proto_family, u_long *dl_tag);
366
367
368 int
369 dlil_event(struct ifnet *ifp, struct kern_event_msg *event);
370
371 int dlil_dereg_if_modules(u_long interface_family);
372
373 int
374 dlil_if_detach(struct ifnet *ifp);
375
376
377 /*
378
379 Function : dlil_if_acquire
380
381 DLIL manages the list of ifnet interfaces allocated using the dlil_if_acquire
382 function. This list if not the same as the list of attached interfaces,
383 visible with ifconfig.
384 This list contains attached as well as detached interfaces.
385 Detached interfaces are kept in the list to prevent the kernel from crashing
386 by using an old ifp.
387
388 if it succeeds, dlil_if_acquire returns an ifnet data structure.
389 This ifnet can either be a new allocated block of memory, or an ifnet
390 that already existed and that DLIL has found in its list of unused
391 interface and that matches the family/uniqueid tuple.
392
393 dlil_if_acquire can fail if the requested interface is already in use,
394 or if no memory is available to create a new interface.
395
396 The typical sequence of call for a driver will be :
397 dlil_if_acquire(... &ifp)
398 ... Fill in the ifnet ...
399 dlil_if_attach(ifp)
400 ... Driver work ...
401 dlil_if_detach(ifp)
402 dlil_if_release(ifp)
403
404 Important : ifnet allocated by DLIL are managed by DLIL. DLIL takes care
405 of them, and keeps them until a driver wants to reuse them, but DLIL may
406 also decide to free them when not in use by a driver.
407
408 Note : the structure returned will actually be large enough to contain
409 an arpcom structure (ifnet + ethernet) structure.
410 Drivers cannot extend the structure and must to store their private
411 information in if_sofc and if_private.
412
413 Parameters :
414 'family' uniquely identifies DLIL interface family.
415 'uniqueid' is a unique identifier for that interface, managed by the
416 driver (for example MAC address for ethernet).
417 'uniqueid_len' is the length of the unique id.
418 'ifp' contains on output the allocated ifnet.
419
420 Return code :
421
422 0 :
423
424 If an ifnet matching the uniqueid is found, the matching ifnet is returned
425 in ifp and the flags IFEF_REUSE and IF_INUSE are set in the if_eflags.
426 The fields in the ifnet are NOT zeroed and may contain old values that
427 the driver can reuse. [They are not necessarily the values that were
428 there when the driver released the ifnet, as protocol might have
429 continued to update them].
430
431 If no matching ifnet is found, a new structure is allocated and returned
432 in ifp with all fields initialized to 0.
433 The flag IF_INUSE is set in the if_eflags. IFEF_REUSE is NOT set.
434 dlil_if_acquire will copy the uniqueid and keep it for matching purpose.
435
436 If 'uniqueid' is NULL, then dlil_if_acquire will return the first
437 ifnet that contains a null uniqueid for that family, with the flags
438 IFEF_REUSE and IF_INUSE set.
439 If no ifnet is available, a new one will be created.
440
441 ENOMEM:
442
443 If no matching interface is found, and no memory can be allocated,
444 dlil_if_acquire will return ENOMEM.
445
446
447 EBUSY:
448
449 If the unique id matches the id of an interface currently in use,
450 dlil_if_acquire will return EBUSY.
451 An interface 'in use' is an allocated interface, not necessarily attached.
452
453 */
454
455 int dlil_if_acquire(u_long family, void *uniqueid, size_t uniqueid_len,
456 struct ifnet **ifp);
457
458
459 /*
460
461 Function : dlil_if_release
462
463 dlil_if_release will transfer control of the ifnet to DLIL.
464 DLIL will keep the interface in its list, marking it unused.
465 The fields will be left in their current state, so the driver can reuse
466 the ifnet later, by calling dlil_if_acquire.
467 The if_eflags IF_INUSE will be cleared.
468 The fields if_output, if_ioctl, if_free and if_set_bpf_tap will be changed
469 to point to DLIL private functions.
470 After calling dlil_if_acquire, the driver can safely terminate and
471 unload if necessary.
472 Note : if the call to dlil_if_detach returns DLIL_WAIT_FOR_FREE, the
473 driver can safely ignore it and call dlil_if_release.
474
475 Parameters :
476 ifp is the pointer to the ifnet to release.
477
478 */
479
480 void dlil_if_release(struct ifnet *ifp);
481
482 #endif /* __APPLE_API_UNSTABLE */
483 #endif /* DLIL_H */