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 56 initdevice(char *device, int tout) 57 { 58 struct bpf_version bv; 59 struct timeval to; 60 struct ifreq ifr; 61 #ifdef _PATH_BPF 62 char *bpfname = _PATH_BPF; 63 int fd; 64 65 if ((fd = open(bpfname, O_RDWR)) < 0) 66 { 67 fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); 68 return (-1); 69 } 70 #else 71 char bpfname[16]; 72 int fd = 0, i; 73 74 for (i = 0; i < 16; i++) 75 { 76 (void) snprintf(bpfname, sizeof(bpfname), "/dev/bpf%d", i); 77 if ((fd = open(bpfname, O_RDWR)) >= 0) 78 break; 79 } 80 if (i == 16) 81 { 82 fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); 83 return (-1); 84 } 85 #endif 86 87 if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) 88 { 89 perror("BIOCVERSION"); 90 return (-1); 91 } 92 if (bv.bv_major != BPF_MAJOR_VERSION || 93 bv.bv_minor < BPF_MINOR_VERSION) 94 { 95 fprintf(stderr, "kernel bpf (v%d.%d) filter out of date:\n", 96 bv.bv_major, bv.bv_minor); 97 fprintf(stderr, "current version: %d.%d\n", 98 BPF_MAJOR_VERSION, BPF_MINOR_VERSION); 99 return (-1); 100 } 101 102 (void) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 103 if (ioctl(fd, BIOCSETIF, &ifr) == -1) 104 { 105 fprintf(stderr, "%s(%d):", ifr.ifr_name, fd); 106 perror("BIOCSETIF"); 107 exit(1); 108 } 109 /* 110 * get kernel buffer size 111 */ 112 if (ioctl(fd, BIOCGBLEN, &bufsize) == -1) 113 { 114 perror("BIOCSBLEN"); 115 exit(-1); 116 } 117 buf = (u_char*)malloc(bufsize); 118 /* 119 * set the timeout 120 */ 121 timeout = tout; 122 to.tv_sec = 1; 123 to.tv_usec = 0; 124 if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&to) == -1) 125 { 126 perror("BIOCSRTIMEOUT"); 127 exit(-1); 128 } 129 130 (void) ioctl(fd, BIOCFLUSH, 0); 131 return (fd); 132 } 133 134 135 /* 136 * output an IP packet onto a fd opened for /dev/bpf 137 */ 138 int 139 sendip(int fd, char *pkt, int len) 140 { 141 if (write(fd, pkt, len) == -1) 142 { 143 perror("send"); 144 return (-1); 145 } 146 147 return (len); 148 } 149