packetgen 2.8.7 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -1
  3. data/README.md +5 -4
  4. data/lib/packetgen.rb +6 -12
  5. data/lib/packetgen/capture.rb +43 -39
  6. data/lib/packetgen/config.rb +0 -1
  7. data/lib/packetgen/deprecation.rb +1 -1
  8. data/lib/packetgen/header.rb +9 -9
  9. data/lib/packetgen/header/asn1_base.rb +10 -10
  10. data/lib/packetgen/header/base.rb +42 -101
  11. data/lib/packetgen/header/dhcp/option.rb +5 -11
  12. data/lib/packetgen/header/dhcpv6/duid.rb +2 -0
  13. data/lib/packetgen/header/dhcpv6/option.rb +2 -19
  14. data/lib/packetgen/header/dhcpv6/options.rb +7 -0
  15. data/lib/packetgen/header/dns.rb +5 -23
  16. data/lib/packetgen/header/dns/name.rb +1 -0
  17. data/lib/packetgen/header/dns/qdsection.rb +1 -0
  18. data/lib/packetgen/header/dns/question.rb +3 -7
  19. data/lib/packetgen/header/dns/rr.rb +3 -0
  20. data/lib/packetgen/header/dns/rrsection.rb +1 -0
  21. data/lib/packetgen/header/dot11.rb +1 -17
  22. data/lib/packetgen/header/dot1x.rb +1 -0
  23. data/lib/packetgen/header/eap.rb +4 -7
  24. data/lib/packetgen/header/eth.rb +2 -0
  25. data/lib/packetgen/header/http/headers.rb +3 -0
  26. data/lib/packetgen/header/http/request.rb +5 -4
  27. data/lib/packetgen/header/http/response.rb +5 -4
  28. data/lib/packetgen/header/icmp.rb +6 -0
  29. data/lib/packetgen/header/icmpv6.rb +6 -0
  30. data/lib/packetgen/header/igmpv3/mq.rb +2 -0
  31. data/lib/packetgen/header/ip.rb +32 -30
  32. data/lib/packetgen/header/ip/addr.rb +1 -0
  33. data/lib/packetgen/header/ip/option.rb +23 -20
  34. data/lib/packetgen/header/ip/options.rb +11 -24
  35. data/lib/packetgen/header/ipv6.rb +45 -34
  36. data/lib/packetgen/header/ipv6/addr.rb +2 -0
  37. data/lib/packetgen/header/ipv6/hop_by_hop.rb +7 -31
  38. data/lib/packetgen/header/mdns.rb +1 -0
  39. data/lib/packetgen/header/mldv2/mlq.rb +2 -0
  40. data/lib/packetgen/header/ospfv2/lsa.rb +15 -25
  41. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +1 -1
  42. data/lib/packetgen/header/ospfv3/lsa.rb +8 -25
  43. data/lib/packetgen/header/snmp.rb +2 -0
  44. data/lib/packetgen/header/tcp.rb +23 -2
  45. data/lib/packetgen/header/tcp/option.rb +51 -52
  46. data/lib/packetgen/header/tcp/options.rb +17 -52
  47. data/lib/packetgen/header/tftp.rb +3 -0
  48. data/lib/packetgen/header/udp.rb +8 -0
  49. data/lib/packetgen/packet.rb +119 -102
  50. data/lib/packetgen/pcapng/block.rb +4 -10
  51. data/lib/packetgen/pcapng/epb.rb +4 -4
  52. data/lib/packetgen/pcapng/file.rb +7 -3
  53. data/lib/packetgen/pcapng/idb.rb +2 -2
  54. data/lib/packetgen/pcapng/shb.rb +3 -3
  55. data/lib/packetgen/pcapng/spb.rb +1 -8
  56. data/lib/packetgen/pcapng/unknown_block.rb +0 -7
  57. data/lib/packetgen/types.rb +1 -0
  58. data/lib/packetgen/types/array.rb +73 -71
  59. data/lib/packetgen/types/cstring.rb +1 -1
  60. data/lib/packetgen/types/enum.rb +3 -3
  61. data/lib/packetgen/types/fields.rb +66 -106
  62. data/lib/packetgen/types/int.rb +9 -5
  63. data/lib/packetgen/types/length_from.rb +45 -0
  64. data/lib/packetgen/types/oui.rb +2 -0
  65. data/lib/packetgen/types/string.rb +10 -16
  66. data/lib/packetgen/types/tlv.rb +7 -15
  67. data/lib/packetgen/utils.rb +8 -8
  68. data/lib/packetgen/utils/arp_spoofer.rb +1 -2
  69. data/lib/packetgen/version.rb +1 -1
  70. metadata +3 -21
  71. data/lib/packetgen/header/crypto.rb +0 -62
  72. data/lib/packetgen/header/esp.rb +0 -413
  73. data/lib/packetgen/header/ike.rb +0 -243
  74. data/lib/packetgen/header/ike/auth.rb +0 -165
  75. data/lib/packetgen/header/ike/cert.rb +0 -76
  76. data/lib/packetgen/header/ike/certreq.rb +0 -66
  77. data/lib/packetgen/header/ike/id.rb +0 -99
  78. data/lib/packetgen/header/ike/ke.rb +0 -79
  79. data/lib/packetgen/header/ike/nonce.rb +0 -40
  80. data/lib/packetgen/header/ike/notify.rb +0 -176
  81. data/lib/packetgen/header/ike/payload.rb +0 -315
  82. data/lib/packetgen/header/ike/sa.rb +0 -561
  83. data/lib/packetgen/header/ike/sk.rb +0 -261
  84. data/lib/packetgen/header/ike/ts.rb +0 -270
  85. data/lib/packetgen/header/ike/vendor_id.rb +0 -39
  86. data/lib/packetgen/header/netbios.rb +0 -20
  87. data/lib/packetgen/header/netbios/datagram.rb +0 -105
  88. data/lib/packetgen/header/netbios/name.rb +0 -67
  89. data/lib/packetgen/header/netbios/session.rb +0 -64
