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
@@ -8,7 +8,6 @@
8
8
  module PacketGen
9
9
  module Header
10
10
  class EAP
11
-
12
11
  # Extensible Authentication Protocol (EAP) - Flexible Authentication variable
13
12
  # Secure Tunneling, {https://tools.ietf.org/html/rfc4851 RFC 4851}
14
13
  #
@@ -8,8 +8,7 @@
8
8
  module PacketGen
9
9
  module Header
10
10
  class EAP
11
-
12
- # Extensible Authentication Protocol (EAP) -
11
+ # Extensible Authentication Protocol (EAP) -
13
12
  # {https://tools.ietf.org/html/rfc3748#section-5.4 MD5 challenge}
14
13
  # @author Sylvain Daubert
15
14
  # @since 2.1.4
@@ -8,7 +8,6 @@
8
8
  module PacketGen
9
9
  module Header
10
10
  class EAP
11
-
12
11
  # Extensible Authentication Protocol (EAP) - TLS,
13
12
  # {https://tools.ietf.org/html/rfc5216 RFC 5216}
14
13
  #
@@ -22,7 +21,7 @@ module PacketGen
22
21
  # @!attribute flags
23
22
  # @return [Integer] 8-bit flags
24
23
  define_field_before :body, :flags, Types::Int8
25
-
24
+
26
25
  # @!attribute l
27
26
  # Say if length field is included. Defined on {#flags} field.
28
27
  # @return [Boolean]
@@ -33,17 +32,17 @@ module PacketGen
33
32
  # If set, this message is a TLS-Start. Defined on {#flags} field.
34
33
  # @return [Boolean]
35
34
  define_bit_fields_on :flags, :l, :m, :s, :reserved, 5
36
- alias :length_present? :l?
37
- alias :more_fragments? :m?
38
- alias :tls_start? :s?
39
-
35
+ alias length_present? l?
36
+ alias more_fragments? m?
37
+ alias tls_start? s?
38
+
40
39
  # @!attribute tls_length
41
40
  # TLS message length. This field provides the total length of the
42
41
  # TLS message or set of messages that is being fragmented. So, it
43
42
  # cannot be automatically calculated (no +#calc_length+ method).
44
43
  # @return [Integer] 32-bit TLS length
45
44
  define_field_before :body, :tls_length, Types::Int32,
46
- optional: ->(h) { h.l? }
45
+ optional: ->(h) { h.l? }
47
46
 
48
47
  # @return [EAP::TLS]
49
48
  def initialize(options={})
@@ -58,11 +57,11 @@ module PacketGen
58
57
  next unless is_present?(attr)
59
58
  if attr == :flags
60
59
  shift = Inspect.shift_level(2)
61
- value = %i(l m s).map { |f| send("#{f}?") ? f.to_s : '.' }.join
60
+ value = %i[l m s].map { |f| send("#{f}?") ? f.to_s : '.' }.join
62
61
  value = '%-10s (0x%02x)' % [value, self.flags]
63
- str << shift
62
+ str << shift
64
63
  str << Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''),
65
- attr, value]
64
+ attr, value]
66
65
  else
67
66
  str << Inspect.inspect_attribute(attr, self[attr], 2)
68
67
  end
@@ -8,7 +8,6 @@
8
8
  module PacketGen
9
9
  module Header
10
10
  class EAP
11
-
12
11
  # Extensible Authentication Protocol (EAP) - Tunneled-TLS,
13
12
  # {https://tools.ietf.org/html/rfc5281 RFC 5281}
14
13
  #
@@ -22,7 +21,7 @@ module PacketGen
22
21
  # @!attribute flags
23
22
  # @return [Integer] 8-bit flags
24
23
  define_field_before :body, :flags, Types::Int8
25
-
24
+
26
25
  # @!attribute l
27
26
  # Say if length field is included. Defined on {#flags} field.
28
27
  # @return [Boolean]
@@ -37,17 +36,17 @@ module PacketGen
37
36
  # @!attribute version
