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