# Hui Lin\_Some question on Binpac

**URL:** <https://community.zeek.org/t/hui-lin-some-question-on-binpac/1920>\
**Category:** Development\
**Tags:** development\
**Created:** [July 12, 2011, 5:10am UTC](https://community.zeek.org/t/hui-lin-some-question-on-binpac/1920 "2011-07-12T05:10:14Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Hui\_Lin](https://avatars.discourse-cdn.com/v4/letter/h/13edae/32.png) [@Hui\_Lin](https://community.zeek.org/u/Hui_Lin)\
**Post date:** [July 12, 2011, 5:10am UTC](https://community.zeek.org/t/hui-lin-some-question-on-binpac/1920/1 "2011-07-12T05:10:14Z")

</div>

Hi,

I have been working on modbus protocol analyzer by Binpac, which is an application-level protocol used in SCADA network. The protocol itself is not complex and it is not hard to express it in Binpac. However, this protocol in application level does not contain the information which can tell whether the parsing packet is a “request” or a “response”. For example, in HTTP protocol, the http header will include such information. But for this protocol, the headers for both the request and response are the same.

So if the traffic dump that I am using for the testing starts with the request, then the analyzer can properly parse it. However, if the traffic dump starts with the response, then the analyzer will not be properly parsing the packet. So I am wondering how to resolve this problem in my protocol analyzer.

Best,

Hui

---

<div class="post-metadata">

**Author:** ![robin](https://yyz1.discourse-cdn.com/flex011/user_avatar/community.zeek.org/robin/32/599_2.png) [@robin](https://community.zeek.org/u/robin)\
**Post date:** [July 12, 2011, 3:09pm UTC](https://community.zeek.org/t/hui-lin-some-question-on-binpac/1920/2 "2011-07-12T15:09:54Z")

</div>

> tell whether the parsing packet is a "request" or a "response". For example,  
> in HTTP protocol, the http header will include such information.

While that's right, BinPAC/Bro is actually not using that information  
to decide which side it's parsing. Generally, Bro always considers the  
originator of a connection to be the client side[1], and then it  
drives BinPAC parsing accordingly.

Take a look at http-procotol.pac, there's this piece:

&nbsp;&nbsp;&nbsp;&nbsp;type HTTP\_PDU(is\_orig: bool) = case is\_orig of {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;true -\> request: HTTP\_Request;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false -\> reply: HTTP\_Reply;  
};

And in http-analyzer.pac, there is:

&nbsp;&nbsp;&nbsp;&nbsp;connection HTTP\_Conn(bro\_analyzer: BroAnalyzer) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upflow = HTTP\_Flow(true);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;downflow = HTTP\_Flow(false);  
&nbsp;&nbsp;&nbsp;&nbsp;};

&nbsp;&nbsp;&nbsp;&nbsp;flow HTTP\_Flow(is\_orig: bool) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flowunit = HTTP\_PDU(is\_orig) withcontext (connection, this);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...

&nbsp;&nbsp;&nbsp;&nbsp;}

When Bro passes in data, it tells BinPAC which of these flows to use.

> From HTTP-binpac.cc:

&nbsp;&nbsp;&nbsp;&nbsp;void HTTP\_Analyzer\_binpac::DeliverStream(int len, const u\_char\* data, bool orig)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;....  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// orig is true here if it's originator-side data.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interp-\>NewData(orig, data, data + len);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

There's a skeleton Bro analyzer on the web page that's based on  
binpac. If you us that skeleton, you should pretty much automatically  
get this direction stuff right. See  
[http://www.bro-ids.org/development/binpac-sample-analyzer.html](http://www.bro-ids.org/development/binpac-sample-analyzer.html)

Robin

[1] With a few additional heuristics for corner-cases.

---

<div class="post-metadata">

**Author:** ![Hui\_Lin](https://avatars.discourse-cdn.com/v4/letter/h/13edae/32.png) [@Hui\_Lin](https://community.zeek.org/u/Hui_Lin)\
**Post date:** [July 13, 2011, 3:28am UTC](https://community.zeek.org/t/hui-lin-some-question-on-binpac/1920/3 "2011-07-13T03:28:26Z")

</div>

Hi,

I do follow the Binpac sample analyzer. And I also notice this part of code which use the value of is\_orig to decide whether the packet is the request.

When Bro is used to parse network traffic on the network card, it is obvious to see what traffic are coming in and what traffic are going out. But i am using the traffic dump to test, so how can Binpac know which traffic is coming in and going out? I use the Wireshark and actually, wireshark can tell whether the packet is a request or response.

Also according to your logic, the Bro considers the originator of the traffic as the client and then this makes sense to my situation. Since the first packet in that dump is a response (without any request before it) and Binpac will consider the source of the packet as the client and the receiver as the server, then this can successfully fool the Binpac to think that this packet is a request. Then the exception can happen.

Best,

Hui

---

<div class="post-metadata">

**Author:** ![robin](https://yyz1.discourse-cdn.com/flex011/user_avatar/community.zeek.org/robin/32/599_2.png) [@robin](https://community.zeek.org/u/robin)\
**Post date:** [July 13, 2011, 4:47pm UTC](https://community.zeek.org/t/hui-lin-some-question-on-binpac/1920/4 "2011-07-13T16:47:53Z")

</div>

Yes, in general that's a problem. Here's what Bro (and thus in turn  
BinPAC) is doing:

&nbsp;&nbsp;&nbsp;&nbsp;(1) by default, the first packet of a new connection indicates the  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;originator.

&nbsp;&nbsp;&nbsp;&nbsp;(2) it however also looks at well-known ports: if with (1), the  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connection would have a well-known port on the originator-side but  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not on the responder-side, it flips the direction.

Is there a well-known port for this protocol? If so, add it to  
policy/server-ports.bro and it should work. If not, you can trigger  
the flipping yourslef by calling Connection::FlipRoles(), but you'd  
need some heuristic to decide who's the client. BinPAC doesn't have  
anything built in for that (yet). Also, flipping should occur as early  
as possible, as otherwise things may get mixed up.

Robin

---

<div class="post-metadata">

**Author:** ![Seth\_Hall3](https://avatars.discourse-cdn.com/v4/letter/s/d6d6ee/32.png) [@Seth\_Hall3](https://community.zeek.org/u/Seth_Hall3)\
**Post date:** [July 13, 2011, 5:02pm UTC](https://community.zeek.org/t/hui-lin-some-question-on-binpac/1920/5 "2011-07-13T17:02:56Z")

</div>

Eek, good reminder. I need to put that back!

&nbsp;&nbsp;.Seth

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex011/uploads/zeek/original/1X/f09d732bc2cc7c7cc7e35db67cf4e1d5233ce7a7.png) [@system](https://community.zeek.org/u/system)\
**Post date:** [May 6, 2022, 3:39pm UTC](https://community.zeek.org/t/hui-lin-some-question-on-binpac/1920/6 "2022-05-06T15:39:39Z")

</div>


