]> git.saurik.com Git - apple/xnu.git/blame - bsd/net/dlil.h
xnu-517.tar.gz
[apple/xnu.git] / bsd / net / dlil.h
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
43866e37 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
43866e37
A
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
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
43866e37
A
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.
1c79356b
A
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
9bccf70c 35#include <sys/appleapiopts.h>
1c79356b
A
36
37#if __STDC__
38
39struct ifnet;
40struct mbuf;
41struct ether_header;
42
43#endif
44
45
9bccf70c 46#ifdef __APPLE_API_UNSTABLE
1c79356b
A
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
60enum {
61 BPF_TAP_DISABLE,
62 BPF_TAP_INPUT,
63 BPF_TAP_OUTPUT,
64 BPF_TAP_INPUT_OUTPUT
65};
66
67
68struct 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
77struct 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);
0b4e3aa0 102 u_long reserved[2];
1c79356b
A
103};
104
105struct 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
0b4e3aa0
A
129 int (*filter_detach)(caddr_t cookie);
130 u_long reserved[2];
1c79356b
A
131};
132
133
134#define DLIL_PR_FILTER 1
135#define DLIL_IF_FILTER 2
136
137
138
139typedef int (*dl_input_func)(struct mbuf *m, char *frame_header,
140 struct ifnet *ifp, u_long dl_tag, int sync_ok);
141typedef 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
149typedef int (*dl_event_func)(struct kern_event_msg *event,
150 u_long dl_tag);
151
152typedef int (*dl_offer_func)(struct mbuf *m, char *frame_header);
153typedef 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
9bccf70c 160#ifdef __APPLE_API_PRIVATE
1c79356b
A
161struct 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};
9bccf70c
A
170#else
171struct dlil_filterq_entry;
172#endif /* __APPLE_API_PRIVATE */
1c79356b
A
173
174TAILQ_HEAD(dlil_filterq_head, dlil_filterq_entry);
175
176
177struct 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;
0b4e3aa0 188 u_long reserved[4];
1c79356b
A
189
190};
191
9bccf70c 192#ifdef __APPLE_API_PRIVATE
1c79356b
A
193TAILQ_HEAD(dlil_proto_head, if_proto);
194
195struct dlil_tag_list_entry {
196 TAILQ_ENTRY(dlil_tag_list_entry) next;
197 struct ifnet *ifp;
198 u_long dl_tag;
199};
9bccf70c 200#endif /* __APPLE_API_PRIVATE */
1c79356b
A
201
202
9bccf70c 203#ifdef __APPLE_API_OBSOLETE
7b1edb79 204/* Obsolete types */
1c79356b
A
205#define DLIL_DESC_RAW 1
206#define DLIL_DESC_802_2 2
207#define DLIL_DESC_802_2_SNAP 3
7b1edb79
A
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 */
9bccf70c 216#endif /* __APPLE_API_OBSOLETE */
7b1edb79
A
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 */
1c79356b
A
237
238struct dlil_demux_desc {
239 TAILQ_ENTRY(dlil_demux_desc) next;
7b1edb79
A
240
241 int type;
242 u_char *native_type;
243
1c79356b 244 union {
7b1edb79
A
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;
1c79356b
A
270 } variants;
271};
272
273TAILQ_HEAD(ddesc_head_str, dlil_demux_desc);
274
275
276struct 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;
7b1edb79 283 dl_pre_output_func pre_output;
1c79356b
A
284 dl_event_func event;
285 dl_offer_func offer;
286 dl_ioctl_func ioctl;
0b4e3aa0 287 u_long reserved[4];
1c79356b
A
288};
289
290
291int 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
296int
297dlil_input(struct ifnet *ifp, struct mbuf *m_head, struct mbuf *m_tail);
298
299int
300dlil_output(u_long dl_tag,
301 struct mbuf *m,
302 caddr_t route,
303 struct sockaddr *dest,
304 int raw);
305
306
307int
308dlil_ioctl(u_long proto_family,
309 struct ifnet *ifp,
310 u_long ioctl_code,
311 caddr_t ioctl_arg);
312
313int
314dlil_attach_protocol(struct dlil_proto_reg_str *proto,
315 u_long *dl_tag);
316
317int
318dlil_detach_protocol(u_long dl_tag);
319
320int
321dlil_if_attach(struct ifnet *ifp);
322
323int
324dlil_attach_protocol_filter(u_long dl_tag,
325 struct dlil_pr_flt_str *proto_filter,
326 u_long *filter_id,
327 int insertion_point);
328int
329dlil_detach_filter(u_long filter_id);
330
331struct 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)();
9bccf70c
A
339 int (*init_if)(struct ifnet *ifp);
340 u_long reserved[3];
1c79356b
A
341};
342
343
344int dlil_reg_if_modules(u_long interface_family,
345 struct dlil_ifmod_reg_str *ifmod_reg);
346
55e303ae
A
347struct dlil_protomod_reg_str {
348 /*
349 * attach the protocol to the interface and return the dl_tag
350 */
351 int (*attach_proto)(struct ifnet *ifp, u_long *dl_tag);
352
353 /*
354 * detach the protocol from the interface.
355 * this is optionnal. If it is NULL, DLIL will use 0 default detach function.
356 */
357 int (*detach_proto)(struct ifnet *ifp, u_long dl_tag);
358
359 /*
360 * reserved for future use. MUST be NULL.
361 */
362 u_long reserved[4];
363};
364
365/*
366
367Function : dlil_reg_proto_module
368
369 A DLIL protocol module is a piece of code that know how to handle a certain type
370 of protocol (PF_INET, PF_INET6, ...) for a certain family of interface (APPLE_IF_FAM_ETHERNET,
371 APPLE_IF_FAM_PPP, ...).
372
373 dlil_reg_proto_module() allows the registration of such a protocol/interface handler before any
374 interface is attached.
375 Typically, the attach and detach function of the protocol handler will call
376 dlil_{attach/detach}_protocol with the parameter specific to the protocol.
377
378 The goal of this modules is to insulate the actual protocol (IP, IPv6) from the DLIL details.
379
380Parameters :
381 'protocol_family' is PF_INET, PF_INET6, ...
382 'interface_family' is APPLE_IF_FAM_ETHERNET, APPLE_IF_FAM_PPP, ...
383 'protomod_reg' is the protocol registration structure.
384 'attach_proto' funtion is mandatory.
385 'detach_proto' funtion is optional (DLIL will manage it).
386
387Return code :
388
3890 :
390
391 No error.
392
393ENOMEM:
394
395 No memory can be allocated for internal data structure.
396
397EEXIST:
398
399 The protocol family has already been registered for this interface family.
400
401EINVAL:
402
403 The dlil_protomod_reg_str structure contains incorrect values.
404
405*/
406
407int dlil_reg_proto_module(u_long protocol_family, u_long interface_family,
408 struct dlil_protomod_reg_str *protomod_reg);
409
410/*
411
412Function : dlil_dereg_proto_module
413
414 dlil_dereg_proto_module() will unregister the protocol module previously
415 registered with dlil_dereg_proto_module().
416
417 There is no restriction when to call it.
418 Interfaces or protoco can be attached, it will not prevent the deregistration of the module.
419
420Parameters :
421 'protocol_family' is PF_INET, PF_INET6, ...
422 'interface_family' is APPLE_IF_FAM_ETHERNET, APPLE_IF_FAM_PPP, ...
423
424Return code :
425
4260 :
427
428 No error.
429
430ENOENT:
431
432 No module was registered..
433
434*/
435
436int dlil_dereg_proto_module(u_long protocol_family, u_long interface_family);
437
438/*
439
440Function : dlil_plumb_protocol
441
442 dlil_plumb_protocol() will plumb a protocol to an actual interface.
443 This will find a registered protocol module and call its attach function.
444 The module will typically call dlil_attach_protocol with the appropriate parameters,
445 and will return the dl_tag of the attachement.
446 It is up to the caller to handle the dl_tag.
447 Some protocol (IPv4) will stick it in their internal structure for future use.
448 Some other protocol (IPv6) can ignore the dl_tag.
449
450Parameters :
451 'protocol_family' is PF_INET, PF_INET6, ...
452 'ifp' is the interface to plumb the protocol to.
453 'dl_tag' is the tag returned from the succesful attachement.
454
455Return code :
456
4570 :
458
459 No error.
460
461ENOENT:
462
463 No module was registered.
464
465other:
466
467 Error returned by the attach_proto function
468
469*/
470int dlil_plumb_protocol(u_long protocol_family, struct ifnet *ifp, u_long *dl_tag);
471
472/*
473
474Function : dlil_unplumb_protocol
475
476 dlil_unplumb_protocol() will unplumb a protocol from an interface.
477 This will find a registered protocol module and call its detach function.
478 The module will typically call dlil_detach_protocol with the appropriate parameters.
479 If no module is found, this function will call dlil_detach_protocol directly.
480
481Parameters :
482 'protocol_family' is PF_INET, PF_INET6, ...
483 'ifp' is APPLE_IF_FAM_ETHERNET, APPLE_IF_FAM_PPP, ...
484
485Return code :
486
4870 :
488
489 No error.
490
491ENOENT:
492
493 No module was registered.
494
495other:
496
497 Error returned by the attach_proto function
498
499*/
500int dlil_unplumb_protocol(u_long protocol_family, struct ifnet *ifp);
501
1c79356b
A
502int
503dlil_inject_if_input(struct mbuf *m, char *frame_header, u_long from_id);
504
505int
506dlil_inject_pr_input(struct mbuf *m, char *frame_header, u_long from_id);
507
508int
509dlil_inject_pr_output(struct mbuf *m,
510 struct sockaddr *dest,
511 int raw,
512 char *frame_type,
513 char *dst_linkaddr,
514 u_long from_id);
515
516int
517dlil_inject_if_output(struct mbuf *m, u_long from_id);
518
519int
520dlil_find_dltag(u_long if_family, short unit, u_long proto_family, u_long *dl_tag);
521
522
523int
524dlil_event(struct ifnet *ifp, struct kern_event_msg *event);
525
526int dlil_dereg_if_modules(u_long interface_family);
527
528int
529dlil_if_detach(struct ifnet *ifp);
530
9bccf70c
A
531
532/*
533
534Function : dlil_if_acquire
535
536 DLIL manages the list of ifnet interfaces allocated using the dlil_if_acquire
537 function. This list if not the same as the list of attached interfaces,
538 visible with ifconfig.
539 This list contains attached as well as detached interfaces.
540 Detached interfaces are kept in the list to prevent the kernel from crashing
541 by using an old ifp.
542
543 if it succeeds, dlil_if_acquire returns an ifnet data structure.
544 This ifnet can either be a new allocated block of memory, or an ifnet
545 that already existed and that DLIL has found in its list of unused
546 interface and that matches the family/uniqueid tuple.
547
548 dlil_if_acquire can fail if the requested interface is already in use,
549 or if no memory is available to create a new interface.
550
551 The typical sequence of call for a driver will be :
552 dlil_if_acquire(... &ifp)
553 ... Fill in the ifnet ...
554 dlil_if_attach(ifp)
555 ... Driver work ...
556 dlil_if_detach(ifp)
557 dlil_if_release(ifp)
558
559 Important : ifnet allocated by DLIL are managed by DLIL. DLIL takes care
560 of them, and keeps them until a driver wants to reuse them, but DLIL may
561 also decide to free them when not in use by a driver.
562
563 Note : the structure returned will actually be large enough to contain
564 an arpcom structure (ifnet + ethernet) structure.
565 Drivers cannot extend the structure and must to store their private
566 information in if_sofc and if_private.
567
568Parameters :
569 'family' uniquely identifies DLIL interface family.
570 'uniqueid' is a unique identifier for that interface, managed by the
571 driver (for example MAC address for ethernet).
572 'uniqueid_len' is the length of the unique id.
573 'ifp' contains on output the allocated ifnet.
574
575Return code :
576
5770 :
578
579 If an ifnet matching the uniqueid is found, the matching ifnet is returned
580 in ifp and the flags IFEF_REUSE and IF_INUSE are set in the if_eflags.
581 The fields in the ifnet are NOT zeroed and may contain old values that
582 the driver can reuse. [They are not necessarily the values that were
583 there when the driver released the ifnet, as protocol might have
584 continued to update them].
585
586 If no matching ifnet is found, a new structure is allocated and returned
587 in ifp with all fields initialized to 0.
588 The flag IF_INUSE is set in the if_eflags. IFEF_REUSE is NOT set.
589 dlil_if_acquire will copy the uniqueid and keep it for matching purpose.
590
591 If 'uniqueid' is NULL, then dlil_if_acquire will return the first
592 ifnet that contains a null uniqueid for that family, with the flags
593 IFEF_REUSE and IF_INUSE set.
594 If no ifnet is available, a new one will be created.
595
596ENOMEM:
597
598 If no matching interface is found, and no memory can be allocated,
599 dlil_if_acquire will return ENOMEM.
600
601
602EBUSY:
603
604 If the unique id matches the id of an interface currently in use,
605 dlil_if_acquire will return EBUSY.
606 An interface 'in use' is an allocated interface, not necessarily attached.
607
608*/
609
610int dlil_if_acquire(u_long family, void *uniqueid, size_t uniqueid_len,
611 struct ifnet **ifp);
612
613
614/*
615
616Function : dlil_if_release
617
618 dlil_if_release will transfer control of the ifnet to DLIL.
619 DLIL will keep the interface in its list, marking it unused.
620 The fields will be left in their current state, so the driver can reuse
621 the ifnet later, by calling dlil_if_acquire.
622 The if_eflags IF_INUSE will be cleared.
623 The fields if_output, if_ioctl, if_free and if_set_bpf_tap will be changed
624 to point to DLIL private functions.
625 After calling dlil_if_acquire, the driver can safely terminate and
626 unload if necessary.
627 Note : if the call to dlil_if_detach returns DLIL_WAIT_FOR_FREE, the
628 driver can safely ignore it and call dlil_if_release.
629
630Parameters :
631 ifp is the pointer to the ifnet to release.
632
633*/
634
635void dlil_if_release(struct ifnet *ifp);
636
637#endif /* __APPLE_API_UNSTABLE */
1c79356b 638#endif /* DLIL_H */