packetgen 2.8.7 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +0 -1
- data/README.md +5 -4
- data/lib/packetgen.rb +6 -12
- data/lib/packetgen/capture.rb +43 -39
- data/lib/packetgen/config.rb +0 -1
- data/lib/packetgen/deprecation.rb +1 -1
- data/lib/packetgen/header.rb +9 -9
- data/lib/packetgen/header/asn1_base.rb +10 -10
- data/lib/packetgen/header/base.rb +42 -101
- data/lib/packetgen/header/dhcp/option.rb +5 -11
- data/lib/packetgen/header/dhcpv6/duid.rb +2 -0
- data/lib/packetgen/header/dhcpv6/option.rb +2 -19
- data/lib/packetgen/header/dhcpv6/options.rb +7 -0
- data/lib/packetgen/header/dns.rb +5 -23
- data/lib/packetgen/header/dns/name.rb +1 -0
- data/lib/packetgen/header/dns/qdsection.rb +1 -0
- data/lib/packetgen/header/dns/question.rb +3 -7
- data/lib/packetgen/header/dns/rr.rb +3 -0
- data/lib/packetgen/header/dns/rrsection.rb +1 -0
- data/lib/packetgen/header/dot11.rb +1 -17
- data/lib/packetgen/header/dot1x.rb +1 -0
- data/lib/packetgen/header/eap.rb +4 -7
- data/lib/packetgen/header/eth.rb +2 -0
- data/lib/packetgen/header/http/headers.rb +3 -0
- data/lib/packetgen/header/http/request.rb +5 -4
- data/lib/packetgen/header/http/response.rb +5 -4
- data/lib/packetgen/header/icmp.rb +6 -0
- data/lib/packetgen/header/icmpv6.rb +6 -0
- data/lib/packetgen/header/igmpv3/mq.rb +2 -0
- data/lib/packetgen/header/ip.rb +32 -30
- data/lib/packetgen/header/ip/addr.rb +1 -0
- data/lib/packetgen/header/ip/option.rb +23 -20
- data/lib/packetgen/header/ip/options.rb +11 -24
- data/lib/packetgen/header/ipv6.rb +45 -34
- data/lib/packetgen/header/ipv6/addr.rb +2 -0
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +7 -31
- data/lib/packetgen/header/mdns.rb +1 -0
- data/lib/packetgen/header/mldv2/mlq.rb +2 -0
- data/lib/packetgen/header/ospfv2/lsa.rb +15 -25
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +1 -1
- data/lib/packetgen/header/ospfv3/lsa.rb +8 -25
- data/lib/packetgen/header/snmp.rb +2 -0
- data/lib/packetgen/header/tcp.rb +23 -2
- data/lib/packetgen/header/tcp/option.rb +51 -52
- data/lib/packetgen/header/tcp/options.rb +17 -52
- data/lib/packetgen/header/tftp.rb +3 -0
- data/lib/packetgen/header/udp.rb +8 -0
- data/lib/packetgen/packet.rb +119 -102
- data/lib/packetgen/pcapng/block.rb +4 -10
- data/lib/packetgen/pcapng/epb.rb +4 -4
- data/lib/packetgen/pcapng/file.rb +7 -3
- data/lib/packetgen/pcapng/idb.rb +2 -2
- data/lib/packetgen/pcapng/shb.rb +3 -3
- data/lib/packetgen/pcapng/spb.rb +1 -8
- data/lib/packetgen/pcapng/unknown_block.rb +0 -7
- data/lib/packetgen/types.rb +1 -0
- data/lib/packetgen/types/array.rb +73 -71
- data/lib/packetgen/types/cstring.rb +1 -1
- data/lib/packetgen/types/enum.rb +3 -3
- data/lib/packetgen/types/fields.rb +66 -106
- data/lib/packetgen/types/int.rb +9 -5
- data/lib/packetgen/types/length_from.rb +45 -0
- data/lib/packetgen/types/oui.rb +2 -0
- data/lib/packetgen/types/string.rb +10 -16
- data/lib/packetgen/types/tlv.rb +7 -15
- data/lib/packetgen/utils.rb +8 -8
- data/lib/packetgen/utils/arp_spoofer.rb +1 -2
- data/lib/packetgen/version.rb +1 -1
- metadata +3 -21
- data/lib/packetgen/header/crypto.rb +0 -62
- data/lib/packetgen/header/esp.rb +0 -413
- data/lib/packetgen/header/ike.rb +0 -243
- data/lib/packetgen/header/ike/auth.rb +0 -165
- data/lib/packetgen/header/ike/cert.rb +0 -76
- data/lib/packetgen/header/ike/certreq.rb +0 -66
- data/lib/packetgen/header/ike/id.rb +0 -99
- data/lib/packetgen/header/ike/ke.rb +0 -79
- data/lib/packetgen/header/ike/nonce.rb +0 -40
- data/lib/packetgen/header/ike/notify.rb +0 -176
- data/lib/packetgen/header/ike/payload.rb +0 -315
- data/lib/packetgen/header/ike/sa.rb +0 -561
- data/lib/packetgen/header/ike/sk.rb +0 -261
- data/lib/packetgen/header/ike/ts.rb +0 -270
- data/lib/packetgen/header/ike/vendor_id.rb +0 -39
- data/lib/packetgen/header/netbios.rb +0 -20
- data/lib/packetgen/header/netbios/datagram.rb +0 -105
- data/lib/packetgen/header/netbios/name.rb +0 -67
- data/lib/packetgen/header/netbios/session.rb +0 -64
@@ -74,6 +74,8 @@ module PacketGen
|
|
74
74
|
# @return [Integer]
|
75
75
|
define_bit_fields_on :u8, :resv, 4, :flag_s, :qrv, 3
|
76
76
|
|
77
|
+
undef qqic, qqic=
|
78
|
+
|
77
79
|
# Get QQIC value
|
78
80
|
# @note May return a different value from value previously set, as a
|
79
81
|
# float encoding is used to encode big values. See {IGMPv3.decode}.
|
data/lib/packetgen/header/ip.rb
CHANGED
@@ -9,6 +9,22 @@ require 'socket'
|
|
9
9
|
|
10
10
|
module PacketGen
|
11
11
|
module Header
|
12
|
+
# IP protocol ({https://tools.ietf.org/html/rfc791 RFC 791})
|
13
|
+
# 0 1 2 3
|
14
|
+
# 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
|
15
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
16
|
+
# |Version| IHL |Type of Service| Total Length |
|
17
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
18
|
+
# | Identification |Flags| Fragment Offset |
|
19
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
20
|
+
# | Time to Live | Protocol | Header Checksum |
|
21
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
22
|
+
# | Source Address |
|
23
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
24
|
+
# | Destination Address |
|
25
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
26
|
+
# | Options | Padding |
|
27
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
12
28
|
# A IP header consists of:
|
13
29
|
# * a first byte ({#u8} of {Types::Int8} type) composed of:
|
14
30
|
# * a 4-bit {#version} field,
|
@@ -24,7 +40,7 @@ module PacketGen
|
|
24
40
|
# * a {#checksum} field (+Int16+),
|
25
41
|
# * a source IP address ({#src}, {Addr} type),
|
26
42
|
# * a destination IP address ({#dst}, +Addr+ type),
|
27
|
-
# * an optional {#options} field ({
|
43
|
+
# * an optional {#options} field ({Options} type),
|
28
44
|
# * and a {#body} ({Types::String} type).
|
29
45
|
#
|
30
46
|
# == Create a IP header
|
@@ -61,6 +77,14 @@ module PacketGen
|
|
61
77
|
# ip[:src] # => PacketGen::Header::IP::Addr
|
62
78
|
# ip.dst = '127.0.0.2'
|
63
79
|
# ip.body.read 'this is a body'
|
80
|
+
#
|
81
|
+
# == Add IP options
|
82
|
+
# IP has an {#options} attribute used to store datagram options.
|
83
|
+
# pkt = PacketGen.gen('IP')
|
84
|
+
# # add option from class
|
85
|
+
# pkt.ip.options << PacketGen::Header::IP::RA.new
|
86
|
+
# # or use a hash
|
87
|
+
# pkt.ip.options << { type: 'RR', data: ['192.168.16.4']}
|
64
88
|
# @author Sylvain Daubert
|
65
89
|
class IP < Base; end
|
66
90
|
|
@@ -84,7 +108,7 @@ module PacketGen
|
|
84
108
|
define_field :length, Types::Int16, default: 20
|
85
109
|
# @!attribute id
|
86
110
|
# @return [Integer] 16-bit ID
|
87
|
-
define_field :id, Types::Int16, default: ->(
|
111
|
+
define_field :id, Types::Int16, default: ->(_) { rand(65_535) }
|
88
112
|
# @!attribute frag
|
89
113
|
# @return [Integer] 16-bit frag word
|
90
114
|
define_field :frag, Types::Int16, default: 0
|
@@ -106,7 +130,8 @@ module PacketGen
|
|
106
130
|
# @!attribute options
|
107
131
|
# @since 2.2.0
|
108
132
|
# @return [Types::String]
|
109
|
-
define_field :options, Options, optional: ->(h) { h.ihl > 5 }
|
133
|
+
define_field :options, Options, optional: ->(h) { h.ihl > 5 },
|
134
|
+
builder: ->(h, t) { t.new(length_from: -> { (h.ihl - 5) * 4 }) }
|
110
135
|
# @!attribute body
|
111
136
|
# @return [Types::String,Header::Base]
|
112
137
|
define_field :body, Types::String
|
@@ -164,31 +189,6 @@ module PacketGen
|
|
164
189
|
checksum.zero? ? 0xffff : checksum
|
165
190
|
end
|
166
191
|
|
167
|
-
# Populate object from a binary string
|
168
|
-
# @param [String] str
|
169
|
-
# @return [Fields] self
|
170
|
-
def read(str)
|
171
|
-
return self if str.nil?
|
172
|
-
force_binary str
|
173
|
-
self[:u8].read str[0, 1]
|
174
|
-
self[:tos].read str[1, 1]
|
175
|
-
self[:length].read str[2, 2]
|
176
|
-
self[:id].read str[4, 2]
|
177
|
-
self[:frag].read str[6, 2]
|
178
|
-
self[:ttl].read str[8, 1]
|
179
|
-
self[:protocol].read str[9, 1]
|
180
|
-
self[:checksum].read str[10, 2]
|
181
|
-
self[:src].read str[12, 4]
|
182
|
-
self[:dst].read str[16, 4]
|
183
|
-
opt_size = 0
|
184
|
-
if self.ihl > 5
|
185
|
-
opt_size = (self.ihl - 5) * 4
|
186
|
-
self[:options].read str[20, opt_size]
|
187
|
-
end
|
188
|
-
self[:body].read str[20 + opt_size..-1]
|
189
|
-
self
|
190
|
-
end
|
191
|
-
|
192
192
|
# Compute checksum and set +checksum+ field
|
193
193
|
# @return [Integer]
|
194
194
|
def calc_checksum
|
@@ -207,10 +207,12 @@ module PacketGen
|
|
207
207
|
self[:checksum].value = IP.reduce_checksum(checksum)
|
208
208
|
end
|
209
209
|
|
210
|
-
# Compute
|
210
|
+
# Compute and set +length+ and +ihl+ field
|
211
211
|
# @return [Integer]
|
212
|
+
# @since 3.0.0 add +ihl+ calculation
|
212
213
|
def calc_length
|
213
214
|
Base.calculate_and_set_length self
|
215
|
+
self.ihl = 5 + self[:options].sz / 4
|
214
216
|
end
|
215
217
|
|
216
218
|
# Get IP part of pseudo header checksum.
|
@@ -265,7 +267,7 @@ module PacketGen
|
|
265
267
|
# Get binary string. Fixup IHL if needed (IP header has options, and IHL
|
266
268
|
# was not set by user).
|
267
269
|
def to_s
|
268
|
-
self.ihl = 5 + options.sz / 4 if self.ihl == 5
|
270
|
+
self.ihl = 5 + self[:options].sz / 4 if self.ihl == 5
|
269
271
|
super
|
270
272
|
end
|
271
273
|
|
@@ -70,15 +70,32 @@ module PacketGen
|
|
70
70
|
# @return [Hash]
|
71
71
|
def self.types
|
72
72
|
return @types if defined? @types
|
73
|
+
|
73
74
|
@types = {}
|
74
75
|
Option.constants.each do |cst|
|
75
76
|
next unless cst.to_s.end_with? '_TYPE'
|
77
|
+
|
76
78
|
optname = cst.to_s.sub(/_TYPE/, '')
|
77
|
-
@types[
|
79
|
+
@types[optname] = Option.const_get(cst)
|
78
80
|
end
|
79
81
|
@types
|
80
82
|
end
|
81
83
|
|
84
|
+
# Factory to build an option from its type
|
85
|
+
# @return [Option]
|
86
|
+
def Option.build(options={})
|
87
|
+
type = options.delete(:type)
|
88
|
+
klass = case type
|
89
|
+
when String
|
90
|
+
types.key?(type) ? IP.const_get(type) : self
|
91
|
+
when Integer
|
92
|
+
types.value?(type) ? IP.const_get(types.key(type)) : self
|
93
|
+
else
|
94
|
+
self
|
95
|
+
end
|
96
|
+
klass.new(options)
|
97
|
+
end
|
98
|
+
|
82
99
|
def initialize(options={})
|
83
100
|
unless options[:type]
|
84
101
|
opt_name = self.class.to_s.gsub(/.*::/, '')
|
@@ -87,6 +104,7 @@ module PacketGen
|
|
87
104
|
end
|
88
105
|
end
|
89
106
|
super
|
107
|
+
self.length = sz if respond_to?(:length) && options[:length].nil?
|
90
108
|
end
|
91
109
|
|
92
110
|
# Get binary string. Set {#length} field.
|
@@ -99,7 +117,7 @@ module PacketGen
|
|
99
117
|
# Get a human readable string
|
100
118
|
# @return [String]
|
101
119
|
def to_human
|
102
|
-
str = self.class == Option ? "unk-#{type}" : self.class.to_s.sub(/.*::/, '')
|
120
|
+
str = self.class == Option ? +"unk-#{type}" : self.class.to_s.sub(/.*::/, '')
|
103
121
|
if respond_to?(:length) && (length > 2) && !self[:data].to_s.empty?
|
104
122
|
str << ":#{self[:data].to_s.inspect}"
|
105
123
|
end
|
@@ -114,8 +132,7 @@ module PacketGen
|
|
114
132
|
end
|
115
133
|
|
116
134
|
# No OPeration IP option
|
117
|
-
class NOP < EOL
|
118
|
-
end
|
135
|
+
class NOP < EOL; end
|
119
136
|
|
120
137
|
# Loose Source and Record Route IP option
|
121
138
|
class LSRR < Option
|
@@ -124,25 +141,11 @@ module PacketGen
|
|
124
141
|
# @!attribute pointer
|
125
142
|
# 8-bit pointer on next address
|
126
143
|
# @return [Integer]
|
127
|
-
define_field :pointer, Types::Int8
|
144
|
+
define_field :pointer, Types::Int8, default: 4
|
128
145
|
# @!attribute data
|
129
146
|
# Array of IP addresses
|
130
147
|
# @return [Types::Array<IP::Addr>]
|
131
|
-
define_field :data, ArrayOfAddr,
|
132
|
-
builder: ->(h, t) { t.new(length_from: -> { h.length - 2 }) }
|
133
|
-
|
134
|
-
# Populate object from a binary string
|
135
|
-
# @param [String] str
|
136
|
-
# @return [Fields] self
|
137
|
-
def read(str)
|
138
|
-
return self if str.nil?
|
139
|
-
force_binary str
|
140
|
-
self[:type].read str[0, 1]
|
141
|
-
self[:length].read str[1, 1]
|
142
|
-
self[:pointer].read str[2, 1]
|
143
|
-
self[:data].read str[3, length - 3]
|
144
|
-
self
|
145
|
-
end
|
148
|
+
define_field :data, ArrayOfAddr, builder: ->(h, t) { t.new(length_from: -> { h.length - 3 }) }
|
146
149
|
|
147
150
|
# Get IP address pointer by {#pointer}
|
148
151
|
# @return [Addr]
|
@@ -15,30 +15,6 @@ module PacketGen
|
|
15
15
|
|
16
16
|
HUMAN_SEPARATOR = ';'
|
17
17
|
|
18
|
-
# Read IP header options from a string
|
19
|
-
# @param [String] str binary string
|
20
|
-
# @return [self]
|
21
|
-
def read(str)
|
22
|
-
clear
|
23
|
-
return self if str.nil?
|
24
|
-
PacketGen.force_binary str
|
25
|
-
|
26
|
-
i = 0
|
27
|
-
types = Option.types
|
28
|
-
while i < str.to_s.length
|
29
|
-
type = str[i, 1].unpack('C').first
|
30
|
-
this_option = if types[type].nil?
|
31
|
-
Option.new
|
32
|
-
else
|
33
|
-
types[type].new
|
34
|
-
end
|
35
|
-
this_option.read str[i, str.size]
|
36
|
-
self << this_option
|
37
|
-
i += this_option.sz
|
38
|
-
end
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
18
|
# Get binary string
|
43
19
|
# @return [String]
|
44
20
|
def to_s
|
@@ -48,6 +24,17 @@ module PacketGen
|
|
48
24
|
end
|
49
25
|
str
|
50
26
|
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def record_from_hash(hsh)
|
31
|
+
Option.build(hsh)
|
32
|
+
end
|
33
|
+
|
34
|
+
def real_type(opt)
|
35
|
+
types = Option.types
|
36
|
+
types.value?(opt.type) ? IP.const_get(types.key(opt.type)) : opt.class
|
37
|
+
end
|
51
38
|
end
|
52
39
|
end
|
53
40
|
end
|
@@ -10,8 +10,33 @@ require 'ipaddr'
|
|
10
10
|
|
11
11
|
module PacketGen
|
12
12
|
module Header
|
13
|
+
# IPv6 ({https://tools.ietf.org/html/rfc8200 RFC 8200})
|
14
|
+
# 0 1 2 3
|
15
|
+
# 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
|
16
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
17
|
+
# |Version| Traffic Class | Flow Label |
|
18
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
19
|
+
# | Payload Length | Next Header | Hop Limit |
|
20
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
21
|
+
# | |
|
22
|
+
# + +
|
23
|
+
# | |
|
24
|
+
# + Source Address +
|
25
|
+
# | |
|
26
|
+
# + +
|
27
|
+
# | |
|
28
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
29
|
+
# | |
|
30
|
+
# + +
|
31
|
+
# | |
|
32
|
+
# + Destination Address +
|
33
|
+
# | |
|
34
|
+
# + +
|
35
|
+
# | |
|
36
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
37
|
+
#
|
13
38
|
# A IPv6 header consists of:
|
14
|
-
# * a first 32-bit word ({#u32}, of {Types::Int32} type)
|
39
|
+
# * a first 32-bit word ({#u32}, of {Types::Int32} type) composed of:
|
15
40
|
# * a 4-bit {#version} field,
|
16
41
|
# * a 8-bit {#traffic_class} field,
|
17
42
|
# * a 20-bit {#flow_label} field,
|
@@ -20,6 +45,7 @@ module PacketGen
|
|
20
45
|
# * a hop-limit field ({#hop}, +Int8+ type),
|
21
46
|
# * a source address field ({#src}, {IPv6::Addr} type),
|
22
47
|
# * a destination address field ({#dst}, +IPv6::Addr+ type),
|
48
|
+
# * and a {#body} ({Types::String} type).
|
23
49
|
#
|
24
50
|
# == Create a IPv6 header
|
25
51
|
# # standalone
|
@@ -44,6 +70,18 @@ module PacketGen
|
|
44
70
|
# ipv6[:src] # => PacketGen::Header::IPv6::Addr
|
45
71
|
# ipv6.dst = '2001:1234:5678:abcd::123'
|
46
72
|
# ipv6.body.read 'this is a body'
|
73
|
+
#
|
74
|
+
# == Add IPv6 extensions
|
75
|
+
# In IPv6, optional extensions are encoded in separate headers that
|
76
|
+
# may be placed between the IPv6 header and the upper-layer header.
|
77
|
+
#
|
78
|
+
# In PacketGen, a IPv6 extension is processedf as a classical header:
|
79
|
+
# pkt = PacketGen.gen('IPv6')
|
80
|
+
# # Add a HopByHop extension
|
81
|
+
# pkt.add('IPv6::HopByHop')
|
82
|
+
# pkt.ipv6_hopbyhop.options << { type: 'router_alert', value: [0].pack('n') }
|
83
|
+
# # Add another header
|
84
|
+
# pkt.add('UDP')
|
47
85
|
# @author Sylvain Daubert
|
48
86
|
class IPv6 < Base; end
|
49
87
|
|
@@ -104,34 +142,14 @@ module PacketGen
|
|
104
142
|
sum
|
105
143
|
end
|
106
144
|
|
107
|
-
# Send IPv6 packet on wire.
|
108
|
-
#
|
109
|
-
# When sending packet at IPv6 level, +version+, +flow_label+ and +length+
|
110
|
-
# fields are set by kernel. Source address should be a unicast address
|
111
|
-
# assigned to the host. To set any of this fields, use {Eth#to_w}.
|
112
|
-
# @param [String] iface interface name
|
145
|
+
# Send IPv6 packet on wire. All fields may be set (even {#version}).
|
146
|
+
# @param [String] _iface interface name (not used)
|
113
147
|
# @return [void]
|
114
|
-
|
115
|
-
|
148
|
+
# @since 3.0.0 no more limitations on +flow_label+, +length+ and +src+ fields.
|
149
|
+
def to_w(_iface=nil)
|
150
|
+
sock = Socket.new(Socket::AF_INET6, Socket::SOCK_RAW, Socket::IPPROTO_RAW)
|
116
151
|
sockaddrin = Socket.sockaddr_in(0, dst)
|
117
|
-
|
118
|
-
# IPv6 RAW sockets don't have IPHDRINCL option to send IPv6 header.
|
119
|
-
# So, header must be built using ancillary data.
|
120
|
-
# Only src address, traffic_class and hop_limit can be set this way.
|
121
|
-
hop_limit = Socket::AncillaryData.int(Socket::AF_INET6,
|
122
|
-
Socket::IPPROTO_IPV6,
|
123
|
-
Socket::IPV6_HOPLIMIT, hop)
|
124
|
-
tc = Socket::AncillaryData.int(Socket::AF_INET6,
|
125
|
-
Socket::IPPROTO_IPV6,
|
126
|
-
Socket::IPV6_TCLASS,
|
127
|
-
traffic_class)
|
128
|
-
|
129
|
-
# src address is set through PKT_INFO, which needs interface index.
|
130
|
-
ifaddr = Socket.getifaddrs.find { |ia| ia.name == iface }
|
131
|
-
raise WireError, "unknown #{iface} interface" if ifaddr.nil?
|
132
|
-
pkt_info = Socket::AncillaryData.ipv6_pktinfo(Addrinfo.ip(src), ifaddr.ifindex)
|
133
|
-
|
134
|
-
sock.sendmsg body.to_s, 0, sockaddrin, hop_limit, tc, pkt_info
|
152
|
+
sock.send to_s, 0, sockaddrin
|
135
153
|
sock.close
|
136
154
|
end
|
137
155
|
|
@@ -190,13 +208,6 @@ module PacketGen
|
|
190
208
|
klass.bind header_klass, args
|
191
209
|
end
|
192
210
|
end
|
193
|
-
# Bind a upper header to IPv6 and its defined extension headers.
|
194
|
-
# @see Base.bind_header
|
195
|
-
# @deprecated USe {bind}.
|
196
|
-
def bind_header(header_klass, args={})
|
197
|
-
Deprecation.deprecated(self, __method__, 'bind', klass_method: true)
|
198
|
-
bind header_klass, args
|
199
|
-
end
|
200
211
|
end
|
201
212
|
end
|
202
213
|
end
|
@@ -52,8 +52,10 @@ module PacketGen
|
|
52
52
|
# @return [self]
|
53
53
|
def from_human(str)
|
54
54
|
return self if str.nil?
|
55
|
+
|
55
56
|
addr = IPAddr.new(str)
|
56
57
|
raise ArgumentError, 'string is not a IPv6 address' unless addr.ipv6?
|
58
|
+
|
57
59
|
addri = addr.to_i
|
58
60
|
self.a1 = addri >> 112
|
59
61
|
self.a2 = addri >> 96 & 0xffff
|
@@ -46,23 +46,6 @@ module PacketGen
|
|
46
46
|
class Options < Types::Array
|
47
47
|
set_of Option
|
48
48
|
|
49
|
-
# Populate object from a binary string
|
50
|
-
# @param [String] str
|
51
|
-
# @return [self]
|
52
|
-
def read(str)
|
53
|
-
clear
|
54
|
-
return self if str.nil?
|
55
|
-
force_binary str
|
56
|
-
klass = self.class.class_eval { @klass }
|
57
|
-
until str.empty?
|
58
|
-
obj = klass.new.read(str)
|
59
|
-
obj = Pad1.new.read(str) if obj.type.zero?
|
60
|
-
self.push obj
|
61
|
-
str.slice!(0, obj.sz)
|
62
|
-
end
|
63
|
-
self
|
64
|
-
end
|
65
|
-
|
66
49
|
# Get options as a binary string. Add padding if needed.
|
67
50
|
# @return [String]
|
68
51
|
def to_s
|
@@ -83,6 +66,12 @@ module PacketGen
|
|
83
66
|
end
|
84
67
|
str
|
85
68
|
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def real_type(opt)
|
73
|
+
opt.type.zero? ? Pad1 : opt.class
|
74
|
+
end
|
86
75
|
end
|
87
76
|
|
88
77
|
# Hop-by-hop IPv6 extension
|
@@ -111,20 +100,7 @@ module PacketGen
|
|
111
100
|
# @!attribute options
|
112
101
|
# Specific options of extension header
|
113
102
|
# @return [Options]
|
114
|
-
define_field_before :body, :options, Options
|
115
|
-
|
116
|
-
# Populate object from a binary string
|
117
|
-
# @param [String] str
|
118
|
-
# @return [self]
|
119
|
-
def read(str)
|
120
|
-
return self if str.nil?
|
121
|
-
force_binary str
|
122
|
-
self[:next].read str[0, 1]
|
123
|
-
self[:length].read str[1, 1]
|
124
|
-
self[:options].read str[2, real_length - 2]
|
125
|
-
self[:body].read str[real_length..-1]
|
126
|
-
self
|
127
|
-
end
|
103
|
+
define_field_before :body, :options, Options, builder: ->(h, t) { t.new(length_from: -> { h.real_length - 2} ) }
|
128
104
|
end
|
129
105
|
end
|
130
106
|
|