38
37
  # @return [Integer] 3-bit version
39
38
  define_bit_fields_on :flags, :l, :m, :s, :reserved, 2, :version, 3
40
- alias :length_present? :l?
41
- alias :more_fragments? :m?
42
- alias :tls_start? :s?
43
-
39
+ alias length_present? l?
40
+ alias more_fragments? m?
41
+ alias tls_start? s?
42
+
44
43
  # @!attribute message_length
45
44
  # Message length. This field provides the total length of the
46
45
  # raw data message sequence prior to fragmentation. So, it
47
46
  # cannot be automatically calculated (no +#calc_length+ method).
48
47
  # @return [Integer] 32-bit message length
49
48
  define_field_before :body, :message_length, Types::Int32,
50
- optional: ->(h) { h.l? }
49
+ optional: ->(h) { h.l? }
51
50
 
52
51
  # @return [EAP::TTLS]
53
52
  def initialize(options={})
@@ -62,11 +61,11 @@ module PacketGen
62
61
  next unless is_present?(attr)
63
62
  if attr == :flags
64
63
  shift = Inspect.shift_level(2)
65
- value = %i(l m s).map { |f| send("#{f}?") ? f.to_s : '.' }.join
64
+ value = %i[l m s].map { |f| send("#{f}?") ? f.to_s : '.' }.join
66
65
  value = '%-10s (0x%02x)' % [value, self.flags]
67
- str << shift
66
+ str << shift
68
67
  str << Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''),
69
- attr, value]
68
+ attr, value]
70
69
  str << Inspect::FMT_ATTR % ['', 'version', self.version]
71
70
  else
72
71
  str << Inspect.inspect_attribute(attr, self[attr], 2)
@@ -7,7 +7,6 @@
7
7
 
8
8
  module PacketGen
9
9
  module Header
10
-
11
10
  # A ESP header consists of:
12
11
  # * a Security Parameters Index (#{spi}, {Types::Int32} type),
13
12
  # * a Sequence Number ({#sn}, +Int32+ type),
@@ -49,7 +48,7 @@ module PacketGen
49
48
  # esp.esp.icv_length = 16
50
49
  # # encapsulate ICMP packet in ESP one
51
50
  # esp.encapsulate icmp
52
- #
51
+ #
53
52
  # # encrypt ESP payload
54
53
  # cipher = OpenSSL::Cipher.new('aes-128-gcm')
55
54
  # cipher.encrypt
@@ -61,11 +60,12 @@ module PacketGen
61
60
  # cipher = OpenSSL::Cipher.new('aes-128-cbc')
62
61
  # cipher.decrypt
63
62
  # cipher.key = 16bytes_key
64
- #
63
+ #
65
64
  # hmac = OpenSSL::HMAC.new(hmac_key, OpenSSL::Digest::SHA256.new)
66
65
  #
67
66
  # pkt.esp.decrypt! cipher, intmode: hmac # => true if ICV check OK
68
67
  # @author Sylvain Daubert
68
+ # @since 1.2.0
69
69
  class ESP < Base
70
70
  include Crypto
71
71
 
@@ -140,11 +140,11 @@ module PacketGen
140
140
  force_binary str
141
141
  self[:spi].read str[0, 4]
142
142
  self[:sn].read str[4, 4]
143
- self[:body].read str[8...-@icv_length-2]
143
+ self[:body].read str[8...-@icv_length - 2]
144
144
  self[:tfc].read ''
145
145
  self[:padding].read ''
146
- self[:pad_length].read str[-@icv_length-2, 1]
147
- self[:next].read str[-@icv_length-1, 1]
146
+ self[:pad_length].read str[-@icv_length - 2, 1]
147
+ self[:next].read str[-@icv_length - 1, 1]
148
148
  self[:icv].read str[-@icv_length, @icv_length] if @icv_length
149
149
  self
150
150
  end
@@ -198,10 +198,10 @@ module PacketGen
198
198
 
