packetgen 3.3.3 → 4.0.0

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.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +37 -21
  3. data/lib/packetgen/capture.rb +2 -2
  4. data/lib/packetgen/config.rb +0 -1
  5. data/lib/packetgen/deprecation.rb +7 -7
  6. data/lib/packetgen/header/arp.rb +13 -13
  7. data/lib/packetgen/header/asn1_base.rb +1 -1
  8. data/lib/packetgen/header/base.rb +17 -18
  9. data/lib/packetgen/header/bootp.rb +32 -34
  10. data/lib/packetgen/header/dhcp/option.rb +19 -19
  11. data/lib/packetgen/header/dhcp/options.rb +1 -1
  12. data/lib/packetgen/header/dhcp.rb +3 -3
  13. data/lib/packetgen/header/dhcpv6/duid.rb +16 -16
  14. data/lib/packetgen/header/dhcpv6/option.rb +53 -53
  15. data/lib/packetgen/header/dhcpv6/options.rb +1 -1
  16. data/lib/packetgen/header/dhcpv6/relay.rb +5 -5
  17. data/lib/packetgen/header/dhcpv6.rb +6 -6
  18. data/lib/packetgen/header/dns/name.rb +14 -10
  19. data/lib/packetgen/header/dns/opt.rb +2 -2
  20. data/lib/packetgen/header/dns/option.rb +11 -11
  21. data/lib/packetgen/header/dns/qdsection.rb +1 -1
  22. data/lib/packetgen/header/dns/question.rb +6 -8
  23. data/lib/packetgen/header/dns/rr.rb +56 -43
  24. data/lib/packetgen/header/dns/rrsection.rb +4 -4
  25. data/lib/packetgen/header/dns.rb +27 -30
  26. data/lib/packetgen/header/dot11/control.rb +11 -11
  27. data/lib/packetgen/header/dot11/data.rb +20 -20
  28. data/lib/packetgen/header/dot11/element.rb +4 -4
  29. data/lib/packetgen/header/dot11/management.rb +8 -8
  30. data/lib/packetgen/header/dot11/sub_mngt.rb +39 -53
  31. data/lib/packetgen/header/dot11.rb +88 -93
  32. data/lib/packetgen/header/dot1q.rb +10 -12
  33. data/lib/packetgen/header/dot1x.rb +9 -9
  34. data/lib/packetgen/header/eap/fast.rb +4 -4
  35. data/lib/packetgen/header/eap/md5.rb +6 -6
  36. data/lib/packetgen/header/eap/tls.rb +13 -15
  37. data/lib/packetgen/header/eap/ttls.rb +13 -15
  38. data/lib/packetgen/header/eap.rb +22 -22
  39. data/lib/packetgen/header/eth.rb +18 -18
  40. data/lib/packetgen/header/gre.rb +8 -10
  41. data/lib/packetgen/header/http/headers.rb +2 -2
  42. data/lib/packetgen/header/http/request.rb +17 -16
  43. data/lib/packetgen/header/http/response.rb +18 -17
  44. data/lib/packetgen/header/http/verbs.rb +1 -3
  45. data/lib/packetgen/header/icmp.rb +8 -8
  46. data/lib/packetgen/header/icmpv6.rb +3 -3
  47. data/lib/packetgen/header/igmp.rb +8 -8
  48. data/lib/packetgen/header/igmpv3/group_record.rb +12 -12
  49. data/lib/packetgen/header/igmpv3/mq.rb +16 -18
  50. data/lib/packetgen/header/igmpv3/mr.rb +4 -4
  51. data/lib/packetgen/header/igmpv3.rb +7 -7
  52. data/lib/packetgen/header/ip/addr.rb +13 -13
  53. data/lib/packetgen/header/ip/option.rb +31 -33
  54. data/lib/packetgen/header/ip/options.rb +1 -1
  55. data/lib/packetgen/header/ip.rb +37 -72
  56. data/lib/packetgen/header/ipv6/addr.rb +14 -14
  57. data/lib/packetgen/header/ipv6/extension.rb +8 -8
  58. data/lib/packetgen/header/ipv6/hop_by_hop.rb +9 -9
  59. data/lib/packetgen/header/ipv6.rb +20 -22
  60. data/lib/packetgen/header/llc.rb +17 -17
  61. data/lib/packetgen/header/mdns.rb +1 -1
  62. data/lib/packetgen/header/mld.rb +6 -6
  63. data/lib/packetgen/header/mldv2/mcast_address_record.rb +11 -11
  64. data/lib/packetgen/header/mldv2/mlq.rb +21 -23
  65. data/lib/packetgen/header/mldv2/mlr.rb +8 -8
  66. data/lib/packetgen/header/ospfv2/db_description.rb +11 -12
  67. data/lib/packetgen/header/ospfv2/hello.rb +11 -11
  68. data/lib/packetgen/header/ospfv2/ls_ack.rb +1 -1
  69. data/lib/packetgen/header/ospfv2/ls_request.rb +9 -9
  70. data/lib/packetgen/header/ospfv2/ls_update.rb +3 -3
  71. data/lib/packetgen/header/ospfv2/lsa.rb +54 -58
  72. data/lib/packetgen/header/ospfv2/lsa_header.rb +9 -9
  73. data/lib/packetgen/header/ospfv2.rb +27 -29
  74. data/lib/packetgen/header/ospfv3/db_description.rb +13 -14
  75. data/lib/packetgen/header/ospfv3/hello.rb +12 -12
  76. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +17 -19
  77. data/lib/packetgen/header/ospfv3/ls_ack.rb +2 -2
  78. data/lib/packetgen/header/ospfv3/ls_request.rb +9 -9
  79. data/lib/packetgen/header/ospfv3/ls_update.rb +4 -4
  80. data/lib/packetgen/header/ospfv3/lsa.rb +48 -51
  81. data/lib/packetgen/header/ospfv3/lsa_header.rb +9 -9
  82. data/lib/packetgen/header/ospfv3.rb +25 -27
  83. data/lib/packetgen/header/sctp/chunk.rb +44 -41
  84. data/lib/packetgen/header/sctp/error.rb +52 -52
  85. data/lib/packetgen/header/sctp/parameter.rb +38 -38
  86. data/lib/packetgen/header/sctp.rb +5 -5
  87. data/lib/packetgen/header/snmp.rb +2 -2
  88. data/lib/packetgen/header/tcp/option.rb +45 -39
  89. data/lib/packetgen/header/tcp/options.rb +2 -2
  90. data/lib/packetgen/header/tcp.rb +55 -44
  91. data/lib/packetgen/header/tftp.rb +16 -16
  92. data/lib/packetgen/header/udp.rb +8 -8
  93. data/lib/packetgen/header.rb +9 -10
  94. data/lib/packetgen/headerable.rb +13 -3
  95. data/lib/packetgen/inspect.rb +2 -2
  96. data/lib/packetgen/packet.rb +54 -37
  97. data/lib/packetgen/pcap.rb +15 -4
  98. data/lib/packetgen/pcapng/block.rb +18 -17
  99. data/lib/packetgen/pcapng/epb.rb +13 -15
  100. data/lib/packetgen/pcapng/file.rb +3 -97
  101. data/lib/packetgen/pcapng/idb.rb +9 -11
  102. data/lib/packetgen/pcapng/shb.rb +13 -15
  103. data/lib/packetgen/pcapng/spb.rb +8 -10
  104. data/lib/packetgen/pcapng/unknown_block.rb +6 -17
  105. data/lib/packetgen/pcapng.rb +4 -4
  106. data/lib/packetgen/pcaprub_wrapper.rb +17 -1
  107. data/lib/packetgen/proto.rb +1 -1
  108. data/lib/packetgen/unknown_packet.rb +2 -2
  109. data/lib/packetgen/utils/arp_spoofer.rb +18 -19
  110. data/lib/packetgen/utils.rb +2 -2
  111. data/lib/packetgen/version.rb +1 -1
  112. data/lib/packetgen.rb +4 -3
  113. metadata +29 -38
  114. data/lib/packetgen/types/abstract_tlv.rb +0 -278
  115. data/lib/packetgen/types/array.rb +0 -287
  116. data/lib/packetgen/types/cstring.rb +0 -109
  117. data/lib/packetgen/types/enum.rb +0 -171
  118. data/lib/packetgen/types/fieldable.rb +0 -66
  119. data/lib/packetgen/types/fields.rb +0 -622
  120. data/lib/packetgen/types/int.rb +0 -473
  121. data/lib/packetgen/types/int_string.rb +0 -102
  122. data/lib/packetgen/types/length_from.rb +0 -54
  123. data/lib/packetgen/types/oui.rb +0 -52
  124. data/lib/packetgen/types/string.rb +0 -97
  125. data/lib/packetgen/types/tlv.rb +0 -161
  126. data/lib/packetgen/types.rb +0 -26
