1 /* $NetBSD: sbpf.c,v 1.3 2012/07/22 14:27:36 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_icmp.h> 32 #include <netinet/ip_var.h> 33 #include <netinet/udp.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 "ip_compat.h" 49 #include "ipsend.h" 50 51 #if !defined(lint) 52 static const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed"; 53 static const char rcsid[] = "@(#)Id: sbpf.c,v 1.1.1.2 2012/07/22 13:44:37 darrenr Exp $"; 54 #endif 55 56 /* 57 * the code herein is dervied from libpcap. 58 */ 59 static u_char *buf = NULL; 60 static int bufsize = 0, timeout = 1; 61 62 63 int initdevice(device, tout) 64 char *device; 65 int tout; 66 { 67 struct bpf_version bv; 68 struct timeval to; 69 struct ifreq ifr; 70 #ifdef _PATH_BPF 71 char *bpfname = _PATH_BPF; 72 int fd; 73 74 if ((fd = open(bpfname, O_RDWR)) < 0) 75 { 76 fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); 77 return -1; 78 } 79 #else 80 char bpfname[16]; 81 int fd = 0, i; 82 83 for (i = 0; i < 16; i++) 84 { 85 (void) sprintf(bpfname, "/dev/bpf%d", i); 86 if ((fd = open(bpfname, O_RDWR)) >= 0) 87 break; 88 } 89 if (i == 16) 90 { 91 fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); 92 return -1; 93 } 94 #endif 95 96 if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) 97 { 98 perror("BIOCVERSION"); 99 return -1; 100 } 101 if (bv.bv_major != BPF_MAJOR_VERSION || 102 bv.bv_minor < BPF_MINOR_VERSION) 103 { 104 fprintf(stderr, "kernel bpf (v%d.%d) filter out of date:\n", 105 bv.bv_major, bv.bv_minor); 106 fprintf(stderr, "current version: %d.%d\n", 107 BPF_MAJOR_VERSION, BPF_MINOR_VERSION); 108 return -1; 109 } 110 111 (void) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 112 if (ioctl(fd, BIOCSETIF, &ifr) == -1) 113 { 114 fprintf(stderr, "%s(%d):", ifr.ifr_name, fd); 115 perror("BIOCSETIF"); 116 exit(1); 117 } 118 /* 119 * get kernel buffer size 120 */ 121 if (ioctl(fd, BIOCGBLEN, &bufsize) == -1) 122 { 123 perror("BIOCSBLEN"); 124 exit(-1); 125 } 126 buf = (u_char*)malloc(bufsize); 127 /* 128 * set the timeout 129 */ 130 timeout = tout; 131 to.tv_sec = 1; 132 to.tv_usec = 0; 133 if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&to) == -1) 134 { 135 perror("BIOCSRTIMEOUT"); 136 exit(-1); 137 } 138 139 (void) ioctl(fd, BIOCFLUSH, 0); 140 return fd; 141 } 142 143 144 /* 145 * output an IP packet onto a fd opened for /dev/bpf 146 */ 147 int sendip(fd, pkt, len) 148 int fd, len; 149 char *pkt; 150 { 151 if (write(fd, pkt, len) == -1) 152 { 153 perror("send"); 154 return -1; 155 } 156 157 return len; 158 } 159