199
199
  if opt[:pad_length]
200
200
  self.pad_length = opt[:pad_length]
201
- padding = force_binary(opt[:padding] || (1..self.pad_length).to_a.pack("C*"))
201
+ padding = force_binary(opt[:padding] || (1..self.pad_length).to_a.pack('C*'))
202
202
  self[:padding].read padding
203
203
  else
204
- padding = force_binary(opt[:padding] || (1..self.pad_length).to_a.pack("C*"))
204
+ padding = force_binary(opt[:padding] || (1..self.pad_length).to_a.pack('C*'))
205
205
  self[:padding].read padding[0...self.pad_length]
206
206
  end
207
207
 
@@ -209,12 +209,12 @@ module PacketGen
209
209
  if opt[:tfc]
210
210
  tfc_size = opt[:tfc_size] - body.sz
211
211
  if tfc_size > 0
212
- case confidentiality_mode
213
- when 'cbc'
214
- tfc_size = (tfc_size / 16) * 16
215
- else
216
- tfc_size = (tfc_size / 4) * 4
217
- end
212
+ tfc_size = case confidentiality_mode
213
+ when 'cbc'
214
+ (tfc_size / 16) * 16
215
+ else
216
+ (tfc_size / 4) * 4
217
+ end
218
218
  tfc = force_binary("\0" * tfc_size)
219
219
  end
220
220
  end
@@ -237,7 +237,7 @@ module PacketGen
237
237
  # Remove enciphered headers from packet
238
238
  id = header_id(self)
239
239
  if id < packet.headers.size - 1
240
- (packet.headers.size-1).downto(id+1) do |index|
240
+ (packet.headers.size - 1).downto(id + 1) do |index|
241
241
  packet.headers.delete_at index
242
242
  end
243
243
  end
@@ -260,7 +260,7 @@ module PacketGen
260
260
  # confidentiality-only cipher. Only HMAC are supported.
261
261
  # @return [Boolean] +true+ if ESP packet is authenticated
262
262
  def decrypt!(cipher, options={})
263
- opt = { :salt => '', parse: true }.merge(options)
263
+ opt = { salt: '', parse: true }.merge(options)
264
264
 
265
265
  set_crypto cipher, opt[:intmode]
266
266
 
@@ -279,7 +279,7 @@ module PacketGen
279
279
  end
280
280
  cipher.iv = real_iv
281
281
 
282
- if authenticated? and (@icv_length == 0 or opt[:icv_length])
282
+ if authenticated? && (@icv_length.zero? || opt[:icv_length])
283
283
  raise ParseError, 'unknown ICV size' unless opt[:icv_length]
284
284
  @icv_length = opt[:icv_length].to_i
285
285
  # reread ESP to handle new ICV size
@@ -292,7 +292,7 @@ module PacketGen
292
292
  end
293
293
 
294
294
  authenticate_esp_header_if_needed options, iv, self[:icv]
295
- private_decrypt cipher, opt
295
+ private_decrypt opt
296
296
  end
297
297
 
298
298
  private
@@ -329,7 +329,7 @@ module PacketGen
329
329
  end
330
330
  end
331
331
 
332
- def private_decrypt(cipher, options)
332
+ def private_decrypt(options)
333
333
  # decrypt
334
334
  msg = self.body.to_s
335
335
  msg += self[:padding].to_s + self[:pad_length].to_s + self[:next].to_s
@@ -356,8 +356,8 @@ module PacketGen
356
356
  pkt = nil
357
357
  case self.next
358
358
  when 4 # IPv4
359
- pkt = Packet.parse(body, first_header: 'IP')
360
- encap_length = pkt.ip.length
359
+ pkt = Packet.parse(body, first_header: 'IP')
360
+ encap_length = pkt.ip.length
361
361
  when 41 # IPv6
362
362
  pkt = Packet.parse(body, first_header: 'IPv6')
363
363
  encap_length = pkt.ipv6.length + pkt.ipv6.sz
