packetgen 2.6.0 → 2.7.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 (134) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +28 -0
  4. data/Rakefile +6 -6
  5. data/bin/pgconsole +6 -6
  6. data/lib/packetgen.rb +4 -3
  7. data/lib/packetgen/capture.rb +5 -7
  8. data/lib/packetgen/config.rb +3 -3
  9. data/lib/packetgen/deprecation.rb +17 -0
  10. data/lib/packetgen/header.rb +40 -38
  11. data/lib/packetgen/header/arp.rb +46 -31
  12. data/lib/packetgen/header/asn1_base.rb +8 -8
  13. data/lib/packetgen/header/base.rb +108 -36
  14. data/lib/packetgen/header/bootp.rb +28 -19
  15. data/lib/packetgen/header/crypto.rb +6 -8
  16. data/lib/packetgen/header/dhcp.rb +4 -5
  17. data/lib/packetgen/header/dhcp/option.rb +46 -34
  18. data/lib/packetgen/header/dhcp/options.rb +0 -1
  19. data/lib/packetgen/header/dhcpv6.rb +10 -10
  20. data/lib/packetgen/header/dhcpv6/duid.rb +2 -3
  21. data/lib/packetgen/header/dhcpv6/option.rb +16 -21
  22. data/lib/packetgen/header/dhcpv6/relay.rb +6 -4
  23. data/lib/packetgen/header/dns.rb +13 -11
  24. data/lib/packetgen/header/dns/name.rb +4 -6
  25. data/lib/packetgen/header/dns/opt.rb +31 -31
  26. data/lib/packetgen/header/dns/option.rb +0 -2
  27. data/lib/packetgen/header/dns/qdsection.rb +1 -2
  28. data/lib/packetgen/header/dns/question.rb +19 -13
  29. data/lib/packetgen/header/dns/rr.rb +11 -14
  30. data/lib/packetgen/header/dns/rrsection.rb +5 -7
  31. data/lib/packetgen/header/dot11.rb +45 -29
  32. data/lib/packetgen/header/dot11/control.rb +3 -5
  33. data/lib/packetgen/header/dot11/data.rb +34 -6
  34. data/lib/packetgen/header/dot11/element.rb +0 -1
  35. data/lib/packetgen/header/dot11/management.rb +9 -5
  36. data/lib/packetgen/header/dot11/sub_mngt.rb +13 -14
  37. data/lib/packetgen/header/dot1q.rb +2 -2
  38. data/lib/packetgen/header/dot1x.rb +3 -4
  39. data/lib/packetgen/header/eap.rb +62 -53
  40. data/lib/packetgen/header/eap/fast.rb +0 -1
  41. data/lib/packetgen/header/eap/md5.rb +1 -2
  42. data/lib/packetgen/header/eap/tls.rb +9 -10
  43. data/lib/packetgen/header/eap/ttls.rb +9 -10
  44. data/lib/packetgen/header/esp.rb +33 -33
  45. data/lib/packetgen/header/eth.rb +11 -8
  46. data/lib/packetgen/header/gre.rb +5 -6
  47. data/lib/packetgen/header/http/headers.rb +11 -14
  48. data/lib/packetgen/header/http/request.rb +20 -20
  49. data/lib/packetgen/header/http/response.rb +16 -18
  50. data/lib/packetgen/header/http/verbs.rb +5 -5
  51. data/lib/packetgen/header/icmp.rb +1 -3
  52. data/lib/packetgen/header/icmpv6.rb +1 -3
  53. data/lib/packetgen/header/igmp.rb +5 -6
  54. data/lib/packetgen/header/igmpv3.rb +5 -9
  55. data/lib/packetgen/header/igmpv3/group_record.rb +4 -5
  56. data/lib/packetgen/header/igmpv3/mq.rb +2 -2
  57. data/lib/packetgen/header/igmpv3/mr.rb +4 -3
  58. data/lib/packetgen/header/ike.rb +33 -8
  59. data/lib/packetgen/header/ike/auth.rb +4 -6
  60. data/lib/packetgen/header/ike/cert.rb +0 -2
  61. data/lib/packetgen/header/ike/certreq.rb +1 -3
  62. data/lib/packetgen/header/ike/id.rb +1 -3
  63. data/lib/packetgen/header/ike/ke.rb +0 -2
  64. data/lib/packetgen/header/ike/nonce.rb +0 -2
  65. data/lib/packetgen/header/ike/notify.rb +22 -24
  66. data/lib/packetgen/header/ike/payload.rb +198 -199
  67. data/lib/packetgen/header/ike/sa.rb +21 -30
  68. data/lib/packetgen/header/ike/sk.rb +16 -17
  69. data/lib/packetgen/header/ike/ts.rb +22 -24
  70. data/lib/packetgen/header/ike/vendor_id.rb +0 -2
  71. data/lib/packetgen/header/ip.rb +30 -23
  72. data/lib/packetgen/header/ip/addr.rb +5 -6
  73. data/lib/packetgen/header/ip/option.rb +11 -15
  74. data/lib/packetgen/header/ip/options.rb +1 -2
  75. data/lib/packetgen/header/ipv6.rb +27 -12
  76. data/lib/packetgen/header/ipv6/addr.rb +2 -2
  77. data/lib/packetgen/header/ipv6/extension.rb +1 -1
  78. data/lib/packetgen/header/ipv6/hop_by_hop.rb +11 -11
  79. data/lib/packetgen/header/llc.rb +4 -3
  80. data/lib/packetgen/header/mdns.rb +11 -5
  81. data/lib/packetgen/header/mld.rb +4 -4
  82. data/lib/packetgen/header/mldv2.rb +4 -3
  83. data/lib/packetgen/header/mldv2/mcast_address_record.rb +3 -4
  84. data/lib/packetgen/header/mldv2/mlq.rb +3 -4
  85. data/lib/packetgen/header/mldv2/mlr.rb +4 -3
  86. data/lib/packetgen/header/netbios.rb +18 -5
  87. data/lib/packetgen/header/ospfv2.rb +6 -7
  88. data/lib/packetgen/header/ospfv2/db_description.rb +3 -4
  89. data/lib/packetgen/header/ospfv2/hello.rb +2 -3
  90. data/lib/packetgen/header/ospfv2/ls_ack.rb +2 -3
  91. data/lib/packetgen/header/ospfv2/ls_request.rb +2 -3
  92. data/lib/packetgen/header/ospfv2/ls_update.rb +5 -6
  93. data/lib/packetgen/header/ospfv2/lsa.rb +13 -14
  94. data/lib/packetgen/header/ospfv2/lsa_header.rb +4 -5
  95. data/lib/packetgen/header/ospfv3.rb +3 -4
  96. data/lib/packetgen/header/ospfv3/db_description.rb +3 -5
  97. data/lib/packetgen/header/ospfv3/hello.rb +2 -3
  98. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +7 -8
  99. data/lib/packetgen/header/ospfv3/ls_ack.rb +2 -3
  100. data/lib/packetgen/header/ospfv3/ls_request.rb +2 -3
  101. data/lib/packetgen/header/ospfv3/ls_update.rb +5 -6
  102. data/lib/packetgen/header/ospfv3/lsa.rb +10 -11
  103. data/lib/packetgen/header/ospfv3/lsa_header.rb +3 -4
  104. data/lib/packetgen/header/snmp.rb +45 -32
  105. data/lib/packetgen/header/tcp.rb +13 -9
  106. data/lib/packetgen/header/tcp/option.rb +16 -11
  107. data/lib/packetgen/header/tcp/options.rb +3 -4
  108. data/lib/packetgen/header/tftp.rb +15 -17
  109. data/lib/packetgen/header/udp.rb +10 -4
  110. data/lib/packetgen/inspect.rb +7 -9
  111. data/lib/packetgen/packet.rb +44 -22
  112. data/lib/packetgen/pcapng.rb +1 -5
  113. data/lib/packetgen/pcapng/block.rb +17 -11
  114. data/lib/packetgen/pcapng/epb.rb +6 -11
  115. data/lib/packetgen/pcapng/file.rb +37 -44
  116. data/lib/packetgen/pcapng/idb.rb +17 -22
  117. data/lib/packetgen/pcapng/shb.rb +7 -10
  118. data/lib/packetgen/pcapng/spb.rb +21 -17
  119. data/lib/packetgen/pcapng/unknown_block.rb +17 -13
  120. data/lib/packetgen/proto.rb +1 -2
  121. data/lib/packetgen/types/array.rb +119 -34
  122. data/lib/packetgen/types/cstring.rb +1 -5
  123. data/lib/packetgen/types/enum.rb +8 -10
  124. data/lib/packetgen/types/fields.rb +34 -28
  125. data/lib/packetgen/types/int.rb +11 -13
  126. data/lib/packetgen/types/int_string.rb +6 -8
  127. data/lib/packetgen/types/oui.rb +3 -6
  128. data/lib/packetgen/types/string.rb +4 -6
  129. data/lib/packetgen/types/tlv.rb +11 -14
  130. data/lib/packetgen/utils.rb +15 -23
  131. data/lib/packetgen/utils/arp_spoofer.rb +12 -18
  132. data/lib/packetgen/version.rb +1 -1
  133. data/packetgen.gemspec +9 -8
  134. metadata +19 -17
