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>