btw. here is my regression test for bpf:
Index: regress/sys/net/Makefile
===================================================================
RCS file: /home/cvs/src/regress/sys/net/Makefile,v
retrieving revision 1.6
diff -u -p -r1.6 Makefile
--- regress/sys/net/Makefile 12 Jul 2014 21:41:49 -0000 1.6
+++ regress/sys/net/Makefile 21 Jan 2015 13:54:05 -0000
@@ -1,6 +1,6 @@
# $OpenBSD: Makefile,v 1.6 2014/07/12 21:41:49 bluhm Exp $
-SUBDIR += pf_divert pf_forward pf_fragment
+SUBDIR += pf_divert pf_forward pf_fragment bpf_features
.MAIN: regress
Index: regress/sys/net/bpf_features/Makefile
===================================================================
RCS file: regress/sys/net/bpf_features/Makefile
diff -N regress/sys/net/bpf_features/Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ regress/sys/net/bpf_features/Makefile 21 Jan 2015 14:21:19 -0000
@@ -0,0 +1,46 @@
+.MAIN: all
+
+CDIAGFLAGS = -std=c99 -Werror -Wall -Wstrict-prototypes \
+ -Wmissing-prototypes -Wno-main -Wno-uninitialized \
+ -Wbad-function-cast -Wcast-align -Wcast-qual \
+ -Wextra -Wmissing-declarations -Wpointer-arith -Wshadow \
+ -Wsign-compare -Wuninitialized -Wunused -Wno-unused-parameter \
+ -Wnested-externs -Wunreachable-code -Winline \
+ -Wdisabled-optimization -Wconversion -Wfloat-equal -Wswitch \
+ -Wswitch-default -Wtrigraphs -Wsequence-point -Wimplicit \
+WARNINGS = yes
+depend: bpf_read_blocking bpf_read_timeout bpf_read_async bpf_read_timeout_loop
+
+bpf_read_blocking: bpf_read_blocking.c
+ ${CC} ${CFLAGS} -o bpf_read_blocking bpf_read_blocking.c
+
+bpf_read_timeout: bpf_read_timeout.c
+ ${CC} ${CFLAGS} -o bpf_read_timeout bpf_read_timeout.c
+
+bpf_read_async: bpf_read_async.c
+ ${CC} ${CFLAGS} -o bpf_read_async bpf_read_async.c
+
+bpf_read_timeout_loop: bpf_read_timeout_loop.c
+ ${CC} ${CFLAGS} -o bpf_read_timeout_loop bpf_read_timeout_loop.c
+
+TARGETS += blocking timeout async timeoutloop
+
+run-regress-blocking: bpf_read_blocking
+ ./bpf_read_blocking
+
+run-regress-timeout: bpf_read_timeout
+ ./bpf_read_timeout
+
+run-regress-async: bpf_read_async
+ @/sbin/ping -c 10 127.0.0.1 > /dev/null 2>&1 &
+ ./bpf_read_async
+
+run-regress-timeoutloop: bpf_read_timeout_loop
+ ./bpf_read_timeout_loop
+
+REGRESS_TARGETS = ${TARGETS:S/^/run-regress-/}
+
+CLEANFILES += bpf_read_timeout bpf_read_blocking bpf_read_async \
+ bpf_read_timeout_loop
+
+.include <bsd.regress.mk>
Index: regress/sys/net/bpf_features/bpf_read_async.c
===================================================================
RCS file: regress/sys/net/bpf_features/bpf_read_async.c
diff -N regress/sys/net/bpf_features/bpf_read_async.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ regress/sys/net/bpf_features/bpf_read_async.c 21 Jan 2015 12:32:01
-0000
@@ -0,0 +1,86 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <err.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/bpf.h>
+#include <net/ethertypes.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <sys/time.h>
+
+#define BUFFFER_SIZE 32786
+u_char buffer[BUFFFER_SIZE];
+u_int buf_size = BUFFFER_SIZE;
+
+struct bpf_program bpf_machine = {
+ 2,
+ (struct bpf_insn []){
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 8),
+ BPF_STMT(BPF_RET+BPF_K, 8),
+ },
+};
+struct ifreq interface;
+struct sigaction sigact;
+int fd, out, pid, flag;
+int async = 1;
+struct sigaction action;
+
+void handler(int);
+
+int
+main(void)
+{
+ action.sa_handler = handler;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ if (sigaction(SIGIO, &action, NULL) < 0)
+ err(1, "sigaction");
+
+ pid = getpid();
+ if (setpgrp(0, 0) < 0)
+ err(1, "setpgrp");
+
+ sigemptyset(&action.sa_mask);
+ if (sigprocmask(SIG_SETMASK, &action.sa_mask, NULL) < 0)
+ err(1, "sigprocmask");
+
+ if ((fd = open("/dev/bpf9", O_RDONLY)) < 0)
+ err(1, "open");
+
+ if (ioctl(fd, BIOCSBLEN, &buf_size) < 0)
+ err(1, "BIOCSBLEN");
+
+ strlcpy(interface.ifr_name, "lo0", sizeof(interface.ifr_name));
+ if(ioctl(fd, BIOCSETIF, &interface) < 0)
+ err(1, "BIOCSETIF");
+
+ if (ioctl(fd, FIOSETOWN, &pid) < 0)
+ err(1, "FIOSETOWN");
+ if (ioctl(fd, FIOASYNC, &async) < 0)
+ err(1, "FIOASYNC");
+
+ if (ioctl(fd, BIOCSETF, &bpf_machine) < 0)
+ err(1, "BIOCSETF");
+
+ out = read(fd, buffer, sizeof(buffer));
+ if (out < 0)
+ err(1, "read");
+
+ errx(1, "ERROR: %s", "you shouldn't see this message");
+}
+
+void
+handler(int _signal)
+{
+ printf("PASSED\n");
+ _exit(0);
+}
Index: regress/sys/net/bpf_features/bpf_read_blocking.c
===================================================================
RCS file: regress/sys/net/bpf_features/bpf_read_blocking.c
diff -N regress/sys/net/bpf_features/bpf_read_blocking.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ regress/sys/net/bpf_features/bpf_read_blocking.c 21 Jan 2015 12:32:21
-0000
@@ -0,0 +1,95 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <err.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/bpf.h>
+#include <net/ethertypes.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <sys/time.h>
+
+void handler(int);
+
+#define BUFFFER_SIZE 32786
+u_char buffer[BUFFFER_SIZE];
+u_int buf_size = BUFFFER_SIZE;
+
+struct bpf_program bpf_machine = {
+ 13,
+ (struct bpf_insn []){
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_IP, 0, 10),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 8),
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0),
+ BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 2, 0),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ },
+};
+struct ifreq interface;
+struct sigaction action;
+int fd, out;
+struct itimerval timer = {
+ {
+ (time_t)1,
+ (suseconds_t)0,
+ },
+ {
+ (time_t)5,
+ (suseconds_t)0,
+ },
+};
+
+int
+main(void)
+{
+ action.sa_handler = handler;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ if (sigaction(SIGALRM, &action, NULL) < 0)
+ err(1, "sigaction");
+
+ if (setitimer(0, &timer, NULL) == -1)
+ err(1, "setitimer");
+
+ if ((fd = open("/dev/bpf9", O_RDONLY)) < 0)
+ err(1, "open");
+
+ if (ioctl(fd, BIOCSBLEN, &buf_size) < 0)
+ err(1, "BIOCSBLEN");
+
+ strlcpy(interface.ifr_name, "lo0", sizeof(interface.ifr_name));
+ if(ioctl(fd, BIOCSETIF, &interface) < 0)
+ err(1, "BIOCSETIF");
+
+ if (ioctl(fd, BIOCSETF, &bpf_machine) < 0)
+ err(1, "BIOCSETF");
+
+ out = read(fd, buffer, sizeof(buffer));
+ if (out < 0)
+ err(1, "read");
+
+ errx(1, "ERROR: %s", "you shouldn't see this message");
+}
+
+void
+handler(int _signal)
+{
+ printf("PASSED\n");
+ _exit(0);
+}
Index: regress/sys/net/bpf_features/bpf_read_timeout.c
===================================================================
RCS file: regress/sys/net/bpf_features/bpf_read_timeout.c
diff -N regress/sys/net/bpf_features/bpf_read_timeout.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ regress/sys/net/bpf_features/bpf_read_timeout.c 21 Jan 2015 12:31:44
-0000
@@ -0,0 +1,109 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <err.h>
+#include <time.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/bpf.h>
+#include <net/ethertypes.h>
+#include <netinet/in.h>
+#include <net/if.h>
+
+#define BUFFFER_SIZE 32786
+u_char buffer[BUFFFER_SIZE];
+u_int buf_size = BUFFFER_SIZE;
+
+struct bpf_program bpf_machine = {
+ 13,
+ (struct bpf_insn []){
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_IP, 0, 10),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 8),
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0),
+ BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 2, 0),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ },
+};
+struct timeval timeout = {
+ (time_t)5,
+ (suseconds_t)0,
+};
+struct ifreq interface;
+struct sigaction action;
+int fd, out;
+time_t cur_time;
+struct itimerval timer = {
+ {
+ (time_t)1,
+ (suseconds_t)0,
+ },
+ {
+ (time_t)10,
+ (suseconds_t)0,
+ }
+};
+
+void handler(int);
+
+int
+main(void)
+{
+ action.sa_handler = handler;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ if (sigaction(SIGALRM, &action, NULL) < 0)
+ err(1, "sigaction");
+
+ if (setitimer(0, &timer, NULL) == -1)
+ err(1, "setitimer");
+
+ cur_time = time(NULL);
+
+ if ((fd = open("/dev/bpf9", O_RDONLY)) < 0)
+ err(1, "open");
+
+ if (ioctl(fd, BIOCSBLEN, &buf_size) < 0)
+ err(1, "BIOCSBLEN");
+
+ strlcpy(interface.ifr_name, "lo0", sizeof(interface.ifr_name));
+ if(ioctl(fd, BIOCSETIF, &interface) < 0)
+ err(1, "BIOCSETIF");
+
+ if (ioctl(fd, BIOCSRTIMEOUT, &timeout) < 0)
+ err(1, "BIOCSRTIMEOUT");
+
+ if (ioctl(fd, BIOCSETF, &bpf_machine) < 0)
+ err(1, "BIOCSETF");
+
+ out = read(fd, buffer, sizeof(buffer));
+ if (out < 0)
+ err(1, "read");
+
+ if ((time(NULL) - cur_time) < 5)
+ errx(1, "ERROR: %s", "you shouldn't see this message");
+ else {
+ printf("PASSED\n");
+ return 0;
+ }
+}
+
+void
+handler(int _signal)
+{
+ errx(1, "ERROR: %s", "you shouldn't see this message");
+}
Index: regress/sys/net/bpf_features/bpf_read_timeout_loop.c
===================================================================
RCS file: regress/sys/net/bpf_features/bpf_read_timeout_loop.c
diff -N regress/sys/net/bpf_features/bpf_read_timeout_loop.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ regress/sys/net/bpf_features/bpf_read_timeout_loop.c 21 Jan 2015
12:31:16 -0000
@@ -0,0 +1,112 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <err.h>
+#include <time.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/bpf.h>
+#include <net/ethertypes.h>
+#include <netinet/in.h>
+#include <net/if.h>
+
+#define BUFFFER_SIZE 32786
+u_char buffer[BUFFFER_SIZE];
+u_int buf_size = BUFFFER_SIZE;
+
+struct bpf_program bpf_machine = {
+ 13,
+ (struct bpf_insn []){
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_IP, 0, 10),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 8),
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0),
+ BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 2, 0),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ },
+};
+struct timeval timeout = {
+ (time_t)5,
+ (suseconds_t)0,
+};
+struct ifreq interface;
+struct sigaction action;
+int fd, out;
+time_t cur_time;
+struct itimerval timer = {
+ {
+ (time_t)1,
+ (suseconds_t)0,
+ },
+ {
+ (time_t)10,
+ (suseconds_t)0,
+ }
+};
+
+void handler(int);
+
+int
+main(void)
+{
+ action.sa_handler = handler;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ if (sigaction(SIGALRM, &action, NULL) < 0)
+ err(1, "sigaction");
+
+ if ((fd = open("/dev/bpf9", O_RDONLY)) < 0)
+ err(1, "open");
+
+ if (ioctl(fd, BIOCSBLEN, &buf_size) < 0)
+ err(1, "BIOCSBLEN");
+
+ strlcpy(interface.ifr_name, "lo0", sizeof(interface.ifr_name));
+ if(ioctl(fd, BIOCSETIF, &interface) < 0)
+ err(1, "BIOCSETIF");
+
+ if (ioctl(fd, BIOCSRTIMEOUT, &timeout) < 0)
+ err(1, "BIOCSRTIMEOUT");
+
+ if (ioctl(fd, BIOCSETF, &bpf_machine) < 0)
+ err(1, "BIOCSETF");
+
+ int i;
+ for (i = 0; i < 3; i++ ) {
+ if (setitimer(0, &timer, NULL) == -1)
+ err(1, "setitimer");
+
+ cur_time = time(NULL);
+
+ out = read(fd, buffer, sizeof(buffer));
+ if (out < 0)
+ err(1, "read");
+
+ if ((time(NULL) - cur_time) < 5)
+ errx(1, "ERROR: %s",
+ "you shouldn't see this message");
+ }
+
+ printf("PASSED\n");
+ return 0;
+}
+
+void
+handler(int _signal)
+{
+ errx(1, "ERROR: %s", "you shouldn't see this message");
+}