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