packetgen 3.1.4 → 3.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/lib/packetgen.rb +8 -1
 - data/lib/packetgen/capture.rb +16 -8
 - data/lib/packetgen/config.rb +15 -9
 - data/lib/packetgen/deprecation.rb +1 -1
 - data/lib/packetgen/header/dhcpv6/option.rb +1 -11
 - data/lib/packetgen/header/dns/qdsection.rb +1 -1
 - data/lib/packetgen/header/dot11.rb +2 -32
 - data/lib/packetgen/header/dot1x.rb +1 -14
 - data/lib/packetgen/header/eap.rb +11 -15
 - data/lib/packetgen/header/eth.rb +3 -0
 - data/lib/packetgen/header/http/headers.rb +3 -0
 - data/lib/packetgen/header/ip/addr.rb +3 -0
 - data/lib/packetgen/header/ipv6/addr.rb +3 -0
 - data/lib/packetgen/header/tcp.rb +1 -20
 - data/lib/packetgen/inspect.rb +1 -17
 - data/lib/packetgen/inspectable.rb +20 -0
 - data/lib/packetgen/pcaprub_wrapper.rb +18 -4
 - data/lib/packetgen/types/abstract_tlv.rb +4 -1
 - data/lib/packetgen/types/array.rb +4 -3
 - data/lib/packetgen/types/cstring.rb +3 -0
 - data/lib/packetgen/types/enum.rb +4 -0
 - data/lib/packetgen/types/fields.rb +121 -89
 - data/lib/packetgen/types/int.rb +14 -0
 - data/lib/packetgen/types/int_string.rb +3 -0
 - data/lib/packetgen/types/oui.rb +3 -0
 - data/lib/packetgen/types/string.rb +1 -0
 - data/lib/packetgen/types/tlv.rb +3 -0
 - data/lib/packetgen/utils.rb +1 -1
 - data/lib/packetgen/version.rb +1 -1
 - metadata +5 -3
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 476cbc2bd2b9fb254ea40fe0a07a4d703a0fc36e4accc823de7e83b640d95a2d
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 375f31ea90589b2b0c0b257b8a3efaa66715e8b369c542124fe3dcac283d9221
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: c518ff72cf70227c8f9ef38cce97ba5036eb3229051d38172ba947898b9051f508670d1e0106bac0f5edf577fe1450d5f71db557aa6968b7e3998945a87177d7
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 9382d6f8a7542c8988dec0aaf92940f1518885133bf9e7c835478e787546309410c7e7bcfb4525c13fb7479a9cad9a7ece3e30a3d3c6bbb4f081c1cc48b7f02e
         
     | 
    
        data/lib/packetgen.rb
    CHANGED
    
    | 
         @@ -97,6 +97,12 @@ module PacketGen 
     | 
|
| 
       97 
97 
     | 
    
         
             
                Interfacez.default
         
     | 
| 
       98 
98 
     | 
    
         
             
              end
         
     | 
| 
       99 
99 
     | 
    
         | 
| 
      
 100 
     | 
    
         
            +
              # Get loopback network interface
         
     | 
| 
      
 101 
     | 
    
         
            +
              # @return [String]
         
     | 
| 
      
 102 
     | 
    
         
            +
              def self.loopback_iface
         
     | 
| 
      
 103 
     | 
    
         
            +
                Interfacez.loopback
         
     | 
| 
      
 104 
     | 
    
         
            +
              end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
       100 
106 
     | 
    
         
             
              # Shortcut to get a header class
         
     | 
| 
       101 
107 
     | 
    
         
             
              # @example builtin class
         
     | 
| 
       102 
108 
     | 
    
         
             
              #   # same as PacketGen::Header::Dot11:Data.new(id: 0xfedc)
         
     | 
| 
         @@ -114,8 +120,9 @@ module PacketGen 
     | 
|
| 
       114 
120 
     | 
    
         
             
            end
         
     | 
| 
       115 
121 
     | 
    
         | 
| 
       116 
122 
     | 
    
         
             
            require 'packetgen/deprecation'
         
     | 
| 
       117 
     | 
    
         
            -
            require 'packetgen/types'
         
     | 
| 
       118 
123 
     | 
    
         
             
            require 'packetgen/inspect'
         
     | 
| 
      
 124 
     | 
    
         
            +
            require 'packetgen/inspectable'
         
     | 
| 
      
 125 
     | 
    
         
            +
            require 'packetgen/types'
         
     | 
| 
       119 
126 
     | 
    
         
             
            require 'packetgen/pcapng'
         
     | 
| 
       120 
127 
     | 
    
         
             
            require 'packetgen/pcap'
         
     | 
| 
       121 
128 
     | 
    
         
             
            require 'packetgen/packet'
         
     | 
    
        data/lib/packetgen/capture.rb
    CHANGED
    
    | 
         @@ -13,7 +13,7 @@ module PacketGen 
     | 
|
| 
       13 
13 
     | 
    
         
             
              class Capture
         
     | 
| 
       14 
14 
     | 
    
         
             
                private
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                attr_reader :filter, :cap_thread, :snaplen, :promisc
         
     | 
| 
      
 16 
     | 
    
         
            +
                attr_reader :filter, :cap_thread, :snaplen, :promisc, :monitor
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
                public
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
         @@ -41,14 +41,18 @@ module PacketGen 
     | 
|
| 
       41 
41 
     | 
    
         
             
                #    yielding.  Default: +true+
         
     | 
| 
       42 
42 
     | 
    
         
             
                # @param [Integer] snaplen maximum number of bytes to capture for
         
     | 
| 
       43 
43 
     | 
    
         
             
                #    each packet.
         
     | 
| 
      
 44 
     | 
    
         
            +
                # @param [Boolean] monitor enable or disable monitor mode on interface (if supported by +iface+).
         
     | 
| 
       44 
45 
     | 
    
         
             
                # @since 2.0.0 remove old 1.x API
         
     | 
| 
       45 
46 
     | 
    
         
             
                # @since 3.0.0 arguments are kwargs and no more a hash
         
     | 
| 
       46 
     | 
    
         
            -
                 
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
      
 47 
     | 
    
         
            +
                # @since 3.1.5 add monitor argument
         
     | 
| 
      
 48 
     | 
    
         
            +
                # @author Sylvain Daubert
         
     | 
| 
      
 49 
     | 
    
         
            +
                # @author optix2000 - add monitor argument
         
     | 
| 
      
 50 
     | 
    
         
            +
                def initialize(iface: nil, max: nil, timeout: nil, filter: nil, promisc: false, parse: true, snaplen: nil, monitor: nil)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  @iface = iface || PacketGen.default_iface || PacketGen.loopback_iface
         
     | 
| 
       48 
52 
     | 
    
         | 
| 
       49 
53 
     | 
    
         
             
                  @packets     = []
         
     | 
| 
       50 
54 
     | 
    
         
             
                  @raw_packets = []
         
     | 
| 
       51 
     | 
    
         
            -
                  set_options iface, max, timeout, filter, promisc, parse, snaplen
         
     | 
| 
      
 55 
     | 
    
         
            +
                  set_options iface, max, timeout, filter, promisc, parse, snaplen, monitor
         
     | 
| 
       52 
56 
     | 
    
         
             
                end
         
     | 
| 
       53 
57 
     | 
    
         | 
| 
       54 
58 
     | 
    
         
             
                # Start capture
         
     | 
| 
         @@ -56,8 +60,11 @@ module PacketGen 
     | 
|
| 
       56 
60 
     | 
    
         
             
                # @yieldparam [Packet,String] packet if a block is given, yield each
         
     | 
| 
       57 
61 
     | 
    
         
             
                #    captured packet (Packet or raw data String, depending on +:parse+ option)
         
     | 
| 
       58 
62 
     | 
    
         
             
                # @since 3.0.0 arguments are kwargs and no more a hash
         
     | 
| 
       59 
     | 
    
         
            -
                 
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
      
 63 
     | 
    
         
            +
                # @since 3.1.5 add monitor argument
         
     | 
| 
      
 64 
     | 
    
         
            +
                # @author Sylvain Daubert
         
     | 
| 
      
 65 
     | 
    
         
            +
                # @author optix2000 - add monitor argument
         
     | 
| 
      
 66 
     | 
    
         
            +
                def start(iface: nil, max: nil, timeout: nil, filter: nil, promisc: false, parse: true, snaplen: nil, monitor: nil, &block)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  set_options iface, max, timeout, filter, promisc, parse, snaplen, monitor
         
     | 
| 
       61 
68 
     | 
    
         | 
| 
       62 
69 
     | 
    
         
             
                  @cap_thread = Thread.new do
         
     | 
| 
       63 
70 
     | 
    
         
             
                    PCAPRUBWrapper.capture(**capture_args) do |packet_data|
         
     | 
| 
         @@ -79,7 +86,7 @@ module PacketGen 
     | 
|
| 
       79 
86 
     | 
    
         | 
| 
       80 
87 
     | 
    
         
             
                private
         
     | 
| 
       81 
88 
     | 
    
         | 
| 
       82 
     | 
    
         
            -
                def set_options(iface, max, timeout, filter, promisc, parse, snaplen)
         
     | 
| 
      
 89 
     | 
    
         
            +
                def set_options(iface, max, timeout, filter, promisc, parse, snaplen, monitor)
         
     | 
| 
       83 
90 
     | 
    
         
             
                  @max = max if max
         
     | 
| 
       84 
91 
     | 
    
         
             
                  @filter = filter unless filter.nil?
         
     | 
| 
       85 
92 
     | 
    
         
             
                  @timeout = timeout unless timeout.nil?
         
     | 
| 
         @@ -87,10 +94,11 @@ module PacketGen 
     | 
|
| 
       87 
94 
     | 
    
         
             
                  @snaplen = snaplen unless snaplen.nil?
         
     | 
| 
       88 
95 
     | 
    
         
             
                  @parse = parse unless parse.nil?
         
     | 
| 
       89 
96 
     | 
    
         
             
                  @iface = iface unless iface.nil?
         
     | 
| 
      
 97 
     | 
    
         
            +
                  @monitor = monitor unless monitor.nil?
         
     | 
| 
       90 
98 
     | 
    
         
             
                end
         
     | 
| 
       91 
99 
     | 
    
         | 
| 
       92 
100 
     | 
    
         
             
                def capture_args
         
     | 
| 
       93 
     | 
    
         
            -
                  h = { iface: iface, filter: filter }
         
     | 
