BIOCSSEESENT ioctl on 5.1 ...
Matthew Grooms
mgrooms at shrew.net
Tue Jul 1 08:34:10 PDT 2003
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 = 0;
char device[ 25 ];
do
{
sprintf( device,"/dev/bpf%d", mnum );
mnum++;
hbpf = open( device, O_RDWR );
}
while( hbpf < 0 && errno == EBUSY );
if( hbpf == -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 ) == -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 = 1;
if( ioctl( hbpf, BIOCIMMEDIATE, &value ) == -1 )
{
printf( "unable to set BIOCIMMEDIATE option for filter
device\n" );
printf( "exiting ...\n" );
return -1;
}
// use promiscuous mode
if( ioctl( hbpf, BIOCPROMISC, &value ) == -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 ) == -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 ) == -1 )
{
printf( "unable to set BIOCGHDRCMPLT option for filter
device\n" );
printf( "exiting ...\n" );
return -1;
}
// don't return localy generated packets
value = 0;
if( ioctl( hbpf, BIOCSSEESENT, &value ) == -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 ) == -1 )
{
printf( "unable to obtain filter buffer size\n" );
printf( "exiting ...\n" );
return -1;
}
// setup our bpf filter machine data
uint32_t ins_count = 8;
uint32_t ins_index = 0;
struct bpf_insn * insns = 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 = BPF_LD+BPF_H+BPF_ABS; //
load data ( half word )
insns[ ins_index ].k = 12; // offset (
protocol )
ins_index++;
insns[ ins_index ].code = BPF_JMP+BPF_JEQ+BPF_K; // cmp
equality and jmp
insns[ ins_index ].jt = 0; // true
offset
insns[ ins_index ].jf = 5; // false
offset
insns[ ins_index ].k = 0x0800; // value
ins_index++;
insns[ ins_index ].code = BPF_LD+BPF_B+BPF_ABS; // load data
( byte )
insns[ ins_index ].k = 23; // offset (
transport type )
ins_index++;
insns[ ins_index ].code = BPF_JMP+BPF_JEQ+BPF_K; // cmp
equality and jmp
insns[ ins_index ].jt = 0; // true
offset
insns[ ins_index ].jf = 3; // false
offset
insns[ ins_index ].k = 0x11; // value
ins_index++;
/*
* TODO : check for a matching port
*/
insns[ ins_index ].code = BPF_LD+BPF_W+BPF_ABS; // load data
( word )
insns[ ins_index ].k = 30; // offset (
destination addre
ins_index++;
insns[ ins_index ].code = BPF_JMP+BPF_JEQ+BPF_K; // cmp
equality and jmp
insns[ ins_index ].jt = 0; // true
offset
insns[ ins_index ].jf = 1; // false
offset
insns[ ins_index ].k = 0xffffffff; // value
ins_index++;
insns[ ins_index ].code = BPF_RET+BPF_K; // return (
passed )
insns[ ins_index ].k = ( u_int ) -1; // accept
byte count ( everyt
ins_index++;
insns[ ins_index ].code = BPF_RET+BPF_K; // return (
failed )
insns[ ins_index ].jt = 0; //
insns[ ins_index ].jf = 0; //
insns[ ins_index ].k = 0; // accept
byte count ( ignore
ins_index++;
// assign the bpf filter program
struct bpf_program bpfp;
bpfp.bf_insns = insns;
bpfp.bf_len = ins_count;
if( ioctl( hbpf, BIOCSETF, &bpfp ) == -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
More information about the freebsd-net
mailing list