Skip site navigation (1)Skip section navigation (2)
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>