@@ -18,12 +18,12 @@ module PacketGen
18
18
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19
19
  #
20
20
  # A IGMP header consists of:
21
- # * a {#type} field ({Types::Int8Enum} type),
22
- # * a {#max_resp_time} field ({Types::Int8} type),
23
- # * a {#checksum} field ({Types::Int16} type),
21
+ # * a {#type} field ({BinStruct::Int8Enum} type),
22
+ # * a {#max_resp_time} field ({BinStruct::Int8} type),
23
+ # * a {#checksum} field ({BinStruct::Int16} type),
24
24
  # * and a {#body}, containing more fields (see below).
25
25
  #
26
- # A IGMPv3 header may have additionnal fields. These fields are handled by
26
+ # A IGMPv3 header may have additionnal fields. These attributes.are handled by
27
27
  # additional headers (see {IGMPv3::MQ}).
28
28
  #
29
29
  # == Create a IGMPv3 header
@@ -50,14 +50,14 @@ module PacketGen
50
50
  # igmp.max_resp_code #=> 9728 error due to encoding as a floating point value
51
51
  #
52
52
  # === IGMPv3 Membership Query
53
- # With IGMPv3, a Membership Query packet has more fields than with IGMPv2. To
53
+ # With IGMPv3, a Membership Query packet has more attributes.than with IGMPv2. To
54
54
  # handle those fields, an additional header should be used:
