packetgen 1.2.0 → 1.3.0
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 +2 -2
- data/lib/packetgen/header/arp.rb +54 -125
- data/lib/packetgen/header/base.rb +175 -0
- data/lib/packetgen/header/dns/name.rb +110 -0
- data/lib/packetgen/header/dns/opt.rb +137 -0
- data/lib/packetgen/header/dns/option.rb +17 -0
- data/lib/packetgen/header/dns/qdsection.rb +39 -0
- data/lib/packetgen/header/dns/question.rb +129 -0
- data/lib/packetgen/header/dns/rr.rb +89 -0
- data/lib/packetgen/header/dns/rrsection.rb +72 -0
- data/lib/packetgen/header/dns.rb +276 -0
- data/lib/packetgen/header/esp.rb +38 -70
- data/lib/packetgen/header/eth.rb +35 -106
- data/lib/packetgen/header/icmp.rb +19 -70
- data/lib/packetgen/header/icmpv6.rb +3 -3
- data/lib/packetgen/header/ip.rb +54 -210
- data/lib/packetgen/header/ipv6.rb +73 -164
- data/lib/packetgen/header/tcp/option.rb +34 -50
- data/lib/packetgen/header/tcp/options.rb +19 -20
- data/lib/packetgen/header/tcp.rb +66 -129
- data/lib/packetgen/header/udp.rb +31 -88
- data/lib/packetgen/header.rb +5 -10
- data/lib/packetgen/inspect.rb +5 -4
- data/lib/packetgen/packet.rb +74 -57
- data/lib/packetgen/pcapng/block.rb +49 -7
- data/lib/packetgen/pcapng/epb.rb +36 -34
- data/lib/packetgen/pcapng/file.rb +24 -8
- data/lib/packetgen/pcapng/idb.rb +28 -33
- data/lib/packetgen/pcapng/shb.rb +35 -39
- data/lib/packetgen/pcapng/spb.rb +18 -27
- data/lib/packetgen/pcapng/unknown_block.rb +11 -21
- data/lib/packetgen/pcapng.rb +9 -7
- data/lib/packetgen/types/array.rb +56 -0
- data/lib/packetgen/types/fields.rb +325 -0
- data/lib/packetgen/types/int.rb +164 -0
- data/lib/packetgen/types/int_string.rb +69 -0
- data/lib/packetgen/types/string.rb +36 -0
- data/lib/packetgen/types/tlv.rb +41 -0
- data/lib/packetgen/types.rb +13 -0
- data/lib/packetgen/version.rb +1 -1
- data/lib/packetgen.rb +1 -1
- metadata +19 -6
- data/lib/packetgen/header/header_class_methods.rb +0 -106
- data/lib/packetgen/header/header_methods.rb +0 -73
- data/lib/packetgen/structfu.rb +0 -363
data/lib/packetgen/header/ip.rb
CHANGED
@@ -8,10 +8,10 @@ module PacketGen
|
|
8
8
|
module Header
|
9
9
|
|
10
10
|
# A IP header consists of:
|
11
|
-
# * a first byte ({#u8} of {Int8} type) composed of:
|
11
|
+
# * a first byte ({#u8} of {Types::Int8} type) composed of:
|
12
12
|
# * a 4-bit {#version} field,
|
13
13
|
# * a 4-bit IP header length ({#ihl}) field,
|
14
|
-
# * a total length ({#length}, {Int16} type),
|
14
|
+
# * a total length ({#length}, {Types::Int16} type),
|
15
15
|
# * a ID ({#id}, +Int16+ type),
|
16
16
|
# * a {#frag} worg (+Int16+) composed of:
|
17
17
|
# * 3 1-bit flags ({#flag_rsv}, {#flag_df} and {#flag_mf}),
|
@@ -21,7 +21,7 @@ module PacketGen
|
|
21
21
|
# * a {#checksum} field (+Int16+),
|
22
22
|
# * a source IP address ({#src}, {Addr} type),
|
23
23
|
# * a destination IP ddress ({#dst}, +Addr+ type),
|
24
|
-
# * and a {#body} ({String} type).
|
24
|
+
# * and a {#body} ({Types::String} type).
|
25
25
|
#
|
26
26
|
# == Create a IP header
|
27
27
|
# # standalone
|
@@ -58,32 +58,26 @@ module PacketGen
|
|
58
58
|
# ip.dst = '127.0.0.2'
|
59
59
|
# ip.body.read 'this is a body'
|
60
60
|
# @author Sylvain Daubert
|
61
|
-
class IP <
|
62
|
-
:protocol, :checksum, :src, :dst, :body)
|
63
|
-
include StructFu
|
64
|
-
include HeaderMethods
|
65
|
-
extend HeaderClassMethods
|
61
|
+
class IP < Base
|
66
62
|
|
67
63
|
# IP address, as a group of 4 bytes
|
68
64
|
# @author Sylvain Daubert
|
69
|
-
class Addr <
|
70
|
-
|
65
|
+
class Addr < Base
|
66
|
+
# @!attribute a1
|
67
|
+
# @return [Integer] IP address first byte
|
68
|
+
define_field :a1, Types::Int8
|
69
|
+
# @!attribute a2
|
70
|
+
# @return [Integer] IP address seconf byte
|
71
|
+
define_field :a2, Types::Int8
|
72
|
+
# @!attribute a3
|
73
|
+
# @return [Integer] IP address third byte
|
74
|
+
define_field :a3, Types::Int8
|
75
|
+
# @!attribute a4
|
76
|
+
# @return [Integer] IP address fourth byte
|
77
|
+
define_field :a4, Types::Int8
|
71
78
|
|
72
79
|
IPV4_ADDR_REGEX = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
|
73
80
|
|
74
|
-
# @param [Hash] options
|
75
|
-
# @option options [Integer] :a1
|
76
|
-
# @option options [Integer] :a2
|
77
|
-
# @option options [Integer] :a3
|
78
|
-
# @option options [Integer] :a4
|
79
|
-
def initialize(options={})
|
80
|
-
super Int8.new(options[:a1]),
|
81
|
-
Int8.new(options[:a2]),
|
82
|
-
Int8.new(options[:a3]),
|
83
|
-
Int8.new(options[:a4])
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
81
|
# Read a dotted address
|
88
82
|
# @param [String] str
|
89
83
|
# @return [self]
|
@@ -99,27 +93,10 @@ module PacketGen
|
|
99
93
|
self
|
100
94
|
end
|
101
95
|
|
102
|
-
# Read a Addr from a string
|
103
|
-
# @param [String] str binary string
|
104
|
-
# @return [self]
|
105
|
-
def read(str)
|
106
|
-
return self if str.nil?
|
107
|
-
raise ParseError, 'string too short for IP::Addr' if str.size < self.sz
|
108
|
-
force_binary str
|
109
|
-
[:a1, :a2, :a3, :a4].each_with_index do |byte, i|
|
110
|
-
self[byte].read str[i, 1]
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
[:a1, :a2, :a3, :a4].each do |sym|
|
115
|
-
class_eval "def #{sym}; self[:#{sym}].to_i; end\n" \
|
116
|
-
"def #{sym}=(v); self[:#{sym}].read v; end"
|
117
|
-
end
|
118
|
-
|
119
96
|
# Addr in human readable form (dotted format)
|
120
97
|
# @return [String]
|
121
98
|
def to_human
|
122
|
-
|
99
|
+
fields.map { |f| "#{self[f].to_i}" }.join('.')
|
123
100
|
end
|
124
101
|
|
125
102
|
# Addr as an integer
|
@@ -130,32 +107,41 @@ module PacketGen
|
|
130
107
|
end
|
131
108
|
end
|
132
109
|
|
133
|
-
#
|
134
|
-
#
|
135
|
-
#
|
136
|
-
|
137
|
-
#
|
138
|
-
#
|
139
|
-
|
140
|
-
#
|
141
|
-
#
|
142
|
-
|
143
|
-
#
|
144
|
-
#
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
110
|
+
# @!attribute u8
|
111
|
+
# First byte of IP header. May be accessed through {#version} and {#ihl}.
|
112
|
+
# @return [Integer] first byte of IP header.
|
113
|
+
define_field :u8, Types::Int8, default: 0x45
|
114
|
+
# @!attribute tos
|
115
|
+
# @return [Integer] 8-bit Type of Service value
|
116
|
+
define_field :tos, Types::Int8, default: 0
|
117
|
+
# @!attribute length
|
118
|
+
# @return [Integer] 16-bit IP total length
|
119
|
+
define_field :length, Types::Int16, default: 20
|
120
|
+
# @!attribute id
|
121
|
+
# @return [Integer] 16-bit ID
|
122
|
+
define_field :id, Types::Int16, default: -> { rand(65535) }
|
123
|
+
# @!attribute frag
|
124
|
+
# @return [Integer] 16-bit frag word
|
125
|
+
define_field :frag, Types::Int16, default: 0
|
126
|
+
# @!attribute ttl
|
127
|
+
# @return [Integer] 8-bit Time To Live value
|
128
|
+
define_field :ttl, Types::Int8, default: 64
|
129
|
+
# @!attribute protocol
|
130
|
+
# @return [Integer] 8-bit upper protocol value
|
131
|
+
define_field :protocol, Types::Int8
|
132
|
+
# @!attribute checksum
|
133
|
+
# @return [Integer] 16-bit IP header checksum
|
134
|
+
define_field :checksum, Types::Int16, default: 0
|
135
|
+
# @!attribute src
|
136
|
+
# @return [Addr] source IP address
|
137
|
+
define_field :src, Addr, default: '127.0.0.1'
|
138
|
+
# @!attribute dst
|
139
|
+
# @return [Addr] destination IP address
|
140
|
+
define_field :dst, Addr, default: '127.0.0.1'
|
141
|
+
# @!attribute body
|
142
|
+
# @return [Types::String,Header::Base]
|
143
|
+
define_field :body, Types::String
|
144
|
+
|
159
145
|
# @!attribute version
|
160
146
|
# @return [Integer] 4-bit version attribute
|
161
147
|
# @!attribute ihl
|
@@ -172,28 +158,7 @@ module PacketGen
|
|
172
158
|
# @return [Integer] 13-bit fragment offset
|
173
159
|
define_bit_fields_on :frag, :flag_rsv, :flag_df, :flag_mf, :fragment_offset, 13
|
174
160
|
|
175
|
-
#
|
176
|
-
# @param [String] str binary string
|
177
|
-
# @return [self]
|
178
|
-
def read(str)
|
179
|
-
return self if str.nil?
|
180
|
-
raise ParseError, 'string too short for IP' if str.size < self.sz
|
181
|
-
force_binary str
|
182
|
-
self[:u8].read str[0, 1]
|
183
|
-
self[:tos].read str[1, 1]
|
184
|
-
self[:length].read str[2, 2]
|
185
|
-
self[:id].read str[4, 2]
|
186
|
-
self[:frag].read str[6, 2]
|
187
|
-
self[:ttl].read str[8, 1]
|
188
|
-
self[:protocol].read str[9, 1]
|
189
|
-
self[:checksum].read str[10, 2]
|
190
|
-
self[:src].read str[12, 4]
|
191
|
-
self[:dst].read str[16, 4]
|
192
|
-
self[:body].read str[20..-1]
|
193
|
-
self
|
194
|
-
end
|
195
|
-
|
196
|
-
# Compute checksum and set +checksum+ field
|
161
|
+
# Compute checksum and set +checksum+ field
|
197
162
|
# @return [Integer]
|
198
163
|
def calc_checksum
|
199
164
|
checksum = (self[:u8].to_i << 8) | self.tos
|
@@ -216,127 +181,6 @@ module PacketGen
|
|
216
181
|
self[:length].value = self.sz
|
217
182
|
end
|
218
183
|
|
219
|
-
# Getter for TOS attribute
|
220
|
-
# @return [Integer]
|
221
|
-
def tos
|
222
|
-
self[:tos].to_i
|
223
|
-
end
|
224
|
-
|
225
|
-
# Setter for TOS attribute
|
226
|
-
# @param [Integer] tos
|
227
|
-
# @return [Integer]
|
228
|
-
def tos=(tos)
|
229
|
-
self[:tos].value = tos
|
230
|
-
end
|
231
|
-
|
232
|
-
# Getter for length attribute
|
233
|
-
# @return [Integer]
|
234
|
-
def length
|
235
|
-
self[:length].to_i
|
236
|
-
end
|
237
|
-
|
238
|
-
# Setter for length attribute
|
239
|
-
# @param [Integer] length
|
240
|
-
# @return [Integer]
|
241
|
-
def length=(length)
|
242
|
-
self[:length].value = length
|
243
|
-
end
|
244
|
-
|
245
|
-
# Getter for id attribute
|
246
|
-
# @return [Integer]
|
247
|
-
def id
|
248
|
-
self[:id].to_i
|
249
|
-
end
|
250
|
-
|
251
|
-
# Setter for id attribute
|
252
|
-
# @param [Integer] id
|
253
|
-
# @return [Integer]
|
254
|
-
def id=(id)
|
255
|
-
self[:id].value = id
|
256
|
-
end
|
257
|
-
|
258
|
-
# Getter for frag attribute
|
259
|
-
# @return [Integer]
|
260
|
-
def frag
|
261
|
-
self[:frag].to_i
|
262
|
-
end
|
263
|
-
|
264
|
-
# Setter for frag attribute
|
265
|
-
# @param [Integer] frag
|
266
|
-
# @return [Integer]
|
267
|
-
def frag=(frag)
|
268
|
-
self[:frag].value = frag
|
269
|
-
end
|
270
|
-
|
271
|
-
# Getter for ttl attribute
|
272
|
-
# @return [Integer]
|
273
|
-
def ttl
|
274
|
-
self[:ttl].to_i
|
275
|
-
end
|
276
|
-
|
277
|
-
# Setter for ttl attribute
|
278
|
-
# @param [Integer] ttl
|
279
|
-
# @return [Integer]
|
280
|
-
def ttl=(ttl)
|
281
|
-
self[:ttl].value = ttl
|
282
|
-
end
|
283
|
-
|
284
|
-
# Getter for protocol attribute
|
285
|
-
# @return [Integer]
|
286
|
-
def protocol
|
287
|
-
self[:protocol].to_i
|
288
|
-
end
|
289
|
-
|
290
|
-
# Setter for protocol attribute
|
291
|
-
# @param [Integer] protocol
|
292
|
-
# @return [Integer]
|
293
|
-
def protocol=(protocol)
|
294
|
-
self[:protocol].value = protocol
|
295
|
-
end
|
296
|
-
|
297
|
-
# Getter for checksum attribute
|
298
|
-
# @return [Integer]
|
299
|
-
def checksum
|
300
|
-
self[:checksum].to_i
|
301
|
-
end
|
302
|
-
|
303
|
-
# Setter for checksum attribute
|
304
|
-
# @param [Integer] checksum
|
305
|
-
# @return [Integer]
|
306
|
-
def checksum=(checksum)
|
307
|
-
self[:checksum].value = checksum
|
308
|
-
end
|
309
|
-
|
310
|
-
# Get IP source address
|
311
|
-
# @return [String] dotted address
|
312
|
-
def src
|
313
|
-
self[:src].to_human
|
314
|
-
end
|
315
|
-
alias :source :src
|
316
|
-
|
317
|
-
# Set IP source address
|
318
|
-
# @param [String] addr dotted IP address
|
319
|
-
# @return [String]
|
320
|
-
def src=(addr)
|
321
|
-
self[:src].from_human addr
|
322
|
-
end
|
323
|
-
alias :source= :src=
|
324
|
-
|
325
|
-
# Get IP destination address
|
326
|
-
# @return [String] dotted address
|
327
|
-
def dst
|
328
|
-
self[:dst].to_human
|
329
|
-
end
|
330
|
-
alias :destination :dst
|
331
|
-
|
332
|
-
# Set IP destination address
|
333
|
-
# @param [String] addr dotted IP address
|
334
|
-
# @return [String]
|
335
|
-
def dst=(addr)
|
336
|
-
self[:dst].from_human addr
|
337
|
-
end
|
338
|
-
alias :destination= :dst=
|
339
|
-
|
340
184
|
# Get IP part of pseudo header checksum.
|
341
185
|
# @return [Integer]
|
342
186
|
def pseudo_header_checksum
|
@@ -9,12 +9,12 @@ module PacketGen
|
|
9
9
|
module Header
|
10
10
|
|
11
11
|
# A IPv6 header consists of:
|
12
|
-
# * a first 32-bit word ({#u32}, of {Int32} type) composoed of:
|
12
|
+
# * a first 32-bit word ({#u32}, of {Types::Int32} type) composoed of:
|
13
13
|
# * a 4-bit {#version} field,
|
14
14
|
# * a 8-bit {#traffic_class} field,
|
15
15
|
# * a 20-bit {#flow_label} field,
|
16
|
-
# * a payload length field ({#length}, {Int16} type}),
|
17
|
-
# * a next header field ({#next}, {Int8} type),
|
16
|
+
# * a payload length field ({#length}, {Types::Int16} type}),
|
17
|
+
# * a next header field ({#next}, {Types::Int8} type),
|
18
18
|
# * a hop-limit field ({#hop}, +Int8+ type),
|
19
19
|
# * a source address field ({#src}, {IPv6::Addr} type),
|
20
20
|
# * a destination address field ({#dst}, +IPv6::Addr+ type),
|
@@ -43,35 +43,44 @@ module PacketGen
|
|
43
43
|
# ipv6.dst = '2001:1234:5678:abcd::123'
|
44
44
|
# ipv6.body.read 'this is a body'
|
45
45
|
# @author Sylvain Daubert
|
46
|
-
class IPv6 <
|
47
|
-
include StructFu
|
48
|
-
include HeaderMethods
|
49
|
-
extend HeaderClassMethods
|
46
|
+
class IPv6 < Base
|
50
47
|
|
51
48
|
# IPv6 address, as a group of 8 2-byte words
|
52
49
|
# @author Sylvain Daubert
|
53
|
-
class Addr <
|
54
|
-
|
55
|
-
|
56
|
-
#
|
57
|
-
#
|
58
|
-
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
|
63
|
-
#
|
64
|
-
#
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
50
|
+
class Addr < Base
|
51
|
+
|
52
|
+
# @!attribute a1
|
53
|
+
# 1st 2-byte word of IPv6 address
|
54
|
+
# @return [Integer]
|
55
|
+
define_field :a1, Types::Int16
|
56
|
+
# @!attribute a2
|
57
|
+
# 2nd 2-byte word of IPv6 address
|
58
|
+
# @return [Integer]
|
59
|
+
define_field :a2, Types::Int16
|
60
|
+
# @!attribute a3
|
61
|
+
# 3rd 2-byte word of IPv6 address
|
62
|
+
# @return [Integer]
|
63
|
+
define_field :a3, Types::Int16
|
64
|
+
# @!attribute a4
|
65
|
+
# 4th 2-byte word of IPv6 address
|
66
|
+
# @return [Integer]
|
67
|
+
define_field :a4, Types::Int16
|
68
|
+
# @!attribute a5
|
69
|
+
# 5th 2-byte word of IPv6 address
|
70
|
+
# @return [Integer]
|
71
|
+
define_field :a5, Types::Int16
|
72
|
+
# @!attribute a6
|
73
|
+
# 6th 2-byte word of IPv6 address
|
74
|
+
# @return [Integer]
|
75
|
+
define_field :a6, Types::Int16
|
76
|
+
# @!attribute a7
|
77
|
+
# 7th 2-byte word of IPv6 address
|
78
|
+
# @return [Integer]
|
79
|
+
define_field :a7, Types::Int16
|
80
|
+
# @!attribute a8
|
81
|
+
# 8th 2-byte word of IPv6 address
|
82
|
+
# @return [Integer]
|
83
|
+
define_field :a8, Types::Int16
|
75
84
|
|
76
85
|
# Read a colon-delimited address
|
77
86
|
# @param [String] str
|
@@ -92,57 +101,47 @@ module PacketGen
|
|
92
101
|
self
|
93
102
|
end
|
94
103
|
|
95
|
-
# Read a Addr6 from a binary string
|
96
|
-
# @param [String] str
|
97
|
-
# @return [self]
|
98
|
-
def read(str)
|
99
|
-
force_binary str
|
100
|
-
self[:a1].read str[0, 2]
|
101
|
-
self[:a2].read str[2, 2]
|
102
|
-
self[:a3].read str[4, 2]
|
103
|
-
self[:a4].read str[6, 2]
|
104
|
-
self[:a5].read str[8, 2]
|
105
|
-
self[:a6].read str[10, 2]
|
106
|
-
self[:a7].read str[12, 2]
|
107
|
-
self[:a8].read str[14, 2]
|
108
|
-
self
|
109
|
-
end
|
110
|
-
|
111
|
-
%i(a1 a2 a3 a4 a5 a6 a7 a8).each do |sym|
|
112
|
-
class_eval "def #{sym}; self[:#{sym}].to_i; end\n" \
|
113
|
-
"def #{sym}=(v); self[:#{sym}].read v; end"
|
114
|
-
end
|
115
|
-
|
116
104
|
# Addr6 in human readable form (colon-delimited hex string)
|
117
105
|
# @return [String]
|
118
106
|
def to_human
|
119
107
|
IPAddr.new(to_a.map { |a| a.to_i.to_s(16) }.join(':')).to_s
|
120
108
|
end
|
121
|
-
end
|
122
109
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
# @option options [Integer] :next
|
129
|
-
# @option options [Integer] :hop
|
130
|
-
# @option options [String] :src colon-delimited source address
|
131
|
-
# @option options [String] :dst colon-delimited destination address
|
132
|
-
# @option options [String] :body binary string
|
133
|
-
def initialize(options={})
|
134
|
-
super Int32.new(0x60000000),
|
135
|
-
Int16.new(options[:length]),
|
136
|
-
Int8.new(options[:next]),
|
137
|
-
Int8.new(options[:hop] || 64),
|
138
|
-
Addr.new.from_human(options[:src] || '::1'),
|
139
|
-
Addr.new.from_human(options[:dst] || '::1'),
|
140
|
-
StructFu::String.new.read(options[:body])
|
141
|
-
self.version = options[:version] if options[:version]
|
142
|
-
self.traffic_class = options[:traffic_class] if options[:traffic_class]
|
143
|
-
self.flow_label = options[:flow_label] if options[:flow_label]
|
110
|
+
# Return an array of address 16-bit words
|
111
|
+
# @return [Array<Integer>]
|
112
|
+
def to_a
|
113
|
+
@fields.values
|
114
|
+
end
|
144
115
|
end
|
145
116
|
|
117
|
+
# @!attribute u32
|
118
|
+
# First 32-bit word of IPv6 header
|
119
|
+
# @return [Integer]
|
120
|
+
define_field :u32, Types::Int32, default: 0x6000_0000
|
121
|
+
# @!attribute length
|
122
|
+
# 16-bit word of IPv6 payload length
|
123
|
+
# @return [Integer]
|
124
|
+
define_field :length, Types::Int16
|
125
|
+
# @!attribute next
|
126
|
+
# 8-bit IPv6 next payload value
|
127
|
+
# @return [Integer]
|
128
|
+
define_field :next, Types::Int8
|
129
|
+
# @!attribute hop
|
130
|
+
# 8-bit IPv6 hop limit
|
131
|
+
# @return [Integer]
|
132
|
+
define_field :hop, Types::Int8, default: 64
|
133
|
+
# @!attribute src
|
134
|
+
# IPv6 source address
|
135
|
+
# @return [Addr]
|
136
|
+
define_field :src, Addr, default: '::1'
|
137
|
+
# @!attribute dst
|
138
|
+
# IPv6 destination address
|
139
|
+
# @return [Addr]
|
140
|
+
define_field :dst, Addr, default: '::1'
|
141
|
+
# @!attribute body
|
142
|
+
# @return [Types::String,Header::Base]
|
143
|
+
define_field :body, Types::String
|
144
|
+
|
146
145
|
# @!attribute version
|
147
146
|
# @return [Integer] 4-bit version attribute
|
148
147
|
# @!attribute traffic_class
|
@@ -151,108 +150,18 @@ module PacketGen
|
|
151
150
|
# @return [Integer] 20-bit flow_label attribute
|
152
151
|
define_bit_fields_on :u32, :version, 4, :traffic_class, 8, :flow_label, 20
|
153
152
|
|
154
|
-
# Read a IP header from a string
|
155
|
-
# @param [String] str binary string
|
156
|
-
# @return [self]
|
157
|
-
def read(str)
|
158
|
-
return self if str.nil?
|
159
|
-
raise ParseError, 'string too short for IPv6' if str.size < self.sz
|
160
|
-
force_binary str
|
161
|
-
first32 = str[0, 4].unpack('N').first
|
162
|
-
self.version = first32 >> 28
|
163
|
-
self.traffic_class = (first32 >> 20) & 0xff
|
164
|
-
self.flow_label = first32 & 0xfffff
|
165
|
-
|
166
|
-
self[:length].read str[4, 2]
|
167
|
-
self[:next].read str[6, 1]
|
168
|
-
self[:hop].read str[7, 1]
|
169
|
-
self[:src].read str[8, 16]
|
170
|
-
self[:dst].read str[24, 16]
|
171
|
-
self[:body].read str[40..-1]
|
172
|
-
self
|
173
|
-
end
|
174
|
-
|
175
153
|
# Compute length and set +len+ field
|
176
154
|
# @return [Integer]
|
177
155
|
def calc_length
|
178
156
|
self.length = body.sz
|
179
157
|
end
|
180
158
|
|
181
|
-
# @!attribute length
|
182
|
-
# 16-bit payload length attribute
|
183
|
-
# @return [Integer]
|
184
|
-
def length
|
185
|
-
self[:length].to_i
|
186
|
-
end
|
187
|
-
|
188
|
-
# @param [Integer] i
|
189
|
-
# @return [Integer]
|
190
|
-
def length=(i)
|
191
|
-
self[:length].read i
|
192
|
-
end
|
193
|
-
|
194
|
-
# Getter for next attribute
|
195
|
-
# @return [Integer]
|
196
|
-
def next
|
197
|
-
self[:next].to_i
|
198
|
-
end
|
199
|
-
|
200
|
-
# Setter for next attribute
|
201
|
-
# @param [Integer] i
|
202
|
-
# @return [Integer]
|
203
|
-
def next=(i)
|
204
|
-
self[:next].read i
|
205
|
-
end
|
206
|
-
|
207
|
-
# Getter for hop attribute
|
208
|
-
# @return [Integer]
|
209
|
-
def hop
|
210
|
-
self[:hop].to_i
|
211
|
-
end
|
212
|
-
|
213
|
-
# Setter for hop attribute
|
214
|
-
# @param [Integer] i
|
215
|
-
# @return [Integer]
|
216
|
-
def hop=(i)
|
217
|
-
self[:hop].read i
|
218
|
-
end
|
219
|
-
|
220
|
-
# Getter for src attribute
|
221
|
-
# @return [String]
|
222
|
-
def src
|
223
|
-
self[:src].to_human
|
224
|
-
end
|
225
|
-
alias :source :src
|
226
|
-
|
227
|
-
# Setter for src attribute
|
228
|
-
# @param [String] addr
|
229
|
-
# @return [Integer]
|
230
|
-
def src=(addr)
|
231
|
-
self[:src].from_human addr
|
232
|
-
end
|
233
|
-
alias :source= :src=
|
234
|
-
|
235
|
-
# Getter for dst attribute
|
236
|
-
# @return [String]
|
237
|
-
def dst
|
238
|
-
self[:dst].to_human
|
239
|
-
end
|
240
|
-
alias :destination :dst
|
241
|
-
|
242
|
-
# Setter for dst attribute
|
243
|
-
# @param [String] addr
|
244
|
-
# @return [Integer]
|
245
|
-
def dst=(addr)
|
246
|
-
self[:dst].from_human addr
|
247
|
-
end
|
248
|
-
alias :destination= :dst=
|
249
|
-
|
250
159
|
# Get IPv6 part of pseudo header checksum.
|
251
160
|
# @return [Integer]
|
252
161
|
def pseudo_header_checksum
|
253
162
|
sum = 0
|
254
|
-
self[:src].each { |word| sum += word.to_i }
|
255
|
-
self[:dst].each { |word| sum += word.to_i }
|
163
|
+
self[:src].to_a.each { |word| sum += word.to_i }
|
164
|
+
self[:dst].to_a.each { |word| sum += word.to_i }
|
256
165
|
sum
|
257
166
|
end
|
258
167
|
|