@@ -9,7 +9,6 @@
9
9
  module PacketGen
10
10
  module Header
11
11
  class IKE
12
-
13
12
  # Transform attribute.
14
13
  # 1 2 3
15
14
  # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -24,7 +23,6 @@ module PacketGen
24
23
  # or a TV format (AF=1).
25
24
  # @author Sylvain Daubert
26
25
  class Attribute < Types::Fields
27
-
28
26
  TYPE_KEY_LENGTH = 14
29
27
 
30
28
  # @!attribute type
@@ -82,8 +80,8 @@ module PacketGen
82
80
  # Get a human readable string
83
81
  # @return [String]
84
82
  def to_human
85
- name = self.class.constants.grep(/TYPE_/).
86
- detect { |c| self.class.const_get(c) == (type & 0x7fff) } || "attr[#{type & 0x7fff}]"
83
+ name = self.class.constants.grep(/TYPE_/)
84
+ .detect { |c| self.class.const_get(c) == (type & 0x7fff) } || "attr[#{type & 0x7fff}]"
87
85
  name = name.to_s.sub(/TYPE_/, '')
88
86
  "#{name}=#{value}"
89
87
  end
@@ -127,7 +125,6 @@ module PacketGen
127
125
  # trans.attributes << { type: 14, value: 128 }
