Hi , I am very glad to write this email . I am a user of bro and recently I start to use BinPAC which is a subcomponent of bro . After learning the syntax of BinPAC , I wrote some 
simple BinPAC programs and tested them . I got a problem during the test
 and it really confused me . So I am writing to you and hope to get your
 help . I will describe my problem below . <br>
<p>
        <br>
</p>
<p>
        My BinPAC version is 0.47 .
</p>
<p>
        <br>
</p>
<p>
        In the test I have two machines , A and B . One process on machine A 
sends messages to another process on machine B once per second . the 
message is in this format :
</p>
<p>
        la(uint32) + lb (uint32) + s(a random string
 whose length is not fixed)
</p>
<p>
        In the message , "la" and "lb" are both the
 length of the string "s" . For example , la = 26 , lb = 26 , s = 
"abcdefghijklmnopqrstuvwxyz" . Another example , la = 10 , lb = 10 , s =
 "helloworld" . So I wrote a BinPAC program (<span class="ke-content-forecolor" style="color:#E53333;">see file_1.pac in 
attachment</span>) and it worked as expected . But when I made a small change 
to the BinPAC program (<span class="ke-content-forecolor" style="color:#E53333;">see file_2.pac in attachment</span>), a bug existed .
</p>
<br>
In the first case , I defined a type "header" which contains "la : 
unint32" and "lb : uint32" and I defined another type "body" which 
only contains "s : bytestring" . And I defined a high-level type which 
contains "header" and "body" . Then I print out "la" and the length of "s" . It showed that the program worked 
properly , the output is like this :<br>
<br>
238 238<br>
309 309<br>
311 311<br>
339 339<br>
344 344<br>
252 252<br>
290 290<br>
312 312<br>
298 298<br>
300 300<br>
281 281<br>
...<br>
<br>
That is what I want . The first number in each line is "la" and the second number is the length of "s" .<br>
<br>
<p>
        But when I didn't define the "header" type but wrote "la : uint32 ; lb :
 uint32" in the high-level type directly instead , it failed to work , I mean , nothing was printed out .
</p>
<p>
        <br>
</p>
<p>
        In "file_2.pac" , I wrote like this :
</p>
<p>
        type trans_pdu(is_orig: bool) = record {<br>
&nbsp;&nbsp;&nbsp; la: uint32 &amp;byteorder=bigendian;<br>
&nbsp;&nbsp;&nbsp; lb: uint32 &amp;byteorder=bigendian;<br>
&nbsp;&nbsp;&nbsp; body: trans_body(x) &amp;requires(x);<br>
} &amp;let{<br>
&nbsp;&nbsp;&nbsp; x = la;<br>
} &amp;length = x + 8;
</p>
<br>
I read the file generated by binpac ("file_2.cc") <span class="ke-content-forecolor" style="color:#333333;"><em>, </em></span><span class="ke-content-forecolor" style="color:#333333;"><em></em></span><span class="ke-content-forecolor" style="color:#333333;"><em></em></span><span class="ke-content-forecolor" style="color:#333333;"><em></em></span><span class="ke-content-forecolor" style="color:#333333;"><em></em></span>and I added 2 lines into "file_2.cc" to debug it to see what would happen 
(the additional codes just print out buffering state
 , the address of "t_begin_of_data" , the address of "t_end_of_data" and
 "throw") . The following is part of the code of "file_2.cc" . Only the two "printf" sentences are added by me . <br>
<br>
<em>bool trans_pdu::ParseBuffer(flow_buffer_t t_flow_buffer, Contexttrans * t_context)</em><br>
<em>&nbsp;&nbsp; &nbsp;{</em><br>
<em>&nbsp;&nbsp; &nbsp;bool t_val_parsing_complete;</em><br>
<em>&nbsp;&nbsp; &nbsp;t_val_parsing_complete = false;</em><br>
<em>&nbsp;&nbsp; &nbsp;const_byteptr t_begin_of_data = t_flow_buffer-&gt;begin();</em><br>
<em>&nbsp;&nbsp; &nbsp;const_byteptr t_end_of_data = t_flow_buffer-&gt;end();</em><br>
<em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</em><span class="ke-content-forecolor" style="color:#E53333;"><em>&nbsp;&nbsp;&nbsp;
 printf("buffering state: %d&nbsp; t_begin_of_data: %d&nbsp; t_end_of_data: %d \n"
 , buffering_state_ , (void*)t_begin_of_data , (void*)</em></span><span class="ke-content-forecolor" style="color:#E53333;"><em>t_end_of_data);</em></span><br>
<em>&nbsp;&nbsp; &nbsp;switch ( buffering_state_ )</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<span class="ke-content-forecolor" style="color:#E53333;">case 0:</span></em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if ( buffering_state_ == 0 )</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<span class="ke-content-forecolor" style="color:#E53333;">t_flow_buffer-&gt;</span><span class="ke-content-forecolor" style="color:#E53333;">NewFrame(4, false)</span>;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;buffering_state_ = 1;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;buffering_state_ = 1;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;break;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<span class="ke-content-forecolor" style="color:#E53333;">case 1:</span></em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;buffering_state_ = 2;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="ke-content-forecolor" style="color:#E53333;">&nbsp;// Checking out-of-bound for "trans_pdu:lb"</span></em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if ( (t_begin_of_data + 4) + (4) &gt; t_end_of_data || (t_begin_of_data + 4) + (4) &lt; (t_begin_of_data + 4) )</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{</em><br>
<em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</em><span class="ke-content-forecolor" style="color:#E53333;"> <em>printf("throw</em><em>\n");</em></span><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// Handle out-of-bound condition</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;throw binpac::ExceptionOutOfBound("trans_pdu:lb",</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;(4) + (4), </em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;(t_end_of_data) - (t_begin_of_data));</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// Parse "la"</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;la_ = FixByteOrder(bigendian, *((uint32 const *) (t_begin_of_data)));</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// Evaluate 'let' and 'withinput' fields</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;x_ = la();</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;t_flow_buffer-&gt;GrowFrame(x() + 8);</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;break;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;case 2:</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;BINPAC_ASSERT(t_flow_buffer-&gt;ready());</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if ( t_flow_buffer-&gt;ready() )</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// Parse "lb"</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;lb_ = FixByteOrder(bigendian, *((uint32 const *) ((t_begin_of_data + 4))));</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// Evaluate 'let' and 'withinput' fields</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// Parse "body"</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;body_ = new trans_body(x());</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int t_body__size;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;t_body__size = body_-&gt;Parse((t_begin_of_data + 8), t_end_of_data);</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// Evaluate 'let' and 'withinput' fields</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;t_val_parsing_complete = true;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if ( t_val_parsing_complete )</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// Evaluate 'let' and 'withinput' fields</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proc_ = t_context-&gt;flow()-&gt;proc_sample_message(this);</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;BINPAC_ASSERT(t_val_parsing_complete);</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;buffering_state_ = 0;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;break;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;default:</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;BINPAC_ASSERT(buffering_state_ &lt;= 2);</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;break;</em><br>
<em>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}</em><br>
<em>&nbsp;&nbsp; &nbsp;return t_val_parsing_complete;</em><br>
<p>
        <em>&nbsp;&nbsp; &nbsp;}</em> 
