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