packetgen 2.4.0 → 2.5.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 +5 -5
- data/.travis.yml +13 -4
- data/lib/packetgen.rb +3 -1
- data/lib/packetgen/capture.rb +2 -0
- data/lib/packetgen/config.rb +1 -0
- data/lib/packetgen/header.rb +5 -0
- data/lib/packetgen/header/arp.rb +2 -0
- data/lib/packetgen/header/asn1_base.rb +2 -0
- data/lib/packetgen/header/base.rb +16 -0
- data/lib/packetgen/header/bootp.rb +2 -0
- data/lib/packetgen/header/crypto.rb +2 -0
- data/lib/packetgen/header/dhcp.rb +2 -0
- data/lib/packetgen/header/dhcp/option.rb +3 -0
- data/lib/packetgen/header/dhcp/options.rb +2 -0
- data/lib/packetgen/header/dhcpv6.rb +109 -0
- data/lib/packetgen/header/dhcpv6/duid.rb +147 -0
- data/lib/packetgen/header/dhcpv6/option.rb +391 -0
- data/lib/packetgen/header/dhcpv6/options.rb +29 -0
- data/lib/packetgen/header/dhcpv6/relay.rb +48 -0
- data/lib/packetgen/header/dns.rb +10 -2
- data/lib/packetgen/header/dns/name.rb +7 -0
- data/lib/packetgen/header/dns/opt.rb +6 -0
- data/lib/packetgen/header/dns/option.rb +7 -0
- data/lib/packetgen/header/dns/qdsection.rb +7 -1
- data/lib/packetgen/header/dns/question.rb +7 -0
- data/lib/packetgen/header/dns/rr.rb +7 -0
- data/lib/packetgen/header/dns/rrsection.rb +7 -0
- data/lib/packetgen/header/dot11.rb +4 -2
- data/lib/packetgen/header/dot11/control.rb +2 -0
- data/lib/packetgen/header/dot11/data.rb +2 -0
- data/lib/packetgen/header/dot11/element.rb +2 -0
- data/lib/packetgen/header/dot11/management.rb +2 -0
- data/lib/packetgen/header/dot11/sub_mngt.rb +2 -0
- data/lib/packetgen/header/dot1q.rb +2 -0
- data/lib/packetgen/header/dot1x.rb +3 -1
- data/lib/packetgen/header/eap.rb +3 -1
- data/lib/packetgen/header/eap/fast.rb +2 -0
- data/lib/packetgen/header/eap/md5.rb +2 -0
- data/lib/packetgen/header/eap/tls.rb +2 -0
- data/lib/packetgen/header/eap/ttls.rb +2 -0
- data/lib/packetgen/header/esp.rb +7 -0
- data/lib/packetgen/header/eth.rb +2 -0
- data/lib/packetgen/header/gre.rb +4 -9
- data/lib/packetgen/header/http/headers.rb +2 -0
- data/lib/packetgen/header/http/request.rb +3 -1
- data/lib/packetgen/header/http/response.rb +3 -1
- data/lib/packetgen/header/icmp.rb +4 -11
- data/lib/packetgen/header/icmpv6.rb +4 -11
- data/lib/packetgen/header/igmp.rb +4 -11
- data/lib/packetgen/header/igmpv3.rb +4 -11
- data/lib/packetgen/header/igmpv3/group_record.rb +2 -0
- data/lib/packetgen/header/igmpv3/mq.rb +2 -0
- data/lib/packetgen/header/igmpv3/mr.rb +2 -0
- data/lib/packetgen/header/ike.rb +13 -6
- data/lib/packetgen/header/ike/auth.rb +2 -0
- data/lib/packetgen/header/ike/cert.rb +2 -0
- data/lib/packetgen/header/ike/certreq.rb +2 -0
- data/lib/packetgen/header/ike/id.rb +2 -0
- data/lib/packetgen/header/ike/ke.rb +2 -0
- data/lib/packetgen/header/ike/nonce.rb +2 -0
- data/lib/packetgen/header/ike/notify.rb +7 -0
- data/lib/packetgen/header/ike/payload.rb +9 -0
- data/lib/packetgen/header/ike/sa.rb +11 -4
- data/lib/packetgen/header/ike/sk.rb +7 -0
- data/lib/packetgen/header/ike/ts.rb +2 -0
- data/lib/packetgen/header/ike/vendor_id.rb +2 -0
- data/lib/packetgen/header/ip.rb +48 -11
- data/lib/packetgen/header/ip/addr.rb +8 -0
- data/lib/packetgen/header/ip/option.rb +2 -0
- data/lib/packetgen/header/ip/options.rb +2 -0
- data/lib/packetgen/header/ipv6.rb +5 -3
- data/lib/packetgen/header/ipv6/addr.rb +8 -0
- data/lib/packetgen/header/ipv6/extension.rb +2 -0
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +2 -0
- data/lib/packetgen/header/llc.rb +2 -0
- data/lib/packetgen/header/mld.rb +2 -0
- data/lib/packetgen/header/mldv2.rb +4 -2
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +3 -1
- data/lib/packetgen/header/mldv2/mlq.rb +2 -0
- data/lib/packetgen/header/mldv2/mlr.rb +4 -2
- data/lib/packetgen/header/ospfv2.rb +249 -0
- data/lib/packetgen/header/ospfv2/db_description.rb +105 -0
- data/lib/packetgen/header/ospfv2/hello.rb +104 -0
- data/lib/packetgen/header/ospfv2/ls_ack.rb +55 -0
- data/lib/packetgen/header/ospfv2/ls_request.rb +90 -0
- data/lib/packetgen/header/ospfv2/ls_update.rb +72 -0
- data/lib/packetgen/header/ospfv2/lsa.rb +252 -0
- data/lib/packetgen/header/ospfv2/lsa_header.rb +122 -0
- data/lib/packetgen/header/ospfv3.rb +216 -0
- data/lib/packetgen/header/ospfv3/db_description.rb +114 -0
- data/lib/packetgen/header/ospfv3/hello.rb +104 -0
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +103 -0
- data/lib/packetgen/header/ospfv3/ls_ack.rb +51 -0
- data/lib/packetgen/header/ospfv3/ls_request.rb +108 -0
- data/lib/packetgen/header/ospfv3/ls_update.rb +74 -0
- data/lib/packetgen/header/ospfv3/lsa.rb +252 -0
- data/lib/packetgen/header/ospfv3/lsa_header.rb +123 -0
- data/lib/packetgen/header/snmp.rb +2 -0
- data/lib/packetgen/header/tcp.rb +14 -14
- data/lib/packetgen/header/tcp/option.rb +7 -1
- data/lib/packetgen/header/tcp/options.rb +7 -0
- data/lib/packetgen/header/tftp.rb +2 -0
- data/lib/packetgen/header/udp.rb +6 -14
- data/lib/packetgen/inspect.rb +5 -1
- data/lib/packetgen/packet.rb +3 -1
- data/lib/packetgen/pcapng.rb +2 -0
- data/lib/packetgen/pcapng/block.rb +2 -0
- data/lib/packetgen/pcapng/epb.rb +2 -0
- data/lib/packetgen/pcapng/file.rb +2 -0
- data/lib/packetgen/pcapng/idb.rb +2 -0
- data/lib/packetgen/pcapng/shb.rb +2 -0
- data/lib/packetgen/pcapng/spb.rb +2 -0
- data/lib/packetgen/pcapng/unknown_block.rb +2 -0
- data/lib/packetgen/proto.rb +2 -0
- data/lib/packetgen/types/array.rb +3 -0
- data/lib/packetgen/types/cstring.rb +3 -1
- data/lib/packetgen/types/enum.rb +2 -0
- data/lib/packetgen/types/fields.rb +8 -4
- data/lib/packetgen/types/int.rb +3 -1
- data/lib/packetgen/types/int_string.rb +2 -0
- data/lib/packetgen/types/oui.rb +2 -0
- data/lib/packetgen/types/string.rb +3 -0
- data/lib/packetgen/types/tlv.rb +8 -0
- data/lib/packetgen/utils.rb +6 -4
- data/lib/packetgen/utils/arp_spoofer.rb +2 -0
- data/lib/packetgen/version.rb +3 -1
- metadata +25 -3
@@ -3,6 +3,8 @@
|
|
3
3
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
4
|
# This program is published under MIT license.
|
5
5
|
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
6
8
|
module PacketGen
|
7
9
|
module Header
|
8
10
|
|
@@ -126,17 +128,8 @@ module PacketGen
|
|
126
128
|
# Compute checksum and set +checksum+ field
|
127
129
|
# @return [Integer]
|
128
130
|
def calc_checksum
|
129
|
-
sum = (
|
130
|
-
|
131
|
-
payload = body.to_s
|
132
|
-
payload << "\x00" unless payload.size % 2 == 0
|
133
|
-
payload.unpack('n*').each { |x| sum += x; }
|
134
|
-
|
135
|
-
while sum > 0xffff do
|
136
|
-
sum = (sum & 0xffff) + (sum >> 16)
|
137
|
-
end
|
138
|
-
sum = ~sum & 0xffff
|
139
|
-
self[:checksum].value = (sum == 0) ? 0xffff : sum
|
131
|
+
sum = IP.sum16(self)
|
132
|
+
self.checksum = IP.reduce_checksum(sum)
|
140
133
|
end
|
141
134
|
end
|
142
135
|
|
@@ -2,6 +2,8 @@
|
|
2
2
|
# See https://github.com/sdaubert/packetgen for more informations
|
3
3
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
4
|
# This program is published under MIT license.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
5
7
|
require_relative 'group_record'
|
6
8
|
|
7
9
|
module PacketGen
|
data/lib/packetgen/header/ike.rb
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# This file is part of PacketGen
|
2
|
+
# See https://github.com/sdaubert/packetgen for more informations
|
3
|
+
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
+
# This program is published under MIT license.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
1
8
|
module PacketGen
|
2
9
|
module Header
|
3
10
|
|
@@ -167,7 +174,7 @@ module PacketGen
|
|
167
174
|
# Calculate length field
|
168
175
|
# @return [Integer]
|
169
176
|
def calc_length
|
170
|
-
|
177
|
+
Base.calculate_and_set_length self
|
171
178
|
end
|
172
179
|
|
173
180
|
# IKE payloads
|
@@ -185,23 +192,23 @@ module PacketGen
|
|
185
192
|
# @return [String]
|
186
193
|
def inspect
|
187
194
|
str = Inspect.dashed_line(self.class, 2)
|
188
|
-
|
195
|
+
fields.each do |attr|
|
189
196
|
next if attr == :body
|
190
197
|
case attr
|
191
198
|
when :flags
|
192
|
-
str_flags = ''
|
199
|
+
str_flags = ''.dup
|
193
200
|
%w(r v i).each do |flag|
|
194
201
|
str_flags << (send("flag_#{flag}?") ? flag.upcase : '.')
|
195
202
|
end
|
196
203
|
str << Inspect.shift_level(2)
|
197
|
-
str << Inspect::FMT_ATTR % [
|
204
|
+
str << Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''), attr,
|
198
205
|
str_flags]
|
199
206
|
when :exchange_type
|
200
207
|
str << Inspect.shift_level(2)
|
201
|
-
str << Inspect::FMT_ATTR % [
|
208
|
+
str << Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''), attr,
|
202
209
|
human_exchange_type]
|
203
210
|
else
|
204
|
-
str << Inspect.inspect_attribute(attr,
|
211
|
+
str << Inspect.inspect_attribute(attr, self[attr], 2)
|
205
212
|
end
|
206
213
|
end
|
207
214
|
str
|
@@ -1,4 +1,11 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# This file is part of PacketGen
|
3
|
+
# See https://github.com/sdaubert/packetgen for more informations
|
4
|
+
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
5
|
+
# This program is published under MIT license.
|
6
|
+
|
7
|
+
# frozen_string_literal: true
|
8
|
+
|
2
9
|
module PacketGen
|
3
10
|
module Header
|
4
11
|
class IKE
|
@@ -1,3 +1,10 @@
|
|
1
|
+
# This file is part of PacketGen
|
2
|
+
# See https://github.com/sdaubert/packetgen for more informations
|
3
|
+
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
+
# This program is published under MIT license.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
1
8
|
module PacketGen
|
2
9
|
module Header
|
3
10
|
class IKE
|
@@ -67,6 +74,8 @@ module PacketGen
|
|
67
74
|
# Compute length and set {#length} field
|
68
75
|
# @return [Integer] new length
|
69
76
|
def calc_length
|
77
|
+
# Here, #body is next payload, so body size should not be taken in
|
78
|
+
# account (payload's real body is #content).
|
70
79
|
self[:length].value = sz - body.sz
|
71
80
|
end
|
72
81
|
end
|
@@ -1,4 +1,11 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# This file is part of PacketGen
|
3
|
+
# See https://github.com/sdaubert/packetgen for more informations
|
4
|
+
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
5
|
+
# This program is published under MIT license.
|
6
|
+
|
7
|
+
# frozen_string_literal: true
|
8
|
+
|
2
9
|
module PacketGen
|
3
10
|
module Header
|
4
11
|
class IKE
|
@@ -268,13 +275,13 @@ module PacketGen
|
|
268
275
|
# Compute length and set {#length} field
|
269
276
|
# @return [Integer] new length
|
270
277
|
def calc_length
|
271
|
-
|
278
|
+
Base.calculate_and_set_length self
|
272
279
|
end
|
273
280
|
|
274
281
|
# Get a human readable string
|
275
282
|
# @return [String]
|
276
283
|
def to_human
|
277
|
-
h = "#{human_type}(#{human_id}"
|
284
|
+
h = "#{human_type}(#{human_id}".dup
|
278
285
|
h << ",#{attributes.to_human}" if attributes.size > 0
|
279
286
|
h << ')'
|
280
287
|
end
|
@@ -443,13 +450,13 @@ module PacketGen
|
|
443
450
|
# @return [Integer] new length
|
444
451
|
def calc_length
|
445
452
|
transforms.each { |t| t.calc_length }
|
446
|
-
|
453
|
+
Base.calculate_and_set_length self
|
447
454
|
end
|
448
455
|
|
449
456
|
# Get a human readable string
|
450
457
|
# @return [String]
|
451
458
|
def to_human
|
452
|
-
str = "##{num} #{human_protocol}"
|
459
|
+
str = "##{num} #{human_protocol}".dup
|
453
460
|
case spi_size
|
454
461
|
when 4
|
455
462
|
str << "(spi:0x%08x)" % Types::Int32.new.read(spi).to_i
|
@@ -1,4 +1,11 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# This file is part of PacketGen
|
3
|
+
# See https://github.com/sdaubert/packetgen for more informations
|
4
|
+
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
5
|
+
# This program is published under MIT license.
|
6
|
+
|
7
|
+
# frozen_string_literal: true
|
8
|
+
|
2
9
|
module PacketGen
|
3
10
|
module Header
|
4
11
|
class IKE
|
data/lib/packetgen/header/ip.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
# See https://github.com/sdaubert/packetgen for more informations
|
3
3
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
4
|
# This program is published under MIT license.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
5
7
|
require 'socket'
|
6
8
|
|
7
9
|
module PacketGen
|
@@ -76,7 +78,7 @@ require_relative 'ip/options'
|
|
76
78
|
# @return [Integer] first byte of IP header.
|
77
79
|
define_field :u8, Types::Int8, default: 0x45
|
78
80
|
# @!attribute tos
|
79
|
-
# @return [Integer] 8-bit Type of Service
|
81
|
+
# @return [Integer] 8-bit Type of Service self[attr]
|
80
82
|
define_field :tos, Types::Int8, default: 0
|
81
83
|
# @!attribute length
|
82
84
|
# @return [Integer] 16-bit IP total length
|
@@ -88,10 +90,10 @@ require_relative 'ip/options'
|
|
88
90
|
# @return [Integer] 16-bit frag word
|
89
91
|
define_field :frag, Types::Int16, default: 0
|
90
92
|
# @!attribute ttl
|
91
|
-
# @return [Integer] 8-bit Time To Live
|
93
|
+
# @return [Integer] 8-bit Time To Live self[attr]
|
92
94
|
define_field :ttl, Types::Int8, default: 64
|
93
95
|
# @!attribute protocol
|
94
|
-
# @return [Integer] 8-bit upper protocol
|
96
|
+
# @return [Integer] 8-bit upper protocol self[attr]
|
95
97
|
define_field :protocol, Types::Int8
|
96
98
|
# @!attribute checksum
|
97
99
|
# @return [Integer] 16-bit IP header checksum
|
@@ -126,6 +128,43 @@ require_relative 'ip/options'
|
|
126
128
|
# @return [Integer] 13-bit fragment offset
|
127
129
|
define_bit_fields_on :frag, :flag_rsv, :flag_df, :flag_mf, :fragment_offset, 13
|
128
130
|
|
131
|
+
# Helper method to compute sum of 16-bit words. Used to compute IP-style
|
132
|
+
# checksums.
|
133
|
+
# @param [#to_s] hdr header or other object on which calculates a sum
|
134
|
+
# of 16-bit words.
|
135
|
+
# @return [Integer]
|
136
|
+
def IP.sum16(hdr)
|
137
|
+
old_checksum = nil
|
138
|
+
if hdr.respond_to? :checksum=
|
139
|
+
old_checksum = hdr.checksum
|
140
|
+
hdr.checksum = 0
|
141
|
+
end
|
142
|
+
|
143
|
+
data = hdr.to_s
|
144
|
+
data << "\x00" if data.size % 2 == 1
|
145
|
+
sum = data.unpack('n*').reduce(:+)
|
146
|
+
|
147
|
+
hdr.checksum = old_checksum if old_checksum
|
148
|
+
|
149
|
+
sum
|
150
|
+
end
|
151
|
+
|
152
|
+
# Helper method to reduce an IP checksum.
|
153
|
+
# This method:
|
154
|
+
# * checks a checksum is not greater than 0xffff. If it is,
|
155
|
+
# reduces it.
|
156
|
+
# * inverts reduced self[attr].
|
157
|
+
# * forces self[attr] to 0xffff if computed self[attr] is 0.
|
158
|
+
# @param [Integer] checksum checksum to reduce
|
159
|
+
# @return [Integer] reduced checksum
|
160
|
+
def IP.reduce_checksum(checksum)
|
161
|
+
while checksum > 0xffff do
|
162
|
+
checksum = (checksum & 0xffff) + (checksum >> 16)
|
163
|
+
end
|
164
|
+
checksum = ~checksum & 0xffff
|
165
|
+
(checksum == 0) ? 0xffff : checksum
|
166
|
+
end
|
167
|
+
|
129
168
|
# Populate object from a binary string
|
130
169
|
# @param [String] str
|
131
170
|
# @return [Fields] self
|
@@ -154,6 +193,8 @@ require_relative 'ip/options'
|
|
154
193
|
# Compute checksum and set +checksum+ field
|
155
194
|
# @return [Integer]
|
156
195
|
def calc_checksum
|
196
|
+
# Checksum is only on header, so cannot use IP.sum16,
|
197
|
+
# which also calcultes checksum on #body.
|
157
198
|
checksum = (self[:u8].to_i << 8) | self.tos
|
158
199
|
checksum += self.length
|
159
200
|
checksum += self.id
|
@@ -164,17 +205,13 @@ require_relative 'ip/options'
|
|
164
205
|
checksum += self[:dst].to_i >> 16
|
165
206
|
checksum += self[:dst].to_i & 0xffff
|
166
207
|
options.to_s.unpack('n*').each { |x| checksum += x }
|
167
|
-
|
168
|
-
checksum = (checksum & 0xffff) + (checksum >> 16)
|
169
|
-
end
|
170
|
-
checksum = ~checksum & 0xffff
|
171
|
-
self[:checksum].value = (checksum == 0) ? 0xffff : checksum
|
208
|
+
self[:checksum].value = IP.reduce_checksum(checksum)
|
172
209
|
end
|
173
210
|
|
174
211
|
# Compute length and set +length+ field
|
175
212
|
# @return [Integer]
|
176
213
|
def calc_length
|
177
|
-
|
214
|
+
Base.calculate_and_set_length self
|
178
215
|
end
|
179
216
|
|
180
217
|
# Get IP part of pseudo header checksum.
|
@@ -201,9 +238,9 @@ require_relative 'ip/options'
|
|
201
238
|
def inspect
|
202
239
|
str = Inspect.dashed_line(self.class, 2)
|
203
240
|
shift = Inspect.shift_level(2)
|
204
|
-
|
241
|
+
fields.each do |attr|
|
205
242
|
next if attr == :body
|
206
|
-
str << Inspect.inspect_attribute(attr,
|
243
|
+
str << Inspect.inspect_attribute(attr, self[attr], 2)
|
207
244
|
if attr == :u8
|
208
245
|
str << shift + Inspect::FMT_ATTR % ['', 'version', version]
|
209
246
|
str << shift + Inspect::FMT_ATTR % ['', 'ihl', ihl]
|
@@ -3,6 +3,8 @@
|
|
3
3
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
4
|
# This program is published under MIT license.
|
5
5
|
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
6
8
|
module PacketGen
|
7
9
|
module Header
|
8
10
|
class IP
|
@@ -52,6 +54,12 @@ module PacketGen
|
|
52
54
|
(self.a1 << 24) | (self.a2 << 16) | (self.a3 << 8) |
|
53
55
|
self.a4
|
54
56
|
end
|
57
|
+
|
58
|
+
# Return true if this address is a multicast one
|
59
|
+
# @return [Boolean]
|
60
|
+
def mcast?
|
61
|
+
self.a1 >= 224 && self.a1 <= 239
|
62
|
+
end
|
55
63
|
end
|
56
64
|
end
|
57
65
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
# See https://github.com/sdaubert/packetgen for more informations
|
4
4
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
5
5
|
# This program is published under MIT license.
|
6
|
+
|
7
|
+
# frozen_string_literal: true
|
6
8
|
require 'ipaddr'
|
7
9
|
|
8
10
|
module PacketGen
|
@@ -90,7 +92,7 @@ module PacketGen
|
|
90
92
|
# Compute length and set +len+ field
|
91
93
|
# @return [Integer]
|
92
94
|
def calc_length
|
93
|
-
|
95
|
+
Base.calculate_and_set_length self, header_in_size: false
|
94
96
|
end
|
95
97
|
|
96
98
|
# Get IPv6 part of pseudo header checksum.
|
@@ -136,9 +138,9 @@ module PacketGen
|
|
136
138
|
# @return [String]
|
137
139
|
def inspect
|
138
140
|
str = Inspect.dashed_line(self.class, 2)
|
139
|
-
|
141
|
+
fields.each do |attr|
|
140
142
|
next if attr == :body
|
141
|
-
str << Inspect.inspect_attribute(attr,
|
143
|
+
str << Inspect.inspect_attribute(attr, self[attr], 2)
|
142
144
|
if attr == :u32
|
143
145
|
shift = Inspect.shift_level(2)
|
144
146
|
str << shift + Inspect::FMT_ATTR % ['', 'version', version]
|