55
55
  # pkt = PacketGen.gen('IP').add('IGMPv3', type: 'MembershipQuery').add('IGMPv3::MQ')
56
56
  # pkt.igmpv3 #=> PacketGen::Header::IGMPv3
57
57
  # pkt.igmpv3_mq #=> PacketGen::Header::IGMPv3::MQ
58
58
  #
59
59
  # === IGMPv3 Membership Report
60
- # With IGMPv3, a Membership Report packet has more fields than with IGMPv2. To
60
+ # With IGMPv3, a Membership Report packet has more attributes.than with IGMPv2. To
61
61
  # handle those fields, an additional header should be used:
62
62
  # pkt = PacketGen.gen('IP').add('IGMPv3', type: 'MembershipQuery').add('IGMPv3::MR')
63
63
  # pkt.igmpv3 #=> PacketGen::Header::IGMPv3
@@ -71,7 +71,7 @@ module PacketGen
71
71
  'MembershipReport' => 0x22,
72
72
  }.freeze
73
73
 
74
- remove_field :group_addr
74
+ remove_attr :group_addr
75
75
 
76
76
  # Encode value for IGMPv3 Max Resp Code and QQIC.
77
77
  # Value may be encoded as a float, so some error may occur.
@@ -11,23 +11,23 @@ module PacketGen
11
11
  class IP
12
12
  # IP address, as a group of 4 bytes
13
13
  # @author Sylvain Daubert
14
- class Addr < Types::Fields
15
- include Types::Fieldable
14
+ class Addr < BinStruct::Struct
15
+ include BinStruct::Structable
16
16
 
17
17
  # @!attribute a1
18
18
  # @return [Integer] IP address first byte
19
- define_field :a1, Types::Int8
19
+ define_attr :a1, BinStruct::Int8
20
20
  # @!attribute a2
21
21
  # @return [Integer] IP address seconf byte
22
- define_field :a2, Types::Int8
22
+ define_attr :a2, BinStruct::Int8
23
23
  # @!attribute a3
24
24
  # @return [Integer] IP address third byte
25
- define_field :a3, Types::Int8
25
+ define_attr :a3, BinStruct::Int8
26
26
  # @!attribute a4
27
27
  # @return [Integer] IP address fourth byte
28
- define_field :a4, Types::Int8
28
+ define_attr :a4, BinStruct::Int8
29
29
 
30
- IPV4_ADDR_REGEX = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.freeze
30
+ IPV4_ADDR_REGEX = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
31
31
 
32
32
  # Read a dotted address
33
33
  # @param [String] str
@@ -37,10 +37,10 @@ module PacketGen
37
37
 
38
38
  m = str.match(IPV4_ADDR_REGEX)
39
39
  if m
40
- self[:a1].read m[1].to_i
41
- self[:a2].read m[2].to_i
42
- self[:a3].read m[3].to_i
43
- self[:a4].read m[4].to_i
40
+ self[:a1].from_human(m[1].to_i)
41
+ self[:a2].from_human(m[2].to_i)
42
+ self[:a3].from_human(m[3].to_i)
43
+ self[:a4].from_human(m[4].to_i)
44
44
  end
45
45
  self
46
46
  end
@@ -48,7 +48,7 @@ module PacketGen
48
48
  # Addr in human readable form (dotted format)
49
49
  # @return [String]
50
50
  def to_human
51
- fields.map { |f| self[f].to_i.to_s }.join('.')
51
+ attributes.map { |f| self[f].to_i.to_s }.join('.')
52
52
  end
53
53
 
54
54
  # Addr as an integer
@@ -66,7 +66,7 @@ module PacketGen
66
66
 
67
67
  def ==(other)
68
68
  other.is_a?(self.class) &&
69
- fields.all? { |attr| self[attr].value == other[attr].value }
69
+ attributes.all? { |attr| self[attr].value == other[attr].value }
70
70
  end
71
71
  end
72
72
  end
@@ -11,7 +11,7 @@ module PacketGen
11
11
  class IP
12
12
  # Class to handle series of IP addresses
13
13
  # @author Sylvain Daubert
14
- class ArrayOfAddr < Types::Array
14
+ class ArrayOfAddr < BinStruct::Array
15
15
  set_of IP::Addr
16
16
 
17
17
  # Push a IP address to the array
@@ -20,14 +20,14 @@ module PacketGen
20
20
  # array << '192.168.1.12'
21
21
  def push(addr)
22
22
  addr = Addr.new.from_human(addr) unless addr.is_a?(Addr)
23
- super(addr)
23
+ super
24
24
  end
25
25
  end
26
26
 
27
27
  # Base class for IP options
