packetgen 3.3.3 → 4.1.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 (128) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +38 -22
  3. data/lib/packetgen/capture.rb +2 -2
  4. data/lib/packetgen/config.rb +0 -1
  5. data/lib/packetgen/deprecation.rb +14 -8
  6. data/lib/packetgen/header/arp.rb +17 -18
  7. data/lib/packetgen/header/asn1_base.rb +2 -1
  8. data/lib/packetgen/header/base.rb +42 -40
  9. data/lib/packetgen/header/bootp.rb +35 -37
  10. data/lib/packetgen/header/dhcp/option.rb +21 -21
  11. data/lib/packetgen/header/dhcp/options.rb +3 -3
  12. data/lib/packetgen/header/dhcp.rb +8 -9
  13. data/lib/packetgen/header/dhcpv6/duid.rb +16 -16
  14. data/lib/packetgen/header/dhcpv6/option.rb +83 -61
  15. data/lib/packetgen/header/dhcpv6/options.rb +4 -4
  16. data/lib/packetgen/header/dhcpv6/relay.rb +6 -5
  17. data/lib/packetgen/header/dhcpv6.rb +17 -18
  18. data/lib/packetgen/header/dns/name.rb +21 -16
  19. data/lib/packetgen/header/dns/opt.rb +5 -2
  20. data/lib/packetgen/header/dns/option.rb +14 -14
  21. data/lib/packetgen/header/dns/qdsection.rb +3 -3
  22. data/lib/packetgen/header/dns/question.rb +7 -8
  23. data/lib/packetgen/header/dns/rr.rb +56 -43
  24. data/lib/packetgen/header/dns/rrsection.rb +6 -6
  25. data/lib/packetgen/header/dns.rb +103 -90
  26. data/lib/packetgen/header/dot11/control.rb +12 -12
  27. data/lib/packetgen/header/dot11/data.rb +25 -24
  28. data/lib/packetgen/header/dot11/element.rb +4 -4
  29. data/lib/packetgen/header/dot11/management.rb +21 -18
  30. data/lib/packetgen/header/dot11/sub_mngt.rb +40 -53
  31. data/lib/packetgen/header/dot11.rb +117 -122
  32. data/lib/packetgen/header/dot1q.rb +12 -13
  33. data/lib/packetgen/header/dot1x.rb +13 -13
  34. data/lib/packetgen/header/eap/fast.rb +4 -4
  35. data/lib/packetgen/header/eap/md5.rb +16 -8
  36. data/lib/packetgen/header/eap/tls.rb +18 -19
  37. data/lib/packetgen/header/eap/ttls.rb +22 -21
  38. data/lib/packetgen/header/eap.rb +73 -48
  39. data/lib/packetgen/header/eth.rb +41 -27
  40. data/lib/packetgen/header/gre.rb +33 -11
  41. data/lib/packetgen/header/http/headers.rb +7 -6
  42. data/lib/packetgen/header/http/request.rb +38 -29
  43. data/lib/packetgen/header/http/response.rb +35 -27
  44. data/lib/packetgen/header/http/verbs.rb +1 -3
  45. data/lib/packetgen/header/icmp.rb +14 -14
  46. data/lib/packetgen/header/icmpv6.rb +10 -9
  47. data/lib/packetgen/header/igmp.rb +26 -15
  48. data/lib/packetgen/header/igmpv3/group_record.rb +18 -13
  49. data/lib/packetgen/header/igmpv3/mq.rb +16 -18
  50. data/lib/packetgen/header/igmpv3/mr.rb +5 -5
  51. data/lib/packetgen/header/igmpv3.rb +12 -11
  52. data/lib/packetgen/header/ip/addr.rb +19 -15
  53. data/lib/packetgen/header/ip/option.rb +47 -36
  54. data/lib/packetgen/header/ip/options.rb +1 -1
  55. data/lib/packetgen/header/ip.rb +77 -95
  56. data/lib/packetgen/header/ipv6/addr.rb +28 -27
  57. data/lib/packetgen/header/ipv6/extension.rb +13 -11
  58. data/lib/packetgen/header/ipv6/hop_by_hop.rb +32 -13
  59. data/lib/packetgen/header/ipv6.rb +42 -35
  60. data/lib/packetgen/header/llc.rb +28 -21
  61. data/lib/packetgen/header/mdns.rb +10 -3
  62. data/lib/packetgen/header/mld.rb +15 -13
  63. data/lib/packetgen/header/mldv2/mcast_address_record.rb +17 -12
  64. data/lib/packetgen/header/mldv2/mlq.rb +22 -24
  65. data/lib/packetgen/header/mldv2/mlr.rb +8 -8
  66. data/lib/packetgen/header/mldv2.rb +1 -1
  67. data/lib/packetgen/header/ospfv2/db_description.rb +17 -18
  68. data/lib/packetgen/header/ospfv2/hello.rb +18 -17
  69. data/lib/packetgen/header/ospfv2/ls_ack.rb +6 -7
  70. data/lib/packetgen/header/ospfv2/ls_request.rb +14 -13
  71. data/lib/packetgen/header/ospfv2/ls_update.rb +9 -9
  72. data/lib/packetgen/header/ospfv2/lsa.rb +79 -60
  73. data/lib/packetgen/header/ospfv2/lsa_header.rb +12 -11
  74. data/lib/packetgen/header/ospfv2.rb +49 -46
  75. data/lib/packetgen/header/ospfv3/db_description.rb +20 -22
  76. data/lib/packetgen/header/ospfv3/hello.rb +17 -16
  77. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +22 -20
  78. data/lib/packetgen/header/ospfv3/ls_ack.rb +7 -8
  79. data/lib/packetgen/header/ospfv3/ls_request.rb +18 -18
  80. data/lib/packetgen/header/ospfv3/ls_update.rb +10 -10
  81. data/lib/packetgen/header/ospfv3/lsa.rb +62 -51
  82. data/lib/packetgen/header/ospfv3/lsa_header.rb +12 -11
  83. data/lib/packetgen/header/ospfv3.rb +54 -52
  84. data/lib/packetgen/header/sctp/chunk.rb +80 -56
  85. data/lib/packetgen/header/sctp/error.rb +174 -202
  86. data/lib/packetgen/header/sctp/padded32.rb +3 -3
  87. data/lib/packetgen/header/sctp/parameter.rb +89 -136
  88. data/lib/packetgen/header/sctp.rb +19 -8
  89. data/lib/packetgen/header/snmp.rb +108 -7
  90. data/lib/packetgen/header/tcp/option.rb +52 -39
  91. data/lib/packetgen/header/tcp/options.rb +13 -5
  92. data/lib/packetgen/header/tcp.rb +83 -65
  93. data/lib/packetgen/header/tftp.rb +31 -25
  94. data/lib/packetgen/header/udp.rb +21 -19
  95. data/lib/packetgen/header.rb +23 -18
  96. data/lib/packetgen/headerable.rb +21 -5
  97. data/lib/packetgen/inspect.rb +3 -8
  98. data/lib/packetgen/packet.rb +146 -71
  99. data/lib/packetgen/pcap.rb +15 -4
  100. data/lib/packetgen/pcapng/block.rb +20 -18
  101. data/lib/packetgen/pcapng/epb.rb +13 -15
  102. data/lib/packetgen/pcapng/file.rb +44 -111
  103. data/lib/packetgen/pcapng/idb.rb +11 -12
  104. data/lib/packetgen/pcapng/shb.rb +15 -16
  105. data/lib/packetgen/pcapng/spb.rb +9 -11
  106. data/lib/packetgen/pcapng/unknown_block.rb +6 -17
  107. data/lib/packetgen/pcapng.rb +6 -4
  108. data/lib/packetgen/pcaprub_wrapper.rb +17 -1
  109. data/lib/packetgen/proto.rb +5 -1
  110. data/lib/packetgen/unknown_packet.rb +5 -5
  111. data/lib/packetgen/utils/arp_spoofer.rb +18 -19
  112. data/lib/packetgen/utils.rb +4 -3
  113. data/lib/packetgen/version.rb +1 -1
  114. data/lib/packetgen.rb +12 -5
  115. metadata +29 -38
  116. data/lib/packetgen/types/abstract_tlv.rb +0 -278
  117. data/lib/packetgen/types/array.rb +0 -287
  118. data/lib/packetgen/types/cstring.rb +0 -109
  119. data/lib/packetgen/types/enum.rb +0 -171
  120. data/lib/packetgen/types/fieldable.rb +0 -66
  121. data/lib/packetgen/types/fields.rb +0 -622
  122. data/lib/packetgen/types/int.rb +0 -473
  123. data/lib/packetgen/types/int_string.rb +0 -102
  124. data/lib/packetgen/types/length_from.rb +0 -54
  125. data/lib/packetgen/types/oui.rb +0 -52
  126. data/lib/packetgen/types/string.rb +0 -97
  127. data/lib/packetgen/types/tlv.rb +0 -161
  128. data/lib/packetgen/types.rb +0 -26