@@ -56,9 +56,6 @@ module PacketGen
56
56
  74 => ['IRC_server', length: 4, v: IP::Addr]
57
57
  }.freeze
58
58
 
59
- # @deprecated Use {DHCP_OPTIONS} instead.
60
- DCHPOptions = DHCP_OPTIONS
61
-
62
59
  # Class to indicate DHCP options end
63
60
  class End < Types::Int8
64
61
  def initialize(value=255)
@@ -98,9 +95,10 @@ module PacketGen
98
95
  def initialize(options={})
99
96
  super
100
97
  return unless DHCP_OPTIONS.key?(self.type)
101
- h = DHCP_OPTIONS[self.type].last
102
98
 
99
+ h = DHCP_OPTIONS[self.type].last
103
100
  return unless h.is_a? Hash
101
+
104
102
  h.each do |k, v|
105
103
  self.length = v if k == :length
106
104
  if k == :v
@@ -135,13 +133,8 @@ module PacketGen
135
133
  true
136
134
  end
137
135
 
138
- # @deprecated Use {#human_types?} instead
139
- # @return [true]
140
- def has_human_types?
141
- Deprecation.deprecated(self.class, __method__, 'human_types?')
142
- human_types?
143
- end
144
-
136
+ # Get human-readable type
137
+ # @return [String]
145
138
  def human_type
146
139
  if DHCP_OPTIONS.key?(type)
147
140
  DHCP_OPTIONS[type].first.dup
@@ -150,6 +143,7 @@ module PacketGen
150
143
  end
151
144
  end
152
145
 
146
+ # @return [String]
153
147
  def to_human
154
148
  s = human_type
155
149
  if length > 0
@@ -78,6 +78,8 @@ module PacketGen
78
78
  # @return [Eth::MacAddr]
79
79
  define_field :link_addr, Eth::MacAddr
80
80
 
81
+ undef time, time=
82
+
81
83
  # @return [Time]
82
84
  def time
83
85
  BASE_TIME + self[:time].to_i
@@ -36,10 +36,12 @@ module PacketGen
36
36
  # @return [Hash]
37
37
  def subclasses
38
38
  return @klasses if defined? @klasses
39
+
39
40
  @klasses = []
40
41
  DHCPv6.constants.each do |cst|
41
42
  klass = DHCPv6.const_get(cst)
42
43
  next unless klass.is_a?(Class) && (klass < Option)
44
+
43
45
  @klasses[klass.new.type] = klass
44
46
  end
45
47
  @klasses
@@ -80,25 +82,6 @@ module PacketGen
80
82
  alias private_read read
81
83
  private :private_read
82
84
 
83
- # Populate object from binary string
84
- # @param [String] str
85
- # @return [Option]
86
- def read(str)
87
- if self.class == Option
88
- return self if str.nil?
89
- PacketGen.force_binary str
90
- type = Types::Int16.new.read(str).to_i
91
- klass = Option.subclasses[type]
92
- if klass
93
- klass.new.read(str)
94
- else
95
- private_read str
96
- end
97
- else
98
- private_read str
99
- end
100
- end
101
-
102
85
  # Get human-readable {#type}
