1/* $NetBSD: sbpf.c,v 1.8 2010/04/17 21:00:09 darrenr Exp $ */ 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 <sys/param.h> 10#include <sys/types.h> 11#include <sys/mbuf.h> 12#include <sys/time.h> 13#include <sys/timeb.h> 14#include <sys/socket.h> 15#include <sys/file.h> 16#include <sys/ioctl.h> 17#if BSD < 199103 18#include <sys/fcntlcom.h> 19#endif 20#if (__FreeBSD_version >= 300000) 21# include <sys/dirent.h> 22#else 23# include <sys/dir.h> 24#endif 25#include <net/bpf.h> 26 27#include <net/if.h> 28#include <netinet/in.h> 29#include <netinet/in_systm.h> 30#include <netinet/ip.h> 31#include <netinet/ip_var.h> 32#include <netinet/udp.h> 33#include <netinet/udp_var.h> 34#include <netinet/tcp.h> 35 36#include <stdio.h> 37#include <netdb.h> 38#include <string.h> 39#include <unistd.h> 40#include <stdlib.h> 41#ifdef __NetBSD__ 42# include <paths.h> 43#endif 44#include <ctype.h> 45#include <signal.h> 46#include <errno.h> 47 48#include "ipsend.h" 49 50#if !defined(lint) 51static const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed"; 52static const char rcsid[] = "@(#)Id: sbpf.c,v 2.5.4.2 2009/12/27 06:53:15 darrenr Exp"; 53#endif 54 55/* 56 * the code herein is dervied from libpcap. 57 */ 58static u_char *buf = NULL; 59static int bufsize = 0, timeout = 1; 60 61 62int initdevice(device, tout) 63char *device; 64int tout; 65{ 66 struct bpf_version bv; 67 struct timeval to; 68 struct ifreq ifr; 69#ifdef _PATH_BPF 70 char *bpfname = _PATH_BPF; 71 int fd; 72 73 if ((fd = open(bpfname, O_RDWR)) < 0) 74 { 75 fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); 76 return -1; 77 } 78#else 79 char bpfname[16]; 80 int fd = 0, i; 81 82 for (i = 0; i < 16; i++) 83 { 84 (void) sprintf(bpfname, "/dev/bpf%d", i); 85 if ((fd = open(bpfname, O_RDWR)) >= 0) 86 break; 87 } 88 if (i == 16) 89 { 90 fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); 91 return -1; 92 } 93#endif 94 95 if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) 96 { 97 perror("BIOCVERSION"); 98 return -1; 99 } 100 if (bv.bv_major != BPF_MAJOR_VERSION || 101 bv.bv_minor < BPF_MINOR_VERSION) 102 { 103 fprintf(stderr, "kernel bpf (v%d.%d) filter out of date:\n", 104 bv.bv_major, bv.bv_minor); 105 fprintf(stderr, "current version: %d.%d\n", 106 BPF_MAJOR_VERSION, BPF_MINOR_VERSION); 107 return -1; 108 } 109 110 (void) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 111 if (ioctl(fd, BIOCSETIF, &ifr) == -1) 112 { 113 fprintf(stderr, "%s(%d):", ifr.ifr_name, fd); 114 perror("BIOCSETIF"); 115 exit(1); 116 } 117 /* 118 * get kernel buffer size 119 */ 120 if (ioctl(fd, BIOCGBLEN, &bufsize) == -1) 121 { 122 perror("BIOCSBLEN"); 123 exit(-1); 124 } 125 buf = (u_char*)malloc(bufsize); 126 /* 127 * set the timeout 128 */ 129 timeout = tout; 130 to.tv_sec = 1; 131 to.tv_usec = 0; 132 if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&to) == -1) 133 { 134 perror("BIOCSRTIMEOUT"); 135 exit(-1); 136 } 137 138 (void) ioctl(fd, BIOCFLUSH, 0); 139 return fd; 140} 141 142 143/* 144 * output an IP packet onto a fd opened for /dev/bpf 145 */ 146int sendip(fd, pkt, len) 147int fd, len; 148char *pkt; 149{ 150 if (write(fd, pkt, len) == -1) 151 { 152 perror("send"); 153 return -1; 154 } 155 156 return len; 157} 158