4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/types.h>
28 #include <sys/stream.h>
30 #include <net/bpfdesc.h>
31 #include <inet/ipnet.h>
34 * This file implements the function calls for ipnet that translate the
35 * calls from BPF into the correct arguments and functions inside of the
38 static const char *ipnet_bpf_name(uintptr_t);
39 static void ipnet_bpf_client_close(uintptr_t);
40 static const char *ipnet_bpf_client_name(uintptr_t);
41 static int ipnet_bpf_client_open(uintptr_t, uintptr_t *);
42 static void ipnet_bpf_close(uintptr_t);
43 static int ipnet_bpf_getdlt(uintptr_t, uint_t
*);
44 static int ipnet_bpf_getlinkid(const char *, datalink_id_t
*, zoneid_t
);
45 static int ipnet_bpf_getzone(uintptr_t, zoneid_t
*);
46 static int ipnet_bpf_open(const char *, uintptr_t *, zoneid_t
);
47 static uintptr_t ipnet_bpf_promisc_add(uintptr_t, int, void *,
49 static void ipnet_bpf_promisc_remove(uintptr_t);
50 static void ipnet_bpf_sdu_get(uintptr_t, uint_t
*);
51 static int ipnet_bpf_tx(uintptr_t, mblk_t
*);
52 static int ipnet_bpf_type(uintptr_t);
54 bpf_provider_t bpf_ipnet
= {
62 ipnet_bpf_promisc_add
,
63 ipnet_bpf_promisc_remove
,
65 ipnet_bpf_client_close
,
66 ipnet_bpf_client_name
,
67 ipnet_bpf_client_open
,
74 ipnet_bpf_open(const char *name
, uintptr_t *mhandlep
, zoneid_t zoneid
)
76 if (zoneid
== ALL_ZONES
)
77 zoneid
= GLOBAL_ZONEID
;
78 return (ipnet_open_byname(name
, (ipnetif_t
**)mhandlep
, zoneid
));
83 ipnet_bpf_close(uintptr_t mhandle
)
85 ipnet_close_byhandle((ipnetif_t
*)mhandle
);
89 ipnet_bpf_name(uintptr_t mhandle
)
91 return (ipnet_name((ipnetif_t
*)mhandle
));
96 ipnet_bpf_type(uintptr_t mhandle
)
103 ipnet_bpf_sdu_get(uintptr_t mhandle
, uint_t
*mtup
)
106 * The choice of 65535 is arbitrary, it could be any smaller number
107 * but it does matche the current default choice of libpcap as the
115 ipnet_bpf_tx(uintptr_t chandle
, mblk_t
*pkt
)
118 * It is not clear what it would mean to send an ipnet packet,
119 * especially since the ipnet device has been implemented to be
120 * an observation (read-only) instrument. Thus a call to send a
121 * packet using ipnet results in the packet being free'd and an
130 * BPF does not provide the means to select which SAP is being sniffed,
131 * so for the purpose of ipnet, all BPF clients are in SAP promiscuous
135 ipnet_bpf_promisc_add(uintptr_t chandle
, int how
, void *arg
,
136 uintptr_t *promisc
, int flags
)
141 * Map the mac values into ipnet values.
144 case MAC_CLIENT_PROMISC_ALL
:
145 newhow
= DL_PROMISC_PHYS
;
146 flags
= IPNET_PROMISC_PHYS
|IPNET_PROMISC_SAP
;
148 case MAC_CLIENT_PROMISC_MULTI
:
149 newhow
= DL_PROMISC_MULTI
;
150 flags
= IPNET_PROMISC_MULTI
|IPNET_PROMISC_SAP
;
157 return (ipnet_promisc_add((void *)chandle
, newhow
,
158 arg
, promisc
, flags
));
162 ipnet_bpf_promisc_remove(uintptr_t phandle
)
164 ipnet_promisc_remove((void *)phandle
);
168 ipnet_bpf_client_open(uintptr_t mhandle
, uintptr_t *chandlep
)
171 return (ipnet_client_open((ipnetif_t
*)mhandle
,
172 (ipnetif_t
**)chandlep
));
177 ipnet_bpf_client_close(uintptr_t chandle
)
179 ipnet_client_close((ipnetif_t
*)chandle
);
183 ipnet_bpf_client_name(uintptr_t chandle
)
185 return (ipnet_bpf_name(chandle
));
189 ipnet_bpf_getlinkid(const char *name
, datalink_id_t
*idp
, zoneid_t zoneid
)
195 VERIFY((ips
= ipnet_find_by_zoneid(zoneid
)) != NULL
);
198 mutex_enter(&ips
->ips_event_lock
);
199 error
= ipnet_get_linkid_byname(name
, &index
, zoneid
);
200 mutex_exit(&ips
->ips_event_lock
);
202 *idp
= (datalink_id_t
)index
;
208 ipnet_bpf_getzone(uintptr_t handle
, zoneid_t
*zip
)
212 ipnetif
= (ipnetif_t
*)handle
;
213 *zip
= ipnetif
->if_zoneid
;
219 ipnet_bpf_getdlt(uintptr_t handle
, uint_t
*dlp
)