28
28
  # @author Sylvain Daubert
29
- class Option < Types::Fields
30
- include Types::Fieldable
29
+ class Option < BinStruct::Struct
30
+ include BinStruct::Structable
31
31
 
32
32
  # EOL option type
33
33
  EOL_TYPE = 0x00
@@ -47,20 +47,9 @@ module PacketGen
47
47
  # @!attribute type
48
48
  # 8-bit option type
49
49
  # @return [Integer]
50
- define_field :type, Types::Int8
51
- # @!attribute length
52
- # 8-bit option length. If 0, there is no +length+ field in option
53
- # @return [Integer]
54
- define_field :length, Types::Int8, default: 0, optional: ->(h) { h.type > 1 }
55
- # @!attribute data
56
- # option data
57
- # @return [String]
58
- define_field :data, Types::String, optional: ->(h) { h.length > 2 },
59
- builder: ->(h, t) { t.new(length_from: -> { h.length - 2 }) }
60
-
61
50
  # @!attribute copied
62
51
  # 1-bit copied flag from {#type} field
63
- # @return [Boolean]
52
+ # @return [Integer]
64
53
  # @!attribute option_class
65
54
  # 2-bit option class (0: control, 2: debug and measurement, 1 and 3:
66
55
  # reserved) from {#type} field
@@ -68,7 +57,16 @@ module PacketGen
68
57
  # !@attribute number
69
58
  # 5-bit option number from {#type} field
70
59
  # @return [Integer]
71
- define_bit_fields_on :type, :copied, :option_class, 2, :number, 5
60
+ define_bit_attr :type, copied: 1, option_class: 2, number: 5
61
+ # @!attribute length
62
+ # 8-bit option length. If 0, there is no +length+ field in option
63
+ # @return [Integer]
64
+ define_attr :length, BinStruct::Int8, default: 0, optional: ->(h) { h.type > 1 }
65
+ # @!attribute data
66
+ # option data
67
+ # @return [String]
68
+ define_attr :data, BinStruct::String, optional: ->(h) { h.length > 2 },
69
+ builder: ->(h, t) { t.new(length_from: -> { h.length - 2 }) }
72
70
 
73
71
  # @return [Hash]
74
72
  def self.types
@@ -76,7 +74,7 @@ module PacketGen
76
74
 
77
75
  @types = {}
78
76
  Option.constants.each do |cst|
79
- next unless cst.to_s.end_with? '_TYPE'
77
+ next unless cst.to_s.end_with?('_TYPE')
80
78
 
81
79
  optname = cst.to_s.sub('_TYPE', '')
82
80
  @types[optname] = Option.const_get(cst)
@@ -109,14 +107,14 @@ module PacketGen
109
107
  # Get binary string. Set {#length} field.
110
108
  # @return [String]
111
109
  def to_s
112
- self.length = super.size if respond_to? :length
110
+ self.length = super.size if respond_to?(:length)
113
111
  super
114
112
  end
115
113
 
116
114
  # Get a human readable string
117
115
  # @return [String]
118
116
  def to_human
119
- str = self.instance_of?(Option) ? +"unk-#{type}" : self.class.to_s.sub(/.*::/, '')
117
+ str = self.instance_of?(Option) ? "unk-#{type}" : self.class.to_s.sub(/.*::/, '')
120
118
  str << ":#{self[:data].to_s.inspect}" if respond_to?(:length) && (length > 2) && !self[:data].to_s.empty?
121
119
  str
122
120
  end
@@ -124,8 +122,8 @@ module PacketGen
124
122
  private
125
123
 
126
124
  def class2type
127
- opt_name = self.class.to_s.gsub(/.*::/, '')
128
- Option.const_get(:"#{opt_name}_TYPE") if Option.const_defined? :"#{opt_name}_TYPE"
125
+ opt_sym = :"#{self.class.to_s.gsub(/.*::/, '')}_TYPE"
126
+ Option.const_get(opt_sym) if Option.const_defined?(opt_sym)
129
127
  end
130
128
 
131
129
  def initialize_length_if_needed(options)
@@ -133,7 +131,7 @@ module PacketGen
133
131
  end
134
132
 
135
133
  def initialize_data_if_needed(options)
136
- return unless fields.include?(:data) && self[:data].respond_to?(:from_human) && options.key?(:data)
134
+ return unless attributes.include?(:data) && self[:data].respond_to?(:from_human) && options.key?(:data)
137
135
 
138
136
  # Force data if data is set in options but not length
139
137
  self.length += options[:data].size
@@ -143,8 +141,8 @@ module PacketGen
143
141
 
144
142
  # End-of-option-List IP option
145
143
  class EOL < Option
146
- remove_field :length
147
- remove_field :data
144
+ remove_attr :length
145
+ remove_attr :data
148
146
  end
149
147
 
150
148
  # No OPeration IP option
@@ -152,16 +150,16 @@ module PacketGen
152
150
 
153
151
  # Loose Source and Record Route IP option
154
152
  class LSRR < Option