@@ -397,17 +397,17 @@ module PacketGen
397
397
 
398
398
  self.add_class ESP
399
399
 
400
- IP.bind_header ESP, protocol: ESP::IP_PROTOCOL
401
- IPv6.bind_header ESP, next: ESP::IP_PROTOCOL
402
- UDP.bind_header ESP, procs: [ ->(f) { f.dport = f.sport = ESP::UDP_PORT },
403
- ->(f) { (f.dport == ESP::UDP_PORT ||
404
- f.sport == ESP::UDP_PORT) &&
405
- Types::Int32.new.read(f.body[0..3]).to_i > 0 }]
406
- ESP.bind_header IP, next: 4
407
- ESP.bind_header IPv6, next: 41
408
- ESP.bind_header TCP, next: TCP::IP_PROTOCOL
409
- ESP.bind_header UDP, next: TCP::IP_PROTOCOL
410
- ESP.bind_header ICMP, next: ICMP::IP_PROTOCOL
411
- ESP.bind_header ICMPv6, next: ICMPv6::IP_PROTOCOL
400
+ IP.bind ESP, protocol: ESP::IP_PROTOCOL
401
+ IPv6.bind ESP, next: ESP::IP_PROTOCOL
402
+ UDP.bind ESP, procs: [->(f) { f.dport = f.sport = ESP::UDP_PORT },
403
+ ->(f) { (f.dport == ESP::UDP_PORT ||
404
+ f.sport == ESP::UDP_PORT) &&
405
+ Types::Int32.new.read(f.body[0..3]).to_i > 0 }]
406
+ ESP.bind IP, next: 4
407
+ ESP.bind IPv6, next: 41
408
+ ESP.bind TCP, next: TCP::IP_PROTOCOL
409
+ ESP.bind UDP, next: TCP::IP_PROTOCOL
410
+ ESP.bind ICMP, next: ICMP::IP_PROTOCOL
411
+ ESP.bind ICMPv6, next: ICMPv6::IP_PROTOCOL
412
412
  end
413
413
  end
@@ -7,7 +7,6 @@
7
7
 
8
8
  module PacketGen
9
9
  module Header
10
-
11
10
  # An Ethernet header consists of:
12
11
  # * a destination MAC address ({MacAddr}),
13
12
  # * a source MAC address (MacAddr),
@@ -31,7 +30,6 @@ module PacketGen
31
30
  #
32
31
  # @author Sylvain Daubert
33
32
  class Eth < Base
34
-
35
33
  # Ethernet MAC address, as a group of 6 bytes
36
34
  # @author Sylvain Daubert
37
35
  class MacAddr < Types::Fields
@@ -53,16 +51,14 @@ module PacketGen
53
51
  # @!attribute a5
54
52
  # @return [Integer] sixth byte from MacAddr
55
53
  define_field :a5, Types::Int8
56
-
54
+
57
55
  # Read a human-readable string to populate +MacAddr+
58
56
  # @param [String] str
59
57
  # @return [self]
60
58
  def from_human(str)
61
59
  return self if str.nil?
62
60
  bytes = str.split(/:/)
63
- unless bytes.size == 6
64
- raise ArgumentError, 'not a MAC address'
65
- end
61
+ raise ArgumentError, 'not a MAC address' unless bytes.size == 6
66
62
  self[:a0].read(bytes[0].to_i(16))
67
63
  self[:a1].read(bytes[1].to_i(16))
68
64
  self[:a2].read(bytes[2].to_i(16))
@@ -75,7 +71,7 @@ module PacketGen
75
71
  # +MacAddr+ in human readable form (colon format)
76
72
  # @return [String]
77
73
  def to_human
78
- fields.map { |m| "#{'%02x' % self[m]}" }.join(':')
74
+ fields.map { |m| '%02x' % self[m] }.join(':')
79
75
  end
80
76
  end
81
77
 
@@ -100,8 +96,15 @@ module PacketGen
100
96
  pcap.inject self.to_s
