any good tools for reading networking data with optional TLV

  • Thread starter Ramana Gollamudi
  • Start date
R

Ramana Gollamudi

Hi,

I am trying to write code that reads data off a socket and processes
that request. This is a proprietary protocol data on UDP. However, the
packet data that is read contains multiple optional TLVs all of which
may not exist in all the packets that are read off the socket. The
existence or non-existence of the TLV in a given data packet is
indicated by the TLV-type and length in the TLV itself.

Is there a good mechanism available in Ruby to read and handle such
data. I can do this easily enough in C/C++ but this seems specially hard
in Ruby. Is the only option pack/unpack methods? I tried to see if
bindata works but the documentation is unclear on whether it can handle
multiple TLVS that may exist in different combination in each packet?

Thanks,

Ramana
 
D

Dion Mendel

Ramana said:
I tried to see if bindata works but the documentation is unclear
on whether it can handle multiple TLVS that may exist in different
combination in each packet?

I am the author of BinData. Yes BinData handles optional TLVs
(type-length-value). You didn't specify if your TLVs are nested or
flat. An example of flat TLVs is given below. Nested TLVs are
slightly more complicated and require more code so I haven't provided
an example. Contact me offlist if you need more details.

Here is an example of a data format (MyFormat) supporting multiple,
optional, unordered TLVs.

class CustomType1 < BinData::Record
int8 :a
int8 :b
...
end

...

class Tlv < BinData::Record
endian :big
uint8 :t
uint32 :l
choice :v, :selection => :chooser do
string "unknown", :read_length => :l
custom_type_1 "v1"
custom_type_2 "v2"
...
end

def chooser
if t == xx and l == yy
"v1"
elsif t == ww and l == zz
...
else
"unknown"
end
end
end

class MyFormat < BinData::Record
...
array :eek:ptions, :type => :tlv,
:read_until => lambda { my_terminating_condition }
end
 
R

Ramana Gollamudi

Dion said:
I am the author of BinData. Yes BinData handles optional TLVs
(type-length-value). You didn't specify if your TLVs are nested or
flat. An example of flat TLVs is given below. Nested TLVs are
slightly more complicated and require more code so I haven't provided
an example. Contact me offlist if you need more details.

Here is an example of a data format (MyFormat) supporting multiple,
optional, unordered TLVs.

class CustomType1 < BinData::Record
int8 :a
int8 :b
...
end

...

class Tlv < BinData::Record
endian :big
uint8 :t
uint32 :l
choice :v, :selection => :chooser do
string "unknown", :read_length => :l
custom_type_1 "v1"
custom_type_2 "v2"
...
end

def chooser
if t == xx and l == yy
"v1"
elsif t == ww and l == zz
...
else
"unknown"
end
end
end

class MyFormat < BinData::Record
...
array :eek:ptions, :type => :tlv,
:read_until => lambda { my_terminating_condition }
end

Dion,

Thanks for clarifying the use of BinData for this. My protocol does not
have nested TLVs. There are only flat TLVs. The message consists of a
header and a bunch of different TLVs. The header has an identifier whose
value identifies the message type. The TLVs are identified by the Type
field that is the first byte in the TLVs.
I will try you choice - selection to see if this works.

Thanks,

Ramana
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,016
Latest member
TatianaCha

Latest Threads

Top