From owner-freebsd-hackers Thu Aug 24 03:22:51 1995 Return-Path: hackers-owner Received: (from majordom@localhost) by freefall.FreeBSD.org (8.6.11/8.6.6) id DAA12065 for hackers-outgoing; Thu, 24 Aug 1995 03:22:51 -0700 Received: from mail0.iij.ad.jp (mail0.iij.ad.jp [192.244.176.61]) by freefall.FreeBSD.org (8.6.11/8.6.6) with ESMTP id DAA12059 for ; Thu, 24 Aug 1995 03:22:48 -0700 Received: from uucp0.iij.ad.jp (uucp0.iij.ad.jp [192.244.176.51]) by mail0.iij.ad.jp (8.6.12+2.4W/3.3W9-MAIL) with ESMTP id TAA18079; Thu, 24 Aug 1995 19:20:14 +0900 Received: (from uucp@localhost) by uucp0.iij.ad.jp (8.6.12+2.4W/3.3W9-UUCP) with UUCP id TAA14430; Thu, 24 Aug 1995 19:20:15 +0900 Received: from xxx.fct.kgc.co.jp by fender.fct.kgc.co.jp (8.6.12+2.4W/3.4W:95071117) id TAA03635; Thu, 24 Aug 1995 19:07:23 +0900 Received: by xxx.fct.kgc.co.jp (8.6.12+2.4W/3.3W8:95062916) id TAA18570; Thu, 24 Aug 1995 19:07:21 +0900 Date: Thu, 24 Aug 1995 19:07:21 +0900 From: Toshihiro Kanda Message-Id: <199508241007.TAA18570@xxx.fct.kgc.co.jp> To: guido@gvr.win.tue.nl (Guido van Rooij) Cc: FreeBSD-hackers@freefall.FreeBSD.org In-reply-to: guido@gvr.win.tue.nl's message of 24 Aug 1995 12:19:38 +0900 Subject: bpf output examples Sender: hackers-owner@FreeBSD.org Precedence: bulk > 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 #include #include #include #include #include /* open */ #include #include /* read */ #include #include #include #include #include #include #include #include /* 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 プログラム */ 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?? をオープン */ 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 をオープンし各種設定をする。 */ static int open_dev(const char *name, struct bpf_program *prog) { int err = -1, fd = open_bpf(); if (fd >= 0) { /* まずバージョンをチェックする。 */ struct bpf_version ver; if (ioctl(fd, BIOCVERSION, &ver) == 0) { if (BPF_MAJOR_VERSION == ver.bv_major && BPF_MINOR_VERSION <= ver.bv_minor) { /* bpf の読み込みバッファサイズを設定する。 */ unsigned int blen = BPF_BUFFER_SIZE; if (ioctl(fd, BIOCSBLEN, &blen) == 0) { /* ハードウエアインターフェースを設定する。 */ struct ifreq ifr; strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); if (ioctl(fd, BIOCSETIF, &ifr) == 0) { /* promiscuous モードにする */ if (ioctl(fd, BIOCPROMISC, NULL) == 0) { /* immediate モードにする */ unsigned int im = 1; if (ioctl(fd, BIOCIMMEDIATE, &im) == 0) { /* フィルタプログラムを設定する。 */ if (ioctl(fd, BIOCSETF, prog) == 0) { #if 0 /* データリンクタイプを調べる */ 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 */