157109Speter/* $FreeBSD: stable/11/contrib/ipfilter/ipsend/sbpf.c 369277 2021-02-16 00:48:38Z cy $ */ 222514Sdarrenr/* 357109Speter * (C)opyright 1995-1998 Darren Reed. (from tcplog) 422514Sdarrenr * 580490Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 6145519Sdarrenr * 722514Sdarrenr */ 8145519Sdarrenr#include <sys/param.h> 922514Sdarrenr#include <sys/types.h> 1022514Sdarrenr#include <sys/mbuf.h> 1122514Sdarrenr#include <sys/time.h> 1222514Sdarrenr#include <sys/socket.h> 1322514Sdarrenr#include <sys/file.h> 1422514Sdarrenr#include <sys/ioctl.h> 15369277Scy#ifdef __FreeBSD__ 1657109Speter# include <sys/dirent.h> 1757109Speter#else 1857109Speter# include <sys/dir.h> 1957109Speter#endif 2022514Sdarrenr#include <net/bpf.h> 2122514Sdarrenr 2222514Sdarrenr#include <net/if.h> 2322514Sdarrenr#include <netinet/in.h> 2422514Sdarrenr#include <netinet/in_systm.h> 2522514Sdarrenr#include <netinet/ip.h> 26255332Scy#include <netinet/udp.h> 27255332Scy#include <netinet/tcp.h> 28145519Sdarrenr 29145519Sdarrenr#include <stdio.h> 30145519Sdarrenr#include <netdb.h> 31145519Sdarrenr#include <string.h> 32145519Sdarrenr#include <unistd.h> 33145519Sdarrenr#include <stdlib.h> 34161357Sguido#ifdef __NetBSD__ 35161357Sguido# include <paths.h> 36161357Sguido#endif 37145519Sdarrenr#include <ctype.h> 38145519Sdarrenr#include <signal.h> 39145519Sdarrenr#include <errno.h> 40145519Sdarrenr 4124583Sdarrenr#include "ipsend.h" 4222514Sdarrenr 4331183Speter#if !defined(lint) 4431183Speterstatic const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed"; 45255332Scystatic const char rcsid[] = "@(#)$Id$"; 4622514Sdarrenr#endif 4722514Sdarrenr 4822514Sdarrenr/* 4922514Sdarrenr * the code herein is dervied from libpcap. 5022514Sdarrenr */ 5122514Sdarrenrstatic u_char *buf = NULL; 5222514Sdarrenrstatic int bufsize = 0, timeout = 1; 5322514Sdarrenr 5422514Sdarrenr 55145519Sdarrenrint initdevice(device, tout) 56255332Scy char *device; 57255332Scy int tout; 5822514Sdarrenr{ 5922514Sdarrenr struct bpf_version bv; 6022514Sdarrenr struct timeval to; 6122514Sdarrenr struct ifreq ifr; 62161357Sguido#ifdef _PATH_BPF 63161357Sguido char *bpfname = _PATH_BPF; 64161357Sguido int fd; 65161357Sguido 66161357Sguido if ((fd = open(bpfname, O_RDWR)) < 0) 67161357Sguido { 68161357Sguido fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); 69161357Sguido return -1; 70161357Sguido } 71161357Sguido#else 7222514Sdarrenr char bpfname[16]; 73145519Sdarrenr int fd = 0, i; 7422514Sdarrenr 7522514Sdarrenr for (i = 0; i < 16; i++) 7622514Sdarrenr { 7722514Sdarrenr (void) sprintf(bpfname, "/dev/bpf%d", i); 7822514Sdarrenr if ((fd = open(bpfname, O_RDWR)) >= 0) 7922514Sdarrenr break; 8022514Sdarrenr } 8122514Sdarrenr if (i == 16) 8222514Sdarrenr { 8322514Sdarrenr fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); 8422514Sdarrenr return -1; 8522514Sdarrenr } 86161357Sguido#endif 8722514Sdarrenr 8822514Sdarrenr if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) 8922514Sdarrenr { 9022514Sdarrenr perror("BIOCVERSION"); 9122514Sdarrenr return -1; 9222514Sdarrenr } 9322514Sdarrenr if (bv.bv_major != BPF_MAJOR_VERSION || 9422514Sdarrenr bv.bv_minor < BPF_MINOR_VERSION) 9522514Sdarrenr { 9622514Sdarrenr fprintf(stderr, "kernel bpf (v%d.%d) filter out of date:\n", 9722514Sdarrenr bv.bv_major, bv.bv_minor); 9822514Sdarrenr fprintf(stderr, "current version: %d.%d\n", 9922514Sdarrenr BPF_MAJOR_VERSION, BPF_MINOR_VERSION); 10022514Sdarrenr return -1; 10122514Sdarrenr } 10222514Sdarrenr 10322514Sdarrenr (void) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 10422514Sdarrenr if (ioctl(fd, BIOCSETIF, &ifr) == -1) 10522514Sdarrenr { 10622514Sdarrenr fprintf(stderr, "%s(%d):", ifr.ifr_name, fd); 10722514Sdarrenr perror("BIOCSETIF"); 10822514Sdarrenr exit(1); 10922514Sdarrenr } 11022514Sdarrenr /* 11122514Sdarrenr * get kernel buffer size 11222514Sdarrenr */ 11322514Sdarrenr if (ioctl(fd, BIOCGBLEN, &bufsize) == -1) 11422514Sdarrenr { 11522514Sdarrenr perror("BIOCSBLEN"); 11622514Sdarrenr exit(-1); 11722514Sdarrenr } 11822514Sdarrenr buf = (u_char*)malloc(bufsize); 11922514Sdarrenr /* 12022514Sdarrenr * set the timeout 12122514Sdarrenr */ 12222514Sdarrenr timeout = tout; 12322514Sdarrenr to.tv_sec = 1; 12422514Sdarrenr to.tv_usec = 0; 12522514Sdarrenr if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&to) == -1) 12622514Sdarrenr { 12722514Sdarrenr perror("BIOCSRTIMEOUT"); 12822514Sdarrenr exit(-1); 12922514Sdarrenr } 13022514Sdarrenr 13122514Sdarrenr (void) ioctl(fd, BIOCFLUSH, 0); 13222514Sdarrenr return fd; 13322514Sdarrenr} 13422514Sdarrenr 13522514Sdarrenr 13622514Sdarrenr/* 13722514Sdarrenr * output an IP packet onto a fd opened for /dev/bpf 13822514Sdarrenr */ 13922514Sdarrenrint sendip(fd, pkt, len) 140255332Scy int fd, len; 141255332Scy char *pkt; 142255332Scy{ 14322514Sdarrenr if (write(fd, pkt, len) == -1) 14422514Sdarrenr { 14522514Sdarrenr perror("send"); 14622514Sdarrenr return -1; 14722514Sdarrenr } 14822514Sdarrenr 14922514Sdarrenr return len; 15022514Sdarrenr} 151