155
- remove_field :data
153
+ remove_attr :data
156
154
 
157
155
  # @!attribute pointer
158
156
  # 8-bit pointer on next address
159
157
  # @return [Integer]
160
- define_field :pointer, Types::Int8, default: 4
158
+ define_attr :pointer, BinStruct::Int8, default: 4
161
159
  # @!attribute data
162
160
  # Array of IP addresses
163
- # @return [Types::Array<IP::Addr>]
164
- define_field :data, ArrayOfAddr, builder: ->(h, t) { t.new(length_from: -> { h.length - 3 }) }
161
+ # @return [BinStruct::Array<IP::Addr>]
162
+ define_attr :data, ArrayOfAddr, builder: ->(h, t) { t.new(length_from: -> { h.length - 3 }) }
165
163
 
166
164
  # Get IP address pointer by {#pointer}
167
165
  # @return [Addr]
@@ -185,12 +183,12 @@ module PacketGen
185
183
 
186
184
  # Stream Identifier IP option
187
185
  class SI < Option
188
- remove_field :data
186
+ remove_attr :data
189
187
 
190
188
  # @!attribute id
191
189
  # 16-bit stream ID
192
190
  # @return [Integer]
193
- define_field :id, Types::Int16
191
+ define_attr :id, BinStruct::Int16
194
192
 
195
193
  def to_human
196
194
  super << ":#{self.id}"
@@ -199,12 +197,12 @@ module PacketGen
199
197
 
200
198
  # Router Alert IP option
201
199
  class RA < Option
202
- remove_field :data
200
+ remove_attr :data
203
201
 
204
202
  # @!attribute value
205
203
  # 16-bit value. Should be 0.
206
204
  # @return [Integer]
207
- define_field :value, Types::Int16, default: 0
205
+ define_attr :value, BinStruct::Int16, default: 0
208
206
 
209
207
  def to_human
210
208
  super << ":#{self.value}"
@@ -11,7 +11,7 @@ module PacketGen
11
11
  class IP
12
12
  # Class to handle IP options
13
13
  # @author Sylvain Daubert
14
- class Options < Types::Array
14
+ class Options < BinStruct::Array
15
15
  set_of Option
16
16
 
17
17
  HUMAN_SEPARATOR = ';'
@@ -27,11 +27,11 @@ module PacketGen
27
27
  # | Options | Padding |
28
28
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
29
29
  # A IP header consists of:
30
- # * a first byte ({#u8} of {Types::Int8} type) composed of:
30
+ # * a first byte ({#u8} of {BinStruct::Int8} type) composed of:
31
31
  # * a 4-bit {#version} field,
32
32
  # * a 4-bit IP header length ({#ihl}) field,
33
- # * a Type of Service field ({#tos}, {Types::Int8} type),
34
- # * a total length ({#length}, {Types::Int16} type),
33
+ # * a Type of Service field ({#tos}, {BinStruct::Int8} type),
34
+ # * a total length ({#length}, {BinStruct::Int16} type),
35
35
  # * a ID ({#id}, +Int16+ type),
36
36
  # * a {#frag} worg (+Int16+) composed of:
37
37
  # * 3 1-bit flags ({#flag_rsv}, {#flag_df} and {#flag_mf}),
@@ -42,7 +42,7 @@ module PacketGen
42
42
  # * a source IP address ({#src}, {Addr} type),
43
43
  # * a destination IP address ({#dst}, +Addr+ type),
44
44
  # * an optional {#options} field ({Options} type),
45
- # * and a {#body} ({Types::String} type).
45
+ # * and a {#body} ({BinStruct::String} type).
46
46
  #
47
47
  # == Create a IP header
48
48
  # # standalone
@@ -100,58 +100,54 @@ module PacketGen
100
100
  # @!attribute u8
101
101
  # First byte of IP header. May be accessed through {#version} and {#ihl}.
102
102
  # @return [Integer] first byte of IP header.
103
- define_field :u8, Types::Int8, default: 0x45
103
+ # @!attribute version
104
+ # @return [Integer] 4-bit version attribute
105
+ # @!attribute ihl
106
+ # @return [Integer] 4-bit IP header length attribute
107
+ define_bit_attr :u8, default: 0x45, version: 4, ihl: 4
104
108
  # @!attribute tos
105
109
  # @return [Integer] 8-bit Type of Service self[attr]
106
- define_field :tos, Types::Int8, default: 0
110
+ define_attr :tos, BinStruct::Int8, default: 0
107
111
  # @!attribute length
108
112
  # @return [Integer] 16-bit IP total length
109
- define_field :length, Types::Int16, default: 20
113
+ define_attr :length, BinStruct::Int16, default: 20
110
114
  # @!attribute id
111
115
  # @return [Integer] 16-bit ID
112
- define_field :id, Types::Int16, default: ->(_) { rand(65_535) }
116
+ define_attr :id, BinStruct::Int16, default: ->(_) { rand(65_535) }
113
117
  # @!attribute frag
