summaryrefslogtreecommitdiffstats
path: root/ipsd/sbpf.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipsd/sbpf.c')
-rw-r--r--ipsd/sbpf.c208
1 files changed, 208 insertions, 0 deletions
diff --git a/ipsd/sbpf.c b/ipsd/sbpf.c
new file mode 100644
index 0000000..457891b
--- /dev/null
+++ b/ipsd/sbpf.c
@@ -0,0 +1,208 @@
+/*
+ * (C)opyright 1995-1998 Darren Reed. (from tcplog)
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ */
+#include <stdio.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <signal.h>
+#include <errno.h>
+#ifdef __NetBSD__
+# include <paths.h>
+#endif
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#if BSD < 199103
+#include <sys/fcntlcom.h>
+#endif
+#include <sys/dir.h>
+#include <net/bpf.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+#include "ip_compat.h"
+
+#ifndef lint
+static char sbpf[] = "@(#)sbpf.c 1.2 12/3/95 (C)1995 Darren Reed";
+#endif
+
+/*
+(000) ldh [12]
+(001) jeq #0x800 jt 2 jf 5
+(002) ldb [23]
+(003) jeq #0x6 jt 4 jf 5
+(004) ret #68
+(005) ret #0
+*/
+struct bpf_insn filter[] = {
+/* 0. */ { BPF_LD|BPF_H|BPF_ABS, 0, 0, 12 },
+/* 1. */ { BPF_JMP|BPF_JEQ, 0, 3, 0x0800 },
+/* 2. */ { BPF_LD|BPF_B|BPF_ABS, 0, 0, 23 },
+/* 3. */ { BPF_JMP|BPF_JEQ, 0, 1, 0x06 },
+/* 4. */ { BPF_RET, 0, 0, 68 },
+/* 5. */ { BPF_RET, 0, 0, 0 }
+};
+/*
+ * the code herein is dervied from libpcap.
+ */
+static u_char *buf = NULL;
+static u_int bufsize = 32768, timeout = 1;
+
+
+int ack_recv(ep)
+char *ep;
+{
+ struct tcpiphdr tip;
+ tcphdr_t *tcp;
+ ip_t *ip;
+
+ ip = (ip_t *)&tip;
+ tcp = (tcphdr_t *)(ip + 1);
+ bcopy(ep + 14, (char *)ip, sizeof(*ip));
+ bcopy(ep + 14 + (ip->ip_hl << 2), (char *)tcp, sizeof(*tcp));
+ if (ip->ip_p != IPPROTO_TCP && ip->ip_p != IPPROTO_UDP)
+ return -1;
+ if (ip->ip_p & 0x1fff != 0)
+ return 0;
+ if (0 == detect(ip, tcp))
+ return 1;
+ return 0;
+}
+
+
+int readloop(fd, port, dst)
+int fd, port;
+struct in_addr dst;
+{
+ register u_char *bp, *cp, *bufend;
+ register struct bpf_hdr *bh;
+ register int cc;
+ time_t in = time(NULL);
+ int done = 0;
+
+ while ((cc = read(fd, buf, bufsize)) >= 0) {
+ if (!cc && (time(NULL) - in) > timeout)
+ return done;
+ bp = buf;
+ bufend = buf + cc;
+ /*
+ * loop through each snapshot in the chunk
+ */
+ while (bp < bufend) {
+ bh = (struct bpf_hdr *)bp;
+ cp = bp + bh->bh_hdrlen;
+ done += ack_recv(cp);
+ bp += BPF_WORDALIGN(bh->bh_caplen + bh->bh_hdrlen);
+ }
+ return done;
+ }
+ perror("read");
+ exit(-1);
+}
+
+int initdevice(device, tout)
+char *device;
+int tout;
+{
+ struct bpf_program prog;
+ struct bpf_version bv;
+ struct timeval to;
+ struct ifreq ifr;
+#ifdef _PATH_BPF
+ char *bpfname = _PATH_BPF;
+ int fd;
+
+ if ((fd = open(bpfname, O_RDWR)) < 0)
+ {
+ fprintf(stderr, "no bpf devices available as /dev/bpfxx\n");
+ return -1;
+ }
+#else
+ char bpfname[16];
+ int fd = -1, i;
+
+ for (i = 0; i < 16; i++)
+ {
+ (void) sprintf(bpfname, "/dev/bpf%d", i);
+ if ((fd = open(bpfname, O_RDWR)) >= 0)
+ break;
+ }
+ if (i == 16)
+ {
+ fprintf(stderr, "no bpf devices available as /dev/bpfxx\n");
+ return -1;
+ }
+#endif
+
+ if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0)
+ {
+ perror("BIOCVERSION");
+ return -1;
+ }
+ if (bv.bv_major != BPF_MAJOR_VERSION ||
+ bv.bv_minor < BPF_MINOR_VERSION)
+ {
+ fprintf(stderr, "kernel bpf (v%d.%d) filter out of date:\n",
+ bv.bv_major, bv.bv_minor);
+ fprintf(stderr, "current version: %d.%d\n",
+ BPF_MAJOR_VERSION, BPF_MINOR_VERSION);
+ return -1;
+ }
+
+ (void) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ if (ioctl(fd, BIOCSETIF, &ifr) == -1)
+ {
+ fprintf(stderr, "%s(%d):", ifr.ifr_name, fd);
+ perror("BIOCSETIF");
+ exit(1);
+ }
+ /*
+ * set the timeout
+ */
+ timeout = tout;
+ to.tv_sec = 1;
+ to.tv_usec = 0;
+ if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&to) == -1)
+ {
+ perror("BIOCSRTIMEOUT");
+ exit(-1);
+ }
+ /*
+ * get kernel buffer size
+ */
+ if (ioctl(fd, BIOCSBLEN, &bufsize) == -1)
+ perror("BIOCSBLEN");
+ if (ioctl(fd, BIOCGBLEN, &bufsize) == -1)
+ {
+ perror("BIOCGBLEN");
+ exit(-1);
+ }
+ printf("BPF buffer size: %d\n", bufsize);
+ buf = (u_char*)malloc(bufsize);
+
+ prog.bf_len = sizeof(filter) / sizeof(struct bpf_insn);
+ prog.bf_insns = filter;
+ if (ioctl(fd, BIOCSETF, (caddr_t)&prog) == -1)
+ {
+ perror("BIOCSETF");
+ exit(-1);
+ }
+ (void) ioctl(fd, BIOCFLUSH, 0);
+ return fd;
+}
OpenPOWER on IntegriCloud