157109Speter/* $FreeBSD: stable/11/contrib/ipfilter/ipsend/sbpf.c 369277 2021-02-16 00:48:38Z cy $ */
222514Sdarrenr/*
357109Speter * (C)opyright 1995-1998 Darren Reed. (from tcplog)
422514Sdarrenr *
580490Sdarrenr * See the IPFILTER.LICENCE file for details on licencing.
6145519Sdarrenr *
722514Sdarrenr */
8145519Sdarrenr#include <sys/param.h>
922514Sdarrenr#include <sys/types.h>
1022514Sdarrenr#include <sys/mbuf.h>
1122514Sdarrenr#include <sys/time.h>
1222514Sdarrenr#include <sys/socket.h>
1322514Sdarrenr#include <sys/file.h>
1422514Sdarrenr#include <sys/ioctl.h>
15369277Scy#ifdef __FreeBSD__
1657109Speter# include <sys/dirent.h>
1757109Speter#else
1857109Speter# include <sys/dir.h>
1957109Speter#endif
2022514Sdarrenr#include <net/bpf.h>
2122514Sdarrenr
2222514Sdarrenr#include <net/if.h>
2322514Sdarrenr#include <netinet/in.h>
2422514Sdarrenr#include <netinet/in_systm.h>
2522514Sdarrenr#include <netinet/ip.h>
26255332Scy#include <netinet/udp.h>
27255332Scy#include <netinet/tcp.h>
28145519Sdarrenr
29145519Sdarrenr#include <stdio.h>
30145519Sdarrenr#include <netdb.h>
31145519Sdarrenr#include <string.h>
32145519Sdarrenr#include <unistd.h>
33145519Sdarrenr#include <stdlib.h>
34161357Sguido#ifdef __NetBSD__
35161357Sguido# include <paths.h>
36161357Sguido#endif
37145519Sdarrenr#include <ctype.h>
38145519Sdarrenr#include <signal.h>
39145519Sdarrenr#include <errno.h>
40145519Sdarrenr
4124583Sdarrenr#include "ipsend.h"
4222514Sdarrenr
4331183Speter#if !defined(lint)
4431183Speterstatic const char sccsid[] = "@(#)sbpf.c	1.3 8/25/95 (C)1995 Darren Reed";
45255332Scystatic const char rcsid[] = "@(#)$Id$";
4622514Sdarrenr#endif
4722514Sdarrenr
4822514Sdarrenr/*
4922514Sdarrenr * the code herein is dervied from libpcap.
5022514Sdarrenr */
5122514Sdarrenrstatic	u_char	*buf = NULL;
5222514Sdarrenrstatic	int	bufsize = 0, timeout = 1;
5322514Sdarrenr
5422514Sdarrenr
55145519Sdarrenrint	initdevice(device, tout)
56255332Scy	char	*device;
57255332Scy	int	tout;
5822514Sdarrenr{
5922514Sdarrenr	struct	bpf_version bv;
6022514Sdarrenr	struct	timeval to;
6122514Sdarrenr	struct	ifreq ifr;
62161357Sguido#ifdef _PATH_BPF
63161357Sguido	char	*bpfname = _PATH_BPF;
64161357Sguido	int	fd;
65161357Sguido
66161357Sguido	if ((fd = open(bpfname, O_RDWR)) < 0)
67161357Sguido	    {
68161357Sguido		fprintf(stderr, "no bpf devices available as /dev/bpfxx\n");
69161357Sguido		return -1;
70161357Sguido	    }
71161357Sguido#else
7222514Sdarrenr	char	bpfname[16];
73145519Sdarrenr	int	fd = 0, i;
7422514Sdarrenr
7522514Sdarrenr	for (i = 0; i < 16; i++)
7622514Sdarrenr	    {
7722514Sdarrenr		(void) sprintf(bpfname, "/dev/bpf%d", i);
7822514Sdarrenr		if ((fd = open(bpfname, O_RDWR)) >= 0)
7922514Sdarrenr			break;
8022514Sdarrenr	    }
8122514Sdarrenr	if (i == 16)
8222514Sdarrenr	    {
8322514Sdarrenr		fprintf(stderr, "no bpf devices available as /dev/bpfxx\n");
8422514Sdarrenr		return -1;
8522514Sdarrenr	    }
86161357Sguido#endif
8722514Sdarrenr
8822514Sdarrenr	if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0)
8922514Sdarrenr	    {
9022514Sdarrenr		perror("BIOCVERSION");
9122514Sdarrenr		return -1;
9222514Sdarrenr	    }
9322514Sdarrenr	if (bv.bv_major != BPF_MAJOR_VERSION ||
9422514Sdarrenr	    bv.bv_minor < BPF_MINOR_VERSION)
9522514Sdarrenr	    {
9622514Sdarrenr		fprintf(stderr, "kernel bpf (v%d.%d) filter out of date:\n",
9722514Sdarrenr			bv.bv_major, bv.bv_minor);
9822514Sdarrenr		fprintf(stderr, "current version: %d.%d\n",
9922514Sdarrenr			BPF_MAJOR_VERSION, BPF_MINOR_VERSION);
10022514Sdarrenr		return -1;
10122514Sdarrenr	    }
10222514Sdarrenr
10322514Sdarrenr	(void) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
10422514Sdarrenr	if (ioctl(fd, BIOCSETIF, &ifr) == -1)
10522514Sdarrenr	    {
10622514Sdarrenr		fprintf(stderr, "%s(%d):", ifr.ifr_name, fd);
10722514Sdarrenr		perror("BIOCSETIF");
10822514Sdarrenr		exit(1);
10922514Sdarrenr	    }
11022514Sdarrenr	/*
11122514Sdarrenr	 * get kernel buffer size
11222514Sdarrenr	 */
11322514Sdarrenr	if (ioctl(fd, BIOCGBLEN, &bufsize) == -1)
11422514Sdarrenr	    {
11522514Sdarrenr		perror("BIOCSBLEN");
11622514Sdarrenr		exit(-1);
11722514Sdarrenr	    }
11822514Sdarrenr	buf = (u_char*)malloc(bufsize);
11922514Sdarrenr	/*
12022514Sdarrenr	 * set the timeout
12122514Sdarrenr	 */
12222514Sdarrenr	timeout = tout;
12322514Sdarrenr	to.tv_sec = 1;
12422514Sdarrenr	to.tv_usec = 0;
12522514Sdarrenr	if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&to) == -1)
12622514Sdarrenr	    {
12722514Sdarrenr		perror("BIOCSRTIMEOUT");
12822514Sdarrenr		exit(-1);
12922514Sdarrenr	    }
13022514Sdarrenr
13122514Sdarrenr	(void) ioctl(fd, BIOCFLUSH, 0);
13222514Sdarrenr	return fd;
13322514Sdarrenr}
13422514Sdarrenr
13522514Sdarrenr
13622514Sdarrenr/*
13722514Sdarrenr * output an IP packet onto a fd opened for /dev/bpf
13822514Sdarrenr */
13922514Sdarrenrint	sendip(fd, pkt, len)
140255332Scy	int	fd, len;
141255332Scy	char	*pkt;
142255332Scy{
14322514Sdarrenr	if (write(fd, pkt, len) == -1)
14422514Sdarrenr	    {
14522514Sdarrenr		perror("send");
14622514Sdarrenr		return -1;
14722514Sdarrenr	    }
14822514Sdarrenr
14922514Sdarrenr	return len;
15022514Sdarrenr}
151