xref: /freebsd/sbin/ipf/ipsend/sbpf.c (revision efeb8bffe34422937c7f8df836afb5b817366d16)
141edb306SCy Schubert /* $FreeBSD$ */
241edb306SCy Schubert /*
341edb306SCy Schubert  * (C)opyright 1995-1998 Darren Reed. (from tcplog)
441edb306SCy Schubert  *
541edb306SCy Schubert  * See the IPFILTER.LICENCE file for details on licencing.
641edb306SCy Schubert  *
741edb306SCy Schubert  */
841edb306SCy Schubert #include <sys/param.h>
941edb306SCy Schubert #include <sys/types.h>
1041edb306SCy Schubert #include <sys/mbuf.h>
1141edb306SCy Schubert #include <sys/time.h>
1241edb306SCy Schubert #include <sys/socket.h>
1341edb306SCy Schubert #include <sys/file.h>
1441edb306SCy Schubert #include <sys/ioctl.h>
1541edb306SCy Schubert #ifdef __FreeBSD__
1641edb306SCy Schubert # include <sys/dirent.h>
1741edb306SCy Schubert #else
1841edb306SCy Schubert # include <sys/dir.h>
1941edb306SCy Schubert #endif
2041edb306SCy Schubert #include <net/bpf.h>
2141edb306SCy Schubert 
2241edb306SCy Schubert #include <net/if.h>
2341edb306SCy Schubert #include <netinet/in.h>
2441edb306SCy Schubert #include <netinet/in_systm.h>
2541edb306SCy Schubert #include <netinet/ip.h>
2641edb306SCy Schubert #include <netinet/udp.h>
2741edb306SCy Schubert #include <netinet/tcp.h>
2841edb306SCy Schubert 
2941edb306SCy Schubert #include <stdio.h>
3041edb306SCy Schubert #include <netdb.h>
3141edb306SCy Schubert #include <string.h>
3241edb306SCy Schubert #include <unistd.h>
3341edb306SCy Schubert #include <stdlib.h>
3441edb306SCy Schubert #ifdef __NetBSD__
3541edb306SCy Schubert # include <paths.h>
3641edb306SCy Schubert #endif
3741edb306SCy Schubert #include <ctype.h>
3841edb306SCy Schubert #include <signal.h>
3941edb306SCy Schubert #include <errno.h>
4041edb306SCy Schubert 
4141edb306SCy Schubert #include "ipsend.h"
4241edb306SCy Schubert 
4341edb306SCy Schubert #if !defined(lint)
4441edb306SCy Schubert static const char sccsid[] = "@(#)sbpf.c	1.3 8/25/95 (C)1995 Darren Reed";
4541edb306SCy Schubert static const char rcsid[] = "@(#)$Id$";
4641edb306SCy Schubert #endif
4741edb306SCy Schubert 
4841edb306SCy Schubert /*
4941edb306SCy Schubert  * the code herein is dervied from libpcap.
5041edb306SCy Schubert  */
5141edb306SCy Schubert static	u_char	*buf = NULL;
5241edb306SCy Schubert static	int	bufsize = 0, timeout = 1;
5341edb306SCy Schubert 
5441edb306SCy Schubert 
55*efeb8bffSCy Schubert int
56*efeb8bffSCy Schubert initdevice(char *device, int tout)
5741edb306SCy Schubert {
5841edb306SCy Schubert 	struct	bpf_version bv;
5941edb306SCy Schubert 	struct	timeval to;
6041edb306SCy Schubert 	struct	ifreq ifr;
6141edb306SCy Schubert #ifdef _PATH_BPF
6241edb306SCy Schubert 	char	*bpfname = _PATH_BPF;
6341edb306SCy Schubert 	int	fd;
6441edb306SCy Schubert 
6541edb306SCy Schubert 	if ((fd = open(bpfname, O_RDWR)) < 0)
6641edb306SCy Schubert 	    {
6741edb306SCy Schubert 		fprintf(stderr, "no bpf devices available as /dev/bpfxx\n");
6841edb306SCy Schubert 		return -1;
6941edb306SCy Schubert 	    }
7041edb306SCy Schubert #else
7141edb306SCy Schubert 	char	bpfname[16];
7241edb306SCy Schubert 	int	fd = 0, i;
7341edb306SCy Schubert 
7441edb306SCy Schubert 	for (i = 0; i < 16; i++)
7541edb306SCy Schubert 	    {
7641edb306SCy Schubert 		(void) snprintf(bpfname, sizeof(bpfname), "/dev/bpf%d", i);
7741edb306SCy Schubert 		if ((fd = open(bpfname, O_RDWR)) >= 0)
7841edb306SCy Schubert 			break;
7941edb306SCy Schubert 	    }
8041edb306SCy Schubert 	if (i == 16)
8141edb306SCy Schubert 	    {
8241edb306SCy Schubert 		fprintf(stderr, "no bpf devices available as /dev/bpfxx\n");
8341edb306SCy Schubert 		return -1;
8441edb306SCy Schubert 	    }
8541edb306SCy Schubert #endif
8641edb306SCy Schubert 
8741edb306SCy Schubert 	if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0)
8841edb306SCy Schubert 	    {
8941edb306SCy Schubert 		perror("BIOCVERSION");
9041edb306SCy Schubert 		return -1;
9141edb306SCy Schubert 	    }
9241edb306SCy Schubert 	if (bv.bv_major != BPF_MAJOR_VERSION ||
9341edb306SCy Schubert 	    bv.bv_minor < BPF_MINOR_VERSION)
9441edb306SCy Schubert 	    {
9541edb306SCy Schubert 		fprintf(stderr, "kernel bpf (v%d.%d) filter out of date:\n",
9641edb306SCy Schubert 			bv.bv_major, bv.bv_minor);
9741edb306SCy Schubert 		fprintf(stderr, "current version: %d.%d\n",
9841edb306SCy Schubert 			BPF_MAJOR_VERSION, BPF_MINOR_VERSION);
9941edb306SCy Schubert 		return -1;
10041edb306SCy Schubert 	    }
10141edb306SCy Schubert 
10241edb306SCy Schubert 	(void) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
10341edb306SCy Schubert 	if (ioctl(fd, BIOCSETIF, &ifr) == -1)
10441edb306SCy Schubert 	    {
10541edb306SCy Schubert 		fprintf(stderr, "%s(%d):", ifr.ifr_name, fd);
10641edb306SCy Schubert 		perror("BIOCSETIF");
10741edb306SCy Schubert 		exit(1);
10841edb306SCy Schubert 	    }
10941edb306SCy Schubert 	/*
11041edb306SCy Schubert 	 * get kernel buffer size
11141edb306SCy Schubert 	 */
11241edb306SCy Schubert 	if (ioctl(fd, BIOCGBLEN, &bufsize) == -1)
11341edb306SCy Schubert 	    {
11441edb306SCy Schubert 		perror("BIOCSBLEN");
11541edb306SCy Schubert 		exit(-1);
11641edb306SCy Schubert 	    }
11741edb306SCy Schubert 	buf = (u_char*)malloc(bufsize);
11841edb306SCy Schubert 	/*
11941edb306SCy Schubert 	 * set the timeout
12041edb306SCy Schubert 	 */
12141edb306SCy Schubert 	timeout = tout;
12241edb306SCy Schubert 	to.tv_sec = 1;
12341edb306SCy Schubert 	to.tv_usec = 0;
12441edb306SCy Schubert 	if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&to) == -1)
12541edb306SCy Schubert 	    {
12641edb306SCy Schubert 		perror("BIOCSRTIMEOUT");
12741edb306SCy Schubert 		exit(-1);
12841edb306SCy Schubert 	    }
12941edb306SCy Schubert 
13041edb306SCy Schubert 	(void) ioctl(fd, BIOCFLUSH, 0);
13141edb306SCy Schubert 	return fd;
13241edb306SCy Schubert }
13341edb306SCy Schubert 
13441edb306SCy Schubert 
13541edb306SCy Schubert /*
13641edb306SCy Schubert  * output an IP packet onto a fd opened for /dev/bpf
13741edb306SCy Schubert  */
138*efeb8bffSCy Schubert int
139*efeb8bffSCy Schubert sendip(int fd, char *pkt, int len)
14041edb306SCy Schubert {
14141edb306SCy Schubert 	if (write(fd, pkt, len) == -1)
14241edb306SCy Schubert 	    {
14341edb306SCy Schubert 		perror("send");
14441edb306SCy Schubert 		return -1;
14541edb306SCy Schubert 	    }
14641edb306SCy Schubert 
14741edb306SCy Schubert 	return len;
14841edb306SCy Schubert }
149