103
86
  # @return [String]
104
87
  def human_type
@@ -23,6 +23,13 @@ module PacketGen
23
23
 
24
24
  # Separator used in {#to_human}.
25
25
  HUMAN_SEPARATOR = ';'
26
+
27
+ private
28
+
29
+ def real_type(opt)
30
+ real_klass = Option.subclasses[opt.type]
31
+ real_klass.nil? ? Option : real_klass
32
+ end
26
33
  end
27
34
  end
28
35
  end
@@ -97,12 +97,12 @@ module PacketGen
97
97
  end
98
98
  end
99
99
 
100
- require_relative 'dns/rrsection'
101
- require_relative 'dns/qdsection'
102
100
  require_relative 'dns/name'
103
101
  require_relative 'dns/question'
104
102
  require_relative 'dns/rr'
105
103
  require_relative 'dns/opt'
104
+ require_relative 'dns/rrsection'
105
+ require_relative 'dns/qdsection'
106
106
 
107
107
  module PacketGen
108
108
  module Header
@@ -184,27 +184,7 @@ module PacketGen
184
184
  define_bit_fields_on :u16, :qr, :opcode, 4, :aa, :tc, :rd, :ra, :z,
185
185
  :ad, :cd, :rcode, 4
186
186
 
187
- # Read DNS header and sections from a string
188
- # @param [String] str binary string
189
- # @return [self]
190
- def read(str)
191
- return self if str.nil?
192
- force_binary str
193
- self[:id].read str[0, 2]
194
- self[:u16].read str[2, 2]
195
- self[:qdcount].read str[4, 2]
196
- self[:ancount].read str[6, 2]
197
- self[:nscount].read str[8, 2]
198
- self[:arcount].read str[10, 2]
199
- self[:qd].read str[12..-1] if self.qdcount > 0
200
- start = 12 + self[:qd].sz
201
- self[:an].read str[start..-1] if self.ancount > 0
202
- start += self[:an].sz
203
- self[:ns].read str[start..-1] if self.nscount > 0
204
- start += self[:ns].sz
205
- self[:ar].read str[start..-1] if self.arcount > 0
206
- self
207
- end
187
+ undef opcode=, rcode=
208
188
 
209
189
  # Set opcode
210
190
  # @param [Integer,String] value
@@ -217,6 +197,7 @@ module PacketGen
217
197
  OPCODES[value.to_s]
218
198
  end
219
199
  raise ArgumentError, "unknown opcode #{value.inspect}" unless intg
200
+
220
201
  self.u16 &= 0x87ff
221
202
  self.u16 |= (intg & 0xf) << 11
222
203
  end
@@ -232,6 +213,7 @@ module PacketGen
232
213
  RCODES[value]
233
214
  end
234
215
  raise ArgumentError, "unknown rcode #{value.inspect}" unless intg
216
+
235
217
  self.u16 &= 0xfff0
236
218
  self.u16 |= intg & 0xf
237
219
  end
@@ -93,6 +93,7 @@ module PacketGen
93
93
 
94
94
  def pointer?(index)
95
95
  return false if index.nil?
96
+
96
97
  index & POINTER_MASK == POINTER_MASK
97
98
  end
98
99
 
@@ -30,6 +30,7 @@ module PacketGen
30
30
  def read(str)
31
31
  clear
32
32
  return self if str.nil?
33
+
33
34
  force_binary str
34
35
  while !str.empty? && (self.size < @counter.to_i)
35
36
  question = Question.new(@dns).read(str)
@@ -78,6 +78,8 @@ module PacketGen
78
78
  self.rrclass = options[:rrclass] if options[:rrclass]
79
79
  end
80
80
 
81
+ undef rrclass=
82
+
81
83
  # Setter for class
82
84
  # @param [Integer] val
83
85
  # @return [Integer,String]
@@ -89,6 +91,7 @@ module PacketGen
89
91
  val
90
92
  end
91
93
  raise ArgumentError, "unknown class #{val.inspect}" unless v
94
+
92
95
  self[:rrclass].read v
93
96
  end
94
97
 
@@ -100,13 +103,6 @@ module PacketGen
100
103
  self.class::TYPES[type] == self.type
101
104
  end
102
105
 
103
- # @deprecated Use {#type?} instead
104
- # @return [Boolean]
105
- def has_type?(type)
106
- Deprecation.deprecated(self.class, __method__, 'type?')
107
- type?(type)
108
- end
109
-
110
106
  # Get human readable type
111
107
  # @return [String]
112
108
  def human_type
