xref: /netbsd-src/external/bsd/ipf/dist/ipsend/sbpf.c (revision 07967fb18af5b87d2d477c5b3e1e438bf0c293fb)
1*07967fb1Smrg /*	$NetBSD: sbpf.c,v 1.4 2018/02/04 08:19:42 mrg Exp $	*/
2bc4097aaSchristos 
3bc4097aaSchristos /*
4bc4097aaSchristos  * (C)opyright 1995-1998 Darren Reed. (from tcplog)
5bc4097aaSchristos  *
6bc4097aaSchristos  * See the IPFILTER.LICENCE file for details on licencing.
7bc4097aaSchristos  *
8bc4097aaSchristos  */
9bc4097aaSchristos #include <sys/param.h>
10bc4097aaSchristos #include <sys/types.h>
11bc4097aaSchristos #include <sys/mbuf.h>
12bc4097aaSchristos #include <sys/time.h>
13bc4097aaSchristos #include <sys/timeb.h>
14bc4097aaSchristos #include <sys/socket.h>
15bc4097aaSchristos #include <sys/file.h>
16bc4097aaSchristos #include <sys/ioctl.h>
17bc4097aaSchristos #if BSD < 199103
18bc4097aaSchristos #include <sys/fcntlcom.h>
19bc4097aaSchristos #endif
20bc4097aaSchristos #if (__FreeBSD_version >= 300000)
21bc4097aaSchristos # include <sys/dirent.h>
22bc4097aaSchristos #else
23bc4097aaSchristos # include <sys/dir.h>
24bc4097aaSchristos #endif
25bc4097aaSchristos #include <net/bpf.h>
26bc4097aaSchristos 
27bc4097aaSchristos #include <net/if.h>
28bc4097aaSchristos #include <netinet/in.h>
29bc4097aaSchristos #include <netinet/in_systm.h>
30bc4097aaSchristos #include <netinet/ip.h>
31e7d50bf6Schristos #include <netinet/ip_icmp.h>
32e7d50bf6Schristos #include <netinet/ip_var.h>
33bc4097aaSchristos #include <netinet/udp.h>
34bc4097aaSchristos #include <netinet/tcp.h>
35bc4097aaSchristos 
36bc4097aaSchristos #include <stdio.h>
37bc4097aaSchristos #include <netdb.h>
38bc4097aaSchristos #include <string.h>
39bc4097aaSchristos #include <unistd.h>
40bc4097aaSchristos #include <stdlib.h>
41bc4097aaSchristos #ifdef __NetBSD__
42bc4097aaSchristos # include <paths.h>
43bc4097aaSchristos #endif
44bc4097aaSchristos #include <ctype.h>
45bc4097aaSchristos #include <signal.h>
46bc4097aaSchristos #include <errno.h>
47bc4097aaSchristos 
48e7d50bf6Schristos #include "ip_compat.h"
49bc4097aaSchristos #include "ipsend.h"
50bc4097aaSchristos 
51bc4097aaSchristos #if !defined(lint)
52*07967fb1Smrg static __attribute__((__used__)) const char sccsid[] = "@(#)sbpf.c	1.3 8/25/95 (C)1995 Darren Reed";
53*07967fb1Smrg static __attribute__((__used__)) const char rcsid[] = "@(#)Id: sbpf.c,v 1.1.1.2 2012/07/22 13:44:37 darrenr Exp $";
54bc4097aaSchristos #endif
55bc4097aaSchristos 
56bc4097aaSchristos /*
57bc4097aaSchristos  * the code herein is dervied from libpcap.
58bc4097aaSchristos  */
59bc4097aaSchristos static	u_char	*buf = NULL;
60bc4097aaSchristos static	int	bufsize = 0, timeout = 1;
61bc4097aaSchristos 
62bc4097aaSchristos 
initdevice(device,tout)63bc4097aaSchristos int	initdevice(device, tout)
64bc4097aaSchristos 	char	*device;
65bc4097aaSchristos 	int	tout;
66bc4097aaSchristos {
67bc4097aaSchristos 	struct	bpf_version bv;
68bc4097aaSchristos 	struct	timeval to;
69bc4097aaSchristos 	struct	ifreq ifr;
70bc4097aaSchristos #ifdef _PATH_BPF
71bc4097aaSchristos 	char	*bpfname = _PATH_BPF;
72bc4097aaSchristos 	int	fd;
73bc4097aaSchristos 
74bc4097aaSchristos 	if ((fd = open(bpfname, O_RDWR)) < 0)
75bc4097aaSchristos 	    {
76bc4097aaSchristos 		fprintf(stderr, "no bpf devices available as /dev/bpfxx\n");
77bc4097aaSchristos 		return -1;
78bc4097aaSchristos 	    }
79bc4097aaSchristos #else
80bc4097aaSchristos 	char	bpfname[16];
81bc4097aaSchristos 	int	fd = 0, i;
82bc4097aaSchristos 
83bc4097aaSchristos 	for (i = 0; i < 16; i++)
84bc4097aaSchristos 	    {
85bc4097aaSchristos 		(void) sprintf(bpfname, "/dev/bpf%d", i);
86bc4097aaSchristos 		if ((fd = open(bpfname, O_RDWR)) >= 0)
87bc4097aaSchristos 			break;
88bc4097aaSchristos 	    }
89bc4097aaSchristos 	if (i == 16)
90bc4097aaSchristos 	    {
91bc4097aaSchristos 		fprintf(stderr, "no bpf devices available as /dev/bpfxx\n");
92bc4097aaSchristos 		return -1;
93bc4097aaSchristos 	    }
94bc4097aaSchristos #endif
95bc4097aaSchristos 
96bc4097aaSchristos 	if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0)
97bc4097aaSchristos 	    {
98bc4097aaSchristos 		perror("BIOCVERSION");
99bc4097aaSchristos 		return -1;
100bc4097aaSchristos 	    }
101bc4097aaSchristos 	if (bv.bv_major != BPF_MAJOR_VERSION ||
102bc4097aaSchristos 	    bv.bv_minor < BPF_MINOR_VERSION)
103bc4097aaSchristos 	    {
104bc4097aaSchristos 		fprintf(stderr, "kernel bpf (v%d.%d) filter out of date:\n",
105bc4097aaSchristos 			bv.bv_major, bv.bv_minor);
106bc4097aaSchristos 		fprintf(stderr, "current version: %d.%d\n",
107bc4097aaSchristos 			BPF_MAJOR_VERSION, BPF_MINOR_VERSION);
108bc4097aaSchristos 		return -1;
109bc4097aaSchristos 	    }
110bc4097aaSchristos 
111bc4097aaSchristos 	(void) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
112bc4097aaSchristos 	if (ioctl(fd, BIOCSETIF, &ifr) == -1)
113bc4097aaSchristos 	    {
114bc4097aaSchristos 		fprintf(stderr, "%s(%d):", ifr.ifr_name, fd);
115bc4097aaSchristos 		perror("BIOCSETIF");
116bc4097aaSchristos 		exit(1);
117bc4097aaSchristos 	    }
118bc4097aaSchristos 	/*
119bc4097aaSchristos 	 * get kernel buffer size
120bc4097aaSchristos 	 */
121bc4097aaSchristos 	if (ioctl(fd, BIOCGBLEN, &bufsize) == -1)
122bc4097aaSchristos 	    {
123bc4097aaSchristos 		perror("BIOCSBLEN");
124bc4097aaSchristos 		exit(-1);
125bc4097aaSchristos 	    }
126bc4097aaSchristos 	buf = (u_char*)malloc(bufsize);
127bc4097aaSchristos 	/*
128bc4097aaSchristos 	 * set the timeout
129bc4097aaSchristos 	 */
130bc4097aaSchristos 	timeout = tout;
131bc4097aaSchristos 	to.tv_sec = 1;
132bc4097aaSchristos 	to.tv_usec = 0;
133bc4097aaSchristos 	if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&to) == -1)
134bc4097aaSchristos 	    {
135bc4097aaSchristos 		perror("BIOCSRTIMEOUT");
136bc4097aaSchristos 		exit(-1);
137bc4097aaSchristos 	    }
138bc4097aaSchristos 
139bc4097aaSchristos 	(void) ioctl(fd, BIOCFLUSH, 0);
140bc4097aaSchristos 	return fd;
141bc4097aaSchristos }
142bc4097aaSchristos 
143bc4097aaSchristos 
144bc4097aaSchristos /*
145bc4097aaSchristos  * output an IP packet onto a fd opened for /dev/bpf
146bc4097aaSchristos  */
sendip(fd,pkt,len)147bc4097aaSchristos int	sendip(fd, pkt, len)
148bc4097aaSchristos 	int	fd, len;
149bc4097aaSchristos 	char	*pkt;
150bc4097aaSchristos {
151bc4097aaSchristos 	if (write(fd, pkt, len) == -1)
152bc4097aaSchristos 	    {
153bc4097aaSchristos 		perror("send");
154bc4097aaSchristos 		return -1;
155bc4097aaSchristos 	    }
156bc4097aaSchristos 
157bc4097aaSchristos 	return len;
158bc4097aaSchristos }
159