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