Hui Lin_Binpac: handle incremental input for flowunit


When I define flowunit data for flow, I am bothered by the not support incremental input. I have searched this error and found a mail from Seth. It seems that flowunit data has to be clearly set the &length. My situation is something like follows

type XXX_Request = record {
header: Header;
data: case header.function_code of {
x → request_type1: Type1;
x → request_type2: Type2;

} &length = …;

XXX_Request is the flowunit data. My problem is that after header is parsed, I still don’t know the length of the whole XXX_Request data unit. The function_code from the header will define what data type follows the header and different data type have different length. So I am wondering what I can do in this situation to set the proper value of length of the XXX_Request. Or flowunit is not supporting this situation, I have to use the datagram?


Presumably this is for the DNP3 protocol? There isn't any framing around the request with the length? Are they framing it to the packet perhaps? (I'm running into sort of similar trouble with the SSL analyzer and binpac doesn't let you frame to the packets).

I don't think you can use datagram if the protocol you're working on is TCP since the packets could be fragmented or out of order. I'd love to be proven wrong though....


It is the DNP3 protocol. I kind of refer to the modbus protocol that shared from Dina. In modbus, the header contain the length field, so it is straightforward to set the length of the flowunit. But DNP3 does not contain such field to directly indicate the length of the application level fragment.

The structure is kind of more complex. Some request will contain addition headers and objects, so you can only know the length of the whole fragment when you parse them all. Or at least parse this additional header (but there is also no length field in this additional header). I don’t quite follow what do you mean “framing it to the packet”. Any further suggestion?

I just mean using the packet length as the length of the request or response. If that's how the protocol works and if binpac supported it (a lot of "if"s), that would provide you the way to give a length to the top parse unit to avoid the incremental parsing error.

Maybe someone else has a suggestion? I'm unfortunately out of ideas.


Obviously, modbus-tcp was on tcp, but is DNP3?

DNP3 protocol do include some support for what it calls Pseudo Transport Layer. And it also mentions that some company would like to see DNP3 can be put on TCP/IP. So I would like to try use flowunit to implement DNP3 protocol.

Hi Seth, Here is a piece code from SSL protocol (as you mentioned that you met the similar problem in SSL protocol)

type SSLRecord(is_orig: bool) = record {
head0 : uint8;
head1 : uint8;
head2 : uint8;
head3 : uint8;
head4 : uint8;
rec : RecordText(this, is_orig) &requires(content_type), &restofdata;
} &length = length+5, &byteorder=bigendian,
&let {
version : int =
$context.analyzer.determine_ssl_version(head0, head1, head2);

content_type : int = case version of {
SSLv20 → head2+300;
default → head0;

length : int = case version of {
SSLv20 → (((head0 & 0x7f) << 8) | head1) - 3;
default → (head3 << 8) | head4;

Here the &length is set by its attribute length and length is then decided according to different situation. so I think this might be working in my case? As I can similarly set length to different value according to the function code and then use this to set the &length.

Yes, you should be able to do something similar to that. I can't claim to have come up with that technique either. Whoever wrote the previous binpac SSL analyzer did it, but we are currently having some trouble with that when DPD is enabled. We're trying to get it fixed for the preview though.