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