Project

bin_struct

0.0
The project is in a healthy, maintained state
BinStruct is a binary dissector and generator. It eases manipulating complex binary data.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies
 Project Readme

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.