[Bro-Dev] binpac usage of &length = -1

Hugo hugolin615 at gmail.com
Mon Feb 11 19:21:38 PST 2013


On Mon, Feb 11, 2013 at 10:00 AM, Robin Sommer <robin at icir.org> wrote:

>
> On Sun, Feb 10, 2013 at 15:48 -0600, you wrote:
>
> > Unfortunately, yes, you needed the &length field. Otherwise:
> >
> > /home/****/bro/src/dnp3-protocol.pac:42: error : cannot handle
> incremental
> > input
>
> Too bad, that sounds like a case it should be able to support rather
> easily.
>
> > Then the interesting question is when binpac can handle incremental
> input?
>
> I have no idea ... It might actually be worth looking at the code and
> see where it stumbles. And/or try the dce_rpc approach as we
> discussed.
>

Reaching a stuck point. I included some of my studies here and also my
question.


**********************************************************************************************
In dce_rpc, it is actually easy for his purpose.

type DCE_RPC_PDU = record {
        # Set header's byteorder to little-endian (or big-endian) to
        # avoid cyclic dependency.
        header  : DCE_RPC_Header;
        frag    : bytestring &length = body_length;
        auth    : DCE_RPC_Auth(header);
} &let {
        body_length: int =
                 header.frag_length - sizeof(header) - header.auth_length;
        frag_reassembled: bool =
                $context.flow.reassemble_fragment(frag, header.lastfrag);
        body:   DCE_RPC_Body(header)
                withinput $context.flow.reassembled_body()
                &if frag_reassembled;
} &byteorder = header.byteorder,
  &length = header.frag_length; # length of the PDU

frag already receive byte string, so it uses a separate flow buffer to
reorder or reassemble the byte string in frag.
"withinput" can be understood as take the following bytes as byte string
and give it to "body" to parse.

**************************************************************************************************

I need to play flow_buffer_. The flow buffer object that is directly used
by binpac.

Let's say I have two network packets of 28 bytes.
1 2 3 ....28

29 30 ... 56

If I define a record like following to parse network packets:

type req = record {
     header: Header; #(8 bytes)
     payload : uint16 (2bytes)
}   &length = 10
&let{
     incBuff : bool = $context.flow.increaseBuffer(18);
}

See that I fixed the length of req record with correct length. In
increaseBuffer function, I directly call GrowFrame function. This can
increase flow buffer from 10 to 18. Then I can see binpac do incremental
parsing. Binpac does not care at all where those bytes spanned, it just
parse like
1 2 3 ....18
19 ...     36
37 ...     54.
55, 56 (probably discarded)

However, the problem is that I can not read bytestring stored in the flow
buffer if it is spanned in two network packets. I try to use
flow_buffer_->begin and ->end to read the starting and ending point of the
flow buffer. But that only works for my manually increase flow buffer
within same network packet (because bytes are all ready). When flow buffer
is spanned into two network packet (like, 19...36), the flow buffer still
fetch data, but I can not use begin and end function, as the bytes are not
ready (assert is generated). Also those bytes are not associated with any
record member. So I could not catch those bytes. These bytes are what I
need for parsing. So any idea to solve this?

Two more study experiments are under go....To be continued.



> Robin
>
> --
> Robin Sommer * Phone +1 (510) 722-6541 * robin at icir.org
> ICSI/LBNL    * Fax   +1 (510) 666-2956 *   www.icir.org
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.icsi.berkeley.edu/pipermail/bro-dev/attachments/20130211/06575bb1/attachment.html 


More information about the bro-dev mailing list