packetgen 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|