Date: Tue, 01 Jul 2003 15:35:30 +0000 From: "Matthew Grooms" <mgrooms@shrew.net> To: freebsd-current@freebsd.org Cc: freebsd-net@freebsd.org Subject: BIOCSSEESENT ioctl on 5.1 ... Message-ID: <200307011535.h61FZVYv045470@hole.shrew.net>
next in thread | raw e-mail | index | archive | help
Question, Is there somthing magic about setting this flag? I wrote a small program ( built on 5.1 ) that uses the bpf to read broadcast packets off a local private network, forward them to a peer ( over IPSEC ) who in turn drops them onto its private network ( and visa-versa ). To prevent looping, I was hoping to set the BIOCSSEESENT flag on the fd. Unfortunately, when this option is set I no longer receive any packets on the interface. Here is the relevent code. // open the berkley packet filter device int32_t hbpf; int32_t mnum =3D 0; char device[ 25 ]; do { sprintf( device,"/dev/bpf%d", mnum ); mnum++; hbpf =3D open( device, O_RDWR ); } while( hbpf < 0 && errno =3D=3D EBUSY ); if( hbpf =3D=3D -1 ) { printf( "failed to open a packet filter device\n" ); printf( "exiting ...\n" ); return -1; } printf( "using filter device '%s'\n", device ); // assign the filter to a network device struct ifreq ifr; strcpy( ifr.ifr_name, config.get_service_iface() ); if( ioctl( hbpf, BIOCSETIF, ( uint32_t ) &ifr ) =3D=3D -1 ) { printf( "unable to assign filter to network device \'%s\'\n", ifr.ifr_name ); printf( "exiting ..." ); return -1; } printf( "using network device \'%s\'\n", ifr.ifr_name ); // dont buffer packet data uint32_t value =3D 1; if( ioctl( hbpf, BIOCIMMEDIATE, &value ) =3D=3D -1 ) { printf( "unable to set BIOCIMMEDIATE option for filter device\n" ); printf( "exiting ...\n" ); return -1; } // use promiscuous mode if( ioctl( hbpf, BIOCPROMISC, &value ) =3D=3D -1 ) { printf( "unable to set BIOCPROMISC option for filter device\n" ); printf( "exiting ...\n" ); return -1; } // use non-blocking io if( ioctl( hbpf, FIONBIO, &value ) =3D=3D -1 ) { printf( "unable to set FIONBIO option for filter device\n" ); printf( "exiting ...\n" ); return -1; } // disable header complete mode if( ioctl( hbpf, BIOCSHDRCMPLT, &value ) =3D=3D -1 ) { printf( "unable to set BIOCGHDRCMPLT option for filter device\n" ); printf( "exiting ...\n" ); return -1; } // don't return localy generated packets value =3D 0; if( ioctl( hbpf, BIOCSSEESENT, &value ) =3D=3D -1 ) { printf( "unable to set BIOCGSEESENT option for filter device\n" ); printf( "exiting ...\n" ); return -1; } // get the filter buffer size int32_t buff_size; if( ioctl( hbpf, BIOCGBLEN, &buff_size ) =3D=3D -1 ) { printf( "unable to obtain filter buffer size\n" ); printf( "exiting ...\n" ); return -1; } // setup our bpf filter machine data uint32_t ins_count =3D 8; uint32_t ins_index =3D 0; struct bpf_insn * insns =3D new struct bpf_insn[ ins_count ]; if( !insns ) { printf( "unable to alloc filter macine data\n" ); printf( "exiting ...\n" ); return -1; } insns[ ins_index ].code =3D BPF_LD+BPF_H+BPF_ABS; // load data ( half word ) insns[ ins_index ].k =3D 12; // offset ( protocol ) ins_index++; insns[ ins_index ].code =3D BPF_JMP+BPF_JEQ+BPF_K; // cmp equality and jmp insns[ ins_index ].jt =3D 0; // true offset insns[ ins_index ].jf =3D 5; // false offset insns[ ins_index ].k =3D 0x0800; // value ins_index++; insns[ ins_index ].code =3D BPF_LD+BPF_B+BPF_ABS; // load data ( byte ) insns[ ins_index ].k =3D 23; // offset ( transport type ) ins_index++; insns[ ins_index ].code =3D BPF_JMP+BPF_JEQ+BPF_K; // cmp equality and jmp insns[ ins_index ].jt =3D 0; // true offset insns[ ins_index ].jf =3D 3; // false offset insns[ ins_index ].k =3D 0x11; // value ins_index++; /* * TODO : check for a matching port */ insns[ ins_index ].code =3D BPF_LD+BPF_W+BPF_ABS; // load data ( word ) insns[ ins_index ].k =3D 30; // offset ( destination addre ins_index++; insns[ ins_index ].code =3D BPF_JMP+BPF_JEQ+BPF_K; // cmp equality and jmp insns[ ins_index ].jt =3D 0; // true offset insns[ ins_index ].jf =3D 1; // false offset insns[ ins_index ].k =3D 0xffffffff; // value ins_index++; insns[ ins_index ].code =3D BPF_RET+BPF_K; // return ( passed ) insns[ ins_index ].k =3D ( u_int ) -1; // accept byte count ( everyt ins_index++; insns[ ins_index ].code =3D BPF_RET+BPF_K; // return ( failed ) insns[ ins_index ].jt =3D 0; // insns[ ins_index ].jf =3D 0; // insns[ ins_index ].k =3D 0; // accept byte count ( ignore ins_index++; // assign the bpf filter program struct bpf_program bpfp; bpfp.bf_insns =3D insns; bpfp.bf_len =3D ins_count; if( ioctl( hbpf, BIOCSETF, &bpfp ) =3D=3D -1 ) { printf( "unable to set filter program\n" ); printf( "exiting ...\n" ); return -1; } PS ... From what I can tell, I am following the bpf manpage to the tee and think there could be possibly an issue with this on 5.1. Could anyone help please. Thanks in advance ... -Matthew
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200307011535.h61FZVYv045470>