101
97
  pcap.close
102
98
  end
103
- end
104
99
 
100
+ # Invert destination and source addresses
101
+ # @return [self]
102
+ # @since 2.7.0
103
+ def reply!
104
+ self[:src], self[:dst] = self[:dst], self[:src]
105
+ self
106
+ end
107
+ end
105
108
  self.add_class Eth
106
109
  end
107
110
  end
@@ -7,7 +7,6 @@
7
7
 
8
8
  module PacketGen
9
9
  module Header
10
-
11
10
  # Generic Routing Encapsulation (RFC 2784 and 2890)
12
11
  # 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
13
12
  # 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
@@ -21,8 +20,8 @@ module PacketGen
21
20
  # | Sequence Number (Optional) |
22
21
  # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23
22
  # @author Sylvain Daubert
23
+ # @since 2.1.0
24
24
  class GRE < Base
25
-
26
25
  # IP protocol number for GRE
27
26
  IP_PROTOCOL = 47
28
27
 
@@ -76,10 +75,10 @@ module PacketGen
76
75
  end
77
76
 
78
77
  self.add_class GRE
79
- IP.bind_header GRE, protocol: GRE::IP_PROTOCOL
80
- IPv6.bind_header GRE, next: GRE::IP_PROTOCOL
78
+ IP.bind GRE, protocol: GRE::IP_PROTOCOL
79
+ IPv6.bind GRE, next: GRE::IP_PROTOCOL
81
80
 
82
- GRE.bind_header IP, protocol_type: IP::ETHERTYPE
83
- GRE.bind_header IPv6, protocol_type: IPv6::ETHERTYPE
81
+ GRE.bind IP, protocol_type: IP::ETHERTYPE
82
+ GRE.bind IPv6, protocol_type: IPv6::ETHERTYPE
84
83
  end
85
84
  end
@@ -7,12 +7,16 @@
7
7
 
8
8
  module PacketGen
9
9
  module Header
10
-
11
10
  # @since 2.2.0
12
- module HTTP
11
+ module HTTP
13
12
  # @abstract Base class for HTTP headers.
14
13
  # @author Kent 'picat' Gruber
15
14
  class Headers
15
+ # Underlying Headers data (or nil).
16
+ # @return [Hash, nil]
17
+ attr_reader :data
18
+ alias to_h data
19
+
16
20
  def initialize
17
21
  @data = nil
18
22
  end
@@ -23,10 +27,10 @@ module PacketGen
23
27
  def read(s_or_h)
24
28
  case s_or_h
25
29
  when String
26
- @data = s_or_h.split("\n").map do |h|
27
- next unless h.include?(":")
28
- k, v = h.split(":", 2)
29
- [k, v.strip]
30
+ @data = s_or_h.split("\n").map do |h|
31
+ next unless h.include?(':')
32
+ k, v = h.split(':', 2)
33
+ [k, v.strip]
30
34
  end.reject(&:nil?).to_h
31
35
  when Hash
32
36
  @data = s_or_h
@@ -40,7 +44,7 @@ module PacketGen
40
44
  return "\r\n" if @data.nil? || @data.empty?
41
45
  d = []
42
46
  @data.map do |k, v|
43
- d << k + ": " + v
47
+ d << k + ': ' + v
44
48
  end
45
49
  d.join("\r\n") << "\r\n\r\n"
46
50
  end
@@ -64,13 +68,6 @@ module PacketGen
64
68
  return true unless @data.nil? || @data.empty?
65
69
  false
66
70
  end
67
-
68
- # Shorcut to the underlying Headers data or nil.
69
- # @return [Hash, nil]
70
- def data
71
- @data
72
- end
73
- alias to_h data
74
71
  end
75
72
  end
76
73
  end
@@ -26,28 +26,28 @@ module PacketGen
26
26
  # attributes of TCP header are not set.
27
27
  #
28
28
  # == HTTP Request attributes