114
118
  # @return [Integer] 16-bit frag word
115
- define_field :frag, Types::Int16, default: 0
119
+ # @!attribute flag_rsv
120
+ # @return [Boolean] reserved bit from flags
121
+ # @!attribute flag_df
122
+ # @return [Boolean] Don't Fragment flag
123
+ # @!attribute flag_mf
124
+ # @return [Boolean] More Fragment flags
125
+ # @!attribute fragment_offset
126
+ # @return [Integer] 13-bit fragment offset
127
+ define_bit_attr :frag, flag_rsv: 1, flag_df: 1, flag_mf: 1, fragment_offset: 13
116
128
  # @!attribute ttl
117
129
  # @return [Integer] 8-bit Time To Live self[attr]
118
- define_field :ttl, Types::Int8, default: 64
130
+ define_attr :ttl, BinStruct::Int8, default: 64
119
131
  # @!attribute protocol
120
132
  # @return [Integer] 8-bit upper protocol self[attr]
121
- define_field :protocol, Types::Int8
133
+ define_attr :protocol, BinStruct::Int8
122
134
  # @!attribute checksum
123
135
  # @return [Integer] 16-bit IP header checksum
124
- define_field :checksum, Types::Int16, default: 0
136
+ define_attr :checksum, BinStruct::Int16, default: 0
125
137
  # @!attribute src
126
138
  # @return [Addr] source IP address
127
- define_field :src, Addr, default: '127.0.0.1'
139
+ define_attr :src, Addr, default: '127.0.0.1'
128
140
  # @!attribute dst
129
141
  # @return [Addr] destination IP address
130
- define_field :dst, Addr, default: '127.0.0.1'
142
+ define_attr :dst, Addr, default: '127.0.0.1'
131
143
  # @!attribute options
132
144
  # @since 2.2.0
133
- # @return [Types::String]
134
- define_field :options, Options, optional: ->(h) { h.ihl > 5 },
135
- builder: ->(h, t) { t.new(length_from: -> { (h.ihl - 5) * 4 }) }
145
+ # @return [BinStruct::String]
146
+ define_attr :options, Options, optional: ->(h) { h.ihl > 5 },
147
+ builder: ->(h, t) { t.new(length_from: -> { (h.ihl - 5) * 4 }) }
136
148
  # @!attribute body
137
- # @return [Types::String,Header::Base]
138
- define_field :body, Types::String
139
-
140
- # @!attribute version
141
- # @return [Integer] 4-bit version attribute
142
- # @!attribute ihl
143
- # @return [Integer] 4-bit IP header length attribute
144
- define_bit_fields_on :u8, :version, 4, :ihl, 4
145
-
146
- # @!attribute flag_rsv
147
- # @return [Boolean] reserved bit from flags
148
- # @!attribute flag_df
149
- # @return [Boolean] Don't Fragment flag
150
- # @!attribute flag_mf
151
- # @return [Boolean] More Fragment flags
152
- # @!attribute fragment_offset
153
- # @return [Integer] 13-bit fragment offset
154
- define_bit_fields_on :frag, :flag_rsv, :flag_df, :flag_mf, :fragment_offset, 13
149
+ # @return [BinStruct::String,Header::Base]
150
+ define_attr :body, BinStruct::String
155
151
 
156
152
  # Helper method to compute sum of 16-bit words. Used to compute IP-style
157
153
  # checksums.
@@ -160,7 +156,7 @@ module PacketGen
160
156
  # @return [Integer]
161
157
  def self.sum16(hdr)
162
158
  old_checksum = nil
163
- if hdr.respond_to? :checksum=
159
+ if hdr.respond_to?(:checksum)
164
160
  old_checksum = hdr.checksum
165
161
  hdr.checksum = 0
166
162
  end
@@ -178,8 +174,8 @@ module PacketGen
178
174
  # This method:
179
175
  # * checks a checksum is not greater than 0xffff. If it is,
180
176
  # reduces it.
181
- # * inverts reduced self[attr].
182
- # * forces self[attr] to 0xffff if computed self[attr] is 0.
177
+ # * inverts reduced checksum.
178
+ # * forces checksum to 0xffff if computed checksum is 0.
183
179
  # @param [Integer] checksum checksum to reduce
184
180
  # @return [Integer] reduced checksum
185
181
  def self.reduce_checksum(checksum)
@@ -203,7 +199,7 @@ module PacketGen
203
199
  # @return [Integer]
204
200
  # @since 3.0.0 add +ihl+ calculation
205
201
  def calc_length
206
- Base.calculate_and_set_length self
202
+ Base.calculate_and_set_length(self)
207
203
  self.ihl = 5 + self[:options].sz / 4
208
204
  end
209
205
 
@@ -216,29 +212,17 @@ module PacketGen
216
212
 
217
213
  # Send IP packet on wire.
218
214
  #
219
- # When sending packet at IP level, +checksum+ and +length+ fields are set by
215
+ # When sending packet at IP level, +checksum+ and +length+ attributes are set by
220
216
  # kernel, so bad IP packets cannot be sent this way. To do so, use {Eth#to_w}.
