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