| 
      
 101 
     | 
    
         
            +
                  h = { iface: iface, filter: filter, monitor: monitor }
         
     | 
| 
       94 
102 
     | 
    
         
             
                  h[:snaplen] = snaplen unless snaplen.nil?
         
     | 
| 
       95 
103 
     | 
    
         
             
                  h[:promisc] = promisc unless promisc.nil?
         
     | 
| 
       96 
104 
     | 
    
         
             
                  h
         
     | 
    
        data/lib/packetgen/config.rb
    CHANGED
    
    | 
         @@ -22,37 +22,43 @@ module PacketGen 
     | 
|
| 
       22 
22 
     | 
    
         
             
                attr_reader :default_iface
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
24 
     | 
    
         
             
                def initialize
         
     | 
| 
       25 
     | 
    
         
            -
                  @default_iface =  
     | 
| 
      
 25 
     | 
    
         
            +
                  @default_iface = PacketGen.default_iface || PacketGen.loopback_iface
         
     | 
| 
       26 
26 
     | 
    
         
             
                  @hwaddr = {}
         
     | 
| 
       27 
27 
     | 
    
         
             
                  @ipaddr = {}
         
     | 
| 
       28 
28 
     | 
    
         
             
                  @ip6addr = {}
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                   
     | 
| 
       31 
     | 
    
         
            -
                    @hwaddr[iface_name] = Interfacez.mac_address_of(iface_name)
         
     | 
| 
       32 
     | 
    
         
            -
                    @ipaddr[iface_name] = Interfacez.ipv4_address_of(iface_name)
         
     | 
| 
       33 
     | 
    
         
            -
                    @ip6addr[iface_name] = Interfacez.ipv6_addresses_of(iface_name)
         
     | 
| 
       34 
     | 
    
         
            -
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  initialize_local_addresses
         
     | 
| 
       35 
31 
     | 
    
         
             
                end
         
     | 
| 
       36 
32 
     | 
    
         | 
| 
       37 
33 
     | 
    
         
             
                # Get MAC address for given network interface
         
     | 
| 
       38 
34 
     | 
    
         
             
                # @param [String,nil] iface network interface. If +nil+, use default one.
         
     | 
| 
       39 
35 
     | 
    
         
             
                # @return [String]
         
     | 
| 
       40 
36 
     | 
    
         
             
                def hwaddr(iface=nil)
         
     | 