221
217
  # @param [String,nil] _iface interface name. Not used
222
218
  # @return [void]
223
219
  def to_w(_iface=nil)
224
220
  sock = Socket.new(Socket::AF_INET, Socket::SOCK_RAW, Socket::IPPROTO_RAW)
225
221
  sockaddrin = Socket.sockaddr_in(0, dst)
226
- sock.send to_s, 0, sockaddrin
222
+ sock.send(to_s, 0, sockaddrin)
227
223
  sock.close
228
224
  end
229
225
 
230
- # @return [String]
231
- def inspect
232
- super do |attr|
233
- case attr
234
- when :u8
235
- inspect_u8
236
- when :frag
237
- inspect_frag
238
- end
239
- end
240
- end
241
-
242
226
  # Check version field
243
227
  # @see [Base#parse?]
244
228
  def parse?
@@ -259,25 +243,6 @@ module PacketGen
259
243
  self[:src], self[:dst] = self[:dst], self[:src]
260
244
  self
261
245
  end
262
-
263
- private
264
-
265
- def inspect_u8
266
- shift = Inspect.shift_level
267
- str = Inspect.inspect_attribute(:u8, self[:u8])
268
- str << shift << Inspect::FMT_ATTR % ['', 'version', version]
269
- str << shift << Inspect::FMT_ATTR % ['', 'ihl', ihl]
270
- end
271
-
272
- def inspect_frag
273
- shift = Inspect.shift_level
274
- str = Inspect.inspect_attribute(:frag, self[:frag])
275
- flags = %i[rsv df mf].select { |flag| send(:"flag_#{flag}?") }.map(&:upcase)
276
- flags_str = flags.empty? ? 'none' : flags.join(',')
277
- str << shift << Inspect::FMT_ATTR % ['', 'flags', flags_str]
278
- foff = Inspect.int_dec_hex(fragment_offset, 4)
279
- str << shift << Inspect::FMT_ATTR % ['', 'frag_offset', foff]
280
- end
281
246
  end
282
247
 
283
248
  self.add_class IP
@@ -14,41 +14,41 @@ module PacketGen
14
14
  class IPv6
15
15
  # IPv6 address, as a group of 8 2-byte words
16
16
  # @author Sylvain Daubert
17
- class Addr < Types::Fields
18
- include Types::Fieldable
17
+ class Addr < BinStruct::Struct
18
+ include BinStruct::Structable
19
19
 
20
20
  # @!attribute a1
21
21
  # 1st 2-byte word of IPv6 address
22
22
  # @return [Integer]
23
- define_field :a1, Types::Int16
23
+ define_attr :a1, BinStruct::Int16
24
24
  # @!attribute a2
25
25
  # 2nd 2-byte word of IPv6 address
26
26
  # @return [Integer]
27
- define_field :a2, Types::Int16
27
+ define_attr :a2, BinStruct::Int16
28
28
  # @!attribute a3
29
29
  # 3rd 2-byte word of IPv6 address
30
30
  # @return [Integer]
31
- define_field :a3, Types::Int16
31
+ define_attr :a3, BinStruct::Int16
32
32
  # @!attribute a4
33
33
  # 4th 2-byte word of IPv6 address
34
34
  # @return [Integer]
35
- define_field :a4, Types::Int16
35
+ define_attr :a4, BinStruct::Int16
36
36
  # @!attribute a5
37
37
  # 5th 2-byte word of IPv6 address
38
38
  # @return [Integer]
39
- define_field :a5, Types::Int16
39
+ define_attr :a5, BinStruct::Int16
40
40
  # @!attribute a6
41
41
  # 6th 2-byte word of IPv6 address
42
42
  # @return [Integer]
43
- define_field :a6, Types::Int16
43
+ define_attr :a6, BinStruct::Int16
44
44
  # @!attribute a7
45
45
  # 7th 2-byte word of IPv6 address
46
46
  # @return [Integer]
47
- define_field :a7, Types::Int16
47
+ define_attr :a7, BinStruct::Int16
48
48
  # @!attribute a8
49
49
  # 8th 2-byte word of IPv6 address
50
50
  # @return [Integer]
51
- define_field :a8, Types::Int16
51
+ define_attr :a8, BinStruct::Int16
52
52
 
53
53
  # rubocop:disable Metrics/AbcSize
54
54
 
@@ -83,7 +83,7 @@ module PacketGen
83
83
  # Return an array of address 16-bit words
84
84
  # @return [Array<Integer>]
85
85
  def to_a
86
- @fields.values
86
+ @attributes.values
87
87
  end
88
88
 
89
89
  # Return true if this address is a multicast one
@@ -94,13 +94,13 @@ module PacketGen
94
94
 
95
95
  def ==(other)
96
96
  other.is_a?(self.class) &&
97
- fields.all? { |attr| self[attr].value == other[attr].value }
97
+ attributes.all? { |attr| self[attr].value == other[attr].value }
98
98
  end
