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