packetgen 3.2.0 → 3.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/packetgen.svg)](https://badge.fury.io/rb/packetgen)
|
3
|
-
|
3
|
+
[![Action status](https://github.com/sdaubert/packetgen/workflows/ci/badge.svg?branch=master)](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
|
|