110639SDarren.Reed@Sun.COM /*
210639SDarren.Reed@Sun.COM * CDDL HEADER START
310639SDarren.Reed@Sun.COM *
410639SDarren.Reed@Sun.COM * The contents of this file are subject to the terms of the
510639SDarren.Reed@Sun.COM * Common Development and Distribution License (the "License").
610639SDarren.Reed@Sun.COM * You may not use this file except in compliance with the License.
710639SDarren.Reed@Sun.COM *
810639SDarren.Reed@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910639SDarren.Reed@Sun.COM * or http://www.opensolaris.org/os/licensing.
1010639SDarren.Reed@Sun.COM * See the License for the specific language governing permissions
1110639SDarren.Reed@Sun.COM * and limitations under the License.
1210639SDarren.Reed@Sun.COM *
1310639SDarren.Reed@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1410639SDarren.Reed@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510639SDarren.Reed@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1610639SDarren.Reed@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1710639SDarren.Reed@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1810639SDarren.Reed@Sun.COM *
1910639SDarren.Reed@Sun.COM * CDDL HEADER END
2010639SDarren.Reed@Sun.COM */
2110639SDarren.Reed@Sun.COM
2210639SDarren.Reed@Sun.COM /*
2310639SDarren.Reed@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2410639SDarren.Reed@Sun.COM * Use is subject to license terms.
2510639SDarren.Reed@Sun.COM */
2610639SDarren.Reed@Sun.COM
2710639SDarren.Reed@Sun.COM #include <sys/types.h>
2810639SDarren.Reed@Sun.COM #include <sys/stream.h>
2910639SDarren.Reed@Sun.COM #include <net/bpf.h>
3010639SDarren.Reed@Sun.COM #include <net/bpfdesc.h>
3110639SDarren.Reed@Sun.COM #include <inet/ipnet.h>
3210639SDarren.Reed@Sun.COM
3310639SDarren.Reed@Sun.COM /*
3410639SDarren.Reed@Sun.COM * This file implements the function calls for ipnet that translate the
3510639SDarren.Reed@Sun.COM * calls from BPF into the correct arguments and functions inside of the
3610639SDarren.Reed@Sun.COM * ipnet device.
3710639SDarren.Reed@Sun.COM */
3810639SDarren.Reed@Sun.COM static const char *ipnet_bpf_name(uintptr_t);
3910639SDarren.Reed@Sun.COM static void ipnet_bpf_client_close(uintptr_t);
4010639SDarren.Reed@Sun.COM static const char *ipnet_bpf_client_name(uintptr_t);
4110639SDarren.Reed@Sun.COM static int ipnet_bpf_client_open(uintptr_t, uintptr_t *);
4210639SDarren.Reed@Sun.COM static void ipnet_bpf_close(uintptr_t);
43*11179SDarren.Reed@Sun.COM static int ipnet_bpf_getdlt(uintptr_t, uint_t *);
4410639SDarren.Reed@Sun.COM static int ipnet_bpf_getlinkid(const char *, datalink_id_t *, zoneid_t);
45*11179SDarren.Reed@Sun.COM static int ipnet_bpf_getzone(uintptr_t, zoneid_t *);
4610639SDarren.Reed@Sun.COM static int ipnet_bpf_open(const char *, uintptr_t *, zoneid_t);
4710639SDarren.Reed@Sun.COM static uintptr_t ipnet_bpf_promisc_add(uintptr_t, int, void *,
4810639SDarren.Reed@Sun.COM uintptr_t *, int);
4910639SDarren.Reed@Sun.COM static void ipnet_bpf_promisc_remove(uintptr_t);
5010639SDarren.Reed@Sun.COM static void ipnet_bpf_sdu_get(uintptr_t, uint_t *);
5110639SDarren.Reed@Sun.COM static int ipnet_bpf_tx(uintptr_t, mblk_t *);
5210639SDarren.Reed@Sun.COM static int ipnet_bpf_type(uintptr_t);
5310639SDarren.Reed@Sun.COM
5410639SDarren.Reed@Sun.COM bpf_provider_t bpf_ipnet = {
5510639SDarren.Reed@Sun.COM BPR_IPNET,
5610639SDarren.Reed@Sun.COM ipnet_bpf_open,
5710639SDarren.Reed@Sun.COM ipnet_bpf_close,
5810639SDarren.Reed@Sun.COM ipnet_bpf_name,
5910639SDarren.Reed@Sun.COM ipnet_bpf_type,
6010639SDarren.Reed@Sun.COM ipnet_bpf_sdu_get,
6110639SDarren.Reed@Sun.COM ipnet_bpf_tx,
6210639SDarren.Reed@Sun.COM ipnet_bpf_promisc_add,
6310639SDarren.Reed@Sun.COM ipnet_bpf_promisc_remove,
6410639SDarren.Reed@Sun.COM ipnet_bpf_getlinkid,
6510639SDarren.Reed@Sun.COM ipnet_bpf_client_close,
6610639SDarren.Reed@Sun.COM ipnet_bpf_client_name,
67*11179SDarren.Reed@Sun.COM ipnet_bpf_client_open,
68*11179SDarren.Reed@Sun.COM ipnet_bpf_getzone,
69*11179SDarren.Reed@Sun.COM ipnet_bpf_getdlt,
7010639SDarren.Reed@Sun.COM };
7110639SDarren.Reed@Sun.COM
7210639SDarren.Reed@Sun.COM /*ARGSUSED*/
7310639SDarren.Reed@Sun.COM static int
ipnet_bpf_open(const char * name,uintptr_t * mhandlep,zoneid_t zoneid)7410639SDarren.Reed@Sun.COM ipnet_bpf_open(const char *name, uintptr_t *mhandlep, zoneid_t zoneid)
7510639SDarren.Reed@Sun.COM {
76*11179SDarren.Reed@Sun.COM if (zoneid == ALL_ZONES)
77*11179SDarren.Reed@Sun.COM zoneid = GLOBAL_ZONEID;
7810639SDarren.Reed@Sun.COM return (ipnet_open_byname(name, (ipnetif_t **)mhandlep, zoneid));
7910639SDarren.Reed@Sun.COM }
8010639SDarren.Reed@Sun.COM
8110639SDarren.Reed@Sun.COM /*ARGSUSED*/
8210639SDarren.Reed@Sun.COM static void
ipnet_bpf_close(uintptr_t mhandle)8310639SDarren.Reed@Sun.COM ipnet_bpf_close(uintptr_t mhandle)
8410639SDarren.Reed@Sun.COM {
8510639SDarren.Reed@Sun.COM ipnet_close_byhandle((ipnetif_t *)mhandle);
8610639SDarren.Reed@Sun.COM }
8710639SDarren.Reed@Sun.COM
8810639SDarren.Reed@Sun.COM static const char *
ipnet_bpf_name(uintptr_t mhandle)8910639SDarren.Reed@Sun.COM ipnet_bpf_name(uintptr_t mhandle)
9010639SDarren.Reed@Sun.COM {
9110639SDarren.Reed@Sun.COM return (ipnet_name((ipnetif_t *)mhandle));
9210639SDarren.Reed@Sun.COM }
9310639SDarren.Reed@Sun.COM
9410639SDarren.Reed@Sun.COM /*ARGSUSED*/
9510639SDarren.Reed@Sun.COM static int
ipnet_bpf_type(uintptr_t mhandle)9610639SDarren.Reed@Sun.COM ipnet_bpf_type(uintptr_t mhandle)
9710639SDarren.Reed@Sun.COM {
9810639SDarren.Reed@Sun.COM return (DL_IPNET);
9910639SDarren.Reed@Sun.COM }
10010639SDarren.Reed@Sun.COM
10110639SDarren.Reed@Sun.COM /*ARGSUSED*/
10210639SDarren.Reed@Sun.COM static void
ipnet_bpf_sdu_get(uintptr_t mhandle,uint_t * mtup)10310639SDarren.Reed@Sun.COM ipnet_bpf_sdu_get(uintptr_t mhandle, uint_t *mtup)
10410639SDarren.Reed@Sun.COM {
10510639SDarren.Reed@Sun.COM /*
10610639SDarren.Reed@Sun.COM * The choice of 65535 is arbitrary, it could be any smaller number
10710639SDarren.Reed@Sun.COM * but it does matche the current default choice of libpcap as the
10810639SDarren.Reed@Sun.COM * packet snap size.
10910639SDarren.Reed@Sun.COM */
11010639SDarren.Reed@Sun.COM *mtup = 65535;
11110639SDarren.Reed@Sun.COM }
11210639SDarren.Reed@Sun.COM
11310639SDarren.Reed@Sun.COM /*ARGSUSED*/
11410639SDarren.Reed@Sun.COM static int
ipnet_bpf_tx(uintptr_t chandle,mblk_t * pkt)11510639SDarren.Reed@Sun.COM ipnet_bpf_tx(uintptr_t chandle, mblk_t *pkt)
11610639SDarren.Reed@Sun.COM {
11710639SDarren.Reed@Sun.COM /*
11810639SDarren.Reed@Sun.COM * It is not clear what it would mean to send an ipnet packet,
11910639SDarren.Reed@Sun.COM * especially since the ipnet device has been implemented to be
12010639SDarren.Reed@Sun.COM * an observation (read-only) instrument. Thus a call to send a
12110639SDarren.Reed@Sun.COM * packet using ipnet results in the packet being free'd and an
12210639SDarren.Reed@Sun.COM * error returned.
12310639SDarren.Reed@Sun.COM */
12410639SDarren.Reed@Sun.COM freemsg(pkt);
12510639SDarren.Reed@Sun.COM
12610639SDarren.Reed@Sun.COM return (EBADF);
12710639SDarren.Reed@Sun.COM }
12810639SDarren.Reed@Sun.COM
12910639SDarren.Reed@Sun.COM /*
13010639SDarren.Reed@Sun.COM * BPF does not provide the means to select which SAP is being sniffed,
13110639SDarren.Reed@Sun.COM * so for the purpose of ipnet, all BPF clients are in SAP promiscuous
13210639SDarren.Reed@Sun.COM * mode.
13310639SDarren.Reed@Sun.COM */
13410639SDarren.Reed@Sun.COM static uintptr_t
ipnet_bpf_promisc_add(uintptr_t chandle,int how,void * arg,uintptr_t * promisc,int flags)13510639SDarren.Reed@Sun.COM ipnet_bpf_promisc_add(uintptr_t chandle, int how, void *arg,
13610639SDarren.Reed@Sun.COM uintptr_t *promisc, int flags)
13710639SDarren.Reed@Sun.COM {
13810639SDarren.Reed@Sun.COM int newhow;
13910639SDarren.Reed@Sun.COM
14010639SDarren.Reed@Sun.COM /*
14110639SDarren.Reed@Sun.COM * Map the mac values into ipnet values.
14210639SDarren.Reed@Sun.COM */
14310639SDarren.Reed@Sun.COM switch (how) {
14410639SDarren.Reed@Sun.COM case MAC_CLIENT_PROMISC_ALL :
14510639SDarren.Reed@Sun.COM newhow = DL_PROMISC_PHYS;
14610639SDarren.Reed@Sun.COM flags = IPNET_PROMISC_PHYS|IPNET_PROMISC_SAP;
14710639SDarren.Reed@Sun.COM break;
14810639SDarren.Reed@Sun.COM case MAC_CLIENT_PROMISC_MULTI :
14910639SDarren.Reed@Sun.COM newhow = DL_PROMISC_MULTI;
15010639SDarren.Reed@Sun.COM flags = IPNET_PROMISC_MULTI|IPNET_PROMISC_SAP;
15110639SDarren.Reed@Sun.COM break;
15210639SDarren.Reed@Sun.COM default :
15310639SDarren.Reed@Sun.COM newhow = 0;
15410639SDarren.Reed@Sun.COM break;
15510639SDarren.Reed@Sun.COM }
15610639SDarren.Reed@Sun.COM
15710639SDarren.Reed@Sun.COM return (ipnet_promisc_add((void *)chandle, newhow,
15810639SDarren.Reed@Sun.COM arg, promisc, flags));
15910639SDarren.Reed@Sun.COM }
16010639SDarren.Reed@Sun.COM
16110639SDarren.Reed@Sun.COM static void
ipnet_bpf_promisc_remove(uintptr_t phandle)16210639SDarren.Reed@Sun.COM ipnet_bpf_promisc_remove(uintptr_t phandle)
16310639SDarren.Reed@Sun.COM {
16410639SDarren.Reed@Sun.COM ipnet_promisc_remove((void *)phandle);
16510639SDarren.Reed@Sun.COM }
16610639SDarren.Reed@Sun.COM
16710639SDarren.Reed@Sun.COM static int
ipnet_bpf_client_open(uintptr_t mhandle,uintptr_t * chandlep)16810639SDarren.Reed@Sun.COM ipnet_bpf_client_open(uintptr_t mhandle, uintptr_t *chandlep)
16910639SDarren.Reed@Sun.COM {
17010639SDarren.Reed@Sun.COM
17110639SDarren.Reed@Sun.COM return (ipnet_client_open((ipnetif_t *)mhandle,
17210639SDarren.Reed@Sun.COM (ipnetif_t **)chandlep));
17310639SDarren.Reed@Sun.COM }
17410639SDarren.Reed@Sun.COM
17510639SDarren.Reed@Sun.COM /*ARGSUSED*/
17610639SDarren.Reed@Sun.COM static void
ipnet_bpf_client_close(uintptr_t chandle)17710639SDarren.Reed@Sun.COM ipnet_bpf_client_close(uintptr_t chandle)
17810639SDarren.Reed@Sun.COM {
17910639SDarren.Reed@Sun.COM ipnet_client_close((ipnetif_t *)chandle);
18010639SDarren.Reed@Sun.COM }
18110639SDarren.Reed@Sun.COM
18210639SDarren.Reed@Sun.COM static const char *
ipnet_bpf_client_name(uintptr_t chandle)18310639SDarren.Reed@Sun.COM ipnet_bpf_client_name(uintptr_t chandle)
18410639SDarren.Reed@Sun.COM {
18510639SDarren.Reed@Sun.COM return (ipnet_bpf_name(chandle));
18610639SDarren.Reed@Sun.COM }
18710639SDarren.Reed@Sun.COM
18810639SDarren.Reed@Sun.COM static int
ipnet_bpf_getlinkid(const char * name,datalink_id_t * idp,zoneid_t zoneid)18910639SDarren.Reed@Sun.COM ipnet_bpf_getlinkid(const char *name, datalink_id_t *idp, zoneid_t zoneid)
19010639SDarren.Reed@Sun.COM {
191*11179SDarren.Reed@Sun.COM uint_t index;
192*11179SDarren.Reed@Sun.COM int error;
193*11179SDarren.Reed@Sun.COM ipnet_stack_t *ips;
194*11179SDarren.Reed@Sun.COM
195*11179SDarren.Reed@Sun.COM VERIFY((ips = ipnet_find_by_zoneid(zoneid)) != NULL);
19610639SDarren.Reed@Sun.COM
19710639SDarren.Reed@Sun.COM index = 0;
198*11179SDarren.Reed@Sun.COM mutex_enter(&ips->ips_event_lock);
19910639SDarren.Reed@Sun.COM error = ipnet_get_linkid_byname(name, &index, zoneid);
200*11179SDarren.Reed@Sun.COM mutex_exit(&ips->ips_event_lock);
20110639SDarren.Reed@Sun.COM if (error == 0)
20210639SDarren.Reed@Sun.COM *idp = (datalink_id_t)index;
203*11179SDarren.Reed@Sun.COM ipnet_rele(ips);
20410639SDarren.Reed@Sun.COM return (error);
20510639SDarren.Reed@Sun.COM }
206*11179SDarren.Reed@Sun.COM
207*11179SDarren.Reed@Sun.COM static int
ipnet_bpf_getzone(uintptr_t handle,zoneid_t * zip)208*11179SDarren.Reed@Sun.COM ipnet_bpf_getzone(uintptr_t handle, zoneid_t *zip)
209*11179SDarren.Reed@Sun.COM {
210*11179SDarren.Reed@Sun.COM ipnetif_t *ipnetif;
211*11179SDarren.Reed@Sun.COM
212*11179SDarren.Reed@Sun.COM ipnetif = (ipnetif_t *)handle;
213*11179SDarren.Reed@Sun.COM *zip = ipnetif->if_zoneid;
214*11179SDarren.Reed@Sun.COM return (0);
215*11179SDarren.Reed@Sun.COM }
216*11179SDarren.Reed@Sun.COM
217*11179SDarren.Reed@Sun.COM /*ARGSUSED*/
218*11179SDarren.Reed@Sun.COM static int
ipnet_bpf_getdlt(uintptr_t handle,uint_t * dlp)219*11179SDarren.Reed@Sun.COM ipnet_bpf_getdlt(uintptr_t handle, uint_t *dlp)
220*11179SDarren.Reed@Sun.COM {
221*11179SDarren.Reed@Sun.COM *dlp = DL_IPNET;
222*11179SDarren.Reed@Sun.COM return (0);
223*11179SDarren.Reed@Sun.COM }
224