Skip to content

Latest commit

 

History

History
107 lines (84 loc) · 4.01 KB

README.md

File metadata and controls

107 lines (84 loc) · 4.01 KB

Gem Version Specs

BinStruct

BinStruct provides a simple way to create and dissect binary data. It is an extraction from PacketGen 3.x Fields.

Installation

Installation using RubyGems is easy:

gem install bin_struct

Or add it to a Gemfile:

gem 'bin_struct'

Usage

Create a struct

To create a BinStruct, create a new class inheriting from BinStruct::Struct. Then, defines struct attributes using .define_attr. .define_bit_attr may also be used to define bit field attributes.

require 'bin_struct'

class IPHeader < BinStruct::Struct
  # Define a bir field, defaulting to 0x45, and splitted in 2 sub-fields: version and ihl,
  # 4-bit size each
  define_bit_attr :u8, default: 0x45, version: 4, ihl: 4
  # Define a 8-bit unsigned integer named tos
  #  1st argument: a symbol to define attribute name
  #  2nd argument: a class to define attribute type. May be a type provided by BinStruct,
  #                or a user-defined class inheriting from one of these classes
  #  others arguments: options. Here, :default defines a default value for the attribute.
  define_attr :tos, BinStruct::Int8, default: 0
  # Define a 16-bit unsigned integer named length. Default to 20.
  define_attr :length, BinStruct::Int16, default: 20
  # Define a 16-bir unsigned integer named id. It is initialized with a random number
  define_attr :id, BinStruct::Int16, default: ->(_) { rand(65_535) }
  # Define a bit field composed of 4 subfields of 1, 1, 1 and 13 bit, respectively
  define_bit_attr :frag, flag_rsv: 1, flag_df: 1, flag_mf: 1, fragment_offset: 13
  # Define TTL field, a 8-bit unsigned integer, default to 64
  define_attr :ttl, BinStruct::Int8, default: 64
  # Define protocol field (8-bit unsigned integer)
  define_attr :protocol, BinStruct::Int8
  # Define checksum field (16-bit unsigned integer), default to 0
  define_attr :checksum, BinStruct::Int16, default: 0
  # Source and destination addresses, defined as array of 4 8-bit unsigned integers
  define_attr :src, BinStruct::ArrayOfInt8, length_from: -> { 4 }
  define_attr :dst, BinStruct::ArrayOfInt8, length_from: -> { 4 }
end

Parse a binary string

# Initialize struct from a binary string
ip = IPHeader.new.read("\x45\x00\x00\x14\x43\x21\x00\x00\x40\x01\x00\x00\x7f\x00\x00\x01\x7f\x00\x00\x01".b)

# Access some fields
p ip.version     #=> 4
p ip.ihl         #=> 5
p ip.id.to_s(16) #=> "4321"
p ip.protocol    #=> 1
p ip.src.map { |byte| byte.to_i }.join('.') #=> "127.0.0.1"
> p IPHeader.new.read("\x45\x00\x00\x14\x43\x21\x00\x00\x40\x01\x00\x00\x7f\x00\x00\x01\x7f\x00\x00\x01")
-- IPHeader -----------------------------------------------------------
          BitAttr8               u8: 69               (0x45)
                                     version:4 ihl:5
              Int8              tos: 0                (0x00)
             Int16           length: 20               (0x0014)
             Int16               id: 17185            (0x4321)
         BitAttr16             frag: 0                (0x0000)
                                     flag_rsv:0 flag_df:0 flag_mf:0 fragment_offset:0
              Int8              ttl: 64               (0x40)
              Int8         protocol: 1                (0x01)
             Int16         checksum: 0                (0x0000)
       ArrayOfInt8              src: 127,0,0,1
       ArrayOfInt8              dst: 127,0,0,1

Generate a binary string

# Create a new struct with some fields initialized
ip = IPHeader.new(tos: 42, id: 0x1234)

# Initialize fields after creation
ip.src = [192, 168, 1, 1]
ip.dst = [192, 168, 1, 2]

# Generate binary string
ip.to_s

License

The gem is available as open source under the terms of the MIT License.