</p>
<p>
        <em><br>
</em> 
</p>
<p>
        <em>void trans_flow::NewData(const_byteptr t_begin_of_data, const_byteptr t_end_of_data)</em> 
</p>
<p>
        <em>&nbsp;&nbsp;&nbsp;&nbsp;{</em> 
</p>
<p>
        <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......</em> 
</p>
<p>
        <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......<br>
</em> 
</p>
<p>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while ( ! t_dataunit_parsing_complete &amp;&amp; flow_buffer_-&gt;ready() )<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;const_byteptr t_begin_of_data = flow_buffer()-&gt;begin();<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;const_byteptr t_end_of_data = flow_buffer()-&gt;end();<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;t_dataunit_parsing_complete = dataunit_-&gt;<span class="ke-content-forecolor" style="color:#E53333;">ParseBuffer</span>(flow_buffer(), context_);<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if ( t_dataunit_parsing_complete )<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// Evaluate 'let' and 'withinput' fields<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>
<em></em> 
</p>
<p>
        <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;......</em> 
</p>
<p>
        <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;......<br>
</em> 
</p>
<p>
        <em>&nbsp;&nbsp;&nbsp;&nbsp;}<br>
</em> 
</p>
<br>
and the following is the output : <br>
<br>
buffering state: 0&nbsp; t_begin_of_data: 44665856&nbsp; t_end_of_data: 44665856 <br>
buffering state: 1&nbsp; t_begin_of_data: 44665856&nbsp; t_end_of_data: 44665860 <br>
throw<br>
buffering state: 0&nbsp; t_begin_of_data: 44669328&nbsp; t_end_of_data: 44669328 <br>
buffering state: 1&nbsp; t_begin_of_data: 44669328&nbsp; t_end_of_data: 44669332 <br>
throw<br>
buffering state: 0&nbsp; t_begin_of_data: 44687568&nbsp; t_end_of_data: 44687568 <br>
buffering state: 1&nbsp; t_begin_of_data: 44687568&nbsp; t_end_of_data: 44687572 <br>
throw<br>
buffering state: 0&nbsp; t_begin_of_data: 44688176&nbsp; t_end_of_data: 44688176 <br>
buffering state: 1&nbsp; t_begin_of_data: 44688176&nbsp; t_end_of_data: 44688180 <br>
throw<br>
...<br>
<p>
        <br>
</p>
<p>
        <br>
</p>
<p>
        I guess that in " case 0 " , the sentence "&nbsp;<span class="ke-content-forecolor" style="color:#E53333;">t_flow_buffer-&gt;NewFrame(4, false)</span> " is used to create a 4-byte frame to parse "la" , since "la" occupies 
the first 4 bytes of the message and BinPAC need it evaluate the length 
of the message ? After this operation , "t_begin_of_data " points to 
the begin of the message and "t_end_of_data" points to the end of "la" 
.&nbsp; But then " case 1 " will take place . "lb" will be checked whether 
out-of-bound . "t_begin_of_data + 4" is the begin of "lb" ,&nbsp; " 4 " is 
the length of "lb" , but "t_end_of_data" still points to the end of la .
 So&nbsp; <span class="ke-content-forecolor" style="color:#E53333;">"(t_begin_of_data + 4) + (4) &gt; 
t_end_of_data</span><span class="ke-content-forecolor" style="color:#E53333;">"</span>&nbsp;
 was met , and the program didn't go ahead . However , that is only 
the direct reason but not the source reason . I guess the source reason 
is that I didn't write the BinPAC code in the correct way somewhere or 
maybe there is a small bug in BinPAC .
</p>
<p>
        <br>
</p>
<p>
        I really really hope to use BinPAC to 
deal with some protocol analysis . I tried to
 read the source code of BinPAC but failed to understand . I don't know 
what to do and I really want to get your help !
</p>
<p>
        Wish to get your reply !
</p>
<p>
        <br>
</p>
<p>
        Good luck !
</p>
<p>
        Yunchao Chen
</p>
<p>
        2018.2.27
</p>