@@ -36,9 +36,12 @@ module PacketGen
36
36
  def initialize(dns, options={})
37
37
  super
38
38
  return unless options[:rdata] && options[:rdlength].nil?
39
+
39
40
  self.rdata = options[:rdata]
40
41
  end
41
42
 
43
+ undef rdata=
44
+
42
45
  # Set rdata and rdlength from +data+
43
46
  # @param [String] data
44
47
  # @return [void]
@@ -25,6 +25,7 @@ module PacketGen
25
25
  def read(str)
26
26
  clear
27
27
  return self if str.nil?
28
+
28
29
  force_binary str
29
30
  while !str.empty? && (self.size < @counter.to_i)
30
31
  rr = RR.new(@dns).read(str)
@@ -68,8 +68,7 @@ module PacketGen
68
68
  # @param [String] iface interface name
69
69
  # @return [void]
70
70
  def to_w(iface)
71
- pcap = PCAPRUB::Pcap.open_live(iface, PCAP_SNAPLEN, PCAP_PROMISC,
72
- PCAP_TIMEOUT)
71
+ pcap = PCAPRUB::Pcap.open_live(iface, PCAP_SNAPLEN, PCAP_PROMISC, PCAP_TIMEOUT)
73
72
  pcap.inject self.to_s
74
73
  pcap.close
75
74
  end
@@ -219,21 +218,6 @@ module PacketGen
219
218
  # @return [Boolean]
220
219
  attr_accessor :fcs
221
220
  alias fcs? fcs
222
-
223
- # rubocop:disable Naming/PredicateName
224
-
225
- # @deprecated Use {.fcs?} instead.
226
- def has_fcs
227
- Deprecation.deprecated(self, __method__, 'fcs?', klass_method: true)
228
- fcs?
229
- end
230
-
231
- # @deprecated Use {.fcs=} instead.
232
- def has_fcs=(fcs)
233
- Deprecation.deprecated(self, __method__, 'fcs=', klass_method: true)
234
- self.fcs = fcs
235
- end
236
- # rubocop:enable Naming/PredicateName
237
221
  end
238
222
  Dot11.fcs = true
239
223
 
@@ -52,6 +52,7 @@ module PacketGen
52
52
  # @return [self]
53
53
  def read(str)
54
54
  return self if str.nil?
55
+
55
56
  self[:version].read(str[0, 1])
56
57
  self[:type].read(str[1, 1])
57
58
  self[:length].read(str[2, 2])
@@ -132,6 +132,7 @@ module PacketGen
132
132
  def read(str)
133
133
  super str
134
134
  return self unless self.class == EAP
135
+
135
136
  if type?
136
137
  obj = case self.type
137
138
  when 4
@@ -162,6 +163,7 @@ module PacketGen
162
163
  # @raise [ParseError] not a Request nor a Response packet
163
164
  def human_type
164
165
  raise ParseError, 'not a Request nor a Response' unless type?
166
+
165
167
  self[:type].to_human
166
168
  end
167
169
 
@@ -194,6 +196,7 @@ module PacketGen
194
196
  # @raise [ParseError] not a Nak packet
195
197
  def desired_auth_type
196
198
  raise ParseError, 'not a Nak response' if (code != 2) && (type != 3)
199
+
197
200
  body.to_s.unpack('C*')
198
201
  end
199
202
 
@@ -210,13 +213,6 @@ module PacketGen
210
213
  [1, 2].include?(self.code)
211
214
  end
212
215
 
213
- # @deprecated Use {#type?} instead.
214
- # @return [Boolean]
215
- def has_type?
216
- Deprecation.deprecated(self.class, __method__, 'type?')
217
- type?
218
- end
219
-
220
216
  # Callback called when a EAP header is added to a packet
221
217
  # Here, add +#eap+ method as a shortcut to existing
222
218
  # +#eap_(md5|tls|ttls|fast)+.
@@ -224,6 +220,7 @@ module PacketGen
224
220
  # @return [void]
225
221
  def added_to_packet(packet)
226
222
  return if packet.respond_to? :eap
223
+
227
224
  packet.instance_eval("def eap(arg=nil); header(#{self.class}, arg); end")
228
225
  end
229
226
 
@@ -57,8 +57,10 @@ module PacketGen
57
57
  # @return [self]
58
58
  def from_human(str)
59
59
  return self if str.nil?
60
+
60
61
  bytes = str.split(/:/)
61
62
  raise ArgumentError, 'not a MAC address' unless bytes.size == 6
63
+
62
64
  self[:a0].read(bytes[0].to_i(16))
