Date: Thu, 24 Aug 1995 19:07:21 +0900 From: Toshihiro Kanda <candy@fct.kgc.co.jp> To: guido@gvr.win.tue.nl (Guido van Rooij) Cc: FreeBSD-hackers@freefall.FreeBSD.org Subject: bpf output examples Message-ID: <199508241007.TAA18570@xxx.fct.kgc.co.jp> In-Reply-To: guido@gvr.win.tue.nl's message of 24 Aug 1995 12:19:38 %2B0900
next in thread | raw e-mail | index | archive | help
> Does anyone have a pointer to a program that uses the write feature
> fopr bpf? Tcpdump only reads, as does libpcap etc..
>
> -Guido
Here's a very PART of my program which talks EtherTalk Phase 2.
Pardon for comments in Japanese. See bpf(4) which once lost in
FreeBSD 2.0 :-)
You can write to bpf by:
err = write(bpf_fd, ether_frame, len);
Warning: If you use FreeBSD 2.0 or 2.0.5, Ethernet type field
(ether_frame[12] and ether_frame[13]) must be in machine byte order
NOT network byte order. I thought it's a bug and asked
hackers@freebsd, though no answer was given yet.
candy@fct.kgc.co.jp (Toshihiro Kanda)
---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ----
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h> /* open */
#include <unistd.h>
#include <sys/uio.h> /* read */
#include <sys/param.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <net/if.h> /* struct ifr */
#define BPF_BUFFER_SIZE 0x8000 /* bpf read buffer */
static volatile unsigned ringring;
static unsigned char mac_addr[6];
static int bpf_fd;
static unsigned int bpf_len;
static struct bpf_program prog;
static char *bpf_buf;
static void (*callback)(unsigned long, void *, unsigned long, unsigned long);
static int pipe_fd[2];
static int child;
/*
* bpf $B%W%m%0%i%`(B
*/
static struct bpf_insn insns[] = {
/* GENERATED by tcpdump. source is:
#!/bin/sh
super tcpdump -dds-1 '
(
(ether[0:2] == 0x0000 and ether[2:4] == 0x1b384d97) or
(ether[0:2] == 0xffff and ether[2:4] == 0xffffffff) or
(ether[0:2] == 0x0900 and
(ether[2:4] == 0x07ffffff or
(ether[2:4] >= 0x07000000 and ether[2:4] <= 0x070000fc)))
)
and
(
(ether[12:2] == 0x809b or ether[12:2] == 0x80f3) or
(ether[12:2] < 0x600 and ether[14:2] == 0xaaaa and
(ether[20:2] == 0x809b or ether[20:2] == 0x80f3))
)
'
*/
{ 0x28, 0, 0, 0x00000000 },
{ 0x15, 0, 2, 0x00000000 },
{ 0x20, 0, 0, 0x00000002 },
{ 0x15, 10, 0, 0x1b384d97 },
{ 0x28, 0, 0, 0x00000000 },
{ 0x15, 0, 2, 0x0000ffff },
{ 0x20, 0, 0, 0x00000002 },
{ 0x15, 6, 0, 0xffffffff },
{ 0x28, 0, 0, 0x00000000 },
{ 0x15, 0, 14, 0x00000900 },
{ 0x20, 0, 0, 0x00000002 },
{ 0x15, 2, 0, 0x07ffffff },
{ 0x35, 0, 11, 0x07000000 },
{ 0x25, 10, 0, 0x070000fc },
{ 0x28, 0, 0, 0x0000000c },
{ 0x15, 7, 0, 0x0000809b },
{ 0x15, 6, 0, 0x000080f3 },
{ 0x35, 6, 0, 0x00000600 },
{ 0x28, 0, 0, 0x0000000e },
{ 0x15, 0, 4, 0x0000aaaa },
{ 0x28, 0, 0, 0x00000014 },
{ 0x15, 1, 0, 0x0000809b },
{ 0x15, 0, 1, 0x000080f3 },
{ 0x6, 0, 0, 0xffffffff },
{ 0x6, 0, 0, 0x00000000 },
};
/*
* bpf?? $B$r%*!<%W%s(B
*/
static int
open_bpf(void)
{
int fd = -1, n = 0;
char name[32];
do {
sprintf(name, "/dev/bpf%d", n++);
errno = 0;
fd = open(name, O_RDWR);
} while (fd < 0 && errno == EBUSY);
return fd;
}/* open_bfp */
/*
* bpf $B$r%*!<%W%s$73F<o@_Dj$r$9$k!#(B
*/
static int
open_dev(const char *name, struct bpf_program *prog)
{
int err = -1, fd = open_bpf();
if (fd >= 0) {
/* $B$^$:%P!<%8%g%s$r%A%'%C%/$9$k!#(B */
struct bpf_version ver;
if (ioctl(fd, BIOCVERSION, &ver) == 0) {
if (BPF_MAJOR_VERSION == ver.bv_major && BPF_MINOR_VERSION <= ver.bv_minor) {
/* bpf $B$NFI$_9~$_%P%C%U%!%5%$%:$r@_Dj$9$k!#(B */
unsigned int blen = BPF_BUFFER_SIZE;
if (ioctl(fd, BIOCSBLEN, &blen) == 0) {
/* $B%O!<%I%&%(%"%$%s%?!<%U%'!<%9$r@_Dj$9$k!#(B */
struct ifreq ifr;
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
if (ioctl(fd, BIOCSETIF, &ifr) == 0) {
/* promiscuous $B%b!<%I$K$9$k(B */
if (ioctl(fd, BIOCPROMISC, NULL) == 0) {
/* immediate $B%b!<%I$K$9$k(B */
unsigned int im = 1;
if (ioctl(fd, BIOCIMMEDIATE, &im) == 0) {
/* $B%U%#%k%?%W%m%0%i%`$r@_Dj$9$k!#(B */
if (ioctl(fd, BIOCSETF, prog) == 0) {
#if 0
/* $B%G!<%?%j%s%/%?%$%W$rD4$Y$k(B */
unsigned dlt;
if (ioctl(fd, BIOCGDLT, &dlt) == 0) {
printf("DLT=%u\n", dlt);
}
#endif
err = fd;
}
}
}
}
}
}
}
if (err < 0)
close(fd);
}
return err;
}/* open_dev */
/*
* unix version only
*/
int
ETDInit(void)
{
int err = -1;
extern int getmac(char *ifname, char *result);
getmac("ed0", mac_addr);
insns[1].k = GETUW(&mac_addr[0]);
insns[3].k = GETUL(&mac_addr[2]);
prog.bf_len = sizeof(insns) / sizeof(insns[0]);
prog.bf_insns = insns;
bpf_fd = open_dev("ed0", &prog);
#ifdef unix
setgid(getgid());
setuid(getuid());
#endif
if (bpf_fd >= 0) {
if (ioctl(bpf_fd, BIOCGBLEN, &bpf_len) == 0) {
bpf_buf = malloc(bpf_len);
if (bpf_buf != NULL) {
err = 0;
}
}
}
return err;
}/* ETDInit */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199508241007.TAA18570>