29
- # http_rqst.version = "HTTP/1.1"
30
- # http_rqst.method = "GET"
31
- # http_rqst.path = "/meow.html"
29
+ # http_rqst.version = "HTTP/1.1"
30
+ # http_rqst.method = "GET"
31
+ # http_rqst.path = "/meow.html"
32
32
  # http_rqst.headers = "Host: tcpdump.org" # string or
33
- # http_rqst.headers = { "Host": "tcpdump.org" } # even a hash
33
+ # http_rqst.headers = { "Host": "tcpdump.org" } # even a hash
34
34
  #
35
35
  # @author Kent 'picat' Gruber
36
36
  class Request < Base
37
37
  # @!attribute method
38
38
  # @return [Types::String]
39
39
  define_field :method, Types::String
40
- # @!attribute path
40
+ # @!attribute path
41
41
  # @return [Types::String]
42
42
  define_field :path, Types::String
43
- # @!attribute version
43
+ # @!attribute version
44
44
  # @return [Types::String]
45
- define_field :version, Types::String, default: "HTTP/1.1"
45
+ define_field :version, Types::String, default: 'HTTP/1.1'
46
46
  # @!attribute headers
47
47
  # associated http/1.1 headers
48
48
  # @return [HTTP::Headers]
49
- define_field :headers, HTTP::Headers
50
- # @!attribute body
49
+ define_field :headers, HTTP::Headers
50
+ # @!attribute body
51
51
  # @return [Types::String]
52
52
  define_field :body, Types::String
53
53
 
@@ -61,7 +61,7 @@ module PacketGen
61
61
  self.headers ||= options[:headers]
62
62
  end
63
63
 
64
- # Read in the HTTP portion of the packet, and parse it.
64
+ # Read in the HTTP portion of the packet, and parse it.
65
65
  # @return [PacketGen::HTTP::Request]
66
66
  def read(str)
67
67
  str = str.bytes.map!(&:chr).join unless str.valid_encoding?
@@ -73,9 +73,9 @@ module PacketGen
73
73
  self[:path] = first_line[1]
74
74
  self[:version] = first_line[2]
75
75
  # requests can sometimes have a payload
76
- if data_index = str.find_index("")
77
- data = str[data_index+1..-1].join("\n")
78
- headers = str[0..data_index-1].join("\n")
76
+ if (data_index = str.find_index(''))
77
+ data = str[data_index + 1..-1].join("\n")
78
+ headers = str[0..data_index - 1].join("\n")
79
79
  else
80
80
  headers = str.join("\n")
81
81
  end
@@ -87,16 +87,16 @@ module PacketGen
87
87
  # String representation of data.
88
88
  # @return [String]
89
89
  def to_s
90
- raise FormatError, "Missing #method." if self.method.empty?
91
- raise FormatError, "Missing #path." if self.path.empty?
92
- raise FormatError, "Missing #version." if self.version.empty?
93
- str = "".dup # build 'dat string
94
- str << self[:method] << " " << self[:path] << " " << self[:version] << "\r\n" << self[:headers].to_s << self[:body]
90
+ raise FormatError, 'Missing #method.' if self.method.empty?
91
+ raise FormatError, 'Missing #path.' if self.path.empty?
92
+ raise FormatError, 'Missing #version.' if self.version.empty?
93
+ str = ''.dup # build 'dat string
94
+ str << self[:method] << ' ' << self[:path] << ' ' << self[:version] << "\r\n" << self[:headers].to_s << self[:body]
95
95
  end
96
96
  end
97
97
  end
98
98
 
99
- self.add_class HTTP::Request
100
- TCP.bind_header HTTP::Request, body: ->(b) { HTTP::REQUEST_REGEX =~ b.chars.select(&:valid_encoding?).join }
99
+ self.add_class HTTP::Request
100
+ TCP.bind HTTP::Request, body: ->(b) { HTTP::REQUEST_REGEX =~ b.chars.select(&:valid_encoding?).join }
101
101
  end
102
102
  end