63
65
  self[:a1].read(bytes[1].to_i(16))
64
66
  self[:a2].read(bytes[2].to_i(16))
@@ -29,6 +29,7 @@ module PacketGen
29
29
  when String
30
30
  @data = s_or_h.split("\n").map do |h|
31
31
  next unless h.include?(':')
32
+
32
33
  k, v = h.split(':', 2)
33
34
  [k, v.strip]
34
35
  end.reject(&:nil?).to_h
@@ -42,6 +43,7 @@ module PacketGen
42
43
  # @return [String]
43
44
  def to_s
44
45
  return "\r\n" if @data.nil? || @data.empty?
46
+
45
47
  d = []
46
48
  @data.map do |k, v|
47
49
  d << k + ': ' + v
@@ -66,6 +68,7 @@ module PacketGen
66
68
  # @return [Boolean]
67
69
  def given?
68
70
  return true unless @data.nil? || @data.empty?
71
+
69
72
  false
70
73
  end
71
74
  end
@@ -69,9 +69,9 @@ module PacketGen
69
69
  str = vrb + str.split(vrb)[-1]
70
70
  str = str.split("\n").map(&:chomp)
71
71
  first_line = str.shift.split
72
- self[:method] = first_line[0]
73
- self[:path] = first_line[1]
74
- self[:version] = first_line[2]
72
+ self[:method].read first_line[0]
73
+ self[:path].read first_line[1]
74
+ self[:version].read first_line[2]
75
75
  # requests can sometimes have a payload
76
76
  if (data_index = str.find_index(''))
77
77
  data = str[data_index + 1..-1].join("\n")
@@ -80,7 +80,7 @@ module PacketGen
80
80
  headers = str.join("\n")
81
81
  end
82
82
  self[:headers].read(headers)
83
- self[:body] = data
83
+ self[:body].read data
84
84
  self
85
85
  end
86
86
 
@@ -90,6 +90,7 @@ module PacketGen
90
90
  raise FormatError, 'Missing #method.' if self.method.empty?
91
91
  raise FormatError, 'Missing #path.' if self.path.empty?
92
92
  raise FormatError, 'Missing #version.' if self.version.empty?
93
+
93
94
  str = ''.dup # build 'dat string
94
95
  str << self[:method] << ' ' << self[:path] << ' ' << self[:version] << "\r\n" << self[:headers].to_s << self[:body]
95
96
  end
@@ -87,12 +87,12 @@ module PacketGen
87
87
  end
88
88
  unless headers.empty?
89
89
  first_line = headers.shift.split
90
- self[:version] = first_line[0]
91
- self[:status_code] = first_line[1]
92
- self[:status_mesg] = first_line[2..-1].join(' ')
90
+ self[:version].read first_line[0]
91
+ self[:status_code].read first_line[1]
92
+ self[:status_mesg].read first_line[2..-1].join(' ')
93
93
  self[:headers].read(headers.join("\n"))
94
94
  end
95
- self[:body] = data.join("\n")
95
+ self[:body].read data.join("\n")
96
96
  self
97
97
  end
98
98
 
@@ -102,6 +102,7 @@ module PacketGen
102
102
  raise FormatError, 'Missing #status_code.' if self.status_code.empty?
103
103
  raise FormatError, 'Missing #status_mesg.' if self.status_mesg.empty?
104
104
  raise FormatError, 'Missing #version.' if self.version.empty?
105
+
105
106
  str = ''.dup # build 'dat string
106
107
  str << self[:version] << ' ' << self[:status_code] << ' ' << self[:status_mesg] << "\r\n"
107
108
  str << self[:headers].to_s if self[:headers].given?
@@ -7,6 +7,12 @@
7
7
 
8
8
  module PacketGen
9
9
  module Header
10
+ # ICMP header ({https://tools.ietf.org/html/rfc792 RFC 792})
11
+ # 0 1 2 3
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
13
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
14
+ # | Type | Code | Checksum |
15
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10
16
  # A ICMP header consists of:
11
17
  # * a {#type} field ({Types::Int8} type),
12
18
  # * a {#code} field ({Types::Int8} type),
@@ -7,6 +7,12 @@
7
7
 
8
8
  module PacketGen
9
9
  module Header
10
+ # ICMPv6 header ({https://tools.ietf.org/html/rfc4443 RFC 4443})
11
+ # 0 1 2 3
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
13
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
14
+ # | Type | Code | Checksum |
15
+ # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10
16
  # A ICMPv6 header consists of:
11
17
  # * a +type+ field ({Types::Int8} type),
12
18
  # * a +code+ field ({Types::Int8} type),