xref: /onnv-gate/usr/src/uts/common/inet/ipnet/ipnet_bpf.c (revision 11179:bfcb8daf999a)
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