]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ipfilter/ipsd/sbpf.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / ipfilter / ipsd / sbpf.c
1 /*      $FreeBSD$       */
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 <stdio.h>
10 #include <netdb.h>
11 #include <ctype.h>
12 #include <signal.h>
13 #include <errno.h>
14 #ifdef __NetBSD__
15 # include <paths.h>
16 #endif
17 #include <sys/types.h>
18 #include <sys/param.h>
19 #include <sys/mbuf.h>
20 #include <sys/time.h>
21 #include <sys/timeb.h>
22 #include <sys/socket.h>
23 #include <sys/file.h>
24 #include <sys/ioctl.h>
25 #if BSD < 199103
26 #include <sys/fcntlcom.h>
27 #endif
28 #include <sys/dir.h>
29 #include <net/bpf.h>
30
31 #include <net/if.h>
32 #include <netinet/in.h>
33 #include <netinet/in_systm.h>
34 #include <netinet/ip.h>
35 #include <netinet/if_ether.h>
36 #include <netinet/ip_var.h>
37 #include <netinet/udp.h>
38 #include <netinet/udp_var.h>
39 #include <netinet/tcp.h>
40 #include <netinet/tcpip.h>
41 #include "ip_compat.h"
42
43 #ifndef lint
44 static  char    sbpf[] = "@(#)sbpf.c    1.2 12/3/95 (C)1995 Darren Reed";
45 #endif
46
47 /*
48 (000) ldh      [12]
49 (001) jeq      #0x800      jt 2 jf 5
50 (002) ldb      [23]
51 (003) jeq      #0x6          jt 4       jf 5
52 (004) ret      #68
53 (005) ret      #0
54 */
55 struct  bpf_insn filter[] = {
56 /* 0. */        { BPF_LD|BPF_H|BPF_ABS,         0, 0, 12 },
57 /* 1. */        { BPF_JMP|BPF_JEQ,              0, 3, 0x0800 },
58 /* 2. */        { BPF_LD|BPF_B|BPF_ABS,         0, 0, 23 },
59 /* 3. */        { BPF_JMP|BPF_JEQ,              0, 1, 0x06 },
60 /* 4. */        { BPF_RET,                      0, 0, 68 },
61 /* 5. */        { BPF_RET,                      0, 0, 0 }
62 };
63 /*
64  * the code herein is dervied from libpcap.
65  */
66 static  u_char  *buf = NULL;
67 static  u_int   bufsize = 32768, timeout = 1;
68
69
70 int     ack_recv(ep)
71         char    *ep;
72 {
73         struct  tcpiphdr        tip;
74         tcphdr_t        *tcp;
75         ip_t    *ip;
76
77         ip = (ip_t *)&tip;
78         tcp = (tcphdr_t *)(ip + 1);
79         bcopy(ep + 14, (char *)ip, sizeof(*ip));
80         bcopy(ep + 14 + (ip->ip_hl << 2), (char *)tcp, sizeof(*tcp));
81         if (ip->ip_p != IPPROTO_TCP && ip->ip_p != IPPROTO_UDP)
82                 return -1;
83         if (ip->ip_p & 0x1fff != 0)
84                 return 0;
85         if (0 == detect(ip, tcp))
86                 return 1;
87         return 0;
88 }
89
90
91 int     readloop(fd, port, dst)
92         int     fd, port;
93         struct  in_addr dst;
94 {
95         register u_char *bp, *cp, *bufend;
96         register struct bpf_hdr *bh;
97         register int    cc;
98         time_t  in = time(NULL);
99         int     done = 0;
100
101         while ((cc = read(fd, buf, bufsize)) >= 0) {
102                 if (!cc && (time(NULL) - in) > timeout)
103                         return done;
104                 bp = buf;
105                 bufend = buf + cc;
106                 /*
107                  * loop through each snapshot in the chunk
108                  */
109                 while (bp < bufend) {
110                         bh = (struct bpf_hdr *)bp;
111                         cp = bp + bh->bh_hdrlen;
112                         done += ack_recv(cp);
113                         bp += BPF_WORDALIGN(bh->bh_caplen + bh->bh_hdrlen);
114                 }
115                 return done;
116         }
117         perror("read");
118         exit(-1);
119 }
120
121 int     initdevice(device, tout)
122         char    *device;
123         int     tout;
124 {
125         struct  bpf_program prog;
126         struct  bpf_version bv;
127         struct  timeval to;
128         struct  ifreq ifr;
129 #ifdef _PATH_BPF
130         char    *bpfname = _PATH_BPF;
131         int     fd;
132
133         if ((fd = open(bpfname, O_RDWR)) < 0)
134             {
135                 fprintf(stderr, "no bpf devices available as /dev/bpfxx\n");
136                 return -1;
137             }
138 #else
139         char    bpfname[16];
140         int     fd = -1, i;
141
142         for (i = 0; i < 16; i++)
143             {
144                 (void) sprintf(bpfname, "/dev/bpf%d", i);
145                 if ((fd = open(bpfname, O_RDWR)) >= 0)
146                         break;
147             }
148         if (i == 16)
149             {
150                 fprintf(stderr, "no bpf devices available as /dev/bpfxx\n");
151                 return -1;
152             }
153 #endif
154
155         if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0)
156             {
157                 perror("BIOCVERSION");
158                 return -1;
159             }
160         if (bv.bv_major != BPF_MAJOR_VERSION ||
161             bv.bv_minor < BPF_MINOR_VERSION)
162             {
163                 fprintf(stderr, "kernel bpf (v%d.%d) filter out of date:\n",
164                         bv.bv_major, bv.bv_minor);
165                 fprintf(stderr, "current version: %d.%d\n",
166                         BPF_MAJOR_VERSION, BPF_MINOR_VERSION);
167                 return -1;
168             }
169
170         (void) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
171         if (ioctl(fd, BIOCSETIF, &ifr) == -1)
172             {
173                 fprintf(stderr, "%s(%d):", ifr.ifr_name, fd);
174                 perror("BIOCSETIF");
175                 exit(1);
176             }
177         /*
178          * set the timeout
179          */
180         timeout = tout;
181         to.tv_sec = 1;
182         to.tv_usec = 0;
183         if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&to) == -1)
184             {
185                 perror("BIOCSRTIMEOUT");
186                 exit(-1);
187             }
188         /*
189          * get kernel buffer size
190          */
191         if (ioctl(fd, BIOCSBLEN, &bufsize) == -1)
192                 perror("BIOCSBLEN");
193         if (ioctl(fd, BIOCGBLEN, &bufsize) == -1)
194             {
195                 perror("BIOCGBLEN");
196                 exit(-1);
197             }
198         printf("BPF buffer size: %d\n", bufsize);
199         buf = (u_char*)malloc(bufsize);
200
201         prog.bf_len = sizeof(filter) / sizeof(struct bpf_insn);
202         prog.bf_insns = filter;
203         if (ioctl(fd, BIOCSETF, (caddr_t)&prog) == -1)
204             {
205                 perror("BIOCSETF");
206                 exit(-1);
207             }
208         (void) ioctl(fd, BIOCFLUSH, 0);
209         return fd;
210 }