1/* $FreeBSD: stable/11/contrib/ipfilter/ipsend/sbpf.c 369277 2021-02-16 00:48:38Z 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#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) 44static const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed"; 45static const char rcsid[] = "@(#)$Id$"; 46#endif 47 48/* 49 * the code herein is dervied from libpcap. 50 */ 51static u_char *buf = NULL; 52static int bufsize = 0, timeout = 1; 53 54 55int 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) sprintf(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 */ 139int 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