/* $NetBSD: sbpf.c,v 1.6 2005/01/04 12:36:02 martti Exp $ */ /* * (C)opyright 1995-1998 Darren Reed. (from tcplog) * * See the IPFILTER.LICENCE file for details on licencing. * */ #include #include #include #include #include #include #include #include #if BSD < 199103 #include #endif #if (__FreeBSD_version >= 300000) # include #else # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipsend.h" #if !defined(lint) static const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed"; static const char rcsid[] = "@(#)Id: sbpf.c,v 2.5 2002/02/24 07:30:03 darrenr Exp"; #endif /* * the code herein is dervied from libpcap. */ static u_char *buf = NULL; static int bufsize = 0, timeout = 1; int initdevice(device, tout) char *device; int tout; { struct bpf_version bv; struct timeval to; struct ifreq ifr; #ifdef _PATH_BPF const char *bpfname = _PATH_BPF; int fd; if ((fd = open(bpfname, O_RDWR)) < 0) { fprintf(stderr, "no bpf devices available (%s)\n", strerror(errno)); return -1; } #else int fd = 0; char bpfname[16]; int 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); } /* * get kernel buffer size */ if (ioctl(fd, BIOCGBLEN, &bufsize) == -1) { perror("BIOCSBLEN"); exit(-1); } buf = (u_char*)malloc(bufsize); /* * 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); } (void) ioctl(fd, BIOCFLUSH, 0); return fd; } /* * output an IP packet onto a fd opened for /dev/bpf */ int sendip(fd, pkt, len) int fd, len; char *pkt; { if (write(fd, pkt, len) == -1) { perror("send"); return -1; } return len; }