141edb306SCy Schubert /* $FreeBSD$ */ 241edb306SCy Schubert /* 341edb306SCy Schubert * (C)opyright 1995-1998 Darren Reed. (from tcplog) 441edb306SCy Schubert * 541edb306SCy Schubert * See the IPFILTER.LICENCE file for details on licencing. 641edb306SCy Schubert * 741edb306SCy Schubert */ 841edb306SCy Schubert #include <sys/param.h> 941edb306SCy Schubert #include <sys/types.h> 1041edb306SCy Schubert #include <sys/mbuf.h> 1141edb306SCy Schubert #include <sys/time.h> 1241edb306SCy Schubert #include <sys/socket.h> 1341edb306SCy Schubert #include <sys/file.h> 1441edb306SCy Schubert #include <sys/ioctl.h> 1541edb306SCy Schubert #ifdef __FreeBSD__ 1641edb306SCy Schubert # include <sys/dirent.h> 1741edb306SCy Schubert #else 1841edb306SCy Schubert # include <sys/dir.h> 1941edb306SCy Schubert #endif 2041edb306SCy Schubert #include <net/bpf.h> 2141edb306SCy Schubert 2241edb306SCy Schubert #include <net/if.h> 2341edb306SCy Schubert #include <netinet/in.h> 2441edb306SCy Schubert #include <netinet/in_systm.h> 2541edb306SCy Schubert #include <netinet/ip.h> 2641edb306SCy Schubert #include <netinet/udp.h> 2741edb306SCy Schubert #include <netinet/tcp.h> 2841edb306SCy Schubert 2941edb306SCy Schubert #include <stdio.h> 3041edb306SCy Schubert #include <netdb.h> 3141edb306SCy Schubert #include <string.h> 3241edb306SCy Schubert #include <unistd.h> 3341edb306SCy Schubert #include <stdlib.h> 3441edb306SCy Schubert #ifdef __NetBSD__ 3541edb306SCy Schubert # include <paths.h> 3641edb306SCy Schubert #endif 3741edb306SCy Schubert #include <ctype.h> 3841edb306SCy Schubert #include <signal.h> 3941edb306SCy Schubert #include <errno.h> 4041edb306SCy Schubert 4141edb306SCy Schubert #include "ipsend.h" 4241edb306SCy Schubert 4341edb306SCy Schubert #if !defined(lint) 4441edb306SCy Schubert static const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed"; 4541edb306SCy Schubert static const char rcsid[] = "@(#)$Id$"; 4641edb306SCy Schubert #endif 4741edb306SCy Schubert 4841edb306SCy Schubert /* 4941edb306SCy Schubert * the code herein is dervied from libpcap. 5041edb306SCy Schubert */ 5141edb306SCy Schubert static u_char *buf = NULL; 5241edb306SCy Schubert static int bufsize = 0, timeout = 1; 5341edb306SCy Schubert 5441edb306SCy Schubert 55*efeb8bffSCy Schubert int 56*efeb8bffSCy Schubert initdevice(char *device, int tout) 5741edb306SCy Schubert { 5841edb306SCy Schubert struct bpf_version bv; 5941edb306SCy Schubert struct timeval to; 6041edb306SCy Schubert struct ifreq ifr; 6141edb306SCy Schubert #ifdef _PATH_BPF 6241edb306SCy Schubert char *bpfname = _PATH_BPF; 6341edb306SCy Schubert int fd; 6441edb306SCy Schubert 6541edb306SCy Schubert if ((fd = open(bpfname, O_RDWR)) < 0) 6641edb306SCy Schubert { 6741edb306SCy Schubert fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); 6841edb306SCy Schubert return -1; 6941edb306SCy Schubert } 7041edb306SCy Schubert #else 7141edb306SCy Schubert char bpfname[16]; 7241edb306SCy Schubert int fd = 0, i; 7341edb306SCy Schubert 7441edb306SCy Schubert for (i = 0; i < 16; i++) 7541edb306SCy Schubert { 7641edb306SCy Schubert (void) snprintf(bpfname, sizeof(bpfname), "/dev/bpf%d", i); 7741edb306SCy Schubert if ((fd = open(bpfname, O_RDWR)) >= 0) 7841edb306SCy Schubert break; 7941edb306SCy Schubert } 8041edb306SCy Schubert if (i == 16) 8141edb306SCy Schubert { 8241edb306SCy Schubert fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); 8341edb306SCy Schubert return -1; 8441edb306SCy Schubert } 8541edb306SCy Schubert #endif 8641edb306SCy Schubert 8741edb306SCy Schubert if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) 8841edb306SCy Schubert { 8941edb306SCy Schubert perror("BIOCVERSION"); 9041edb306SCy Schubert return -1; 9141edb306SCy Schubert } 9241edb306SCy Schubert if (bv.bv_major != BPF_MAJOR_VERSION || 9341edb306SCy Schubert bv.bv_minor < BPF_MINOR_VERSION) 9441edb306SCy Schubert { 9541edb306SCy Schubert fprintf(stderr, "kernel bpf (v%d.%d) filter out of date:\n", 9641edb306SCy Schubert bv.bv_major, bv.bv_minor); 9741edb306SCy Schubert fprintf(stderr, "current version: %d.%d\n", 9841edb306SCy Schubert BPF_MAJOR_VERSION, BPF_MINOR_VERSION); 9941edb306SCy Schubert return -1; 10041edb306SCy Schubert } 10141edb306SCy Schubert 10241edb306SCy Schubert (void) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 10341edb306SCy Schubert if (ioctl(fd, BIOCSETIF, &ifr) == -1) 10441edb306SCy Schubert { 10541edb306SCy Schubert fprintf(stderr, "%s(%d):", ifr.ifr_name, fd); 10641edb306SCy Schubert perror("BIOCSETIF"); 10741edb306SCy Schubert exit(1); 10841edb306SCy Schubert } 10941edb306SCy Schubert /* 11041edb306SCy Schubert * get kernel buffer size 11141edb306SCy Schubert */ 11241edb306SCy Schubert if (ioctl(fd, BIOCGBLEN, &bufsize) == -1) 11341edb306SCy Schubert { 11441edb306SCy Schubert perror("BIOCSBLEN"); 11541edb306SCy Schubert exit(-1); 11641edb306SCy Schubert } 11741edb306SCy Schubert buf = (u_char*)malloc(bufsize); 11841edb306SCy Schubert /* 11941edb306SCy Schubert * set the timeout 12041edb306SCy Schubert */ 12141edb306SCy Schubert timeout = tout; 12241edb306SCy Schubert to.tv_sec = 1; 12341edb306SCy Schubert to.tv_usec = 0; 12441edb306SCy Schubert if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&to) == -1) 12541edb306SCy Schubert { 12641edb306SCy Schubert perror("BIOCSRTIMEOUT"); 12741edb306SCy Schubert exit(-1); 12841edb306SCy Schubert } 12941edb306SCy Schubert 13041edb306SCy Schubert (void) ioctl(fd, BIOCFLUSH, 0); 13141edb306SCy Schubert return fd; 13241edb306SCy Schubert } 13341edb306SCy Schubert 13441edb306SCy Schubert 13541edb306SCy Schubert /* 13641edb306SCy Schubert * output an IP packet onto a fd opened for /dev/bpf 13741edb306SCy Schubert */ 138*efeb8bffSCy Schubert int 139*efeb8bffSCy Schubert sendip(int fd, char *pkt, int len) 14041edb306SCy Schubert { 14141edb306SCy Schubert if (write(fd, pkt, len) == -1) 14241edb306SCy Schubert { 14341edb306SCy Schubert perror("send"); 14441edb306SCy Schubert return -1; 14541edb306SCy Schubert } 14641edb306SCy Schubert 14741edb306SCy Schubert return len; 14841edb306SCy Schubert } 149