packetgen 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/packetgen/header.rb +1 -0
- data/lib/packetgen/header/gre.rb +90 -0
- data/lib/packetgen/packet.rb +1 -1
- data/lib/packetgen/types/fields.rb +35 -5
- data/lib/packetgen/types/int_string.rb +10 -2
- data/lib/packetgen/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0f4985dff6a759aee18e0ca94ec364686d58304
|
4
|
+
data.tar.gz: 5aed1f1d1075e6c00ccac6f76191fcbf537f0005
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ccc6f02e411f0f2632bb21b49859bb4efa4a7cf76c71a32e035796589dd4acddee1508ef47ed26afb426b6e1060b694a88d6872a4f019863274b4bf9573c2dcc
|
7
|
+
data.tar.gz: ea8b5f8819097303c3134b168fa4eaaa4de4fe00d23d7eb5631f1d1279a0b9bbbf0159c3e1fb6dfc71846ecbe1fc0929c4da010710dcb790ce1e5bdceb365d27
|
data/lib/packetgen/header.rb
CHANGED
@@ -90,6 +90,7 @@ require_relative 'header/icmp'
|
|
90
90
|
require_relative 'header/arp'
|
91
91
|
require_relative 'header/ipv6'
|
92
92
|
require_relative 'header/icmpv6'
|
93
|
+
require_relative 'header/gre'
|
93
94
|
require_relative 'header/udp'
|
94
95
|
require_relative 'header/tcp'
|
95
96
|
require_relative 'header/esp'
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# This file is part of PacketGen
|
2
|
+
# See https://github.com/sdaubert/packetgen for more informations
|
3
|
+
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
+
# This program is published under MIT license.
|
5
|
+
|
6
|
+
module PacketGen
|
7
|
+
module Header
|
8
|
+
|
9
|
+
# Generic Routing Encapsulation (RFC 2784 and 2890)
|
10
|
+
# 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
|
11
|
+
# 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
|
12
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
13
|
+
# |C| |K|S| Reserved0 | Ver | Protocol Type |
|
14
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
15
|
+
# | Checksum (optional) | Reserved1 (Optional) |
|
16
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
17
|
+
# | Key (optional) |
|
18
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
19
|
+
# | Sequence Number (Optional) |
|
20
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
21
|
+
# @author Sylvain Daubert
|
22
|
+
class GRE < Base
|
23
|
+
|
24
|
+
# IP protocol number for GRE
|
25
|
+
IP_PROTOCOL = 47
|
26
|
+
|
27
|
+
define_field :u16, Types::Int16
|
28
|
+
|
29
|
+
# @!attribute c
|
30
|
+
# @return [Boolean]
|
31
|
+
# @!attribute k
|
32
|
+
# @return [Boolean]
|
33
|
+
# @!attribute s
|
34
|
+
# @return [Boolean]
|
35
|
+
# @!attribute reserved0
|
36
|
+
# @return [Integer]
|
37
|
+
# @!attribute ver
|
38
|
+
# @return [Integer]
|
39
|
+
define_bit_fields_on :u16, :c, :r, :k, :s, :reserved0, 9, :ver, 3
|
40
|
+
|
41
|
+
# @!attribute protocol_type
|
42
|
+
# @return [Integer]
|
43
|
+
define_field :protocol_type, Types::Int16
|
44
|
+
# @!attribute checksum
|
45
|
+
# @return [Integer]
|
46
|
+
define_field :checksum, Types::Int16, default: 0, optional: ->(gre) { gre.c? }
|
47
|
+
# @!attribute reserved1
|
48
|
+
# @return [Integer]
|
49
|
+
define_field :reserved1, Types::Int16, default: 0, optional: ->(gre) { gre.c? }
|
50
|
+
# @!attribute key
|
51
|
+
# @return [Integer]
|
52
|
+
define_field :key, Types::Int32, optional: ->(gre) { gre.k? }
|
53
|
+
# @!attribute sequence_number
|
54
|
+
# @return [Integer]
|
55
|
+
define_field :sequence_number, Types::Int32, optional: ->(gre) { gre.s? }
|
56
|
+
# @!attribute body
|
57
|
+
# @return [Types::String,Header::Base]
|
58
|
+
define_field :body, Types::String
|
59
|
+
|
60
|
+
alias seqnum sequence_number
|
61
|
+
alias seqnum= sequence_number=
|
62
|
+
|
63
|
+
def initialize(options={})
|
64
|
+
opts = { r: false, reserved0: 0, version: 0 }.merge(options)
|
65
|
+
super(opts)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Compute checksum and set +checksum+ field
|
69
|
+
# @return [Integer]
|
70
|
+
def calc_checksum
|
71
|
+
str = to_s
|
72
|
+
str << "\x00" if str.length % 2 == 1
|
73
|
+
sum = str.unpack('n*').reduce(:+)
|
74
|
+
|
75
|
+
while sum > 0xffff do
|
76
|
+
sum = (sum & 0xffff) + (sum >> 16)
|
77
|
+
end
|
78
|
+
sum = ~sum & 0xffff
|
79
|
+
self[:checksum].value = (sum == 0) ? 0xffff : sum
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
self.add_class GRE
|
84
|
+
IP.bind_header GRE, protocol: GRE::IP_PROTOCOL
|
85
|
+
IPv6.bind_header GRE, next: GRE::IP_PROTOCOL
|
86
|
+
|
87
|
+
GRE.bind_header IP, protocol_type: IP::ETHERTYPE
|
88
|
+
GRE.bind_header IPv6, protocol_type: IPv6::ETHERTYPE
|
89
|
+
end
|
90
|
+
end
|
data/lib/packetgen/packet.rb
CHANGED
@@ -203,7 +203,7 @@ module PacketGen
|
|
203
203
|
# @return [Array] see return from {PcapNG::File#to_file}
|
204
204
|
# @see File
|
205
205
|
def to_f(filename)
|
206
|
-
File.new.array_to_file(filename: filename, array: [self])
|
206
|
+
PcapNG::File.new.array_to_file(filename: filename, array: [self])
|
207
207
|
end
|
208
208
|
alias :write :to_f
|
209
209
|
|
@@ -58,7 +58,9 @@ module PacketGen
|
|
58
58
|
# * +:default+ gives default field value. It may be a simple value (an Integer
|
59
59
|
# for an Int field, for example) or a lambda,
|
60
60
|
# * +:builder+ to give a builder/constructor lambda to create field. The lambda
|
61
|
-
# takes one argument: {Fields} subclass object owning field
|
61
|
+
# takes one argument: {Fields} subclass object owning field,
|
62
|
+
# * +:optional+ to define this field as optional. This option takes a lambda
|
63
|
+
# parameter used to say if this field is present or not.
|
62
64
|
# For example:
|
63
65
|
# # 32-bit integer field defaulting to 1
|
64
66
|
# define_field :type, PacketGen::Types::Int32, default: 1
|
@@ -128,6 +130,9 @@ module PacketGen
|
|
128
130
|
# @option options [Object] :default default value
|
129
131
|
# @option options [Lambda] :builder lambda to construct this field.
|
130
132
|
# Parameter to this lambda is the caller object.
|
133
|
+
# @option options [Lambda] :optional define this field as optional. Given lambda
|
134
|
+
# is used to known if this field is present or not. Parameter to this lambda is
|
135
|
+
# the being defined Field object.
|
131
136
|
# @return [void]
|
132
137
|
def self.define_field(name, type, options={})
|
133
138
|
define = []
|
@@ -147,7 +152,7 @@ module PacketGen
|
|
147
152
|
define.delete(0) if type.instance_methods.include? name
|
148
153
|
class_eval define.join("\n")
|
149
154
|
@field_defs[name] = [type, options.delete(:default), options.delete(:builder),
|
150
|
-
options]
|
155
|
+
options.delete(:optional), options]
|
151
156
|
@ordered_fields << name
|
152
157
|
end
|
153
158
|
|
@@ -274,12 +279,14 @@ module PacketGen
|
|
274
279
|
# attributes, as defined by {.define_field} and by {.define_bit_fields_on}.
|
275
280
|
def initialize(options={})
|
276
281
|
@fields = {}
|
282
|
+
@optional_fields = {}
|
283
|
+
|
277
284
|
self.class.class_eval { @field_defs }.each do |field, ary|
|
278
285
|
default = ary[1].is_a?(Proc) ? ary[1].call : ary[1]
|
279
286
|
@fields[field] = if ary[2]
|
280
287
|
ary[2].call(self)
|
281
|
-
elsif !ary[
|
282
|
-
ary[0].new(ary[
|
288
|
+
elsif !ary[4].empty?
|
289
|
+
ary[0].new(ary[4])
|
283
290
|
else
|
284
291
|
ary[0].new
|
285
292
|
end
|
@@ -292,6 +299,8 @@ module PacketGen
|
|
292
299
|
else
|
293
300
|
@fields[field].from_human(value) if @fields[field].respond_to? :from_human
|
294
301
|
end
|
302
|
+
|
303
|
+
@optional_fields[field] = ary[3] if ary[3]
|
295
304
|
end
|
296
305
|
self.class.class_eval { @bit_fields }.each do |bit_field|
|
297
306
|
self.send "#{bit_field}=", options[bit_field] if options[bit_field]
|
@@ -319,6 +328,24 @@ module PacketGen
|
|
319
328
|
@ordered_fields ||= self.class.class_eval { @ordered_fields }
|
320
329
|
end
|
321
330
|
|
331
|
+
# Get all optional field name
|
332
|
+
def optional_fields
|
333
|
+
fields.select { |f| is_optional?(f) }
|
334
|
+
end
|
335
|
+
|
336
|
+
# Say if this field is optional
|
337
|
+
# @return [Boolean]
|
338
|
+
def is_optional?(field)
|
339
|
+
@optional_fields.has_key? field
|
340
|
+
end
|
341
|
+
|
342
|
+
# Say if an optional field is present
|
343
|
+
# @return [Boolean]
|
344
|
+
def is_present?(field)
|
345
|
+
return true unless is_optional?(field)
|
346
|
+
@optional_fields[field].call(self)
|
347
|
+
end
|
348
|
+
|
322
349
|
# Populate object from a binary string
|
323
350
|
# @param [String] str
|
324
351
|
# @return [Fields] self
|
@@ -327,6 +354,7 @@ module PacketGen
|
|
327
354
|
force_binary str
|
328
355
|
start = 0
|
329
356
|
fields.each do |field|
|
357
|
+
next unless is_present?(field)
|
330
358
|
if self[field].respond_to? :width
|
331
359
|
width = self[field].width
|
332
360
|
self[field].read str[start, width]
|
@@ -350,6 +378,7 @@ module PacketGen
|
|
350
378
|
str = Inspect.dashed_line(self.class, 2)
|
351
379
|
fields.each do |attr|
|
352
380
|
next if attr == :body
|
381
|
+
next unless is_present?(attr)
|
353
382
|
str << Inspect.inspect_attribute(attr, self[attr], 2)
|
354
383
|
end
|
355
384
|
str
|
@@ -358,7 +387,8 @@ module PacketGen
|
|
358
387
|
# Return object as a binary string
|
359
388
|
# @return [String]
|
360
389
|
def to_s
|
361
|
-
fields.
|
390
|
+
fields.select { |f| is_present?(f) }.
|
391
|
+
map! { |f| force_binary @fields[f].to_s }.join
|
362
392
|
end
|
363
393
|
|
364
394
|
# Size of object as binary string
|
@@ -14,7 +14,7 @@ module PacketGen
|
|
14
14
|
|
15
15
|
# internal string
|
16
16
|
# @return [String]
|
17
|
-
|
17
|
+
attr_reader :string
|
18
18
|
|
19
19
|
# @param [::String] str
|
20
20
|
# @param [Class] len_type should be a {Int} subclass
|
@@ -28,7 +28,8 @@ module PacketGen
|
|
28
28
|
# @return [IntString] self
|
29
29
|
def read(str)
|
30
30
|
unless str[0, @length.width].size == @length.width
|
31
|
-
raise ParseError,
|
31
|
+
raise ParseError,
|
32
|
+
"String too short for type #{@length.class.to_s.gsub(/.*::/, '')}"
|
32
33
|
end
|
33
34
|
@length.read str[0, @length.width]
|
34
35
|
@string.read str[@length.width, @length.to_i]
|
@@ -47,6 +48,13 @@ module PacketGen
|
|
47
48
|
@length.to_i
|
48
49
|
end
|
49
50
|
|
51
|
+
# @param [#to_s] s
|
52
|
+
# @return [String]
|
53
|
+
def string=(s)
|
54
|
+
@length.value = s.to_s.size
|
55
|
+
@string = s.to_s
|
56
|
+
end
|
57
|
+
|
50
58
|
# Get binary string
|
51
59
|
# @return [::String]
|
52
60
|
def to_s
|
data/lib/packetgen/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: packetgen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sylvain Daubert
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pcaprub
|
@@ -197,6 +197,7 @@ files:
|
|
197
197
|
- lib/packetgen/header/dot1x.rb
|
198
198
|
- lib/packetgen/header/esp.rb
|
199
199
|
- lib/packetgen/header/eth.rb
|
200
|
+
- lib/packetgen/header/gre.rb
|
200
201
|
- lib/packetgen/header/icmp.rb
|
201
202
|
- lib/packetgen/header/icmpv6.rb
|
202
203
|
- lib/packetgen/header/ike.rb
|