packetgen 3.2.0 → 3.2.1
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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/bin/pgconsole +3 -3
- data/lib/packetgen/header/arp.rb +24 -13
- data/lib/packetgen/header/asn1_base.rb +2 -2
- data/lib/packetgen/header/base.rb +1 -1
- data/lib/packetgen/header/dhcpv6/option.rb +11 -13
- data/lib/packetgen/header/dns/opt.rb +2 -2
- data/lib/packetgen/header/dns/rr.rb +61 -28
- data/lib/packetgen/header/dns.rb +13 -6
- data/lib/packetgen/header/dot11/management.rb +2 -5
- data/lib/packetgen/header/dot11.rb +1 -1
- data/lib/packetgen/header/eap.rb +1 -1
- data/lib/packetgen/header/eth.rb +1 -1
- data/lib/packetgen/header/http/response.rb +43 -23
- data/lib/packetgen/header/igmp.rb +1 -1
- data/lib/packetgen/header/ip/option.rb +2 -1
- data/lib/packetgen/header/ipv6/addr.rb +3 -0
- data/lib/packetgen/header/mdns.rb +19 -25
- data/lib/packetgen/header/mld.rb +1 -1
- data/lib/packetgen/header/ospfv2/lsa_header.rb +2 -4
- data/lib/packetgen/header/ospfv2.rb +1 -1
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +14 -5
- data/lib/packetgen/header/ospfv3/lsa.rb +1 -1
- data/lib/packetgen/header/ospfv3/lsa_header.rb +2 -4
- data/lib/packetgen/header/ospfv3.rb +1 -1
- data/lib/packetgen/header/snmp.rb +20 -14
- data/lib/packetgen/header/tcp/option.rb +1 -1
- data/lib/packetgen/header/tcp.rb +12 -5
- data/lib/packetgen/header/tftp.rb +15 -9
- data/lib/packetgen/inspect.rb +15 -9
- data/lib/packetgen/packet.rb +48 -2
- data/lib/packetgen/pcapng/file.rb +13 -13
- data/lib/packetgen/pcapng.rb +1 -0
- data/lib/packetgen/pcaprub_wrapper.rb +0 -4
- data/lib/packetgen/types/abstract_tlv.rb +1 -1
- data/lib/packetgen/types/array.rb +8 -1
- data/lib/packetgen/types/fields.rb +19 -19
- data/lib/packetgen/types/int.rb +7 -0
- data/lib/packetgen/types/oui.rb +1 -1
- data/lib/packetgen/types/tlv.rb +17 -9
- data/lib/packetgen/utils.rb +55 -21
- data/lib/packetgen/version.rb +1 -1
- data/lib/packetgen.rb +3 -3
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79dc573da10eb15bbd9f38e0c84ecdf9a92d076980628635d1b9e240e3ca2210
|
4
|
+
data.tar.gz: 0ae2bafa08e5a4a0b176276a141b8c8326265873bb20d86a75e07bb7018275ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c405a57b79c4a9bf0d9032b34d7381b33e8c0705c554023f6a8131c19c48fb0118201d94da62e4f74b9d53551cdbcd434cb6363f27a84e5c3e8459cb28d613b
|
7
|
+
data.tar.gz: 835969235415864e05b227dd5f0fb48535e3f414e60852cf788d6d90bf29be9a3a8dcf9b636ce8d500d29720753246e11459da925fea3f72f6cb8e11291565b8
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
2
|
[](https://badge.fury.io/rb/packetgen)
|
3
|
-
|
3
|
+
[](https://github.com/sdaubert/packetgen/actions?query=workflow%3Aci)
|
4
4
|
# PacketGen
|
5
5
|
|
6
6
|
PacketGen provides simple ways to generate, send and capture network packets.
|
data/bin/pgconsole
CHANGED
@@ -31,7 +31,7 @@ class PgConsole
|
|
31
31
|
define_method m, Utils.method(m).to_proc
|
32
32
|
end
|
33
33
|
|
34
|
-
def
|
34
|
+
def console_binding
|
35
35
|
binding
|
36
36
|
end
|
37
37
|
end
|
@@ -52,10 +52,10 @@ if use_pry
|
|
52
52
|
}
|
53
53
|
]
|
54
54
|
Pry.config.prompt_name = 'pg'
|
55
|
-
PgConsole.new.
|
55
|
+
PgConsole.new.console_binding.pry
|
56
56
|
else
|
57
57
|
IRB.setup nil
|
58
|
-
irb = IRB::Irb.new(IRB::WorkSpace.new(PgConsole.new.
|
58
|
+
irb = IRB::Irb.new(IRB::WorkSpace.new(PgConsole.new.console_binding))
|
59
59
|
IRB.conf[:MAIN_CONTEXT] = irb.context
|
60
60
|
irb.context.auto_indent_mode = true
|
61
61
|
irb.context.prompt_i = 'pg> '
|
data/lib/packetgen/header/arp.rb
CHANGED
@@ -81,15 +81,7 @@ module PacketGen
|
|
81
81
|
# @option options [String] :tha target hardware address
|
82
82
|
# @option options [String] :tpa targetr internet address
|
83
83
|
def initialize(options={})
|
84
|
-
options
|
85
|
-
options[:pro] ||= options[:ptype]
|
86
|
-
options[:hln] ||= options[:hlen]
|
87
|
-
options[:pln] ||= options[:plen]
|
88
|
-
options[:op] ||= options[:opcode]
|
89
|
-
options[:sha] ||= options[:src_mac]
|
90
|
-
options[:spa] ||= options[:src_ip]
|
91
|
-
options[:tha] ||= options[:dst_mac]
|
92
|
-
options[:tpa] ||= options[:dst_ip]
|
84
|
+
handle_options(options)
|
93
85
|
super
|
94
86
|
end
|
95
87
|
|
@@ -118,16 +110,35 @@ module PacketGen
|
|
118
110
|
case opcode.to_i
|
119
111
|
when 1
|
120
112
|
self.opcode = 2
|
121
|
-
|
122
|
-
self.sha, self.tha = self.tha, self.sha
|
113
|
+
invert_addresses
|
123
114
|
when 2
|
124
115
|
self.opcode = 1
|
125
|
-
|
126
|
-
self.sha = self.tha
|
116
|
+
invert_addresses
|
127
117
|
self[:tha].from_human('00:00:00:00:00:00')
|
128
118
|
end
|
129
119
|
self
|
130
120
|
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
125
|
+
def handle_options(options)
|
126
|
+
options[:hrd] ||= options[:htype]
|
127
|
+
options[:pro] ||= options[:ptype]
|
128
|
+
options[:hln] ||= options[:hlen]
|
129
|
+
options[:pln] ||= options[:plen]
|
130
|
+
options[:op] ||= options[:opcode]
|
131
|
+
options[:sha] ||= options[:src_mac]
|
132
|
+
options[:spa] ||= options[:src_ip]
|
133
|
+
options[:tha] ||= options[:dst_mac]
|
134
|
+
options[:tpa] ||= options[:dst_ip]
|
135
|
+
end
|
136
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
137
|
+
|
138
|
+
def invert_addresses
|
139
|
+
self.spa, self.tpa = self.tpa, self.spa
|
140
|
+
self.sha, self.tha = self.tha, self.sha
|
141
|
+
end
|
131
142
|
end
|
132
143
|
|
133
144
|
self.add_class ARP
|
@@ -19,7 +19,7 @@ module PacketGen
|
|
19
19
|
class ASN1Base < RASN1::Model
|
20
20
|
include Headerable
|
21
21
|
|
22
|
-
class <<self
|
22
|
+
class << self
|
23
23
|
# Define some methods from given ASN.1 fields to mimic {Base} attributes
|
24
24
|
# @param [Array<Symbol>] attributes
|
25
25
|
# @return [void]
|
@@ -27,7 +27,7 @@ module PacketGen
|
|
27
27
|
@attributes = attributes
|
28
28
|
attributes.each do |attr|
|
29
29
|
class_eval "def #{attr}; @elements[:#{attr}].value; end\n" \
|
30
|
-
|
30
|
+
"def #{attr}=(v); @elements[:#{attr}].value = v; end"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -53,19 +53,17 @@ module PacketGen
|
|
53
53
|
# @param [Hash] options
|
54
54
|
# @return [Option]
|
55
55
|
def new(options={})
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
else
|
68
|
-
super
|
56
|
+
return super unless self == Option
|
57
|
+
|
58
|
+
case options[:type]
|
59
|
+
when Integer
|
60
|
+
klass = Option.subclasses[options[:type]]
|
61
|
+
klass&.new(options)
|
62
|
+
when String
|
63
|
+
if DHCPv6.const_defined?(options[:type])
|
64
|
+
klass = DHCPv6.const_get(options[:type])
|
65
|
+
options.delete :type
|
66
|
+
klass.new(options) if klass < Option
|
69
67
|
end
|
70
68
|
else
|
71
69
|
super
|
@@ -125,8 +125,8 @@ module PacketGen
|
|
125
125
|
# @return [String]
|
126
126
|
def to_human
|
127
127
|
"#{name} #{human_type} UDPsize:#{udp_size} " \
|
128
|
-
|
129
|
-
|
128
|
+
"extRCODE:#{ext_rcode} EDNSversion:#{version} flags:#{human_flags} " \
|
129
|
+
"options:#{options.empty? ? 'none' : options.to_human}"
|
130
130
|
end
|
131
131
|
end
|
132
132
|
end
|
@@ -50,48 +50,29 @@ module PacketGen
|
|
50
50
|
self[:rdata].read data
|
51
51
|
end
|
52
52
|
|
53
|
+
# rubocop:disable Metrics/AbcSize
|
54
|
+
|
53
55
|
# Get human readable rdata
|
54
56
|
# @return [String]
|
55
57
|
def human_rdata
|
56
|
-
str = self[:rdata].inspect
|
57
|
-
|
58
|
-
# Need to mask: mDNS uses leftmost bit as a flag (CACHE FLUSH)
|
59
|
-
if self.rrclass & 0x7fff == CLASSES['IN']
|
60
|
-
case type
|
61
|
-
when TYPES['A'], TYPES['AAAA']
|
62
|
-
str = IPAddr.new_ntoh(self[:rdata]).to_s
|
63
|
-
end
|
64
|
-
end
|
58
|
+
str = human_ip_rdata || self[:rdata].inspect
|
65
59
|
|
66
|
-
name = Name.new
|
67
|
-
name.dns = self[:name].dns
|
68
60
|
case type
|
69
61
|
when TYPES['NS'], TYPES['PTR'], TYPES['CNAME']
|
62
|
+
name = Name.new
|
63
|
+
name.dns = self[:name].dns
|
70
64
|
str = name.read(self[:rdata]).to_human
|
71
65
|
when TYPES['SOA']
|
72
|
-
|
73
|
-
rname = name.read(self[:rdata][mname.sz..-1])
|
74
|
-
serial = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz, 4])
|
75
|
-
refresh = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 4, 4])
|
76
|
-
retryi = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 8, 4])
|
77
|
-
expire = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 12, 4])
|
78
|
-
minimum = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 16, 4])
|
79
|
-
str = "#{mname.to_human} #{rname.to_human} #{serial.to_i} #{refresh.to_i} " \
|
80
|
-
"#{retryi.to_i} #{expire.to_i} #{minimum.to_i}"
|
66
|
+
str = human_soa_rdata
|
81
67
|
when TYPES['MX']
|
82
|
-
|
83
|
-
exchange = name.read(self[:rdata][2..-1]).to_human
|
84
|
-
str = '%u %s' % [pref.to_i, exchange]
|
68
|
+
str = human_mx_data
|
85
69
|
when TYPES['SRV']
|
86
|
-
|
87
|
-
weight = Types::Int16.new.read(self[:rdata][2, 2])
|
88
|
-
port = Types::Int16.new.read(self[:rdata][4, 2])
|
89
|
-
target = name.read(self[:rdata][6, self[:rdata].size]).to_human
|
90
|
-
str = "#{priority.to_i} #{weight.to_i} #{port.to_i} #{target}"
|
70
|
+
str = human_srv_data
|
91
71
|
end
|
92
72
|
|
93
73
|
str
|
94
74
|
end
|
75
|
+
# rubocop:enable Metrics/AbcSize
|
95
76
|
|
96
77
|
# Get human readable class
|
97
78
|
# @return [String]
|
@@ -109,6 +90,58 @@ module PacketGen
|
|
109
90
|
def to_human
|
110
91
|
"#{human_type} #{human_rrclass} #{name} TTL #{ttl} #{human_rdata}"
|
111
92
|
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def human_ip_rdata
|
97
|
+
# Need to mask: mDNS uses leftmost bit as a flag (CACHE FLUSH)
|
98
|
+
return unless self.rrclass & 0x7fff == CLASSES['IN']
|
99
|
+
|
100
|
+
case type
|
101
|
+
when TYPES['A'], TYPES['AAAA']
|
102
|
+
IPAddr.new_ntoh(self[:rdata]).to_s
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def human_mx_data
|
107
|
+
name = Name.new
|
108
|
+
name.dns = self[:name].dns
|
109
|
+
|
110
|
+
pref = Types::Int16.new.read(self[:rdata][0, 2])
|
111
|
+
exchange = name.read(self[:rdata][2..-1]).to_human
|
112
|
+
|
113
|
+
'%u %s' % [pref.to_i, exchange]
|
114
|
+
end
|
115
|
+
|
116
|
+
# rubocop:disable Metrics/AbcSize
|
117
|
+
def human_soa_rdata
|
118
|
+
name = Name.new
|
119
|
+
name.dns = self[:name].dns
|
120
|
+
mname = name.read(self[:rdata]).dup
|
121
|
+
rname = name.read(self[:rdata][mname.sz..-1])
|
122
|
+
|
123
|
+
serial = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz, 4])
|
124
|
+
refresh = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 4, 4])
|
125
|
+
retryi = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 8, 4])
|
126
|
+
expire = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 12, 4])
|
127
|
+
minimum = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 16, 4])
|
128
|
+
|
129
|
+
"#{mname.to_human} #{rname.to_human} #{serial.to_i} #{refresh.to_i} " \
|
130
|
+
"#{retryi.to_i} #{expire.to_i} #{minimum.to_i}"
|
131
|
+
end
|
132
|
+
|
133
|
+
def human_srv_data
|
134
|
+
name = Name.new
|
135
|
+
name.dns = self[:name].dns
|
136
|
+
|
137
|
+
priority = Types::Int16.new.read(self[:rdata][0, 2])
|
138
|
+
weight = Types::Int16.new.read(self[:rdata][2, 2])
|
139
|
+
port = Types::Int16.new.read(self[:rdata][4, 2])
|
140
|
+
target = name.read(self[:rdata][6, self[:rdata].size]).to_human
|
141
|
+
|
142
|
+
"#{priority.to_i} #{weight.to_i} #{port.to_i} #{target}"
|
143
|
+
end
|
144
|
+
# rubocop:enable Metrics/AbcSize
|
112
145
|
end
|
113
146
|
end
|
114
147
|
end
|
data/lib/packetgen/header/dns.rb
CHANGED
@@ -241,18 +241,25 @@ module PacketGen
|
|
241
241
|
super do |attr|
|
242
242
|
next unless attr == :u16
|
243
243
|
|
244
|
-
|
245
|
-
|
246
|
-
str = Inspect.shift_level
|
247
|
-
str << Inspect::FMT_ATTR % ['Flags', 'flags', flags]
|
248
|
-
opcode = '%-16s (%u)' % [OPCODES.key(self.opcode), self.opcode]
|
244
|
+
str = inspect_flags
|
245
|
+
|
249
246
|
str << Inspect.shift_level
|
247
|
+
opcode = '%-16s (%u)' % [OPCODES.key(self.opcode), self.opcode]
|
250
248
|
str << Inspect::FMT_ATTR % ['Integer', 'opcode', opcode]
|
251
|
-
|
249
|
+
|
252
250
|
str << Inspect.shift_level
|
251
|
+
rcode = '%-16s (%u)' % [RCODES.key(self.rcode), self.rcode]
|
253
252
|
str << Inspect::FMT_ATTR % ['Integer', 'rcode', rcode]
|
254
253
|
end
|
255
254
|
end
|
255
|
+
|
256
|
+
private
|
257
|
+
|
258
|
+
def inspect_flags
|
259
|
+
flags = %i[qr aa tc rd ra].select! { |flag| send "#{flag}?" }.map(&:to_s).join(',')
|
260
|
+
str = Inspect.shift_level
|
261
|
+
str << Inspect::FMT_ATTR % ['Flags', 'flags', flags]
|
262
|
+
end
|
256
263
|
end
|
257
264
|
|
258
265
|
self.add_class DNS
|
@@ -53,12 +53,9 @@ module PacketGen
|
|
53
53
|
# @return [self]
|
54
54
|
# @since 2.1.3
|
55
55
|
def add_element(type:, value:)
|
56
|
-
|
57
|
-
self[:body].elements << { type: type, value: value }
|
58
|
-
else
|
59
|
-
raise FormatError, 'Before adding an Element, you have to add a Dot11::SubMngt subclass instance'
|
60
|
-
end
|
56
|
+
raise FormatError, 'Before adding an Element, you have to add a Dot11::SubMngt subclass instance' unless self[:body].is_a? SubMngt
|
61
57
|
|
58
|
+
self[:body].elements << { type: type, value: value }
|
62
59
|
self
|
63
60
|
end
|
64
61
|
|
@@ -355,7 +355,7 @@ module PacketGen
|
|
355
355
|
def added_to_packet(packet)
|
356
356
|
return if packet.respond_to? :dot11
|
357
357
|
|
358
|
-
packet.instance_eval("def dot11(arg=nil); header(#{self.class}, arg); end")
|
358
|
+
packet.instance_eval("def dot11(arg=nil); header(#{self.class}, arg); end") # def dot11(arg=nil); header(Dot11, arg); end
|
359
359
|
end
|
360
360
|
|
361
361
|
private
|
data/lib/packetgen/header/eap.rb
CHANGED
@@ -218,7 +218,7 @@ module PacketGen
|
|
218
218
|
def added_to_packet(packet)
|
219
219
|
return if packet.respond_to? :eap
|
220
220
|
|
221
|
-
packet.instance_eval("def eap(arg=nil); header(#{self.class}, arg); end")
|
221
|
+
packet.instance_eval("def eap(arg=nil); header(#{self.class}, arg); end") # def eap(arg=nil); header(EAP, arg); end
|
222
222
|
end
|
223
223
|
|
224
224
|
# Invert between a request and a response packet. Not action for
|
data/lib/packetgen/header/eth.rb
CHANGED
@@ -67,11 +67,42 @@ module PacketGen
|
|
67
67
|
# Read in the HTTP portion of the packet, and parse it.
|
68
68
|
# @return [PacketGen::HTTP::Response]
|
69
69
|
def read(str)
|
70
|
-
|
71
|
-
|
70
|
+
headers, data = collect_headers_and_data(str)
|
71
|
+
|
72
|
+
unless headers.empty?
|
73
|
+
extract_info_from_first_line(headers)
|
74
|
+
self[:headers].read(headers.join("\n"))
|
75
|
+
end
|
76
|
+
self[:body].read data.join("\n")
|
77
|
+
|
78
|
+
self
|
79
|
+
end
|
80
|
+
|
81
|
+
def parse?
|
82
|
+
version.start_with?('HTTP/1.')
|
83
|
+
end
|
84
|
+
|
85
|
+
# String representation of data.
|
86
|
+
# @return [String]
|
87
|
+
def to_s
|
88
|
+
raise_on_bad_version_status
|
89
|
+
|
90
|
+
str = +''
|
91
|
+
str << self.version << ' ' << self.status_code << ' ' << self.status_mesg << "\r\n"
|
92
|
+
str << self[:headers].to_s if self[:headers].given?
|
93
|
+
str << self.body
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def collect_headers_and_data(str)
|
72
99
|
headers = [] # header stream
|
73
100
|
data = [] # data stream
|
74
101
|
switch = false
|
102
|
+
|
103
|
+
str = str.bytes.map!(&:chr).join unless str.valid_encoding?
|
104
|
+
arr = str.split("\r\n")
|
105
|
+
|
75
106
|
arr.each do |line|
|
76
107
|
if line.empty?
|
77
108
|
data << line if switch # already done
|
@@ -85,34 +116,23 @@ module PacketGen
|
|
85
116
|
headers << line
|
86
117
|
end
|
87
118
|
end
|
88
|
-
|
89
|
-
|
90
|
-
if first_line.size >= 3
|
91
|
-
self[:version].read first_line[0]
|
92
|
-
self[:status_code].read first_line[1]
|
93
|
-
self[:status_mesg].read first_line[2..-1].join(' ')
|
94
|
-
end
|
95
|
-
self[:headers].read(headers.join("\n"))
|
96
|
-
end
|
97
|
-
self[:body].read data.join("\n")
|
98
|
-
self
|
119
|
+
|
120
|
+
[headers, data]
|
99
121
|
end
|
100
122
|
|
101
|
-
def
|
102
|
-
|
123
|
+
def extract_info_from_first_line(headers)
|
124
|
+
first_line = headers.shift.split
|
125
|
+
return if first_line.size < 3
|
126
|
+
|
127
|
+
self[:version].read first_line[0]
|
128
|
+
self[:status_code].read first_line[1]
|
129
|
+
self[:status_mesg].read first_line[2..-1].join(' ')
|
103
130
|
end
|
104
131
|
|
105
|
-
|
106
|
-
# @return [String]
|
107
|
-
def to_s
|
132
|
+
def raise_on_bad_version_status
|
108
133
|
raise FormatError, 'Missing #status_code.' if self.status_code.empty?
|
109
134
|
raise FormatError, 'Missing #status_mesg.' if self.status_mesg.empty?
|
110
135
|
raise FormatError, 'Missing #version.' if self.version.empty?
|
111
|
-
|
112
|
-
str = +''
|
113
|
-
str << self.version << ' ' << self.status_code << ' ' << self.status_mesg << "\r\n"
|
114
|
-
str << self[:headers].to_s if self[:headers].given?
|
115
|
-
str << self.body
|
116
136
|
end
|
117
137
|
end
|
118
138
|
end
|
@@ -77,7 +77,7 @@ module PacketGen
|
|
77
77
|
# directly called
|
78
78
|
def added_to_packet(packet)
|
79
79
|
igmp_idx = packet.headers.size
|
80
|
-
packet.instance_eval "def igmpize() @headers[#{igmp_idx}].igmpize; end"
|
80
|
+
packet.instance_eval "def igmpize() @headers[#{igmp_idx}].igmpize; end" # def igmpize() @headers[2].igmpize; end
|
81
81
|
end
|
82
82
|
|
83
83
|
# Get human readbale type
|
@@ -55,7 +55,7 @@ module PacketGen
|
|
55
55
|
# option data
|
56
56
|
# @return [String]
|
57
57
|
define_field :data, Types::String, optional: ->(h) { h.length > 2 },
|
58
|
-
|
58
|
+
builder: ->(h, t) { t.new(length_from: -> { h.length - 2 }) }
|
59
59
|
|
60
60
|
# @!attribute copied
|
61
61
|
# 1-bit copied flag from {#type} field
|
@@ -161,6 +161,7 @@ module PacketGen
|
|
161
161
|
|
162
162
|
# Strict Source and Record Route IP option
|
163
163
|
class SSRR < LSRR; end
|
164
|
+
|
164
165
|
# Record Route IP option
|
165
166
|
class RR < LSRR; end
|
166
167
|
|
@@ -49,6 +49,8 @@ module PacketGen
|
|
49
49
|
# @return [Integer]
|
50
50
|
define_field :a8, Types::Int16
|
51
51
|
|
52
|
+
# rubocop:disable Metrics/AbcSize
|
53
|
+
|
52
54
|
# Read a colon-delimited address
|
53
55
|
# @param [String] str
|
54
56
|
# @return [self]
|
@@ -69,6 +71,7 @@ module PacketGen
|
|
69
71
|
self.a8 = addri & 0xffff
|
70
72
|
self
|
71
73
|
end
|
74
|
+
# rubocop:enable Metrics/AbcSize
|
72
75
|
|
73
76
|
# Addr6 in human readable form (colon-delimited hex string)
|
74
77
|
# @return [String]
|
@@ -31,32 +31,10 @@ module PacketGen
|
|
31
31
|
case iph
|
32
32
|
when IP
|
33
33
|
iph.dst = '224.0.0.251'
|
34
|
-
|
35
|
-
mac = case llh
|
36
|
-
when Eth
|
37
|
-
llh[:dst]
|
38
|
-
when Dot11
|
39
|
-
if llh.to_ds?
|
40
|
-
llh[:mac3]
|
41
|
-
else
|
42
|
-
llh[:mac1]
|
43
|
-
end
|
44
|
-
end
|
45
|
-
mac.from_human('01:00:5E:00:00:FB')
|
34
|
+
dst_mac.from_human('01:00:5E:00:00:FB')
|
46
35
|
when IPv6
|
47
36
|
iph.dst = 'ff02::fb'
|
48
|
-
|
49
|
-
mac = case llh
|
50
|
-
when Eth
|
51
|
-
llh[:dst]
|
52
|
-
when Dot11
|
53
|
-
if llh.to_ds?
|
54
|
-
llh[:mac3]
|
55
|
-
else
|
56
|
-
llh[:mac1]
|
57
|
-
end
|
58
|
-
end
|
59
|
-
mac.from_human('33:33:00:00:00:FB')
|
37
|
+
dst_mac.from_human('33:33:00:00:00:FB')
|
60
38
|
end
|
61
39
|
end
|
62
40
|
|
@@ -67,12 +45,28 @@ module PacketGen
|
|
67
45
|
# Needed by new bind API.
|
68
46
|
def added_to_packet(packet)
|
69
47
|
mdns_idx = packet.headers.size
|
70
|
-
packet.instance_eval "def mdnsize() @headers[#{mdns_idx}].mdnsize; end"
|
48
|
+
packet.instance_eval "def mdnsize() @headers[#{mdns_idx}].mdnsize; end" # def mdnsize() @headers[4].mdnsize; end
|
71
49
|
return unless packet.is? 'UDP'
|
72
50
|
return unless packet.udp.sport.zero?
|
73
51
|
|
74
52
|
packet.udp.sport = UDP_PORT
|
75
53
|
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def dst_mac
|
58
|
+
llh = ll_header(self)
|
59
|
+
case llh
|
60
|
+
when Eth
|
61
|
+
llh[:dst]
|
62
|
+
when Dot11
|
63
|
+
if llh.to_ds?
|
64
|
+
llh[:mac3]
|
65
|
+
else
|
66
|
+
llh[:mac1]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
76
70
|
end
|
77
71
|
|
78
72
|
self.add_class MDNS
|
data/lib/packetgen/header/mld.rb
CHANGED
@@ -68,7 +68,7 @@ module PacketGen
|
|
68
68
|
# directly called
|
69
69
|
def added_to_packet(packet)
|
70
70
|
mld_idx = packet.headers.size
|
71
|
-
packet.instance_eval "def mldize() @headers[#{mld_idx}].mldize; end"
|
71
|
+
packet.instance_eval "def mldize() @headers[#{mld_idx}].mldize; end" # def mldize() @headers[3].mldize; end
|
72
72
|
end
|
73
73
|
|
74
74
|
# Fixup IP header according to RFC 2710:
|
@@ -77,17 +77,15 @@ module PacketGen
|
|
77
77
|
# Compute and set Fletcher-16 checksum on LSA
|
78
78
|
# @return [Integer]
|
79
79
|
def calc_checksum
|
80
|
-
bytes = to_s[2..-1].unpack('C*')
|
81
|
-
|
82
80
|
c0 = c1 = 0
|
83
|
-
|
81
|
+
to_s[2..-1].unpack('C*').each do |byte|
|
84
82
|
c0 += byte
|
85
83
|
c1 += c0
|
86
84
|
end
|
87
85
|
c0 %= 255
|
88
86
|
c1 %= 255
|
89
87
|
|
90
|
-
x = ((sz -
|
88
|
+
x = ((sz - 17) * c0 - c1) % 255
|
91
89
|
x += 255 if x <= 0
|
92
90
|
y = 255 * 2 - c0 - x
|
93
91
|
y -= 255 if y > 255
|
@@ -167,7 +167,7 @@ module PacketGen
|
|
167
167
|
# directly called
|
168
168
|
def added_to_packet(packet)
|
169
169
|
ospf_idx = packet.headers.size
|
170
|
-
packet.instance_eval "def ospfize(**kwargs) @headers[#{ospf_idx}].ospfize(**kwargs); end"
|
170
|
+
packet.instance_eval "def ospfize(**kwargs) @headers[#{ospf_idx}].ospfize(**kwargs); end" # def ospfize(**kwargs) @headers[2].ospfize(**kwargs); end
|
171
171
|
end
|
172
172
|
|
173
173
|
# Compute checksum and set +checksum+ field
|
@@ -71,11 +71,8 @@ module PacketGen
|
|
71
71
|
# @param [String] str
|
72
72
|
# @return [void]
|
73
73
|
def from_human(str)
|
74
|
-
|
75
|
-
|
76
|
-
addr = IPv6::Addr.new.from_human(pfx)
|
77
|
-
ary_size = (len + 31) / 32
|
78
|
-
ary = addr.to_a[0...ary_size * 2]
|
74
|
+
ary, len = ary_and_prefix_len_from_str(str)
|
75
|
+
|
79
76
|
self.prefix.clear
|
80
77
|
ary.each_with_index do |v, i|
|
81
78
|
if i.even?
|
@@ -86,6 +83,18 @@ module PacketGen
|
|
86
83
|
end
|
87
84
|
self.length = len
|
88
85
|
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def ary_and_prefix_len_from_str(str)
|
90
|
+
pfx, len = str.split('/')
|
91
|
+
len = (len || 128).to_i
|
92
|
+
addr = IPv6::Addr.new.from_human(pfx)
|
93
|
+
ary_size = (len + 31) / 32
|
94
|
+
ary = addr.to_a[0...ary_size * 2]
|
95
|
+
|
96
|
+
[ary, len]
|
97
|
+
end
|
89
98
|
end
|
90
99
|
|
91
100
|
# Array of {IPv6Prefix}
|
@@ -35,7 +35,7 @@ module PacketGen
|
|
35
35
|
# @return [String]
|
36
36
|
def to_human
|
37
37
|
"Link<type:#{type},metric:#{metric},id:#{interface_id}," \
|
38
|
-
|
38
|
+
"neighbor_id:#{neighbor_interface_id},neighbor_router:#{neighbor_router_id}>"
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|