2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1999 Apple Computer, Inc.
28 * Data Link Inteface Layer
35 #include <sys/appleapiopts.h>
46 #ifdef __APPLE_API_UNSTABLE
47 #define DLIL_LAST_FILTER -1
48 #define DLIL_NULL_FILTER -2
50 #define DLIL_WAIT_FOR_FREE -2
52 #define DLIL_BLUEBOX 1
57 #include <net/if_var.h>
58 #include <sys/kern_event.h>
68 struct dl_tag_attr_str
{
73 u_long protocol_family
;
77 struct dlil_pr_flt_str
{
80 int (*filter_dl_input
)(caddr_t cookie
,
86 int (*filter_dl_output
)(caddr_t cookie
,
89 struct sockaddr
**dest
,
93 int (*filter_dl_event
)(caddr_t cookie
,
94 struct kern_event_msg
*event_msg
);
96 int (*filter_dl_ioctl
)(caddr_t cookie
,
101 int (*filter_detach
)(caddr_t cookie
);
105 struct dlil_if_flt_str
{
107 int (*filter_if_input
)(caddr_t cookie
,
108 struct ifnet
**ifnet_ptr
,
109 struct mbuf
**mbuf_ptr
,
112 int (*filter_if_event
)(caddr_t cookie
,
113 struct ifnet
**ifnet_ptr
,
114 struct kern_event_msg
**event_msg_ptr
);
116 int (*filter_if_output
)(caddr_t cookie
,
117 struct ifnet
**ifnet_ptr
,
118 struct mbuf
**mbuf_ptr
);
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
);
126 int (*filter_if_free
)(caddr_t cookie
,
127 struct ifnet
*ifnet_ptr
);
129 int (*filter_detach
)(caddr_t cookie
);
134 #define DLIL_PR_FILTER 1
135 #define DLIL_IF_FILTER 2
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
,
143 struct sockaddr
*dest
,
149 typedef int (*dl_event_func
)(struct kern_event_msg
*event
,
152 typedef int (*dl_offer_func
)(struct mbuf
*m
, char *frame_header
);
153 typedef int (*dl_ioctl_func
)(u_long dl_tag
,
160 #ifdef __APPLE_API_PRIVATE
161 struct dlil_filterq_entry
{
162 TAILQ_ENTRY(dlil_filterq_entry
) que
;
166 struct dlil_if_flt_str if_filter
;
167 struct dlil_pr_flt_str pr_filter
;
171 struct dlil_filterq_entry
;
172 #endif /* __APPLE_API_PRIVATE */
174 TAILQ_HEAD(dlil_filterq_head
, dlil_filterq_entry
);
178 TAILQ_ENTRY(if_proto
) next
;
180 struct dlil_filterq_head pr_flt_head
;
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
;
192 #ifdef __APPLE_API_PRIVATE
193 TAILQ_HEAD(dlil_proto_head
, if_proto
);
195 struct dlil_tag_list_entry
{
196 TAILQ_ENTRY(dlil_tag_list_entry
) next
;
200 #endif /* __APPLE_API_PRIVATE */
203 #ifdef __APPLE_API_OBSOLETE
205 #define DLIL_DESC_RAW 1
206 #define DLIL_DESC_802_2 2
207 #define DLIL_DESC_802_2_SNAP 3
209 * DLIL_DESC_RAW - obsolete type, data in variants.bitmask or native_type
210 * if variants.bitmask.proto_id_length, native_type in host
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
216 #endif /* __APPLE_API_OBSOLETE */
218 /* Ehernet specific types */
219 #define DLIL_DESC_ETYPE2 4
220 #define DLIL_DESC_SAP 5
221 #define DLIL_DESC_SNAP 6
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
230 * All protocols must be in Network byte order.
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.
238 struct dlil_demux_desc
{
239 TAILQ_ENTRY(dlil_demux_desc
) next
;
245 /* Structs in this union are obsolete. They exist for binary compatability only */
246 /* Only the native_type_length is used */
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
;
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 */
265 u_short protocol_type
; /* In host byte order */
268 /* Length of data pointed to by native_type, must be set correctly */
269 u_int32_t native_type_length
;
273 TAILQ_HEAD(ddesc_head_str
, dlil_demux_desc
);
276 struct dlil_proto_reg_str
{
277 struct ddesc_head_str demux_desc_head
;
278 u_long interface_family
;
279 u_long protocol_family
;
281 int default_proto
; /* 0 or 1 */
283 dl_pre_output_func pre_output
;
291 int dlil_attach_interface_filter(struct ifnet
*ifnet_ptr
,
292 struct dlil_if_flt_str
*interface_filter
,
294 int insertion_point
);
297 dlil_input(struct ifnet
*ifp
, struct mbuf
*m_head
, struct mbuf
*m_tail
);
300 dlil_output(u_long dl_tag
,
303 struct sockaddr
*dest
,
308 dlil_ioctl(u_long proto_family
,
314 dlil_attach_protocol(struct dlil_proto_reg_str
*proto
,
318 dlil_detach_protocol(u_long dl_tag
);
321 dlil_if_attach(struct ifnet
*ifp
);
324 dlil_attach_protocol_filter(u_long dl_tag
,
325 struct dlil_pr_flt_str
*proto_filter
,
327 int insertion_point
);
329 dlil_detach_filter(u_long filter_id
);
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
);
339 int (*init_if
)(struct ifnet
*ifp
);
344 int dlil_reg_if_modules(u_long interface_family
,
345 struct dlil_ifmod_reg_str
*ifmod_reg
);
348 dlil_inject_if_input(struct mbuf
*m
, char *frame_header
, u_long from_id
);
351 dlil_inject_pr_input(struct mbuf
*m
, char *frame_header
, u_long from_id
);
354 dlil_inject_pr_output(struct mbuf
*m
,
355 struct sockaddr
*dest
,
362 dlil_inject_if_output(struct mbuf
*m
, u_long from_id
);
365 dlil_find_dltag(u_long if_family
, short unit
, u_long proto_family
, u_long
*dl_tag
);
369 dlil_event(struct ifnet
*ifp
, struct kern_event_msg
*event
);
371 int dlil_dereg_if_modules(u_long interface_family
);
374 dlil_if_detach(struct ifnet
*ifp
);
379 Function : dlil_if_acquire
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
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.
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.
396 The typical sequence of call for a driver will be :
397 dlil_if_acquire(... &ifp)
398 ... Fill in the ifnet ...
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.
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.
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.
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].
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.
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.
443 If no matching interface is found, and no memory can be allocated,
444 dlil_if_acquire will return ENOMEM.
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.
455 int dlil_if_acquire(u_long family
, void *uniqueid
, size_t uniqueid_len
,
461 Function : dlil_if_release
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
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.
476 ifp is the pointer to the ifnet to release.
480 void dlil_if_release(struct ifnet
*ifp
);
482 #endif /* __APPLE_API_UNSTABLE */