99
99
  end
100
100
 
101
101
  # Class to handle series of IPv6 addresses
102
102
  # @author Sylvain Daubert
103
- class ArrayOfAddr < Types::Array
103
+ class ArrayOfAddr < BinStruct::Array
104
104
  set_of IPv6::Addr
105
105
 
106
106
  # Push a IPv6 address to the array
@@ -109,7 +109,7 @@ module PacketGen
109
109
  # array << '2001:1234::125'
110
110
  def push(addr)
111
111
  addr = Addr.new.from_human(addr) unless addr.is_a?(Addr)
112
- super(addr)
112
+ super
113
113
  end
114
114
  end
115
115
  end
@@ -25,29 +25,29 @@ module PacketGen
25
25
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
26
26
  #
27
27
  # Such a header consists of:
28
- # * a {#next} header field ({Types::Int8}),
29
- # * a {#length} field ({Types::Int8}),
30
- # * an {#options} field ({Types::String}),
28
+ # * a {#next} header field ({BinStruct::Int8}),
29
+ # * a {#length} field ({BinStruct::Int8}),
30
+ # * an {#options} field ({BinStruct::String}),
31
31
  # * and a {#body}, containing next header.
32
32
  # @author Sylvain Daubert
33
33
  class Extension < Base
34
34
  # @!attribute next
35
35
  # 8-bit Next header field
36
36
  # @return [Integer]
37
- define_field :next, Types::Int8
37
+ define_attr :next, BinStruct::Int8
38
38
  # @!attribute length
39
39
  # 8-bit extension length, in 8-octets units, not including the
40
40
  # first 8 octets.
41
41
  # @return [Integer]
42
- define_field :length, Types::Int8
42
+ define_attr :length, BinStruct::Int8
43
43
  # @!attribute options
44
44
  # Specific options of extension header
45
45
  # @return [String]
46
- define_field :options, Types::String,
47
- builder: ->(h, t) { t.new(length_from: -> { h.real_length }) }
46
+ define_attr :options, BinStruct::String,
47
+ builder: ->(h, t) { t.new(length_from: -> { h.real_length }) }
48
48
  # @!attribute body
49
49
  # @return [String,Base]
50
- define_field :body, Types::String
50
+ define_attr :body, BinStruct::String
51
51
 
52
52
  # Get real extension header length
53
53
  # @return [Integer]
@@ -11,10 +11,10 @@ module PacketGen
11
11
  class IPv6
12
12
  # @!parse
13
13
  # # Option for {HopByHop} IPv6 extension header.
14
- # # @since 3.1.0 subclass of {Types::AbstractTLV}
14
+ # # @since 3.1.0 subclass of {BinStruct::AbstractTLV}
15
15
  # class Option <AbstractTLV; end
16
16
  # @private
17
- Option = Types::AbstractTLV.create
17
+ Option = BinStruct::AbstractTLV.create
18
18
 
19
19
  class Option
20
20
  # Known option types
@@ -37,10 +37,10 @@ module PacketGen
37
37
 
38
38
  # Special option pad1, for {HopByHop} IPv6 extension header
39
39
  # @author Sylvain Daubert
40
- class Pad1 < Types::Fields
40
+ class Pad1 < BinStruct::Struct
41
41
  # @!attribute pad
42
42
  # @return [Integer]
43
- define_field :pad, Types::Int8, default: 0
43
+ define_attr :pad, BinStruct::Int8, default: 0
44
44
 
45
45
  # @return [String]
46
46
  def to_human
@@ -50,7 +50,7 @@ module PacketGen
50
50
 
51
51
  # Array of {Option}, for {HopByHop} IPv6 extension header
52
52
  # @author Sylvain Daubert
53
- class Options < Types::Array
53
+ class Options < BinStruct::Array
54
54
  set_of Option
55
55
 
56
56
  # Get options as a binary string. Add padding if needed.
@@ -96,18 +96,18 @@ module PacketGen
96
96
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
97
97
  #
98
98
  # Hop-by-hop IPv6 extension header consists of:
99
- # * a {#next} header field ({Types::Int8}),
100
- # * a {#length} field ({Types::Int8}),
99
+ # * a {#next} header field ({BinStruct::Int8}),
100
+ # * a {#length} field ({BinStruct::Int8}),
101
101
  # * an {#options} field ({Options}),
102
102
  # * and a {#body}, containing next header.
103
103
  # @author Sylvain Daubert
104
104
  class HopByHop < Extension
105
105
  # redefine options field
106
- remove_field :options
106
+ remove_attr :options
107
107
  # @!attribute options
108
108
  # Specific options of extension header
109
109
  # @return [Options]
110
- define_field_before :body, :options, Options, builder: ->(h, t) { t.new(length_from: -> { h.real_length - 2 }) }
110
+ define_attr_before :body, :options, Options, builder: ->(h, t) { t.new(length_from: -> { h.real_length - 2 }) }
111
111
  end
112
112
  end
113
113