@@ -17,25 +17,24 @@ module PacketGen
17
17
  class PPI < Base
18
18
  # @!attribute version
19
19
  # @return [Integer] 8-bit PPI version
20
- define_field :version, Types::Int8, default: 0
20
+ define_attr :version, BinStruct::Int8, default: 0
21
21
  # @!attribute flags
22
22
  # @return [Integer] 8-bit PPI flags
23
- define_field :flags, Types::Int8
23
+ # @!attribute align
24
+ # @return [Boolean] align flag from {#flags} attribute
25
+ define_bit_attr :flags, reserved: 7, align: 1
24
26
  # @!attribute length
25
27
  # @return [Integer] 16-bit PPI header length
26
- define_field :length, Types::Int16le, default: 8
28
+ define_attr :length, BinStruct::Int16le, default: 8
27
29
  # @!attribute dlt
28
30
  # @return [Integer] 32-bit PPI data link type
29
- define_field :dlt, Types::Int32le
31
+ define_attr :dlt, BinStruct::Int32le
30
32
  # @!attribute ppi_fields
31
33
  # @return [Type::String] concatenation of PPI fields
32
- define_field :ppi_fields, Types::String, builder: ->(h, t) { t.new(length_from: -> { h.length - 8 }) }
34
+ define_attr :ppi_fields, BinStruct::String, builder: ->(h, t) { t.new(length_from: -> { h.length - 8 }) }
33
35
  # @!attribute body
