Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.
Showing results for
Search instead for
Did you mean:
HowTo: Techniques for inspecting binary protocols
There are several TrafficScript functions that will help you to manage binary data. Here are some points that may help:
Strings in TrafficScript can contain binary data as well as ascii text. They are not null terminated, or limited in size.
You can use request.get( n ) to retrieve the first n bytes of the request data. Trafficscript Request rules are executed when Stingray receives the first request data; if Stingray has not received all n bytes, the request.get() function will block until the data is collected from the client.
request.getline( regex ) can be used instead; it will happily parse binary data, so if you can identify the end of your request with a regular expression, this may be suitable.
You can then use string.substring() to extract substrings from binary data.
The following functions may help to parse binary strings:
lang.ord( str ) returns the value of the first byte in str
lang.chr( i ) returns a 1-byte string with the value 'i'
string.intToBytes() and string.bytesToInt() convert between network-order byte strings and integers
string.BERToInt() and string.intToBER() converts variable length BER-encoded integers in byte strings to integers, and vice versa.
You can assemble a binary string using:
string.replaceBytes() does an in-place replacement
string.insertBytes() does an insertion
You can encode non-printable bytes in a string literal using octal escapes:
$str = "\123\047\110\077";
There are also a range of functions that convert between different ASCII encodings of strings, such as hex, base64 and %-encoding, which may also be useful.
Suppose that you have a protocol in which the request looks like the following:
<2-byte msg length><msg>
You wish to add a header to the msg and update the length in a request rule:
<2-byte msg length><header><msg>
The following TrafficScript rule may suffice:
# 1. calculate the length of the entire message:
$len_str = request.get( 2 ); # read the 2-byte length
$len = string.bytesToInt( $len_str, 2 ); # parse it
# 2. read the entire message
$msg = request.get( 2 + $len );
# 3. Insert the header just after the length
$msg = string.insertBytes( $msg, $header, 2 );
# 4. Update the length
$len = $len + string.len( $header );
$len_str = string.intToBytes( $len );
$msg = string.replaceBytes( $msg, $len_str, 0 );
# 5. Change the request data
request.set( $msg );