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