128
126
  # @author Sylvain Daubert
129
127
  class Transform < Types::Fields
130
-
131
128
  TYPES = {
132
129
  'ENCR' => 1,
133
130
  'PRF' => 2,
@@ -281,14 +278,14 @@ module PacketGen
281
278
  # @return [String]
282
279
  def to_human
283
280
  h = "#{human_type}(#{human_id}".dup
284
- h << ",#{attributes.to_human}" if attributes.size > 0
281
+ h << ",#{attributes.to_human}" unless attributes.empty?
285
282
  h << ')'
286
283
  end
287
284
 
288
285
  # Get human-readable type
289
286
  # @return [String]
290
287
  def human_type
291
- if self[:type].enum.has_value? self.type
288
+ if self[:type].enum.value? self.type
292
289
  self[:type].to_human
293
290
  else
294
291
  "type[#{self.type}]"
@@ -298,9 +295,9 @@ module PacketGen
298
295
  # Get human-readable ID
299
296
  # @return [String]
300
297
  def human_id
301
- name = self.class.constants.grep(/#{human_type}_/).
302
- detect { |c| self.class.const_get(c) == id } || "ID=#{id}"
303
- name.to_s.sub(/#{human_type}_/, '')
298
+ name = self.class.constants.grep(/#{human_type}_/)
299
+ .detect { |c| self.class.const_get(c) == id } || "ID=#{id}"
300
+ name.to_s.sub(/#{human_type}_/, '')
304
301
  end
305
302
 
306
303
  # Say if this transform is the last one (from {#last} field)
@@ -311,8 +308,6 @@ module PacketGen
311
308
  true
312
309
  when 3
313
310
  false
314
- else
315
- nil
316
311
  end
317
312
  end
318
313
  end
@@ -360,7 +355,6 @@ module PacketGen
360
355
  # proposal.transforms << { type: 'ENCR', id: '3DES' }
361
356
  # @author Sylvain Daubert
362
357
  class SAProposal < Types::Fields
363
-
364
358
  # @!attribute last
365
359
  # 8-bit last substructure. Specifies whether or not this is the
366
360
  # last Proposal Substructure in the SA. This field has a value of 0
@@ -410,7 +404,7 @@ module PacketGen
410
404
  define_field :transforms, Transforms, builder: ->(h, t) { t.new(counter: h[:num_trans]) }
411
405
 
412
406
  def initialize(options={})
413
- if options[:spi] and options[:spi_size].nil?
407
+ if options[:spi] && options[:spi_size].nil?
414
408
  options[:spi_size] = options[:spi].size
415
409
  end
416
410
  super
@@ -423,12 +417,12 @@ module PacketGen
423
417
  # @return [Integer]
424
418
  def protocol=(value)
425
419
  proto = case value
426
- when Integer
427
- value
428
- else
429
- c = IKE.constants.grep(/PROTO_#{value}/).first
430
- c ? IKE.const_get(c) : nil
431
- end
420
+ when Integer
421
+ value
422
+ else
423
+ c = IKE.constants.grep(/PROTO_#{value}/).first
424
+ c ? IKE.const_get(c) : nil
425
+ end
432
426
  raise ArgumentError, "unknown protocol #{value.inspect}" unless proto
433
427
  self[:protocol].value = proto
434
428
  end
@@ -447,7 +441,7 @@ module PacketGen
447
441
  # Compute length and set {#length} field
448
442
  # @return [Integer] new length
449
443
  def calc_length
450
- transforms.each { |t| t.calc_length }
444
+ transforms.each(&:calc_length)
451
445
  Base.calculate_and_set_length self
452
446
  end
453
447
 
@@ -457,9 +451,9 @@ module PacketGen
457
451
  str = "##{num} #{human_protocol}".dup
458
452
  case spi_size
459
453
  when 4
460
- str << "(spi:0x%08x)" % Types::Int32.new.read(spi).to_i
454
+ str << '(spi:0x%08x)' % Types::Int32.new.read(spi).to_i
461
455
  when 8
462
- str << "(spi:0x%016x)" % Types::Int64.new.read(spi).to_i
456
+ str << '(spi:0x%016x)' % Types::Int64.new.read(spi).to_i
463
457
  end
464
458
  str << ":#{transforms.to_human}"
465
459
  end
@@ -467,8 +461,8 @@ module PacketGen
467
461
  # Get protocol name
468
462
  # @return [String]
469
463
  def human_protocol
470
- name = IKE.constants.grep(/PROTO/).
471
- detect { |c| IKE.const_get(c) == protocol } || "proto #{protocol}"
464
+ name = IKE.constants.grep(/PROTO/)
465
+ .detect { |c| IKE.const_get(c) == protocol } || "proto #{protocol}"
472
466
  name.to_s.sub(/PROTO_/, '')
473
467
  end
474
468
 
@@ -481,8 +475,6 @@ module PacketGen
481
475
  true
482
476
  when 2
483
477
  false
484
- else
485
- nil
486
478
  end
487
479
  end
488
480
  end
@@ -533,7 +525,6 @@ module PacketGen
533
525
  # pkt.calc_length
534
526
  # @author Sylvain Daubert
535
527
  class SA < Payload
536
-
537
528
  # Payload type number
538
529
  PAYLOAD_TYPE = 33
539
530
 
@@ -553,14 +544,14 @@ module PacketGen
553
544
  hlen = self.class.new.sz
554
545
  plen = length - hlen
555
546
  proposals.read str[hlen, plen]
556
- body.read str[hlen+plen..-1]
547
+ body.read str[hlen + plen..-1]
557
548
  self
558
549
  end
559
550
 
560
551
  # Compute length and set {#length} field
561
552
  # @return [Integer] new length
562
553
  def calc_length
563
- proposals.each { |p| p.calc_length }
554
+ proposals.each(&:calc_length)
564
555
  super
565
556
  end
566
557
  end
@@ -9,7 +9,6 @@
9
9
  module PacketGen
10
10
  module Header
11
11
  class IKE
12
-
13
12
  # This class handles encrypted payloads, denoted SK.
14
13
  #
15
14
  # The encrypted payload contains other payloads in encrypted form.
@@ -114,15 +113,15 @@ module PacketGen
114
113
  cipher.iv = real_iv
115
114
 
116
115
  if authenticated?
117
- if @icv_length == 0
116
+ if @icv_length.zero?
118
117
  @icv_length = opt[:icv_length].to_i if opt[:icv_length]
119
- raise ParseError, 'unknown ICV size' if @icv_length == 0
118
+ raise ParseError, 'unknown ICV size' if @icv_length.zero?
120
119
  end
121
120
  icv = self.content.slice!(-@icv_length, @icv_length)
122
121
  end
123
122
 
124
- authenticate_if_needed opt, iv, icv
125
- private_decrypt cipher, opt
123
+ authenticate_if_needed iv, icv
124
+ private_decrypt opt
126
125
  end
127
126
 
128
127
  # Encrypt in-place SK payload.
@@ -151,14 +150,14 @@ module PacketGen
151
150
  real_iv += [1].pack('N') if confidentiality_mode == 'ctr'
152
151
  cipher.iv = real_iv
153
152
 
154
- authenticate_if_needed options, iv
153
+ authenticate_if_needed iv
155
154
 
156
155
  if opt[:pad_length]
157
156
  pad_length = opt[:pad_length]
158
157
  padding = force_binary(opt[:padding] || ([0] * pad_length).pack('C*'))
159
158
  else
160
159
  pad_length = cipher.block_size
161
- pad_length = 16 if cipher.block_size == 1 # Some AES mode returns 1...
160
+ pad_length = 16 if cipher.block_size == 1 # Some AES mode returns 1...
162
161
  pad_length -= (self.body.sz + iv.size + 1) % cipher.block_size
163
162
  pad_length = 0 if pad_length == 16
164
163
  padding = force_binary(opt[:padding] || ([0] * pad_length).pack('C*'))
@@ -170,13 +169,13 @@ module PacketGen
170
169
 
171
170
  if authenticated?
172
171
  @icv_length = opt[:icv_length] if opt[:icv_length]
173
- if @conf.authenticated?
174
- encrypted_msg << @conf.auth_tag[0, @icv_length]
175
- else
176
- encrypted_msg << @intg.digest[0, @icv_length]
177
- end
172
+ encrypted_msg << if @conf.authenticated?
173
+ @conf.auth_tag[0, @icv_length]
174
+ else
175
+ @intg.digest[0, @icv_length]
176
+ end
178
177
  end
179
- self[:content].read (iv + encrypted_msg)
178
+ self[:content].read(iv + encrypted_msg)
180
179
 
181
180
  # Remove plain payloads
182
181
  self[:body] = Types::String.new
@@ -184,7 +183,7 @@ module PacketGen
184
183
  # Remove enciphered payloads from packet
185
184
  id = header_id(self)
186
185
  if id < packet.headers.size - 1
187
- (packet.headers.size-1).downto(id+1) do |index|
186
+ (packet.headers.size - 1).downto(id + 1) do |index|
188
187
  packet.headers.delete_at index
189
188
  end
190
189
  end
@@ -195,7 +194,7 @@ module PacketGen
195
194
 
196
195
  private
197
196
 
198
- def authenticate_if_needed(options, iv, icv=nil)
197
+ def authenticate_if_needed(iv, icv=nil)
199
198
  if @conf.authenticated?
200
199
  @conf.auth_tag = icv if icv
201
200
  @conf.auth_data = get_ad
@@ -216,14 +215,14 @@ module PacketGen
216
215
  def get_ad
217
216
  str = packet.ike.to_s[0, IKE.new.sz]
218
217
  current_payload = packet.ike.body
219
- until current_payload.is_a? SK do
218
+ until current_payload.is_a? SK
220
219
  str << current_payload.to_s[0, current_payload.length]
221
220
  current_payload = current_payload.body
222
221
  end
223
222
  str << self.to_s[0, SK.new.sz]
224
223
  end
225
224
 
226
- def private_decrypt(cipher, options)
225
+ def private_decrypt(options)
227
226
  # decrypt
228
227
  plain_msg = decipher(content.to_s)
229
228
  # Remove cipher text
@@ -9,7 +9,6 @@
9
9
  module PacketGen
10
10
  module Header
11
11
  class IKE
12
-
13
12
  # TrafficSelector substructure, as defined in RFC 7296, §3.13.1:
14
13
  # 1 2 3
15
14
  # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -52,7 +51,7 @@ module PacketGen
52
51
  # @!attribute end_port
53
52
  # 16-bit End port
54
53
  # @return [Integer]
55
- define_field :end_port, Types::Int16, default: 65535
54
+ define_field :end_port, Types::Int16, default: 65_535
56
55
  # @!attribute start_addr
57
56
  # starting address
58
57
  # @return [IP::Addr, IPv6::Addr]
@@ -74,10 +73,10 @@ module PacketGen
74
73
  self[:length].value = sz unless options[:length]
75
74
  self.type = options[:type] if options[:type]
76
75
  self.protocol = options[:protocol] if options[:protocol]
77
- if options[:ports]
78
- self.start_port = options[:ports].begin
79
- self.end_port = options[:ports].end
80
- end
76
+
77
+ return unless options[:ports]
78
+ self.start_port = options[:ports].begin
79
+ self.end_port = options[:ports].end
81
80
  end
82
81
 
83
82
  # Populate object from a string
@@ -94,12 +93,12 @@ module PacketGen
94
93
  # @return [Integer]
95
94
  def type=(value)
96
95
  type = case value
97
- when Integer
98
- value
99
- else
100
- c = self.class.constants.grep(/TS_#{value.upcase}/).first
101
- c ? self.class.const_get(c) : nil
102
- end
96
+ when Integer
97
+ value
98
+ else
99
+ c = self.class.constants.grep(/TS_#{value.upcase}/).first
100
+ c ? self.class.const_get(c) : nil
101
+ end
103
102
  raise ArgumentError, "unknown type #{value.inspect}" unless type
104
103
  select_addr_from_type type
105
104
  self[:type].value = type
@@ -110,11 +109,11 @@ module PacketGen
110
109
  # @return [Integer]
111
110
  def protocol=(value)
112
111
  protocol = case value
113
- when Integer
114
- value
115
- else
116
- Proto.getprotobyname(value)
117
- end
112
+ when Integer
113
+ value
114
+ else
115
+ Proto.getprotobyname(value)
116
+ end
118
117
  raise ArgumentError, "unknown protocol #{value.inspect}" unless protocol
119
118
  self[:protocol].value = protocol
120
119
  end
@@ -125,7 +124,7 @@ module PacketGen
125
124
  h = start_addr << '-' << end_addr
126
125
  unless human_protocol.empty?
127
126
  h << "/#{human_protocol}"
128
- h << "[#{start_port}-#{end_port}]" if (start_port..end_port) != (0..65535)
127
+ h << "[#{start_port}-#{end_port}]" if (start_port..end_port) != (0..65_535)
129
128
  end
130
129
  h
131
130
  end
@@ -134,10 +133,10 @@ module PacketGen
134
133
  # is returned.
135
134
  # @return [String]
136
135
  def human_protocol
137
- if protocol == 0
136
+ if protocol.zero?
138
137
  ''
139
138
  else
140
- Proto.getprotobynumber(protocol) || "#{protocol}"
139
+ Proto.getprotobynumber(protocol) || protocol.to_s
141
140
  end
142
141
  end
143
142
 
@@ -218,7 +217,6 @@ module PacketGen
218
217
  # pkt.ike_tsi.traffic_selectors << { start_addr: '2001::1', end_addr: '200a:ffff:ffff:ffff:ffff:ffff:ffff:ffff' }
219
218
  # @author Sylvain Daubert
220
219
  class TSi < Payload
221
-
222
220
  # Payload type number
223
221
  PAYLOAD_TYPE = 44
224
222
 
@@ -239,7 +237,7 @@ module PacketGen
239
237
  # @return {TrafficSelectors}
240
238
  define_field_before :body, :traffic_selectors, TrafficSelectors,
241
239
  builder: ->(h, t) { t.new(counter: h[:num_ts]) }
242
- alias :selectors :traffic_selectors
240
+ alias selectors traffic_selectors
243
241
 
244
242
  # Populate object from a string
245
243
  # @param [String] str
@@ -249,14 +247,14 @@ module PacketGen
249
247
  hlen = self.class.new.sz
250
248
  tslen = length - hlen
251
249
  selectors.read str[hlen, tslen]
252
- body.read str[hlen+tslen..-1]
250
+ body.read str[hlen + tslen..-1]
253
251
  self
254
252
  end
255
253
 
256
254
  # Compute length and set {#length} field
257
255
  # @return [Integer] new length
258
256
  def calc_length
259
- selectors.each { |p| p.calc_length }
257
+ selectors.each(&:calc_length)
260
258
  super
261
259
  end
262
260
  end
@@ -9,7 +9,6 @@
9
9
  module PacketGen
10
10
  module Header
11
11
  class IKE
12
-
13
12
  # This class handles Vendor ID payloads, as defined in RFC 7296 §3.12.
14
13
  #
15
14
  # A Vendor ID payload contains a generic payload header (see {Payload})
@@ -30,7 +29,6 @@ module PacketGen
30
29
  # pkt.add('IKE::VendorID', data: "abcdefgh")
31
30
  # @author Sylvain Daubert
32
31
  class VendorID < Payload
33
-
34
32
  # Payload type number
35
33
  PAYLOAD_TYPE = 43
36
34
  end
@@ -4,11 +4,11 @@
4
4
  # This program is published under MIT license.
5
5
 
6
6
  # frozen_string_literal: true
7
+
7
8
  require 'socket'
8
9
 
9
10
  module PacketGen
10
11
  module Header
11
-
12
12
  # A IP header consists of:
13
13
  # * a first byte ({#u8} of {Types::Int8} type) composed of:
14
14
  # * a 4-bit {#version} field,
@@ -62,14 +62,13 @@ module PacketGen
62
62
  # ip.dst = '127.0.0.2'
63
63
  # ip.body.read 'this is a body'
64
64
  # @author Sylvain Daubert
65
- class IP < Base;end
65
+ class IP < Base; end
66
66
 
67
- require_relative 'ip/addr'
68
- require_relative 'ip/option'
69
- require_relative 'ip/options'
67
+ require_relative 'ip/addr'
68
+ require_relative 'ip/option'
69
+ require_relative 'ip/options'
70
70
 
71
71
  class IP
72
-
73
72
  # IP Ether type
74
73
  ETHERTYPE = 0x0800
75
74
 
@@ -85,7 +84,7 @@ require_relative 'ip/options'
85
84
  define_field :length, Types::Int16, default: 20
86
85
  # @!attribute id
87
86
  # @return [Integer] 16-bit ID
88
- define_field :id, Types::Int16, default: -> { rand(65535) }
87
+ define_field :id, Types::Int16, default: -> { rand(65_535) }
89
88
  # @!attribute frag
90
89
  # @return [Integer] 16-bit frag word
91
90
  define_field :frag, Types::Int16, default: 0
@@ -111,7 +110,7 @@ require_relative 'ip/options'
111
110
  # @!attribute body
112
111
  # @return [Types::String,Header::Base]
113
112
  define_field :body, Types::String
114
-
113
+
115
114
  # @!attribute version
116
115
  # @return [Integer] 4-bit version attribute
117
116
  # @!attribute ihl
@@ -121,7 +120,7 @@ require_relative 'ip/options'
121
120
  # @!attribute flag_rsv
122
121
  # @return [Boolean] reserved bit from flags
123
122
  # @!attribute flag_df
124
- # @return [Boolean] Don't Fragment flag
123
+ # @return [Boolean] Don't Fragment flag
125
124
  # @!attribute flag_mf
126
125
  # @return [Boolean] More Fragment flags
127
126
  # @!attribute fragment_offset
@@ -133,7 +132,7 @@ require_relative 'ip/options'
133
132
  # @param [#to_s] hdr header or other object on which calculates a sum
134
133
  # of 16-bit words.
135
134
  # @return [Integer]
136
- def IP.sum16(hdr)
135
+ def self.sum16(hdr)
137
136
  old_checksum = nil
138
137
  if hdr.respond_to? :checksum=
139
138
  old_checksum = hdr.checksum
@@ -141,11 +140,11 @@ require_relative 'ip/options'
141
140
  end
142
141
 
143
142
  data = hdr.to_s
144
- data << "\x00" if data.size % 2 == 1
143
+ data << "\x00" if data.size.odd?
145
144
  sum = data.unpack('n*').reduce(:+)
146
145
 
147
146
  hdr.checksum = old_checksum if old_checksum
148
-
147
+
149
148
  sum
150
149
  end
151
150
 
@@ -157,12 +156,12 @@ require_relative 'ip/options'
157
156
  # * forces self[attr] to 0xffff if computed self[attr] is 0.
158
157
  # @param [Integer] checksum checksum to reduce
159
158
  # @return [Integer] reduced checksum
160
- def IP.reduce_checksum(checksum)
161
- while checksum > 0xffff do
159
+ def self.reduce_checksum(checksum)
160
+ while checksum > 0xffff
162
161
  checksum = (checksum & 0xffff) + (checksum >> 16)
163
162
  end
164
163
  checksum = ~checksum & 0xffff
165
- (checksum == 0) ? 0xffff : checksum
164
+ checksum.zero? ? 0xffff : checksum
166
165
  end
167
166
 
168
167
  # Populate object from a binary string
@@ -186,7 +185,7 @@ require_relative 'ip/options'
186
185
  opt_size = (self.ihl - 5) * 4
187
186
  self[:options].read str[20, opt_size]
188
187
  end
189
- self[:body].read str[20+opt_size..-1]
188
+ self[:body].read str[20 + opt_size..-1]
190
189
  self
191
190
  end
192
191
 
@@ -227,7 +226,7 @@ require_relative 'ip/options'
227
226
  # kernel, so bad IP packets cannot be sent this way. To do so, use {Eth#to_w}.
228
227
  # @param [String,nil] iface interface name. Not used
229
228
  # @return [void]
230
- def to_w(iface=nil)
229
+ def to_w(_iface=nil)
231
230
  sock = Socket.new(Socket::AF_INET, Socket::SOCK_RAW, Socket::IPPROTO_RAW)
232
231
  sockaddrin = Socket.sockaddr_in(0, dst)
233
232
  sock.send to_s, 0, sockaddrin
@@ -245,7 +244,7 @@ require_relative 'ip/options'
245
244
  str << shift + Inspect::FMT_ATTR % ['', 'version', version]
246
245
  str << shift + Inspect::FMT_ATTR % ['', 'ihl', ihl]
247
246
  elsif attr == :frag
248
- flags = flag_rsv? ? %w(RSV) : []
247
+ flags = flag_rsv? ? %w[RSV] : []
249
248
  flags << 'DF' if flag_df?
250
249
  flags << 'MF' if flag_mf?
251
250
  flags_str = flags.empty? ? 'none' : flags.join(',')
@@ -260,7 +259,7 @@ require_relative 'ip/options'
260
259
  # Check version field
261
260
  # @see [Base#parse?]
262
261
  def parse?
263
- version == 4 and ihl >= 5
262
+ (version == 4) && (ihl >= 5)
264
263
  end
265
264
 
266
265
  # Get binary string. Fixup IHL if needed (IP header has options, and IHL
@@ -269,13 +268,21 @@ require_relative 'ip/options'
269
268
  self.ihl = 5 + options.sz / 4 if self.ihl == 5
270
269
  super
271
270
  end
271
+
272
+ # Invert source and destination addresses
273
+ # @return [self]
274
+ # @since 2.7.0
275
+ def reply!
276
+ self[:src], self[:dst] = self[:dst], self[:src]
277
+ self
278
+ end
272
279
  end
273
280
 
274
281
  self.add_class IP
275
282
 
276
- Eth.bind_header IP, ethertype: IP::ETHERTYPE
277
- SNAP.bind_header IP, proto_id: IP::ETHERTYPE
278
- Dot1q.bind_header IP, ethertype: IP::ETHERTYPE
279
- IP.bind_header IP, protocol: 4
283
+ Eth.bind IP, ethertype: IP::ETHERTYPE
284
+ SNAP.bind IP, proto_id: IP::ETHERTYPE
285
+ Dot1q.bind IP, ethertype: IP::ETHERTYPE
286
+ IP.bind IP, protocol: 4
280
287
  end
281
288
  end