| 
       41 
     | 
    
         
            -
                  @hwaddr[iface ||  
     | 
| 
      
 37 
     | 
    
         
            +
                  @hwaddr[iface || default_iface]
         
     | 
| 
       42 
38 
     | 
    
         
             
                end
         
     | 
| 
       43 
39 
     | 
    
         | 
| 
       44 
40 
     | 
    
         
             
                # Get IP address for given network interface
         
     | 
| 
       45 
41 
     | 
    
         
             
                # @param [String,nil] iface network interface. If +nil+, use default one.
         
     | 
| 
       46 
42 
     | 
    
         
             
                # @return [String]
         
     | 
| 
       47 
43 
     | 
    
         
             
                def ipaddr(iface=nil)
         
     | 
| 
       48 
     | 
    
         
            -
                  @ipaddr[iface ||  
     | 
| 
      
 44 
     | 
    
         
            +
                  @ipaddr[iface || default_iface]
         
     | 
| 
       49 
45 
     | 
    
         
             
                end
         
     | 
| 
       50 
46 
     | 
    
         | 
| 
       51 
47 
     | 
    
         
             
                # Get IPv6 addresses for given network interface
         
     | 
| 
       52 
48 
     | 
    
         
             
                # @param [String,nil] iface network interface. If +nil+, use default one.
         
     | 
| 
       53 
49 
     | 
    
         
             
                # @return [Array<String>]
         
     | 
| 
       54 
50 
     | 
    
         
             
                def ip6addr(iface=nil)
         
     | 
| 
       55 
     | 
    
         
            -
                  @ip6addr[iface ||  
     | 
| 
      
 51 
     | 
    
         
            +
                  @ip6addr[iface || default_iface]
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                private
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                def initialize_local_addresses
         
     | 
| 
      
 57 
     | 
    
         
            +
                  Interfacez.all do |iface_name|
         
     | 
| 
      
 58 
     | 
    
         
            +
                    @hwaddr[iface_name] = Interfacez.mac_address_of(iface_name)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    @ipaddr[iface_name] = Interfacez.ipv4_address_of(iface_name)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    @ip6addr[iface_name] = Interfacez.ipv6_addresses_of(iface_name)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
       56 
62 
     | 
    
         
             
                end
         
     | 
| 
       57 
63 
     | 
    
         
             
              end
         
     | 
| 
       58 
64 
     | 
    
         
             
            end
         
     | 
| 
         @@ -31,7 +31,7 @@ module PacketGen 
     | 
|
| 
       31 
31 
     | 
    
         
             
                  complete_deprecated_method_name = "#{base_name}#{deprecated_method}"
         
     | 
| 
       32 
32 
     | 
    
         
             
                  complete_new_method_name = "#{base_name}#{new_method}" unless new_method.nil?
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
                  file, line = caller(2..2).split(':')[0, 2]
         
     | 
| 
      
 34 
     | 
    
         
            +
                  file, line = caller(2..2).first.split(':')[0, 2]
         
     | 
| 
       35 
35 
     | 
    
         
             
                  message = +"#{file}:#{line}: #{complete_deprecated_method_name} is deprecated"
         
     | 
| 
       36 
36 
     | 
    
         
             
                  message << " in favor of #{complete_new_method_name}" unless new_method.nil?
         
     | 
| 
       37 
37 
     | 
    
         
             
                  message << '. ' << self.removed(remove_version)
         
     | 
| 
         @@ -230,17 +230,7 @@ module PacketGen 
     | 
|
| 
       230 
230 
     | 
    
         | 
| 
       231 
231 
     | 
    
         
             
                    # @!attribute options
         
     | 
| 
       232 
232 
     | 
    
         
             
                    #   @return [RequestedOptions]
         
     | 
| 
       233 
     | 
    
         
            -
                    define_field :options, RequestedOptions
         
     | 
| 
       234 
     | 
    
         
            -
             
     | 
| 
       235 
     | 
    
         
            -
                    # Populate object from +str+
         
     | 
| 
       236 
     | 
    
         
            -
                    # @param [String] str
         
     | 
| 
       237 
     | 
    
         
            -
                    # @return [self]
         
     | 
| 
       238 
     | 
    
         
            -
                    def read(str)
         
     | 
| 
       239 
     | 
    
         
            -
                      self[:type].read str[0, 2]
         
     | 
| 
       240 
     | 
    
         
            -
                      self[:length].read str[2, 2]
         
     | 
| 
       241 
     | 
    
         
            -
                      self[:options].read str[4, self.length]
         
     | 
| 
       242 
     | 
    
         
            -
                      self
         
     | 
| 
       243 
     | 
    
         
            -
                    end
         
     | 
| 
      
 233 
     | 
    
         
            +
                    define_field :options, RequestedOptions, builder: ->(h, t) { t.new(length_from: h[:length]) }
         
     | 
| 
       244 
234 
     | 
    
         | 
| 
       245 
235 
     | 
    
         
             
                    # Get human-readable data
         
     | 
| 
       246 
236 
     | 
    
         
             
                    # @return [String]
         
     | 
| 
         @@ -28,7 +28,7 @@ module PacketGen 
     | 
|
| 
       28 
28 
     | 
    
         
             
                  define_field :dlt, Types::Int32le
         
     | 
| 
       29 
29 
     | 
    
         
             
                  # @!attribute ppi_fields
         
     | 
| 
       30 
30 
     | 
    
         
             
                  #  @return [Type::String] concatenation of PPI fields
         
     | 
| 
       31 
     | 
    
         
            -
                  define_field :ppi_fields, Types::String
         
     | 
| 
      
 31 
     | 
    
         
            +
                  define_field :ppi_fields, Types::String, builder: ->(h, t) { t.new(length_from: -> { h.length - 8 }) }
         
     | 
| 
       32 
32 
     | 
    
         
             
                  # @!attribute body
         
     | 
| 
       33 
33 
     | 
    
         
             
                  #  @return [Type::String]
         
     | 
| 
       34 
34 
     | 
    
         
             
                  define_field :body, Types::String
         
     | 
| 
         @@ -36,21 +36,6 @@ module PacketGen 
     | 
|
| 
       36 
36 
     | 
    
         
             
                  #  @return [Boolean] align flag from {#flags} attribute
         
     | 
| 
       37 
37 
     | 
    
         
             
                  define_bit_fields_on :flags, :reserved, 7, :align
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                  # @param [String] str
         
     | 
| 
       40 
     | 
    
         
            -
                  # @return [PPI] self
         
     | 
| 
       41 
     | 
    
         
            -
                  def read(str)
         
     | 
| 
       42 
     | 
    
         
            -
                    return self if str.nil?
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                    force_binary str
         
     | 
| 
       45 
     | 
    
         
            -
                    self[:version].read str[0, 1]
         
     | 
| 
       46 
     | 
    
         
            -
                    self[:flags].read str[1, 1]
         
     | 
| 
       47 
     | 
    
         
            -
                    self[:length].read str[2, 2]
         
     | 
| 
       48 
     | 
    
         
            -
                    self[:dlt].read str[4, 4]
         
     | 
| 
       49 
     | 
    
         
            -
                    self[:ppi_fields].read str[8, length - 8]
         
     | 
| 
       50 
     | 
    
         
            -
                    self[:body].read str[length, str.size]
         
     | 
| 
       51 
     | 
    
         
            -
                    self
         
     | 
| 
       52 
     | 
    
         
            -
                  end
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
39 
     | 
    
         
             
                  # Check version field
         
     | 
| 
       55 
40 
     | 
    
         
             
                  # @see [Base#parse?]
         
     | 
| 
       56 
41 
     | 
    
         
             
                  def parse?
         
     | 
| 
         @@ -91,26 +76,11 @@ module PacketGen 
     | 
|
| 
       91 
76 
     | 
    
         
             
                  define_field :present_flags, Types::Int32le
         
     | 
| 
       92 
77 
     | 
    
         
             
                  # @!attribute radio_fields
         
     | 
| 
       93 
78 
     | 
    
         
             
                  #  @return [Type::String] concatenation of RadioTap fields
         
     | 
| 
       94 
     | 
    
         
            -
                  define_field :radio_fields, Types::String
         
     | 
| 
      
 79 
     | 
    
         
            +
                  define_field :radio_fields, Types::String, builder: ->(h, t) { t.new(length_from: -> { h.length - 8 }) }
         
     | 
| 
       95 
80 
     | 
    
         
             
                  # @!attribute body
         
     | 
| 
       96 
81 
     | 
    
         
             
                  #  @return [Type::String]
         
     | 
| 
       97 
82 
     | 
    
         
             
                  define_field :body, Types::String
         
     | 
| 
       98 
83 
     | 
    
         | 
| 
       99 
     | 
    
         
            -
                  # @param [String] str
         
     | 
| 
       100 
     | 
    
         
            -
                  # @return [RadioTap] self
         
     | 
| 
       101 
     | 
    
         
            -
                  def read(str)
         
     | 
| 
       102 
     | 
    
         
            -
                    return self if str.nil?
         
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
                    force_binary str
         
     | 
| 
       105 
     | 
    
         
            -
                    self[:version].read str[0, 1]
         
     | 
| 
       106 
     | 
    
         
            -
                    self[:pad].read str[1, 1]
         
     | 
| 
       107 
     | 
    
         
            -
                    self[:length].read str[2, 2]
         
     | 
| 
       108 
     | 
    
         
            -
                    self[:present_flags].read str[4, 4]
         
     | 
| 
       109 
     | 
    
         
            -
                    self[:radio_fields].read str[8, length - 8]
         
     | 
| 
       110 
     | 
    
         
            -
                    self[:body].read str[length, str.size]
         
     | 
| 
       111 
     | 
    
         
            -
                    self
         
     | 
| 
       112 
     | 
    
         
            -
                  end
         
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
84 
     | 
    
         
             
                  # Check version field
         
     | 
| 
       115 
85 
     | 
    
         
             
                  # @see [Base#parse?]
         
     | 
| 
       116 
86 
     | 
    
         
             
                  def parse?
         
     | 
| 
         @@ -45,20 +45,7 @@ module PacketGen 
     | 
|
| 
       45 
45 
     | 
    
         
             
                  define_field :length, Types::Int16
         
     | 
| 
       46 
46 
     | 
    
         
             
                  # @!attribute body
         
     | 
| 
       47 
47 
     | 
    
         
             
                  #  @return [Types::String,Header::Base]
         
     | 
| 
       48 
     | 
    
         
            -
                  define_field :body, Types::String
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                  # Populate object from string
         
     | 
| 
       51 
     | 
    
         
            -
                  # @param [String] str
         
     | 
| 
       52 
     | 
    
         
            -
                  # @return [self]
         
     | 
| 
       53 
     | 
    
         
            -
                  def read(str)
         
     | 
| 
       54 
     | 
    
         
            -
                    return self if str.nil?
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                    self[:version].read(str[0, 1])
         
     | 
| 
       57 
     | 
    
         
            -
                    self[:type].read(str[1, 1])
         
     | 
| 
       58 
     | 
    
         
            -
                    self[:length].read(str[2, 2])
         
     | 
| 
       59 
     | 
    
         
            -
                    self[:body].read(str[4, self.length])
         
     | 
| 
       60 
     | 
    
         
            -
                    self
         
     | 
| 
       61 
     | 
    
         
            -
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                  define_field :body, Types::String, builder: ->(h, t) { t.new(length_from: h[:length]) }
         
     | 
| 
       62 
49 
     | 
    
         | 
| 
       63 
50 
     | 
    
         
             
                  # Get human readable type
         
     | 
| 
       64 
51 
     | 
    
         
             
                  # @return [String]
         
     | 
    
        data/lib/packetgen/header/eap.rb
    CHANGED
    
    | 
         @@ -132,21 +132,17 @@ module PacketGen 
     | 
|
| 
       132 
132 
     | 
    
         
             
                  def read(str)
         
     | 
| 
       133 
133 
     | 
    
         
             
                    super str
         
     | 
| 
       134 
134 
     | 
    
         
             
                    return self unless self.class == EAP
         
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
                            else
         
     | 
| 
       147 
     | 
    
         
            -
                              self
         
     | 
| 
       148 
     | 
    
         
            -
                            end
         
     | 
| 
       149 
     | 
    
         
            -
                      obj
         
     | 
| 
      
 135 
     | 
    
         
            +
                    return self unless type?
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
                    case self.type
         
     | 
| 
      
 138 
     | 
    
         
            +
                    when 4
         
     | 
| 
      
 139 
     | 
    
         
            +
                      EAP::MD5.new.read(str)
         
     | 
| 
      
 140 
     | 
    
         
            +
                    when 13
         
     | 
| 
      
 141 
     | 
    
         
            +
                      EAP::TLS.new.read(str)
         
     | 
| 
      
 142 
     | 
    
         
            +
                    when 21
         
     | 
| 
      
 143 
     | 
    
         
            +
                      EAP::TTLS.new.read(str)
         
     | 
| 
      
 144 
     | 
    
         
            +
                    when 43
         
     | 
| 
      
 145 
     | 
    
         
            +
                      EAP::FAST.new.read(str)
         
     | 
| 
       150 
146 
     | 
    
         
             
                    else
         
     | 
| 
       151 
147 
     | 
    
         
             
                      self
         
     | 
| 
       152 
148 
     | 
    
         
             
                    end
         
     | 
    
        data/lib/packetgen/header/eth.rb
    CHANGED
    
    | 
         @@ -33,6 +33,8 @@ module PacketGen 
     | 
|
| 
       33 
33 
     | 
    
         
             
                  # Ethernet MAC address, as a group of 6 bytes
         
     | 
| 
       34 
34 
     | 
    
         
             
                  # @author Sylvain Daubert
         
     | 
| 
       35 
35 
     | 
    
         
             
                  class MacAddr < Types::Fields
         
     | 
| 
      
 36 
     | 
    
         
            +
                    include Inspectable
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
       36 
38 
     | 
    
         
             
                    # @!attribute a0
         
     | 
| 
       37 
39 
     | 
    
         
             
                    #  @return [Integer] first byte from MacAddr
         
     | 
| 
       38 
40 
     | 
    
         
             
                    define_field :a0, Types::Int8
         
     | 
| 
         @@ -75,6 +77,7 @@ module PacketGen 
     | 
|
| 
       75 
77 
     | 
    
         
             
                    def to_human
         
     | 
| 
       76 
78 
     | 
    
         
             
                      fields.map { |m| '%02x' % self[m] }.join(':')
         
     | 
| 
       77 
79 
     | 
    
         
             
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
                    alias format_inspect to_human
         
     | 
| 
       78 
81 
     | 
    
         | 
| 
       79 
82 
     | 
    
         
             
                    def ==(other)
         
     | 
| 
       80 
83 
     | 
    
         
             
                      other.is_a?(self.class) &&
         
     | 
| 
         @@ -12,6 +12,8 @@ module PacketGen 
     | 
|
| 
       12 
12 
     | 
    
         
             
                  # @abstract Base class for HTTP headers.
         
     | 
| 
       13 
13 
     | 
    
         
             
                  # @author Kent 'picat' Gruber
         
     | 
| 
       14 
14 
     | 
    
         
             
                  class Headers
         
     | 
| 
      
 15 
     | 
    
         
            +
                    include Inspectable
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
       15 
17 
     | 
    
         
             
                    # Underlying Headers data (or nil).
         
     | 
| 
       16 
18 
     | 
    
         
             
                    # @return [Hash, nil]
         
     | 
| 
       17 
19 
     | 
    
         
             
                    attr_reader :data
         
     | 
| 
         @@ -56,6 +58,7 @@ module PacketGen 
     | 
|
| 
       56 
58 
     | 
    
         
             
                    def to_human
         
     | 
| 
       57 
59 
     | 
    
         
             
                      @data
         
     | 
| 
       58 
60 
     | 
    
         
             
                    end
         
     | 
| 
      
 61 
     | 
    
         
            +
                    alias format_inspect to_human
         
     | 
| 
       59 
62 
     | 
    
         | 
| 
       60 
63 
     | 
    
         
             
                    # Read human-readable data to populate header data.
         
     | 
| 
       61 
64 
     | 
    
         
             
                    # @param [String, Hash] data
         
     | 
| 
         @@ -11,6 +11,8 @@ module PacketGen 
     | 
|
| 
       11 
11 
     | 
    
         
             
                  # IP address, as a group of 4 bytes
         
     | 
| 
       12 
12 
     | 
    
         
             
                  # @author Sylvain Daubert
         
     | 
| 
       13 
13 
     | 
    
         
             
                  class Addr < Types::Fields
         
     | 
| 
      
 14 
     | 
    
         
            +
                    include Inspectable
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
       14 
16 
     | 
    
         
             
                    # @!attribute a1
         
     | 
| 
       15 
17 
     | 
    
         
             
                    #  @return [Integer] IP address first byte
         
     | 
| 
       16 
18 
     | 
    
         
             
                    define_field :a1, Types::Int8
         
     | 
| 
         @@ -47,6 +49,7 @@ module PacketGen 
     | 
|
| 
       47 
49 
     | 
    
         
             
                    def to_human
         
     | 
| 
       48 
50 
     | 
    
         
             
                      fields.map { |f| self[f].to_i.to_s }.join('.')
         
     | 
| 
       49 
51 
     | 
    
         
             
                    end
         
     | 
| 
      
 52 
     | 
    
         
            +
                    alias format_inspect to_human
         
     | 
| 
       50 
53 
     | 
    
         | 
| 
       51 
54 
     | 
    
         
             
                    # Addr as an integer
         
     | 
| 
       52 
55 
     | 
    
         
             
                    # @return [Integer]
         
     | 
| 
         @@ -14,6 +14,8 @@ module PacketGen 
     | 
|
| 
       14 
14 
     | 
    
         
             
                  # IPv6 address, as a group of 8 2-byte words
         
     | 
| 
       15 
15 
     | 
    
         
             
                  # @author Sylvain Daubert
         
     | 
| 
       16 
16 
     | 
    
         
             
                  class Addr < Types::Fields
         
     | 
| 
      
 17 
     | 
    
         
            +
                    include Inspectable
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
       17 
19 
     | 
    
         
             
                    # @!attribute a1
         
     | 
| 
       18 
20 
     | 
    
         
             
                    #  1st 2-byte word of IPv6 address
         
     | 
| 
       19 
21 
     | 
    
         
             
                    #  @return [Integer]
         
     | 
| 
         @@ -73,6 +75,7 @@ module PacketGen 
     | 
|
| 
       73 
75 
     | 
    
         
             
                    def to_human
         
     | 
| 
       74 
76 
     | 
    
         
             
                      IPAddr.new(to_a.map { |a| a.to_i.to_s(16) }.join(':')).to_s
         
     | 
| 
       75 
77 
     | 
    
         
             
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
                    alias format_inspect to_human
         
     | 
| 
       76 
79 
     | 
    
         | 
| 
       77 
80 
     | 
    
         
             
                    # Return an array of address 16-bit words
         
     | 
| 
       78 
81 
     | 
    
         
             
                    # @return [Array<Integer>]
         
     | 
    
        data/lib/packetgen/header/tcp.rb
    CHANGED
    
    | 
         @@ -121,7 +121,7 @@ module PacketGen 
     | 
|
| 
       121 
121 
     | 
    
         
             
                  # @!attribute options
         
     | 
| 
       122 
122 
     | 
    
         
             
                  #  TCP options
         
     | 
| 
       123 
123 
     | 
    
         
             
                  #  @return [Options]
         
     | 
| 
       124 
     | 
    
         
            -
                  define_field :options, TCP::Options
         
     | 
| 
      
 124 
     | 
    
         
            +
                  define_field :options, TCP::Options, builder: ->(h, t) { t.new(length_from: -> { h.data_offset > 5 ? (h.data_offset - 5) * 4 : 0 }) }
         
     | 
| 
       125 
125 
     | 
    
         
             
                  # @!attribute body
         
     | 
| 
       126 
126 
     | 
    
         
             
                  #  @return [Types::String,Header::Base]
         
     | 
| 
       127 
127 
     | 
    
         
             
                  define_field :body, Types::String
         
     | 
| 
         @@ -189,25 +189,6 @@ module PacketGen 
     | 
|
| 
       189 
189 
     | 
    
         
             
                  #  @return [Boolean] 1-bit FIN flag
         
     | 
| 
       190 
190 
     | 
    
         
             
                  define_bit_fields_on :u16, :_, 7, :flag_ns, :flag_cwr, :flag_ece, :flag_urg,
         
     | 
| 
       191 
191 
     | 
    
         
             
                                       :flag_ack, :flag_psh, :flag_rst, :flag_syn, :flag_fin
         
     | 
| 
       192 
     | 
    
         
            -
                  # Read a TCP header from a string
         
     | 
| 
       193 
     | 
    
         
            -
                  # @param [String] str binary string
         
     | 
| 
       194 
     | 
    
         
            -
                  # @return [self]
         
     | 
| 
       195 
     | 
    
         
            -
                  def read(str)
         
     | 
| 
       196 
     | 
    
         
            -
                    return self if str.nil?
         
     | 
| 
       197 
     | 
    
         
            -
             
     | 
| 
       198 
     | 
    
         
            -
                    force_binary str
         
     | 
| 
       199 
     | 
    
         
            -
                    self[:sport].read str[0, 2]
         
     | 
| 
       200 
     | 
    
         
            -
                    self[:dport].read str[2, 2]
         
     | 
| 
       201 
     | 
    
         
            -
                    self[:seqnum].read str[4, 4]
         
     | 
| 
       202 
     | 
    
         
            -
                    self[:acknum].read str[8, 4]
         
     | 
| 
       203 
     | 
    
         
            -
                    self[:u16].read str[12, 2]
         
     | 
| 
       204 
     | 
    
         
            -
                    self[:window].read str[14, 2]
         
     | 
| 
       205 
     | 
    
         
            -
                    self[:checksum].read str[16, 2]
         
     | 
| 
       206 
     | 
    
         
            -
                    self[:urg_pointer].read str[18, 2]
         
     | 
| 
       207 
     | 
    
         
            -
                    self[:options].read str[20, (self.data_offset - 5) * 4] if self.data_offset > 5
         
     | 
| 
       208 
     | 
    
         
            -
                    self[:body].read str[self.data_offset * 4..-1]
         
     | 
| 
       209 
     | 
    
         
            -
                    self
         
     | 
| 
       210 
     | 
    
         
            -
                  end
         
     | 
| 
       211 
192 
     | 
    
         | 
| 
       212 
193 
     | 
    
         
             
                  # Compute checksum and set +checksum+ field
         
     | 
| 
       213 
194 
     | 
    
         
             
                  # @return [Integer]
         
     | 
    
        data/lib/packetgen/inspect.rb
    CHANGED
    
    | 
         @@ -68,23 +68,7 @@ module PacketGen 
     | 
|
| 
       68 
68 
     | 
    
         
             
                # @return [String]
         
     | 
| 
       69 
69 
     | 
    
         
             
                def self.inspect_attribute(attr, value, level=1)
         
     | 
| 
       70 
70 
     | 
    
         
             
                  type = value.class.to_s.sub(/.*::/, '')
         
     | 
| 
       71 
     | 
    
         
            -
                   
     | 
| 
       72 
     | 
    
         
            -
                        when Types::Enum
         
     | 
| 
       73 
     | 
    
         
            -
                          enum_human_hex(value.to_human, value.to_i, value.sz * 2)
         
     | 
| 
       74 
     | 
    
         
            -
                        when Types::Int
         
     | 
| 
       75 
     | 
    
         
            -
                          int_dec_hex(value, value.sz * 2)
         
     | 
| 
       76 
     | 
    
         
            -
                        when Integer
         
     | 
| 
       77 
     | 
    
         
            -
                          int_dec_hex(value, value.sz * 2)
         
     | 
| 
       78 
     | 
    
         
            -
                        when String
         
     | 
| 
       79 
     | 
    
         
            -
                          value.to_s.inspect
         
     | 
| 
       80 
     | 
    
         
            -
                        else
         
     | 
| 
       81 
     | 
    
         
            -
                          if value.respond_to? :to_human
         
     | 
| 
       82 
     | 
    
         
            -
                            value.to_human
         
     | 
| 
       83 
     | 
    
         
            -
                          else
         
     | 
| 
       84 
     | 
    
         
            -
                            value.to_s.inspect
         
     | 
| 
       85 
     | 
    
         
            -
                          end
         
     | 
| 
       86 
     | 
    
         
            -
                        end
         
     | 
| 
       87 
     | 
    
         
            -
                  self.format(type, attr, val, level)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  self.format(type, attr, value.format_inspect, level)
         
     | 
| 
       88 
72 
     | 
    
         
             
                end
         
     | 
| 
       89 
73 
     | 
    
         | 
| 
       90 
74 
     | 
    
         
             
                # Format a ASN.1 attribute for +#inspect+.
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # This file is part of PacketGen
         
     | 
| 
      
 4 
     | 
    
         
            +
            # See https://github.com/sdaubert/packetgen for more informations
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
         
     | 
| 
      
 6 
     | 
    
         
            +
            # This program is published under MIT license.
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module PacketGen
         
     | 
| 
      
 9 
     | 
    
         
            +
              # Module to add common methods to format types when inspecting packets/headers.
         
     | 
| 
      
 10 
     | 
    
         
            +
              # @author Sylvain Daubert
         
     | 
| 
      
 11 
     | 
    
         
            +
              # @since 3.1.5
         
     | 
| 
      
 12 
     | 
    
         
            +
              module Inspectable
         
     | 
| 
      
 13 
     | 
    
         
            +
                # Format attribute for inspecting
         
     | 
| 
      
 14 
     | 
    
         
            +
                # @abstract should be overriden by types.
         
     | 
| 
      
 15 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 16 
     | 
    
         
            +
                def format_inspect
         
     | 
| 
      
 17 
     | 
    
         
            +
                  to_s.inspect
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -23,9 +23,19 @@ module PacketGen 
     | 
|
| 
       23 
23 
     | 
    
         
             
                # @param [String] iface interface name
         
     | 
| 
       24 
24 
     | 
    
         
             
                # @param [Integer] snaplen
         
     | 
| 
       25 
25 
     | 
    
         
             
                # @param [Boolean] promisc
         
     | 
| 
      
 26 
     | 
    
         
            +
                # @param [Boolean] monitor
         
     | 
| 
       26 
27 
     | 
    
         
             
                # @return [PCAPRUB::Pcap]
         
     | 
| 
       27 
     | 
    
         
            -
                 
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
      
 28 
     | 
    
         
            +
                # @author Sylvain Daubert
         
     | 
| 
      
 29 
     | 
    
         
            +
                # @author optix2000 - add support for setting monitor mode
         
     | 
| 
      
 30 
     | 
    
         
            +
                # @since 3.1.5 add monitor argument
         
     | 
| 
      
 31 
     | 
    
         
            +
                def self.open_iface(iface:, snaplen: DEFAULT_SNAPLEN, promisc: DEFAULT_PROMISC, monitor: nil)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  pcap = PCAPRUB::Pcap.create(iface)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  pcap.setsnaplen(snaplen)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  pcap.setpromisc(promisc)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  pcap.settimeout(TIMEOUT)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # Monitor MUST be set before pcap is activated
         
     | 
| 
      
 37 
     | 
    
         
            +
                  pcap.setmonitor monitor unless monitor.nil?
         
     | 
| 
      
 38 
     | 
    
         
            +
                  pcap.activate
         
     | 
| 
       29 
39 
     | 
    
         
             
                end
         
     | 
| 
       30 
40 
     | 
    
         | 
| 
       31 
41 
     | 
    
         
             
                # Capture packets from a network interface
         
     | 
| 
         @@ -33,10 +43,14 @@ module PacketGen 
     | 
|
| 
       33 
43 
     | 
    
         
             
                # @param [Integer] snaplen
         
     | 
| 
       34 
44 
     | 
    
         
             
                # @param [Boolean] promisc
         
     | 
| 
       35 
45 
     | 
    
         
             
                # @param [String] filter BPF filter
         
     | 
| 
      
 46 
     | 
    
         
            +
                # @param [Boolean] monitor
         
     | 
| 
       36 
47 
     | 
    
         
             
                # @yieldparam [String] packet_data binary packet data
         
     | 
| 
       37 
48 
     | 
    
         
             
                # @return [void]
         
     | 
| 
       38 
     | 
    
         
            -
                 
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
      
 49 
     | 
    
         
            +
                # @author Sylvain Daubert
         
     | 
| 
      
 50 
     | 
    
         
            +
                # @author optix2000 - add support for setting monitor mode
         
     | 
| 
      
 51 
     | 
    
         
            +
                # @since 3.1.5 add monitor argument
         
     | 
| 
      
 52 
     | 
    
         
            +
                def self.capture(iface:, snaplen: DEFAULT_SNAPLEN, promisc: DEFAULT_PROMISC, filter: nil, monitor: nil)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  pcap = self.open_iface(iface: iface, snaplen: snaplen, promisc: promisc, monitor: monitor)
         
     | 
| 
       40 
54 
     | 
    
         
             
                  pcap.setfilter filter unless filter.nil?
         
     | 
| 
       41 
55 
     | 
    
         
             
                  pcap.each do |packet_data|
         
     | 
| 
       42 
56 
     | 
    
         
             
                    yield packet_data
         
     | 
| 
         @@ -58,6 +58,8 @@ module PacketGen 
     | 
|
| 
       58 
58 
     | 
    
         
             
                # @since 3.1.0
         
     | 
| 
       59 
59 
     | 
    
         
             
                # @since 3.1.1 add +:aliases+ keyword to {#initialize}
         
     | 
| 
       60 
60 
     | 
    
         
             
                class AbstractTLV < Types::Fields
         
     | 
| 
      
 61 
     | 
    
         
            +
                  include Inspectable
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
       61 
63 
     | 
    
         
             
                  class <<self
         
     | 
| 
       62 
64 
     | 
    
         
             
                    # @return [Hash]
         
     | 
| 
       63 
65 
     | 
    
         
             
                    attr_accessor :aliases
         
     | 
| 
         @@ -169,8 +171,9 @@ module PacketGen 
     | 
|
| 
       169 
171 
     | 
    
         
             
                  # @return [String]
         
     | 
| 
       170 
172 
     | 
    
         
             
                  def to_human
         
     | 
| 
       171 
173 
     | 
    
         
             
                    my_value = self[:value].is_a?(String) ? self[:value].inspect : self[:value].to_human
         
     | 
| 
       172 
     | 
    
         
            -
                    "type:%s,length:%u,value 
     | 
| 
      
 174 
     | 
    
         
            +
                    "type:%s,length:%u,value:%s" % [human_type, length, my_value]
         
     | 
| 
       173 
175 
     | 
    
         
             
                  end
         
     | 
| 
      
 176 
     | 
    
         
            +
                  alias format_inspect to_human
         
     | 
| 
       174 
177 
     | 
    
         | 
| 
       175 
178 
     | 
    
         
             
                  private
         
     | 
| 
       176 
179 
     | 
    
         | 
| 
         @@ -27,6 +27,9 @@ module PacketGen 
     | 
|
| 
       27 
27 
     | 
    
         
             
                # @author Sylvain Daubert
         
     | 
| 
       28 
28 
     | 
    
         
             
                class Array
         
     | 
| 
       29 
29 
     | 
    
         
             
                  extend Forwardable
         
     | 
| 
      
 30 
     | 
    
         
            +
                  include Inspectable
         
     | 
| 
      
 31 
     | 
    
         
            +
                  include Enumerable
         
     | 
| 
      
 32 
     | 
    
         
            +
                  include LengthFrom
         
     | 
| 
       30 
33 
     | 
    
         | 
| 
       31 
34 
     | 
    
         
             
                  # @!method [](index)
         
     | 
| 
       32 
35 
     | 
    
         
             
                  #   Return the element at +index+.
         
     | 
| 
         @@ -54,9 +57,6 @@ module PacketGen 
     | 
|
| 
       54 
57 
     | 
    
         
             
                  def_delegators :@array, :[], :clear, :each, :empty?, :first, :last, :size
         
     | 
| 
       55 
58 
     | 
    
         
             
                  alias length size
         
     | 
| 
       56 
59 
     | 
    
         | 
| 
       57 
     | 
    
         
            -
                  include Enumerable
         
     | 
| 
       58 
     | 
    
         
            -
                  include LengthFrom
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
60 
     | 
    
         
             
                  # Separator used in {#to_human}.
         
     | 
| 
       61 
61 
     | 
    
         
             
                  # May be ovverriden by subclasses
         
     | 
| 
       62 
62 
     | 
    
         
             
                  HUMAN_SEPARATOR = ','
         
     | 
| 
         @@ -198,6 +198,7 @@ module PacketGen 
     | 
|
| 
       198 
198 
     | 
    
         
             
                  def to_human
         
     | 
| 
       199 
199 
     | 
    
         
             
                    @array.map(&:to_human).join(self.class::HUMAN_SEPARATOR)
         
     | 
| 
       200 
200 
     | 
    
         
             
                  end
         
     | 
| 
      
 201 
     | 
    
         
            +
                  alias format_inspect to_human
         
     | 
| 
       201 
202 
     | 
    
         | 
| 
       202 
203 
     | 
    
         
             
                  private
         
     | 
| 
       203 
204 
     | 
    
         | 
| 
         @@ -11,6 +11,8 @@ module PacketGen 
     | 
|
| 
       11 
11 
     | 
    
         
             
                # This class handles null-terminated strings (aka C strings).
         
     | 
| 
       12 
12 
     | 
    
         
             
                # @author Sylvain Daubert
         
     | 
| 
       13 
13 
     | 
    
         
             
                class CString < ::String
         
     | 
| 
      
 14 
     | 
    
         
            +
                  include Inspectable
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
       14 
16 
     | 
    
         
             
                  # @param [Hash] options
         
     | 
| 
       15 
17 
     | 
    
         
             
                  # @option options [Integer] :static_length set a static length for this string
         
     | 
| 
       16 
18 
     | 
    
         
             
                  def initialize(options={})
         
     | 
| 
         @@ -66,6 +68,7 @@ module PacketGen 
     | 
|
| 
       66 
68 
     | 
    
         
             
                    idx = self.index(+"\x00".encode(self.encoding)) || self.sz
         
     | 
| 
       67 
69 
     | 
    
         
             
                    self[0, idx]
         
     | 
| 
       68 
70 
     | 
    
         
             
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
                  alias format_inspect to_human
         
     | 
| 
       69 
72 
     | 
    
         
             
                end
         
     | 
| 
       70 
73 
     | 
    
         
             
              end
         
     | 
| 
       71 
74 
     | 
    
         
             
            end
         
     | 
    
        data/lib/packetgen/types/enum.rb
    CHANGED
    
    
| 
         @@ -119,6 +119,10 @@ module PacketGen 
     | 
|
| 
       119 
119 
     | 
    
         
             
                    # @return [Hash]
         
     | 
| 
       120 
120 
     | 
    
         
             
                    # @since 3.1.0
         
     | 
| 
       121 
121 
     | 
    
         
             
                    attr_reader :field_defs
         
     | 
| 
      
 122 
     | 
    
         
            +
                    # Get bit fields defintions for this class
         
     | 
| 
      
 123 
     | 
    
         
            +
                    # @return [Hash]
         
     | 
| 
      
 124 
     | 
    
         
            +
                    # @since 3.1.5
         
     | 
| 
      
 125 
     | 
    
         
            +
                    attr_reader :bit_fields
         
     | 
| 
       122 
126 
     | 
    
         | 
| 
       123 
127 
     | 
    
         
             
                    # On inheritage, create +@field_defs+ class variable
         
     | 
| 
       124 
128 
     | 
    
         
             
                    # @param [Class] klass
         
     | 
| 
         @@ -129,7 +133,7 @@ module PacketGen 
     | 
|
| 
       129 
133 
     | 
    
         
             
                        field_defs[k] = v.clone
         
     | 
| 
       130 
134 
     | 
    
         
             
                      end
         
     | 
| 
       131 
135 
     | 
    
         
             
                      ordered = @ordered_fields.clone
         
     | 
| 
       132 
     | 
    
         
            -
                      bf =  
     | 
| 
      
 136 
     | 
    
         
            +
                      bf = bit_fields.clone
         
     | 
| 
       133 
137 
     | 
    
         | 
| 
       134 
138 
     | 
    
         
             
                      klass.class_eval do
         
     | 
| 
       135 
139 
     | 
    
         
             
                        @ordered_fields = ordered
         
     | 
| 
         @@ -172,37 +176,15 @@ module PacketGen 
     | 
|
| 
       172 
176 
     | 
    
         
             
                    #   Define enumeration: hash's keys are +String+, and values are +Integer+.
         
     | 
| 
       173 
177 
     | 
    
         
             
                    # @return [void]
         
     | 
| 
       174 
178 
     | 
    
         
             
                    def define_field(name, type, options={})
         
     | 
| 
       175 
     | 
    
         
            -
                       
     | 
| 
       176 
     | 
    
         
            -
                      if type < Types::Enum
         
     | 
| 
       177 
     | 
    
         
            -
                        define << "def #{name}; self[:#{name}].to_i; end"
         
     | 
| 
       178 
     | 
    
         
            -
                        define << "def #{name}=(val) self[:#{name}].value = val; end"
         
     | 
| 
       179 
     | 
    
         
            -
                      else
         
     | 
| 
       180 
     | 
    
         
            -
                        define << "def #{name}\n" \
         
     | 
| 
       181 
     | 
    
         
            -
                                  "  if self[:#{name}].respond_to?(:to_human) && self[:#{name}].respond_to?(:from_human)\n" \
         
     | 
| 
       182 
     | 
    
         
            -
                                  "    self[:#{name}].to_human\n" \
         
     | 
| 
       183 
     | 
    
         
            -
                                  "  else\n" \
         
     | 
| 
       184 
     | 
    
         
            -
                                  "    self[:#{name}]\n" \
         
     | 
| 
       185 
     | 
    
         
            -
                                  "  end\n" \
         
     | 
| 
       186 
     | 
    
         
            -
                                  'end'
         
     | 
| 
       187 
     | 
    
         
            -
                        define << "def #{name}=(val)\n" \
         
     | 
| 
       188 
     | 
    
         
            -
                                  "  if self[:#{name}].respond_to?(:to_human) && self[:#{name}].respond_to?(:from_human)\n" \
         
     | 
| 
       189 
     | 
    
         
            -
                                  "    self[:#{name}].from_human val\n" \
         
     | 
| 
       190 
     | 
    
         
            -
                                  "  else\n" \
         
     | 
| 
       191 
     | 
    
         
            -
                                  "    self[:#{name}].read val\n" \
         
     | 
| 
       192 
     | 
    
         
            -
                                  "  end\n" \
         
     | 
| 
       193 
     | 
    
         
            -
                                  'end'
         
     | 
| 
       194 
     | 
    
         
            -
                      end
         
     | 
| 
       195 
     | 
    
         
            -
             
     | 
| 
       196 
     | 
    
         
            -
                      define.delete_at(1) if instance_methods.include? "#{name}=".to_sym
         
     | 
| 
       197 
     | 
    
         
            -
                      define.delete_at(0) if instance_methods.include? name
         
     | 
| 
       198 
     | 
    
         
            -
                      class_eval define.join("\n")
         
     | 
| 
      
 179 
     | 
    
         
            +
                      fields << name
         
     | 
| 
       199 
180 
     | 
    
         
             
                      field_defs[name] = FieldDef.new(type,
         
     | 
| 
       200 
181 
     | 
    
         
             
                                                      options.delete(:default),
         
     | 
| 
       201 
182 
     | 
    
         
             
                                                      options.delete(:builder),
         
     | 
| 
       202 
183 
     | 
    
         
             
                                                      options.delete(:optional),
         
     | 
| 
       203 
184 
     | 
    
         
             
                                                      options.delete(:enum),
         
     | 
| 
       204 
185 
     | 
    
         
             
                                                      options)
         
     | 
| 
       205 
     | 
    
         
            -
             
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                      add_methods(name, type)
         
     | 
| 
       206 
188 
     | 
    
         
             
                    end
         
     | 
| 
       207 
189 
     | 
    
         | 
| 
       208 
190 
     | 
    
         
             
                    # Define a field, before another one
         
     | 
| 
         @@ -300,8 +282,8 @@ module PacketGen 
     | 
|
| 
       300 
282 
     | 
    
         
             
                      total_size = type.new.width * 8
         
     | 
| 
       301 
283 
     | 
    
         
             
                      idx = total_size - 1
         
     | 
| 
       302 
284 
     | 
    
         | 
| 
       303 
     | 
    
         
            -
                       
     | 
| 
       304 
     | 
    
         
            -
             
     | 
| 
      
 285 
     | 
    
         
            +
                      until args.empty?
         
     | 
| 
      
 286 
     | 
    
         
            +
                        field = args.shift
         
     | 
| 
       305 
287 
     | 
    
         
             
                        next unless field.is_a? Symbol
         
     | 
| 
       306 
288 
     | 
    
         | 
| 
       307 
289 
     | 
    
         
             
                        size = if args.first.is_a? Integer
         
     | 
| 
         @@ -309,41 +291,13 @@ module PacketGen 
     | 
|
| 
       309 
291 
     | 
    
         
             
                               else
         
     | 
| 
       310 
292 
     | 
    
         
             
                                 1
         
     | 
| 
       311 
293 
     | 
    
         
             
                               end
         
     | 
| 
      
 294 
     | 
    
         
            +
             
     | 
| 
       312 
295 
     | 
    
         
             
                        unless field == :_
         
     | 
| 
       313 
     | 
    
         
            -
                           
     | 
| 
       314 
     | 
    
         
            -
                           
     | 
| 
       315 
     | 
    
         
            -
                          clear_mask = (2**total_size - 1) & (~field_mask & (2**total_size - 1))
         
     | 
| 
       316 
     | 
    
         
            -
             
     | 
| 
       317 
     | 
    
         
            -
                          if size == 1
         
     | 
| 
       318 
     | 
    
         
            -
                            class_eval <<-METHODS
         
     | 
| 
       319 
     | 
    
         
            -
                            def #{field}?
         
     | 
| 
       320 
     | 
    
         
            -
                              val = (self[:#{attr}].to_i & #{field_mask}) >> #{shift}
         
     | 
| 
       321 
     | 
    
         
            -
                              val != 0
         
     | 
| 
       322 
     | 
    
         
            -
                            end
         
     | 
| 
       323 
     | 
    
         
            -
                            def #{field}=(v)
         
     | 
| 
       324 
     | 
    
         
            -
                              val = v ? 1 : 0
         
     | 
| 
       325 
     | 
    
         
            -
                              self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask}
         
     | 
| 
       326 
     | 
    
         
            -
                              self[:#{attr}].value |= val << #{shift}
         
     | 
| 
       327 
     | 
    
         
            -
                            end
         
     | 
| 
       328 
     | 
    
         
            -
                            METHODS
         
     | 
| 
       329 
     | 
    
         
            -
                          else
         
     | 
| 
       330 
     | 
    
         
            -
                            class_eval <<-METHODS
         
     | 
| 
       331 
     | 
    
         
            -
                            def #{field}
         
     | 
| 
       332 
     | 
    
         
            -
                              (self[:#{attr}].to_i & #{field_mask}) >> #{shift}
         
     | 
| 
       333 
     | 
    
         
            -
                            end
         
     | 
| 
       334 
     | 
    
         
            -
                            def #{field}=(v)
         
     | 
| 
       335 
     | 
    
         
            -
                              self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask}
         
     | 
| 
       336 
     | 
    
         
            -
                              self[:#{attr}].value |= (v & #{2**size - 1}) << #{shift}
         
     | 
| 
       337 
     | 
    
         
            -
                            end
         
     | 
| 
       338 
     | 
    
         
            -
                            METHODS
         
     | 
| 
       339 
     | 
    
         
            -
                          end
         
     | 
| 
       340 
     | 
    
         
            -
             
     | 
| 
       341 
     | 
    
         
            -
                          @bit_fields[attr] = {} if @bit_fields[attr].nil?
         
     | 
| 
       342 
     | 
    
         
            -
                          @bit_fields[attr][field] = size
         
     | 
| 
      
 296 
     | 
    
         
            +
                          add_bit_methods(attr, field, size, total_size, idx)
         
     | 
| 
      
 297 
     | 
    
         
            +
                          register_bit_field_size(attr, field, size)
         
     | 
| 
       343 
298 
     | 
    
         
             
                        end
         
     | 
| 
       344 
299 
     | 
    
         | 
| 
       345 
300 
     | 
    
         
             
                        idx -= size
         
     | 
| 
       346 
     | 
    
         
            -
                        field = args.shift
         
     | 
| 
       347 
301 
     | 
    
         
             
                      end
         
     | 
| 
       348 
302 
     | 
    
         
             
                    end
         
     | 
| 
       349 
303 
     | 
    
         | 
| 
         @@ -352,7 +306,7 @@ module PacketGen 
     | 
|
| 
       352 
306 
     | 
    
         
             
                    # @return [void]
         
     | 
| 
       353 
307 
     | 
    
         
             
                    # @since 2.8.4
         
     | 
| 
       354 
308 
     | 
    
         
             
                    def remove_bit_fields_on(attr)
         
     | 
| 
       355 
     | 
    
         
            -
                      fields =  
     | 
| 
      
 309 
     | 
    
         
            +
                      fields = bit_fields.delete(attr)
         
     | 
| 
       356 
310 
     | 
    
         
             
                      return if fields.nil?
         
     | 
| 
       357 
311 
     | 
    
         | 
| 
       358 
312 
     | 
    
         
             
                      fields.each do |field, size|
         
     | 
| 
         @@ -360,6 +314,62 @@ module PacketGen 
     | 
|
| 
       360 
314 
     | 
    
         
             
                        undef_method(size == 1 ? "#{field}?" : field)
         
     | 
| 
       361 
315 
     | 
    
         
             
                      end
         
     | 
| 
       362 
316 
     | 
    
         
             
                    end
         
     | 
| 
      
 317 
     | 
    
         
            +
             
     | 
| 
      
 318 
     | 
    
         
            +
                    private
         
     | 
| 
      
 319 
     | 
    
         
            +
             
     | 
| 
      
 320 
     | 
    
         
            +
                    def add_methods(name, type)
         
     | 
| 
      
 321 
     | 
    
         
            +
                      define = []
         
     | 
| 
      
 322 
     | 
    
         
            +
                      if type < Types::Enum
         
     | 
| 
      
 323 
     | 
    
         
            +
                        define << "def #{name}; self[:#{name}].to_i; end"
         
     | 
| 
      
 324 
     | 
    
         
            +
                        define << "def #{name}=(val) self[:#{name}].value = val; end"
         
     | 
| 
      
 325 
     | 
    
         
            +
                      else
         
     | 
| 
      
 326 
     | 
    
         
            +
                        define << "def #{name}\n" \
         
     | 
| 
      
 327 
     | 
    
         
            +
                                  "  to_and_from_human?(:#{name}) ? self[:#{name}].to_human : self[:#{name}]\n" \
         
     | 
| 
      
 328 
     | 
    
         
            +
                                  'end'
         
     | 
| 
      
 329 
     | 
    
         
            +
                        define << "def #{name}=(val)\n" \
         
     | 
| 
      
 330 
     | 
    
         
            +
                                  "  to_and_from_human?(:#{name}) ? self[:#{name}].from_human(val) : self[:#{name}].read(val)\n" \
         
     | 
| 
      
 331 
     | 
    
         
            +
                                  'end'
         
     | 
| 
      
 332 
     | 
    
         
            +
                      end
         
     | 
| 
      
 333 
     | 
    
         
            +
             
     | 
| 
      
 334 
     | 
    
         
            +
                      define.delete_at(1) if instance_methods.include? "#{name}=".to_sym
         
     | 
| 
      
 335 
     | 
    
         
            +
                      define.delete_at(0) if instance_methods.include? name
         
     | 
| 
      
 336 
     | 
    
         
            +
                      class_eval define.join("\n")
         
     | 
| 
      
 337 
     | 
    
         
            +
                    end
         
     | 
| 
      
 338 
     | 
    
         
            +
             
     | 
| 
      
 339 
     | 
    
         
            +
                    def add_bit_methods(attr, name, size, total_size, idx)
         
     | 
| 
      
 340 
     | 
    
         
            +
                      shift = idx - (size - 1)
         
     | 
| 
      
 341 
     | 
    
         
            +
                      field_mask = (2**size - 1) << shift
         
     | 
| 
      
 342 
     | 
    
         
            +
                      clear_mask = (2**total_size - 1) & (~field_mask & (2**total_size - 1))
         
     | 
| 
      
 343 
     | 
    
         
            +
             
     | 
| 
      
 344 
     | 
    
         
            +
                      if size == 1
         
     | 
| 
      
 345 
     | 
    
         
            +
                        class_eval <<-METHODS
         
     | 
| 
      
 346 
     | 
    
         
            +
                        def #{name}?
         
     | 
| 
      
 347 
     | 
    
         
            +
                          val = (self[:#{attr}].to_i & #{field_mask}) >> #{shift}
         
     | 
| 
      
 348 
     | 
    
         
            +
                          val != 0
         
     | 
| 
      
 349 
     | 
    
         
            +
                        end
         
     | 
| 
      
 350 
     | 
    
         
            +
                        def #{name}=(v)
         
     | 
| 
      
 351 
     | 
    
         
            +
                          val = v ? 1 : 0
         
     | 
| 
      
 352 
     | 
    
         
            +
                          self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask}
         
     | 
| 
      
 353 
     | 
    
         
            +
                          self[:#{attr}].value |= val << #{shift}
         
     | 
| 
      
 354 
     | 
    
         
            +
                        end
         
     | 
| 
      
 355 
     | 
    
         
            +
                        METHODS
         
     | 
| 
      
 356 
     | 
    
         
            +
                      else
         
     | 
| 
      
 357 
     | 
    
         
            +
                        class_eval <<-METHODS
         
     | 
| 
      
 358 
     | 
    
         
            +
                        def #{name}
         
     | 
| 
      
 359 
     | 
    
         
            +
                          (self[:#{attr}].to_i & #{field_mask}) >> #{shift}
         
     | 
| 
      
 360 
     | 
    
         
            +
                        end
         
     | 
| 
      
 361 
     | 
    
         
            +
                        def #{name}=(v)
         
     | 
| 
      
 362 
     | 
    
         
            +
                          self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask}
         
     | 
| 
      
 363 
     | 
    
         
            +
                          self[:#{attr}].value |= (v & #{2**size - 1}) << #{shift}
         
     | 
| 
      
 364 
     | 
    
         
            +
                        end
         
     | 
| 
      
 365 
     | 
    
         
            +
                        METHODS
         
     | 
| 
      
 366 
     | 
    
         
            +
                      end
         
     | 
| 
      
 367 
     | 
    
         
            +
                    end
         
     | 
| 
      
 368 
     | 
    
         
            +
             
     | 
| 
      
 369 
     | 
    
         
            +
                    def register_bit_field_size(attr, field, size)
         
     | 
| 
      
 370 
     | 
    
         
            +
                      bit_fields[attr] = {} if bit_fields[attr].nil?
         
     | 
| 
      
 371 
     | 
    
         
            +
                      bit_fields[attr][field] = size
         
     | 
| 
      
 372 
     | 
    
         
            +
                    end
         
     | 
| 
       363 
373 
     | 
    
         
             
                  end
         
     | 
| 
       364 
374 
     | 
    
         | 
| 
       365 
375 
     | 
    
         
             
                  # Create a new fields object
         
     | 
| 
         @@ -369,36 +379,13 @@ module PacketGen 
     | 
|
| 
       369 
379 
     | 
    
         
             
                    @fields = {}
         
     | 
| 
       370 
380 
     | 
    
         
             
                    @optional_fields = {}
         
     | 
| 
       371 
381 
     | 
    
         | 
| 
       372 
     | 
    
         
            -
                    field_defs = self.class.field_defs
         
     | 
| 
       373 
382 
     | 
    
         
             
                    self.class.fields.each do |field|
         
     | 
| 
       374 
     | 
    
         
            -
                       
     | 
| 
       375 
     | 
    
         
            -
                       
     | 
| 
       376 
     | 
    
         
            -
                       
     | 
| 
       377 
     | 
    
         
            -
                      builder = field_defs[field].builder
         
     | 
| 
       378 
     | 
    
         
            -
                      optional = field_defs[field].optional
         
     | 
| 
       379 
     | 
    
         
            -
                      enum = field_defs[field].enum
         
     | 
| 
       380 
     | 
    
         
            -
                      field_options = field_defs[field].options
         
     | 
| 
       381 
     | 
    
         
            -
             
     | 
| 
       382 
     | 
    
         
            -
                      @fields[field] = if builder
         
     | 
| 
       383 
     | 
    
         
            -
                                         builder.call(self, type)
         
     | 
| 
       384 
     | 
    
         
            -
                                       elsif enum
         
     | 
| 
       385 
     | 
    
         
            -
                                         type.new(enum)
         
     | 
| 
       386 
     | 
    
         
            -
                                       elsif !field_options.empty?
         
     | 
| 
       387 
     | 
    
         
            -
                                         type.new(field_options)
         
     | 
| 
       388 
     | 
    
         
            -
                                       else
         
     | 
| 
       389 
     | 
    
         
            -
                                         type.new
         
     | 
| 
       390 
     | 
    
         
            -
                                       end
         
     | 
| 
       391 
     | 
    
         
            -
             
     | 
| 
       392 
     | 
    
         
            -
                      value = options[field] || default
         
     | 
| 
       393 
     | 
    
         
            -
                      if value.class <= type
         
     | 
| 
       394 
     | 
    
         
            -
                        @fields[field] = value
         
     | 
| 
       395 
     | 
    
         
            -
                      elsif @fields[field].respond_to? :from_human
         
     | 
| 
       396 
     | 
    
         
            -
                        @fields[field].from_human(value)
         
     | 
| 
       397 
     | 
    
         
            -
                      end
         
     | 
| 
       398 
     | 
    
         
            -
             
     | 
| 
       399 
     | 
    
         
            -
                      @optional_fields[field] = optional if optional
         
     | 
| 
      
 383 
     | 
    
         
            +
                      build_field field
         
     | 
| 
      
 384 
     | 
    
         
            +
                      initialize_value field, options[field]
         
     | 
| 
      
 385 
     | 
    
         
            +
                      initialize_optional field
         
     | 
| 
       400 
386 
     | 
    
         
             
                    end
         
     | 
| 
       401 
     | 
    
         
            -
             
     | 
| 
      
 387 
     | 
    
         
            +
             
     | 
| 
      
 388 
     | 
    
         
            +
                    self.class.bit_fields.each do |_, hsh|
         
     | 
| 
       402 
389 
     | 
    
         
             
                      hsh.each_key do |bit_field|
         
     | 
| 
       403 
390 
     | 
    
         
             
                        self.send "#{bit_field}=", options[bit_field] if options[bit_field]
         
     | 
| 
       404 
391 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -528,7 +515,7 @@ module PacketGen 
     | 
|
| 
       528 
515 
     | 
    
         
             
                  # @return [Hash,nil] keys: bit fields, values: their size in bits
         
     | 
| 
       529 
516 
     | 
    
         
             
                  # @since 2.8.3
         
     | 
| 
       530 
517 
     | 
    
         
             
                  def bits_on(field)
         
     | 
| 
       531 
     | 
    
         
            -
                    self.class. 
     | 
| 
      
 518 
     | 
    
         
            +
                    self.class.bit_fields[field]
         
     | 
| 
       532 
519 
     | 
    
         
             
                  end
         
     | 
| 
       533 
520 
     | 
    
         | 
| 
       534 
521 
     | 
    
         
             
                  private
         
     | 
| 
         @@ -547,6 +534,51 @@ module PacketGen 
     | 
|
| 
       547 
534 
     | 
    
         
             
                  def force_binary(str)
         
     | 
| 
       548 
535 
     | 
    
         
             
                    PacketGen.force_binary(str)
         
     | 
| 
       549 
536 
     | 
    
         
             
                  end
         
     | 
| 
      
 537 
     | 
    
         
            +
             
     | 
| 
      
 538 
     | 
    
         
            +
                  # @param [Symbol] attr attribute
         
     | 
| 
      
 539 
     | 
    
         
            +
                  # @return [Boolean] +tru+e if #from_human and #to_human are both defined for given attribute
         
     | 
| 
      
 540 
     | 
    
         
            +
                  def to_and_from_human?(attr)
         
     | 
| 
      
 541 
     | 
    
         
            +
                    self[attr].respond_to?(:to_human) && self[attr].respond_to?(:from_human)
         
     | 
| 
      
 542 
     | 
    
         
            +
                  end
         
     | 
| 
      
 543 
     | 
    
         
            +
             
     | 
| 
      
 544 
     | 
    
         
            +
                  def field_defs
         
     | 
| 
      
 545 
     | 
    
         
            +
                    self.class.field_defs
         
     | 
| 
      
 546 
     | 
    
         
            +
                  end
         
     | 
| 
      
 547 
     | 
    
         
            +
             
     | 
| 
      
 548 
     | 
    
         
            +
                  def build_field(field)
         
     | 
| 
      
 549 
     | 
    
         
            +
                    type = field_defs[field].type
         
     | 
| 
      
 550 
     | 
    
         
            +
                    builder = field_defs[field].builder
         
     | 
| 
      
 551 
     | 
    
         
            +
                    enum = field_defs[field].enum
         
     | 
| 
      
 552 
     | 
    
         
            +
                    field_options = field_defs[field].options
         
     | 
| 
      
 553 
     | 
    
         
            +
             
     | 
| 
      
 554 
     | 
    
         
            +
                    @fields[field] = if builder
         
     | 
| 
      
 555 
     | 
    
         
            +
                                       builder.call(self, type)
         
     | 
| 
      
 556 
     | 
    
         
            +
                                     elsif enum
         
     | 
| 
      
 557 
     | 
    
         
            +
                                       type.new(enum)
         
     | 
| 
      
 558 
     | 
    
         
            +
                                     elsif !field_options.empty?
         
     | 
| 
      
 559 
     | 
    
         
            +
                                       type.new(field_options)
         
     | 
| 
      
 560 
     | 
    
         
            +
                                     else
         
     | 
| 
      
 561 
     | 
    
         
            +
                                       type.new
         
     | 
| 
      
 562 
     | 
    
         
            +
                                     end
         
     | 
| 
      
 563 
     | 
    
         
            +
                  end
         
     | 
| 
      
 564 
     | 
    
         
            +
             
     | 
| 
      
 565 
     | 
    
         
            +
                  def initialize_value(field, val)
         
     | 
| 
      
 566 
     | 
    
         
            +
                    type = field_defs[field].type
         
     | 
| 
      
 567 
     | 
    
         
            +
                    default = field_defs[field].default
         
     | 
| 
      
 568 
     | 
    
         
            +
                    default = default.to_proc.call(self) if default.is_a?(Proc)
         
     | 
| 
      
 569 
     | 
    
         
            +
             
     | 
| 
      
 570 
     | 
    
         
            +
                    value = val || default
         
     | 
| 
      
 571 
     | 
    
         
            +
                    if value.class <= type
         
     | 
| 
      
 572 
     | 
    
         
            +
                      @fields[field] = value
         
     | 
| 
      
 573 
     | 
    
         
            +
                    elsif @fields[field].respond_to? :from_human
         
     | 
| 
      
 574 
     | 
    
         
            +
                      @fields[field].from_human(value)
         
     | 
| 
      
 575 
     | 
    
         
            +
                    end
         
     | 
| 
      
 576 
     | 
    
         
            +
                  end
         
     | 
| 
      
 577 
     | 
    
         
            +
             
     | 
| 
      
 578 
     | 
    
         
            +
                  def initialize_optional(field)
         
     | 
| 
      
 579 
     | 
    
         
            +
                    optional = field_defs[field].optional
         
     | 
| 
      
 580 
     | 
    
         
            +
                    @optional_fields[field] = optional if optional
         
     | 
| 
      
 581 
     | 
    
         
            +
                  end
         
     | 
| 
       550 
582 
     | 
    
         
             
                end
         
     | 
| 
       551 
583 
     | 
    
         
             
              end
         
     | 
| 
       552 
584 
     | 
    
         
             
            end
         
     | 
    
        data/lib/packetgen/types/int.rb
    CHANGED
    
    | 
         @@ -12,6 +12,8 @@ module PacketGen 
     | 
|
| 
       12 
12 
     | 
    
         
             
                # @abstract
         
     | 
| 
       13 
13 
     | 
    
         
             
                # @author Sylvain Daubert
         
     | 
| 
       14 
14 
     | 
    
         
             
                class Int
         
     | 
| 
      
 15 
     | 
    
         
            +
                  include Inspectable
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
       15 
17 
     | 
    
         
             
                  # Integer value
         
     | 
| 
       16 
18 
     | 
    
         
             
                  # @return [Integer]
         
     | 
| 
       17 
19 
     | 
    
         
             
                  attr_accessor :value
         
     | 
| 
         @@ -80,6 +82,18 @@ module PacketGen 
     | 
|
| 
       80 
82 
     | 
    
         
             
                  def sz
         
     | 
| 
       81 
83 
     | 
    
         
             
                    width
         
     | 
| 
       82 
84 
     | 
    
         
             
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                  # Format Int type when inspecting header or packet
         
     | 
| 
      
 87 
     | 
    
         
            +
                  # @return [String]
         
     | 
| 
      
 88 
     | 
    
         
            +
                  def format_inspect
         
     | 
| 
      
 89 
     | 
    
         
            +
                    format_str % [to_i.to_s, to_i]
         
     | 
| 
      
 90 
     | 
    
         
            +
                  end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                  private
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  def format_str
         
     | 
| 
      
 95 
     | 
    
         
            +
                    "%-16s (0x%0#{width * 2}x)"
         
     | 
| 
      
 96 
     | 
    
         
            +
                  end
         
     | 
| 
       83 
97 
     | 
    
         
             
                end
         
     | 
| 
       84 
98 
     | 
    
         | 
| 
       85 
99 
     | 
    
         
             
                # One byte unsigned integer
         
     | 
| 
         @@ -12,6 +12,8 @@ module PacketGen 
     | 
|
| 
       12 
12 
     | 
    
         
             
                # By default, a null string will have one byte length (length byte set to 0).
         
     | 
| 
       13 
13 
     | 
    
         
             
                # @author Sylvain Daubert
         
     | 
| 
       14 
14 
     | 
    
         
             
                class IntString
         
     | 
| 
      
 15 
     | 
    
         
            +
                  include Inspectable
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
       15 
17 
     | 
    
         
             
                  # internal string
         
     | 
| 
       16 
18 
     | 
    
         
             
                  # @return [String]
         
     | 
| 
       17 
19 
     | 
    
         
             
                  attr_reader :string
         
     | 
| 
         @@ -76,6 +78,7 @@ module PacketGen 
     | 
|
| 
       76 
78 
     | 
    
         
             
                  def to_human
         
     | 
| 
       77 
79 
     | 
    
         
             
                    @string
         
     | 
| 
       78 
80 
     | 
    
         
             
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
                  alias format_inspect to_human
         
     | 
| 
       79 
82 
     | 
    
         | 
| 
       80 
83 
     | 
    
         
             
                  # Set length from internal string length
         
     | 
| 
       81 
84 
     | 
    
         
             
                  # @return [Integer]
         
     | 
    
        data/lib/packetgen/types/oui.rb
    CHANGED
    
    | 
         @@ -14,6 +14,8 @@ module PacketGen 
     | 
|
| 
       14 
14 
     | 
    
         
             
                #  oui.to_human   # => "00:01:02"
         
     | 
| 
       15 
15 
     | 
    
         
             
                # @author Sylvain Daubert
         
     | 
| 
       16 
16 
     | 
    
         
             
                class OUI < Types::Fields
         
     | 
| 
      
 17 
     | 
    
         
            +
                  include Inspectable
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
       17 
19 
     | 
    
         
             
                  # @attribute b2
         
     | 
| 
       18 
20 
     | 
    
         
             
                  #  @return [Integer] left-most byte
         
     | 
| 
       19 
21 
     | 
    
         
             
                  define_field :b2, Types::Int8
         
     | 
| 
         @@ -44,6 +46,7 @@ module PacketGen 
     | 
|
| 
       44 
46 
     | 
    
         
             
                  def to_human
         
     | 
| 
       45 
47 
     | 
    
         
             
                    fields.map { |m| '%02x' % self[m] }.join(':')
         
     | 
| 
       46 
48 
     | 
    
         
             
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  alias format_inspect to_human
         
     | 
| 
       47 
50 
     | 
    
         
             
                end
         
     | 
| 
       48 
51 
     | 
    
         
             
              end
         
     | 
| 
       49 
52 
     | 
    
         
             
            end
         
     | 
    
        data/lib/packetgen/types/tlv.rb
    CHANGED
    
    | 
         @@ -31,6 +31,8 @@ module PacketGen 
     | 
|
| 
       31 
31 
     | 
    
         
             
                # @deprecated Use {AbstractTLV} instead.
         
     | 
| 
       32 
32 
     | 
    
         
             
                # @since 3.1.0 deprecated
         
     | 
| 
       33 
33 
     | 
    
         
             
                class TLV < Fields
         
     | 
| 
      
 34 
     | 
    
         
            +
                  include Inspectable
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
       34 
36 
     | 
    
         
             
                  # @!attribute type
         
     | 
| 
       35 
37 
     | 
    
         
             
                  #  @return [Integer]
         
     | 
| 
       36 
38 
     | 
    
         
             
                  define_field :type, Int8
         
     | 
| 
         @@ -139,6 +141,7 @@ module PacketGen 
     | 
|
| 
       139 
141 
     | 
    
         
             
                    "#{name} type:#{@typestr} length:#{@lenstr} value:#{value.inspect}" % [human_type,
         
     | 
| 
       140 
142 
     | 
    
         
             
                                                                                           length]
         
     | 
| 
       141 
143 
     | 
    
         
             
                  end
         
     | 
| 
      
 144 
     | 
    
         
            +
                  alias format_inspect to_human
         
     | 
| 
       142 
145 
     | 
    
         | 
| 
       143 
146 
     | 
    
         
             
                  private
         
     | 
| 
       144 
147 
     | 
    
         | 
    
        data/lib/packetgen/utils.rb
    CHANGED
    
    | 
         @@ -53,7 +53,7 @@ module PacketGen 
     | 
|
| 
       53 
53 
     | 
    
         
             
                  timeout = options[:timeout] || 1
         
     | 
| 
       54 
54 
     | 
    
         
             
                  my_hwaddr = Config.instance.hwaddr(iface)
         
     | 
| 
       55 
55 
     | 
    
         
             
                  arp_pkt = Packet.gen('Eth', dst: 'ff:ff:ff:ff:ff:ff', src: my_hwaddr)
         
     | 
| 
       56 
     | 
    
         
            -
                  arp_pkt.add('ARP', sha: Config.instance.hwaddr, spa: Config.instance.ipaddr,
         
     | 
| 
      
 56 
     | 
    
         
            +
                  arp_pkt.add('ARP', sha: Config.instance.hwaddr(iface), spa: Config.instance.ipaddr(iface),
         
     | 
| 
       57 
57 
     | 
    
         
             
                                     tpa: ipaddr)
         
     | 
| 
       58 
58 
     | 
    
         | 
| 
       59 
59 
     | 
    
         
             
                  capture = Capture.new(iface: iface, timeout: timeout, max: 1,
         
     | 
    
        data/lib/packetgen/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: packetgen
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 3.1. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 3.1.5
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Sylvain Daubert
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2020-03- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2020-03-31 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: interfacez
         
     | 
| 
         @@ -208,6 +208,7 @@ files: 
     | 
|
| 
       208 
208 
     | 
    
         
             
            - lib/packetgen/headerable.rb
         
     | 
| 
       209 
209 
     | 
    
         
             
            - lib/packetgen/inject.rb
         
     | 
| 
       210 
210 
     | 
    
         
             
            - lib/packetgen/inspect.rb
         
     | 
| 
      
 211 
     | 
    
         
            +
            - lib/packetgen/inspectable.rb
         
     | 
| 
       211 
212 
     | 
    
         
             
            - lib/packetgen/packet.rb
         
     | 
| 
       212 
213 
     | 
    
         
             
            - lib/packetgen/pcap.rb
         
     | 
| 
       213 
214 
     | 
    
         
             
            - lib/packetgen/pcapng.rb
         
     | 
| 
         @@ -235,10 +236,11 @@ files: 
     | 
|
| 
       235 
236 
     | 
    
         
             
            - lib/packetgen/utils.rb
         
     | 
| 
       236 
237 
     | 
    
         
             
            - lib/packetgen/utils/arp_spoofer.rb
         
     | 
| 
       237 
238 
     | 
    
         
             
            - lib/packetgen/version.rb
         
     | 
| 
       238 
     | 
    
         
            -
            homepage:  
     | 
| 
      
 239 
     | 
    
         
            +
            homepage: 
         
     | 
| 
       239 
240 
     | 
    
         
             
            licenses:
         
     | 
| 
       240 
241 
     | 
    
         
             
            - MIT
         
     | 
| 
       241 
242 
     | 
    
         
             
            metadata:
         
     | 
| 
      
 243 
     | 
    
         
            +
              homepage_uri: https://github.com/sdaubert/packetgen
         
     | 
| 
       242 
244 
     | 
    
         
             
              bug_tracker_uri: https://github.com/sdaubert/packetgen/issues
         
     | 
| 
       243 
245 
     | 
    
         
             
              documentation_uri: https://www.rubydoc.info/gems/packetgen
         
     | 
| 
       244 
246 
     | 
    
         
             
              source_code_uri: https://github.com/sdaubert/packetgen
         
     |