34
36
  # @return [Type::String]
35
- define_field :body, Types::String
36
- # @!attribute align
37
- # @return [Boolean] align flag from {#flags} attribute
38
- define_bit_fields_on :flags, :reserved, 7, :align
37
+ define_attr :body, BinStruct::String
39
38
 
40
39
  # Check version field
41
40
  # @see [Base#parse?]
@@ -65,22 +64,22 @@ module PacketGen
65
64
  class RadioTap < Base
66
65
  # @!attribute version
67
66
  # @return [Integer] 8-bit version
68
- define_field :version, Types::Int8, default: 0
67
+ define_attr :version, BinStruct::Int8, default: 0
69
68
  # @!attribute pad
70
69
  # @return [Integer] 8-bit pad
71
- define_field :pad, Types::Int8, default: 0
70
+ define_attr :pad, BinStruct::Int8, default: 0
72
71
  # @!attribute length
73
72
  # @return [Integer] 16-bit RadioTap header length
74
- define_field :length, Types::Int16le, default: 8
73
+ define_attr :length, BinStruct::Int16le, default: 8
75
74
  # @!attribute present_flags
76
75
  # @return [Integer] 32-bit integer
77
- define_field :present_flags, Types::Int32le
76
+ define_attr :present_flags, BinStruct::Int32le
78
77
  # @!attribute radio_fields
79
78
  # @return [Type::String] concatenation of RadioTap fields
80
- define_field :radio_fields, Types::String, builder: ->(h, t) { t.new(length_from: -> { h.length - 8 }) }
79
+ define_attr :radio_fields, BinStruct::String, builder: ->(h, t) { t.new(length_from: -> { h.length - 8 }) }
81
80
  # @!attribute body
82
81
  # @return [Type::String]
83
- define_field :body, Types::String
82
+ define_attr :body, BinStruct::String
84
83
 
85
84
  # Check version field
86
85
  # @see [Base#parse?]
@@ -104,58 +103,54 @@ module PacketGen
104
103
  end
105
104
  self.add_class RadioTap
106
105
 
107
- # IEEE 802.11 header
108
106
  # @abstract This is a base class to demultiplex different IEEE 802.11 frames when
109
107
  # parsing.
110
108
  # A IEEE 802.11 header may consist of at least:
111
- # * a {#frame_ctrl} ({Types::Int16}),
112
- # * a {#id}/duration ({Types::Int16le}),
109
+ # * a {#frame_ctrl} (+BinStruct::Int16+),
110
+ # * a {#id}/duration (+BinStruct::Int16le+),
113
111
  # * and a {#mac1} ({Eth::MacAddr}).
114
112
  # Depending on frame type and subtype, it may also contains:
115
113
  # * a {#mac2} ({Eth::MacAddr}),
116
114
  # * a {#mac3} ({Eth::MacAddr}),
117
- # * a {#sequence_ctrl} ({Types::Int16}),
115
+ # * a {#sequence_ctrl} (+BinStruct::Int16+),
118
116
  # * a {#mac4} ({Eth::MacAddr}),
119
- # * a {#qos_ctrl} ({Types::Int16}),
120
- # * a {#ht_ctrl} ({Types::Int32}),
121
- # * a {#body} (a {Types::String} or another {Base} class),
122
- # * a Frame check sequence ({#fcs}, of type {Types::Int32le})
117
+ # * a {#qos_ctrl} (+BinStruct::Int16+),
118
+ # * a {#ht_ctrl} (+BinStruct::Int32+),
119
+ # * a {#body} (a +BinStruct::String+ or another {Headerable} class),
120
+ # * a Frame check sequence ({#fcs}, of type +BinStruct::Int32le+)
123
121
  #
124
122
  # == Header accessors
125
123
  # As Dot11 header types are defined under Dot11 namespace, Dot11 header accessors
126
- # have a specific name. By example, to access to a {Dot11::Beacon} header,
124
+ # have a specific name. For example, to access to a {Dot11::Beacon} header,
127
125
  # accessor is +#dot11_beacon+.
128
126
  #
129
127
  # == Create Dot11 packets
130
128
  # As {Dot11} is an abstract class, you have to use one of its subclasses to
131
- # instanciate a IEEE802.11 header.
129
+ # instanciate a IEEE802.11 header (see examples below).
132
130
  #
133
- # === IEEE802.11 control frames
134
- # Control frames may be created this way:
131
+ # @example Create IEEE802.11 control frames
135
132
  # pkt = PacketGen.gen('Dot11::Control', subtype: 13) # Ack control frame
136
- # pkt.dot11_control # => PacketGen::Header::Dot11::Control
133
+ # pkt.dot11_control.class # => PacketGen::Header::Dot11::Control
137
134
  # # #dot11 is a shortcut for #dot11_control
138
- # pkt.dot11 # => PacketGen::Header::Dot11::Control
135
+ # pkt.dot11.class # => PacketGen::Header::Dot11::Control
139
136
  #
140
- # === IEEE802.11 management frames
141
- # Management frames may be created this way:
137
+ # @example Create IEEE802.11 management frames
142
138
  # pkt = PacketGen.gen('Dot11::Management')
143
- # pkt.dot11_management # => PacketGen::Header::Dot11::Management
139
+ # pkt.dot11_management.class # => PacketGen::Header::Dot11::Management
144
140
  # # #dot11 is a shortcut for #dot11_management
145
- # pkt.dot11 # => PacketGen::Header::Dot11::Management
146
- # Management frames are usually specialized, AssociationRequest by example:
141
+ # pkt.dot11.class # => PacketGen::Header::Dot11::Management
142
+ # # Management frames are usually specialized, AssociationRequest by example
147
143
  # pkt.add('Dot11::AssoReq')
148
- # pkt.dot11_assoreq # => PacketGen::Header::Dot11::AssoReq
149
- # Management frames also may contain some elements (see IEEE 802.11 standard):
150
- # pkt.dot11_assoreq.add_elements(type: 'SSID', value: "My SSID")
151
- # pkt.dot11_assoreq.add_elements(type: 'Rates', value: supported_rates)
144
+ # pkt.dot11_assoreq .class # => PacketGen::Header::Dot11::AssoReq
145
+ # # Management frames also may contain some elements (see IEEE 802.11 standard)
146
+ # pkt.dot11_assoreq.elements << { type: 'SSID', value: "My SSID" }
147
+ # pkt.dot11_assoreq.elements << { type: 'Rates', value: "\x8c\x12\x98\x24\xb0" }
152
148
  #
153
- # === IEEE802.11 data frames
154
- # Data frames may be created this way:
149
+ # @example Create IEEE802.11 data frames
155
150
  # pkt = PacketGen.gen('Dot11::Data')
156
- # pkt.dot11_data # => PacketGen::Header::Dot11::Data
151
+ # pkt.dot11_data.class # => PacketGen::Header::Dot11::Data
157
152
  # # #dot11 is a shortcut for #dot11_data
158
- # pkt.dot11 # => PacketGen::Header::Dot11::Data
153
+ # pkt.dot11.class # => PacketGen::Header::Dot11::Data
159
154
  #
160
155
  # == Parse Dot11 packets
161
156
  # When parsing a Dot11 packet, Dot11 subclass is created from +type+ value.
@@ -164,13 +159,12 @@ module PacketGen
164
159
  # for a control frame, +Packet#dot11_control+ may also be used.
165
160
  #
166
161
  # == Send Dot11 packets
167
- # To send a Dot11 packet, a RadioTap header is needed:
162
+ # To send a Dot11 packet, a RadioTap or PPI header is needed (depending on your hardware):
168
163
  # pkt = PacketGen.gen('RadioTap')
169
164
  # pkt.add('Dot11::Management', mac1: client, mac2: bssid, mac3: bssid)
170
165
  # pkt.add('Dot11::Beacon')
171
- # pkt.dot11_beacon.add_element(type: 'SSID', value: 'My SSID')
172
- # pkt.dot11_beacon.add_element(type: 'Rates', value: "\x85\x0c")
173
- # pkt.calc
166
+ # pkt.dot11_management.add_element(type: 'SSID', value: 'My SSID')
167
+ # pkt.dot11_management.add_element(type: 'Rates', value: "\x85\x0c")
174
168
  # pkt.to_w('wlan0')
175
169
  # @author Sylvain Daubert
176
170
  # @since 1.4.0
@@ -189,38 +183,6 @@ module PacketGen
189
183
 
190
184
  # @!attribute frame_ctrl
191
185
  # @return [Integer] 16-bit frame control word
192
- define_field :frame_ctrl, Types::Int16, default: 0
193
- # @!attribute id
194
- # @return [Integer] 16-bit ID/Duration word
195
- define_field :id, Types::Int16le, default: 0
196
- # @!attribute mac1
197
- # @return [Eth::MacAddr]
198
- define_field :mac1, Eth::MacAddr
199
- # @!attribute mac2
200
- # @return [Eth::MacAddr]
201
- define_field :mac2, Eth::MacAddr
202
- # @!attribute mac3
203
- # @return [Eth::MacAddr]
204
- define_field :mac3, Eth::MacAddr
205
- # @!attribute sequence_ctrl
206
- # @return [Integer] 16-bit sequence control word
207
- define_field :sequence_ctrl, Types::Int16le, default: 0
208
- # @!attribute mac4
209
- # @return [Eth::MacAddr]
210
- define_field :mac4, Eth::MacAddr
211
- # @!attribute qos_ctrl
212
- # @return [Integer] 16-bit QoS control word
213
- define_field :qos_ctrl, Types::Int16
214
- # @!attribute ht_ctrl
215
- # @return [Integer] 16-bit HT control word
216
- define_field :ht_ctrl, Types::Int32
217
- # @!attribute body
218
- # @return [Types::String]
219
- define_field :body, Types::String
220
- # @!attribute fcs
221
- # @return [Types::Int32le]
222
- define_field :fcs, Types::Int32le
223
-
224
186
  # @!attribute subtype
225
187
  # @return [Integer] 4-bit frame subtype from {#frame_ctrl}
226
188
  # @!attribute type
@@ -243,32 +205,64 @@ module PacketGen
243
205
  # @return [Boolean] from_ds flag from {#frame_ctrl}
244
206
  # @!attribute to_ds
245
207
  # @return [Boolean] to_ds flag from {#frame_ctrl}
246
- define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
247
- :order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds
248
-
249
- # @!attribute sequence_number (12-bit field from {#sequence_ctrl})
208
+ define_bit_attr :frame_ctrl, subtype: 4, type: 2, proto_version: 2, order: 1,
209
+ wep: 1, md: 1, pwmngt: 1, retry: 1, mf: 1, from_ds: 1, to_ds: 1
210
+ # @!attribute id
211
+ # @return [Integer] 16-bit ID/Duration word
212
+ define_attr :id, BinStruct::Int16le, default: 0
213
+ # @!attribute mac1
214
+ # @return [Eth::MacAddr]
215
+ define_attr :mac1, Eth::MacAddr
216
+ # @!attribute mac2
217
+ # @return [Eth::MacAddr]
218
+ define_attr :mac2, Eth::MacAddr
219
+ # @!attribute mac3
220
+ # @return [Eth::MacAddr]
221
+ define_attr :mac3, Eth::MacAddr
222
+ # @!attribute sequence_ctrl
223
+ # @return [Integer] 16-bit sequence control word
224
+ # @!attribute sequence_number
225
+ # 12-bit field from {#sequence_ctrl}
250
226
  # @return [Integer]
251
227
  # @since 2.1.3
252
- # @!attribute fragment_number (4-bit field from {#sequence_ctrl})
228
+ # @!attribute fragment_number
229
+ # 4-bit attribute from {#sequence_ctrl}
253
230
  # @return [Integer]
254
231
  # @since 2.1.3
255
- define_bit_fields_on :sequence_ctrl, :sequence_number, 12, :fragment_number, 4
232
+ define_bit_attr :sequence_ctrl, sequence_number: 12, fragment_number: 4
233
+ # @!attribute mac4
234
+ # @return [Eth::MacAddr]
235
+ define_attr :mac4, Eth::MacAddr
236
+ # @!attribute qos_ctrl
237
+ # @return [Integer] 16-bit QoS control word
238
+ define_attr :qos_ctrl, BinStruct::Int16
239
+ # @!attribute ht_ctrl
240
+ # @return [Integer] 16-bit HT control word
241
+ define_attr :ht_ctrl, BinStruct::Int32
242
+ # @!attribute body
243
+ # Dot11 body, if any
244
+ # @return [BinStruct::String]
245
+ define_attr :body, BinStruct::String
246
+ # @!attribute fcs
247
+ # Checksum of the Dot11 frame.
248
+ # @return [BinStruct::Int32le]
249
+ define_attr :fcs, BinStruct::Int32le
256
250
 
257
251
  alias duration id
258
252
  # @private
259
- alias old_fields fields
253
+ alias old_attributes attributes
260
254
 
261
255
  # @param [Hash] options
262
256
  # @see Base#initialize
263
257
  def initialize(options={})
264
258
  super
265
- @applicable_fields = old_fields
259
+ @applicable_attributes = old_attributes
266
260
  end
267
261
 
268
- # Get all used field names
262
+ # Get all used attribute names
269
263
  # @return [Array<Symbol>]
270
- def fields
271
- @applicable_fields
264
+ def attributes
265
+ @applicable_attributes
272
266
  end
273
267
 
274
268
  # @private
@@ -281,24 +275,24 @@ module PacketGen
281
275
  def read(str)
282
276
  fcs = Dot11.fcs?
283
277
 
284
- if self.instance_of? Dot11
278
+ if self.instance_of?(Dot11)
285
279
  return self if str.nil?
286
280
 
287
- force_binary str
288
- self[:frame_ctrl].read str[0, 2]
281
+ str = str.b unless str.encoding == Encoding::BINARY
282
+ self[:frame_ctrl].read(str[0, 2])
289
283
 
290
284
  case type
291
285
  when 0
292
- Dot11::Management.new.read str
286
+ Dot11::Management.new.read(str)
293
287
  when 1
294
- Dot11::Control.new.read str
288
+ Dot11::Control.new.read(str)
295
289
  when 2
296
- Dot11::Data.new.read str
290
+ Dot11::Data.new.read(str)
297
291
  else
298
- private_read str, fcs
292
+ private_read(str, fcs)
299
293
  end
300
294
  else
301
- private_read str, fcs
295
+ private_read(str, fcs)
302
296
  end
303
297
  end
304
298
 
@@ -310,10 +304,11 @@ module PacketGen
310
304
  fcs
311
305
  end
312
306
 
307
+ # Generate binary string
313
308
  # @return [String]
314
309
  def to_s
315
- define_applicable_fields
316
- @applicable_fields.map { |f| force_binary @fields[f].to_s }.join
310
+ define_applicable_attributes
311
+ @applicable_attributes.map { |f| @attributes[f].to_s.b }.join
317
312
  end
318
313
 
319
314
  # Get human readable type
@@ -324,19 +319,19 @@ module PacketGen
324
319
 
325
320
  # @return [String]
326
321
  def inspect
327
- str = if self.instance_of? Dot11
322
+ str = if self.instance_of?(Dot11)
328
323
  Inspect.dashed_line("#{self.class} #{human_type}", 1)
329
- elsif self.respond_to? :human_subtype
324
+ elsif self.respond_to?(:human_subtype)
330
325
  Inspect.dashed_line("#{self.class} #{human_subtype}", 1)
331
326
  else
332
327
  Inspect.dashed_line(self.class.to_s, 1)
333
328
  end
334
329
 
335
- define_applicable_fields
336
- @applicable_fields.each do |attr|
330
+ define_applicable_attributes
331
+ @applicable_attributes.each do |attr|
337
332
  next if attr == :body
338
333
 
339
- str << Inspect.inspect_attribute(attr, @fields[attr], 1)
334
+ str << Inspect.inspect_attribute(attr, @attributes[attr], 1)
340
335
  end
341
336
  str
342
337
  end
@@ -348,52 +343,52 @@ module PacketGen
348
343
  Inject.inject(iface: iface, data: self)
349
344
  end
350
345
 
351
- # Callback called when a Dot11 header is added to a packet
346
+ # Callback called when a Dot11 header is added to a packet.
352
347
  # Here, add +#dot11+ method as a shortcut to existing
353
348
  # +#dot11_(control|management|data)+.
354
349
  # @param [Packet] packet
355
350
  # @return [void]
356
351
  def added_to_packet(packet)
357
- return if packet.respond_to? :dot11
352
+ return if packet.respond_to?(:dot11)
358
353
 
359
354
  packet.instance_eval("def dot11(arg=nil); header(#{self.class}, arg); end") # def dot11(arg=nil); header(Dot11, arg); end
360
355
  end
361
356
 
362
357
  private
363
358
 
364
- def remove_from_applicable_fields(fields)
365
- fields = [fields] unless fields.is_a? Array
366
- @applicable_fields -= fields
359
+ def remove_from_applicable_attributes(attributes)
360
+ attributes = [attributes] unless attributes.is_a?(Array)
361
+ @applicable_attributes -= attributes
367
362
  end
368
363
 
369
364
  def handle_mac4
370
365
  if to_ds? && from_ds?
371
- @applicable_fields[6, 0] = :mac4 unless @applicable_fields.include? :mac4
366
+ @applicable_attributes[6, 0] = :mac4 unless @applicable_attributes.include?(:mac4)
372
367
  else
373
- remove_from_applicable_fields :mac4
368
+ remove_from_applicable_attributes(:mac4)
374
369
  end
375
370
  end
376
371
 
377
372
  def handle_ht_ctrl
378
373
  if order?
379
- unless @applicable_fields.include? :ht_ctrl
380
- idx = @applicable_fields.index(:body)
381
- @applicable_fields[idx, 0] = :ht_ctrl
374
+ unless @applicable_attributes.include?(:ht_ctrl)
375
+ idx = @applicable_attributes.index(:body)
376
+ @applicable_attributes[idx, 0] = :ht_ctrl
382
377
  end
383
378
  else
384
- remove_from_applicable_fields %i[ht_ctrl]
379
+ remove_from_applicable_attributes %i[ht_ctrl]
385
380
  end
386
381
  end
387
382
 
388
383
  def handle_fcs
389
384
  if Dot11.fcs?
390
- @applicable_fields << :fcs unless @applicable_fields.include? :fcs
385
+ @applicable_attributes << :fcs unless @applicable_attributes.include?(:fcs)
391
386
  else
392
- remove_from_applicable_fields :fcs
387
+ remove_from_applicable_attributes(:fcs)
393
388
  end
394
389
  end
395
390
 
396
- def define_applicable_fields
391
+ def define_applicable_attributes
397
392
  handle_mac4
398
393
  handle_ht_ctrl
399
394
  handle_fcs
@@ -401,12 +396,12 @@ module PacketGen
401
396
 
402
397
  def private_read(str, fcs)
403
398
  self[:frame_ctrl].read str[0, 2]
404
- define_applicable_fields
399
+ define_applicable_attributes
405
400
  if fcs
406
- old_read str[0...-4]
407
- self[:fcs].read str[-4..]
401
+ old_read(str[0...-4])
402
+ self[:fcs].read(str[-4..])
408
403
  else
409
- old_read str
404
+ old_read(str)
410
405
  end
411
406
  self
412
407
  end
@@ -11,33 +11,32 @@ module PacketGen
11
11
  # IEEE 802.1Q VLAN tagging
12
12
  #
13
13
  # A VLAN tag consists of:
14
- # * a {#tci Tag Control Information} ({Types::Int16}),
15
- # * a {#ethertype} ({Types::Int16}),
16
- # * and a body (a {Types::String} or another Header class).
14
+ # * a {#tci Tag Control Information} (+BinStruct::Int16+),
15
+ # * a {#ethertype} (+BinStruct::Int16+),
16
+ # * and a body (a +BinStruct::String+ or another {Headerable} class).
17
17
  #
18
- # == Create a Dot1q header
18
+ # @example Create a Dot1q header
19
19
  # # Create a IP packet in VLAN #43
20
20
  # pkt = PacketGen.gen('Eth').add('Dot1q', vid: 43).add('IP')
21
+ # pkt.is?('Dot1q') #=> true
21
22
  # @author Sylvain Daubert
22
23
  # @since 1.4.0
23
24
  class Dot1q < Base
24
25
  # @!attribute tci
25
26
  # @return [Integer] 16-bit Tag Control Information
26
- define_field :tci, Types::Int16
27
- # @!attribute ethertype
28
- # @return [Integer] 16-bit EtherType
29
- define_field :ethertype, Types::Int16
30
- # @!attribute body
31
- # @return [Types::String,Header::Base]
32
- define_field :body, Types::String
33
-
34
27
  # @!attribute pcp
35
28
  # @return [Integer] 3-bit Priority Code Point from {#tci}
36
29
  # @!attribute dei
37
30
  # @return [Boolean] Drop Eligible Indicator from {#tci}
38
31
  # @!attribute vid
39
32
  # @return [Integer] 12-bit VLAN ID from {#tci}
40
- define_bit_fields_on :tci, :pcp, 3, :dei, :vid, 12
33
+ define_bit_attr :tci, pcp: 3, dei: 1, vid: 12
34
+ # @!attribute ethertype
35
+ # @return [Integer] 16-bit EtherType
36
+ define_attr :ethertype, BinStruct::Int16
37
+ # @!attribute body
38
+ # @return [BinStruct::String,Header::Base]
39
+ define_attr :body, BinStruct::String
41
40
  end
42
41
 
43
42
  Eth.bind Dot1q, ethertype: 0x8100
@@ -11,15 +11,15 @@ module PacketGen
11
11
  # IEEE 802.1X / EAPOL
12
12
  #
13
13
  # A IEEE 802.1X header consists of:
14
- # * a {#version} ({Types::Int8}),
15
- # * a packet {#type} ({Types::Int8}),
16
- # * a {#length} ({Types::Int16}),
17
- # * and a body (a {Types::String} or another Header class).
18
- # == Create a Dot1x header
14
+ # * a {#version} (+BinStruct::Int8+),
15
+ # * a packet {#type} (+BinStruct::Int8+),
16
+ # * a {#length} (+BinStruct::Int16+),
17
+ # * and a body (a +BinStruct::String+ or another {Headerable} class).
18
+ # @example Create a Dot1x header
19
+ # # Create with integer type
19
20
  # pkt1 = PacketGen.gen('Eth').add('Dot1x', type: 1)
20
- # pkt2 = PacketGen.gen('Eth').add('Dot1x')
21
- # pkt2.dot1x.type = 'EAP Packet'
22
- # pkt2.dot1x.body.read 'body'
21
+ # # Create with human-readable type
22
+ # pkt2 = PacketGen.gen('Eth').add('Dot1x', type: 'EAP Packet')
23
23
  # @author Sylvain Daubert
24
24
  # @since 1.4.0
25
25
  class Dot1x < Base
@@ -37,16 +37,16 @@ module PacketGen
37
37
 
38
38
  # @!attribute version
39
39
  # @return [Integer] 8-bit Protocol Version
40
- define_field :version, Types::Int8, default: 1
40
+ define_attr :version, BinStruct::Int8, default: 1
41
41
  # @!attribute type
42
42
  # @return [Integer] 8-bit Packet Type
43
- define_field :type, Types::Int8Enum, enum: TYPES
43
+ define_attr :type, BinStruct::Int8Enum, enum: TYPES
44
44
  # @!attribute length
45
45
  # @return [Integer] 16-bit body length
46
- define_field :length, Types::Int16
46
+ define_attr :length, BinStruct::Int16
47
47
  # @!attribute body
48
- # @return [Types::String,Header::Base]
49
- define_field :body, Types::String, builder: ->(h, t) { t.new(length_from: h[:length]) }
48
+ # @return [BinStruct::String,Header::Base]
49
+ define_attr :body, BinStruct::String, builder: ->(h, t) { t.new(length_from: h[:length]) }
50
50
 
51
51
  # Get human readable type
52
52
  # @return [String]
@@ -13,13 +13,13 @@ module PacketGen
13
13
  # Secure Tunneling, {https://tools.ietf.org/html/rfc4851 RFC 4851}
14
14
  #
15
15
  # {EAP::FAST} has following fields:
16
- # * {#flags} ({Types::Int8}),
17
- # * optionally {#message_length} ({Types::Int32}), if +#l?+ is +true+,
18
- # * {#body} ({Types::String}).
16
+ # * {#flags} (+BinStruct::Int8+),
17
+ # * optionally {#message_length} (+BinStruct::Int32+), if +#l?+ is +true+,
18
+ # * {#body} (+BinStruct::String+).
19
19
  # @author Sylvain Daubert
20
20
  # @since 2.1.4
21
21
  class FAST < TTLS
22
- update_field :type, default: 43
22
+ update_attr :type, default: 43
23
23
  end
24
24
  end
25
25
  end
@@ -14,19 +14,27 @@ module PacketGen
14
14
  # @author Sylvain Daubert
15
15
  # @since 2.1.4
16
16
  class MD5 < EAP
17
- update_field :type, default: 4
18
- remove_field :body
17
+ update_attr :type, default: 4
18
+ remove_attr :body
19
19
 
20
20
  # @!attribute value_size
21
- # @return [Integer] 8-bit value size
22
- define_field :value_size, Types::Int8
21
+ # 8-bit size of the {#value} attribute.
22
+ # @return [Integer]
23
+ define_attr :value_size, BinStruct::Int8
23
24
  # @!attribute value
25
+ # MD5 challenge value, as an octet stream, as per {https://datatracker.ietf.org/doc/html/rfc1994#section-4 RFC1994}
24
26
  # @return [::String]
25
- define_field :value, Types::String,
26
- builder: ->(h, t) { t.new(length_from: h[:value_size]) }
27
- # @!attribute optional_name
27
+ define_attr :value, BinStruct::String,
28
+ builder: ->(h, t) { t.new(length_from: h[:value_size]) }
29
+ # @!attribute name
30
+ # Name identifying the system sending the packet. It is or or more octets. Its size is
31
+ # determined from the {#length} attribute.
28
32
  # @return [::String]
29
- define_field :optional_name, Types::String
33
+ # @since 4.1.0 Attribute renamed from +optioanl_name+ to +name+
34
+ define_attr :name, BinStruct::String
35
+
36
+ # @deprecated
37
+ alias optional_name name
30
38
  end
31
39
  end
32
40
  end
@@ -13,27 +13,26 @@ module PacketGen
13
13
  # {https://tools.ietf.org/html/rfc5216 RFC 5216}
14
14
  #
15
15
  # {EAP::TLS} has following fields:
16
- # * {#flags} ({Types::Int8}),
17
- # * optionally {#tls_length} ({Types::Int32}), if +#l?+ is +true+,
18
- # * {#body} ({Types::String}).
16
+ # * {#flags} (+BinStruct::Int8+),
17
+ # * optionally {#tls_length} (+BinStruct::Int32+), if +#l?+ is +true+,
18
+ # * {#body} (+BinStruct::String+).
19
19
  # @author Sylvain Daubert
20
20
  # @since 2.1.4
21
21
  class TLS < EAP
22
- update_field :type, default: 13
22
+ update_attr :type, default: 13
23
23
  # @!attribute flags
24
- # @return [Integer] 8-bit flags
25
- define_field_before :body, :flags, Types::Int8
26
-
27
- # @!attribute l
28
- # Say if length field is included. Defined on {#flags} field.
29
- # @return [Boolean]
30
- # @!attribute m
31
- # Say if there are more fragments. Defined on {#flags} field.
32
- # @return [Boolean]
33
- # @!attribute s
34
- # If set, this message is a TLS-Start. Defined on {#flags} field.
35
- # @return [Boolean]
36
- define_bit_fields_on :flags, :l, :m, :s, :reserved, 5
24
+ # 8-bit flags
25
+ # @return [Integer]
26
+ # @!attribute l?
27
+ # Say if {#tls_length 32-bit TLS length attribute} is included.
28
+ # @return [Integer]
29
+ # @!attribute m?
30
+ # Say if there are more fragments
31
+ # @return [Integer]
32
+ # @!attribute s?
33
+ # If set, this message is a TLS-Start
34
+ # @return [Integer]
35
+ define_bit_attr_before :body, :flags, l: 1, m: 1, s: 1, reserved: 5
37
36
  alias length_present? l?
38
37
  alias more_fragments? m?
39
38
  alias tls_start? s?
@@ -43,8 +42,8 @@ module PacketGen
43
42
  # TLS message or set of messages that is being fragmented. So, it
44
43
  # cannot be automatically calculated (no +#calc_length+ method).
45
44
  # @return [Integer] 32-bit TLS length
46
- define_field_before :body, :tls_length, Types::Int32,
47
- optional: ->(h) { h.l? }
45
+ define_attr_before :body, :tls_length, BinStruct::Int32,
46
+ optional: lambda(&:l?)
48
47
 
49
48
  # @return [String]
50
49
  def inspect