Any good tools for reading networking data with optional TLV

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

Ramana Gollamudi wrote:

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 :options, :type => :tlv,
:read_until => lambda { my_terminating_condition }
end

Dion Mendel wrote:

Ramana Gollamudi wrote:

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 :options, :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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs