packetfu 1.1.5 → 1.1.6

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.
Files changed (52) hide show
  1. data/.document +5 -2
  2. data/.gitignore +1 -0
  3. data/LICENSE.txt +1 -1
  4. data/bench/after-2012-07-28.txt +25 -0
  5. data/bench/before-2012-07-28.txt +25 -0
  6. data/bench/benchit.rb +68 -0
  7. data/bench/calc_delta.rb +17 -0
  8. data/bench/octets.rb +22 -0
  9. data/bench/octets_after.txt +8 -0
  10. data/bench/octets_after_refactor.txt +8 -0
  11. data/bench/octets_before.txt +8 -0
  12. data/lib/packetfu.rb +8 -3
  13. data/lib/packetfu/packet.rb +2 -2
  14. data/lib/packetfu/pcap.rb +20 -4
  15. data/lib/packetfu/protos/arp.rb +7 -160
  16. data/lib/packetfu/protos/arp/header.rb +160 -0
  17. data/lib/packetfu/protos/arp/mixin.rb +38 -0
  18. data/lib/packetfu/protos/eth.rb +5 -247
  19. data/lib/packetfu/protos/eth/header.rb +247 -0
  20. data/lib/packetfu/protos/eth/mixin.rb +20 -0
  21. data/lib/packetfu/protos/hsrp.rb +13 -123
  22. data/lib/packetfu/protos/hsrp/header.rb +120 -0
  23. data/lib/packetfu/protos/hsrp/mixin.rb +31 -0
  24. data/lib/packetfu/protos/icmp.rb +10 -97
  25. data/lib/packetfu/protos/icmp/header.rb +93 -0
  26. data/lib/packetfu/protos/icmp/mixin.rb +17 -0
  27. data/lib/packetfu/protos/ip.rb +7 -295
  28. data/lib/packetfu/protos/ip/header.rb +335 -0
  29. data/lib/packetfu/protos/ip/mixin.rb +43 -0
  30. data/lib/packetfu/protos/ipv6.rb +7 -191
  31. data/lib/packetfu/protos/ipv6/header.rb +190 -0
  32. data/lib/packetfu/protos/ipv6/mixin.rb +31 -0
  33. data/lib/packetfu/protos/tcp.rb +13 -939
  34. data/lib/packetfu/protos/tcp/ecn.rb +42 -0
  35. data/lib/packetfu/protos/tcp/flags.rb +83 -0
  36. data/lib/packetfu/protos/tcp/header.rb +307 -0
  37. data/lib/packetfu/protos/tcp/hlen.rb +40 -0
  38. data/lib/packetfu/protos/tcp/mixin.rb +48 -0
  39. data/lib/packetfu/protos/tcp/option.rb +323 -0
  40. data/lib/packetfu/protos/tcp/options.rb +106 -0
  41. data/lib/packetfu/protos/tcp/reserved.rb +42 -0
  42. data/lib/packetfu/protos/udp.rb +12 -110
  43. data/lib/packetfu/protos/udp/header.rb +107 -0
  44. data/lib/packetfu/protos/udp/mixin.rb +23 -0
  45. data/lib/packetfu/utils.rb +24 -24
  46. data/lib/packetfu/version.rb +1 -1
  47. data/packetfu.gemspec +2 -2
  48. data/test/test_ip.rb +0 -19
  49. data/test/test_octets.rb +18 -21
  50. data/test/test_tcp.rb +10 -0
  51. data/test/test_udp.rb +17 -0
  52. metadata +79 -50
@@ -0,0 +1,335 @@
1
+ require 'ipaddr'
2
+
3
+ module PacketFu
4
+ # Octets implements the addressing scheme for IP.
5
+ #
6
+ # ==== Header Definition
7
+ #
8
+ # Int32 :ip_addr
9
+ class Octets < Struct.new(:ip_addr)
10
+ include StructFu
11
+
12
+ IPV4_RE = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
13
+ def initialize(args={})
14
+ super(
15
+ Int32.new(args[:ip_addr]))
16
+ end
17
+
18
+ # Returns the object in string form.
19
+ def to_s
20
+ [self[:ip_addr].to_i].pack("N")
21
+ end
22
+
23
+ # Reads a string to populate the object.
24
+ def read(str)
25
+ force_binary(str)
26
+ return self if str.nil?
27
+ self[:ip_addr].read str[0,4]
28
+ self
29
+ end
30
+
31
+ # Returns an address in dotted-quad format.
32
+ def to_x
33
+ # This could be slightly faster if we reproduced the code in
34
+ # 'octets()' and didn't have to map to strings.
35
+ self.octets.map(&:to_s).join('.')
36
+ end
37
+
38
+ # Returns an address in numerical format.
39
+ def to_i
40
+ self[:ip_addr].to_i
41
+ end
42
+
43
+ # Set the IP Address by reading a dotted-quad address.
44
+ def read_quad(str)
45
+ match = IPV4_RE.match(str)
46
+ if match.nil?
47
+ raise ArgumentError.new("str is not a valid IPV4 address")
48
+ end
49
+ a = match[1].to_i
50
+ b = match[2].to_i
51
+ c = match[3].to_i
52
+ d = match[4].to_i
53
+ unless (a >= 0 && a <= 255 &&
54
+ b >= 0 && b <= 255 &&
55
+ c >= 0 && c <= 255 &&
56
+ d >= 0 && d <= 255)
57
+ raise ArgumentError.new("str is not a valid IPV4 address")
58
+ end
59
+
60
+ self[:ip_addr].value = (a<<24) + (b<<16) + (c<<8) + d
61
+ self
62
+ end
63
+
64
+ # Returns the IP address as 4 octets
65
+ def octets
66
+ addr = self.to_i
67
+ [
68
+ ((addr >> 24) & 0xff),
69
+ ((addr >> 16) & 0xff),
70
+ ((addr >> 8) & 0xff),
71
+ (addr & 0xff)
72
+ ]
73
+ end
74
+
75
+ # Returns the value for the first octet
76
+ def o1
77
+ (self.to_i >> 24) & 0xff
78
+ end
79
+
80
+ # Returns the value for the second octet
81
+ def o2
82
+ (self.to_i >> 16) & 0xff
83
+ end
84
+
85
+ # Returns the value for the third octet
86
+ def o3
87
+ (self.to_i >> 8) & 0xff
88
+ end
89
+
90
+ # Returns the value for the fourth octet
91
+ def o4
92
+ self.to_i & 0xff
93
+ end
94
+
95
+ end
96
+
97
+ # IPHeader is a complete IP struct, used in IPPacket. Most traffic on most networks today is IP-based.
98
+ #
99
+ # For more on IP packets, see http://www.networksorcery.com/enp/protocol/ip.htm
100
+ #
101
+ # ==== Header Definition
102
+ #
103
+ # Fixnum (4 bits) :ip_v, Default: 4
104
+ # Fixnum (4 bits) :ip_hl, Default: 5
105
+ # Int8 :ip_tos, Default: 0 # TODO: Break out the bits
106
+ # Int16 :ip_len, Default: calculated
107
+ # Int16 :ip_id, Default: calculated # IRL, hardly random.
108
+ # Int16 :ip_frag, Default: 0 # TODO: Break out the bits
109
+ # Int8 :ip_ttl, Default: 0xff # Changes per flavor
110
+ # Int8 :ip_proto, Default: 0x01 # TCP: 0x06, UDP 0x11, ICMP 0x01
111
+ # Int16 :ip_sum, Default: calculated
112
+ # Octets :ip_src
113
+ # Octets :ip_dst
114
+ # String :body
115
+ #
116
+ # Note that IPPackets will always be somewhat incorrect upon initalization,
117
+ # and want an IPHeader#recalc() to become correct before a
118
+ # Packet#to_f or Packet#to_w.
119
+ class IPHeader < Struct.new(:ip_v, :ip_hl, :ip_tos, :ip_len,
120
+ :ip_id, :ip_frag, :ip_ttl, :ip_proto,
121
+ :ip_sum, :ip_src, :ip_dst, :body)
122
+ include StructFu
123
+
124
+ def initialize(args={})
125
+ @random_id = rand(0xffff)
126
+ super(
127
+ (args[:ip_v] || 4),
128
+ (args[:ip_hl] || 5),
129
+ Int8.new(args[:ip_tos]),
130
+ Int16.new(args[:ip_len] || 20),
131
+ Int16.new(args[:ip_id] || ip_calc_id),
132
+ Int16.new(args[:ip_frag]),
133
+ Int8.new(args[:ip_ttl] || 32),
134
+ Int8.new(args[:ip_proto]),
135
+ Int16.new(args[:ip_sum] || ip_calc_sum),
136
+ Octets.new.read(args[:ip_src] || "\x00\x00\x00\x00"),
137
+ Octets.new.read(args[:ip_dst] || "\x00\x00\x00\x00"),
138
+ StructFu::String.new.read(args[:body])
139
+ )
140
+ end
141
+
142
+ # Returns the object in string form.
143
+ def to_s
144
+ byte_v_hl = [(self.ip_v << 4) + self.ip_hl].pack("C")
145
+ byte_v_hl + (self.to_a[2,10].map {|x| x.to_s}.join)
146
+ end
147
+
148
+ # Reads a string to populate the object.
149
+ def read(str)
150
+ force_binary(str)
151
+ return self if str.nil?
152
+ self[:ip_v] = str[0,1].unpack("C").first >> 4
153
+ self[:ip_hl] = str[0,1].unpack("C").first.to_i & 0x0f
154
+ self[:ip_tos].read(str[1,1])
155
+ self[:ip_len].read(str[2,2])
156
+ self[:ip_id].read(str[4,2])
157
+ self[:ip_frag].read(str[6,2])
158
+ self[:ip_ttl].read(str[8,1])
159
+ self[:ip_proto].read(str[9,1])
160
+ self[:ip_sum].read(str[10,2])
161
+ self[:ip_src].read(str[12,4])
162
+ self[:ip_dst].read(str[16,4])
163
+ self[:body].read(str[20,str.size]) if str.size > 20
164
+ self
165
+ end
166
+
167
+ # Setter for the version.
168
+ def ip_v=(i); self[:ip_v] = i.to_i; end
169
+ # Getter for the version.
170
+ def ip_v; self[:ip_v].to_i; end
171
+ # Setter for the header length (divide by 4)
172
+ def ip_hl=(i); self[:ip_hl] = i.to_i; end
173
+ # Getter for the header length (multiply by 4)
174
+ def ip_hl; self[:ip_hl].to_i; end
175
+ # Setter for the differentiated services
176
+ def ip_tos=(i); typecast i; end
177
+ # Getter for the differentiated services
178
+ def ip_tos; self[:ip_tos].to_i; end
179
+ # Setter for total length.
180
+ def ip_len=(i); typecast i; end
181
+ # Getter for total length.
182
+ def ip_len; self[:ip_len].to_i; end
183
+ # Setter for the identication number.
184
+ def ip_id=(i); typecast i; end
185
+ # Getter for the identication number.
186
+ def ip_id; self[:ip_id].to_i; end
187
+ # Setter for the fragmentation ID.
188
+ def ip_frag=(i); typecast i; end
189
+ # Getter for the fragmentation ID.
190
+ def ip_frag; self[:ip_frag].to_i; end
191
+ # Setter for the time to live.
192
+ def ip_ttl=(i); typecast i; end
193
+ # Getter for the time to live.
194
+ def ip_ttl; self[:ip_ttl].to_i; end
195
+ # Setter for the protocol number.
196
+ def ip_proto=(i); typecast i; end
197
+ # Getter for the protocol number.
198
+ def ip_proto; self[:ip_proto].to_i; end
199
+ # Setter for the checksum.
200
+ def ip_sum=(i); typecast i; end
201
+ # Getter for the checksum.
202
+ def ip_sum; self[:ip_sum].to_i; end
203
+ # Setter for the source IP address.
204
+ def ip_src=(i)
205
+ case i
206
+ when Numeric
207
+ self[:ip_src] = Octets.new.read([i].pack("N"))
208
+ when Octets
209
+ self[:ip_src] = i
210
+ else
211
+ typecast i
212
+ end
213
+ end
214
+ # Getter for the source IP address.
215
+ def ip_src; self[:ip_src].to_i; end
216
+ # Setter for the destination IP address.
217
+ def ip_dst=(i)
218
+ case i
219
+ when Numeric
220
+ self[:ip_dst] = Octets.new.read([i].pack("N"))
221
+ when Octets
222
+ self[:ip_dst] = i
223
+ else
224
+ typecast i
225
+ end
226
+ end
227
+ # Getter for the destination IP address.
228
+ def ip_dst; self[:ip_dst].to_i; end
229
+
230
+ # Calulcate the true length of the packet.
231
+ def ip_calc_len
232
+ (ip_hl * 4) + body.to_s.length
233
+ end
234
+
235
+ # Return the claimed header length
236
+ def ip_hlen
237
+ (ip_hl * 4)
238
+ end
239
+
240
+ # Calculate the true checksum of the packet.
241
+ # (Yes, this is the long way to do it, but it's e-z-2-read for mathtards like me.)
242
+ def ip_calc_sum
243
+ checksum = (((self.ip_v << 4) + self.ip_hl) << 8) + self.ip_tos
244
+ checksum += self.ip_len
245
+ checksum += self.ip_id
246
+ checksum += self.ip_frag
247
+ checksum += (self.ip_ttl << 8) + self.ip_proto
248
+ checksum += (self.ip_src >> 16)
249
+ checksum += (self.ip_src & 0xffff)
250
+ checksum += (self.ip_dst >> 16)
251
+ checksum += (self.ip_dst & 0xffff)
252
+ checksum = checksum % 0xffff
253
+ checksum = 0xffff - checksum
254
+ checksum == 0 ? 0xffff : checksum
255
+ end
256
+
257
+ # Retrieve the IP ID
258
+ def ip_calc_id
259
+ @random_id
260
+ end
261
+
262
+ # Sets a more readable IP address. If you wants to manipulate individual octets,
263
+ # (eg, for host scanning in one network), it would be better use ip_src.o1 through
264
+ # ip_src.o4 instead.
265
+ def ip_saddr=(addr)
266
+ self[:ip_src].read_quad(addr)
267
+ end
268
+
269
+ # Returns a more readable IP source address.
270
+ def ip_saddr
271
+ self[:ip_src].to_x
272
+ end
273
+
274
+ # Sets a more readable IP address.
275
+ def ip_daddr=(addr)
276
+ self[:ip_dst].read_quad(addr)
277
+ end
278
+
279
+ # Returns a more readable IP destination address.
280
+ def ip_daddr
281
+ self[:ip_dst].to_x
282
+ end
283
+
284
+ # Translate various formats of IPv4 Addresses to an array of digits.
285
+ def self.octet_array(addr)
286
+ if addr.class == String
287
+ oa = addr.split('.').collect {|x| x.to_i}
288
+ elsif addr.class == Fixnum
289
+ oa = IPAddr.new(addr, Socket::AF_INET).to_s.split('.')
290
+ elsif addr.class == Bignum
291
+ oa = IPAddr.new(addr, Socket::AF_INET).to_s.split('.')
292
+ elsif addr.class == Array
293
+ oa = addr
294
+ else
295
+ raise ArgumentError, "IP Address should be a dotted quad string, an array of ints, or a bignum"
296
+ end
297
+ end
298
+
299
+ # Recalculate the calculated IP fields. Valid arguments are:
300
+ # :all
301
+ # :ip_len
302
+ # :ip_sum
303
+ # :ip_id
304
+ def ip_recalc(arg=:all)
305
+ case arg
306
+ when :ip_len
307
+ self.ip_len=ip_calc_len
308
+ when :ip_sum
309
+ self.ip_sum=ip_calc_sum
310
+ when :ip_id
311
+ @random_id = rand(0xffff)
312
+ when :all
313
+ self.ip_id= ip_calc_id
314
+ self.ip_len= ip_calc_len
315
+ self.ip_sum= ip_calc_sum
316
+ else
317
+ raise ArgumentError, "No such field `#{arg}'"
318
+ end
319
+ end
320
+
321
+ # Readability aliases
322
+
323
+ alias :ip_src_readable :ip_saddr
324
+ alias :ip_dst_readable :ip_daddr
325
+
326
+ def ip_id_readable
327
+ "0x%04x" % ip_id
328
+ end
329
+
330
+ def ip_sum_readable
331
+ "0x%04x" % ip_sum
332
+ end
333
+
334
+ end
335
+ end
@@ -0,0 +1,43 @@
1
+
2
+ module PacketFu
3
+ # This Mixin simplifies access to the IPHeaders. Mix this in with your
4
+ # packet interface, and it will add methods that essentially delegate to
5
+ # the 'ip_header' method (assuming that it is a IPHeader object)
6
+ module IPHeaderMixin
7
+ def ip_calc_id; self.ip_header.ip_calc_id ; end
8
+ def ip_calc_len; self.ip_header.ip_calc_len ; end
9
+ def ip_calc_sum; self.ip_header.ip_calc_sum ; end
10
+ def ip_daddr; self.ip_header.ip_daddr ; end
11
+ def ip_daddr=(v); self.ip_header.ip_daddr= v; end
12
+ def ip_dst; self.ip_header.ip_dst ; end
13
+ def ip_dst=(v); self.ip_header.ip_dst= v; end
14
+ def ip_dst_readable; self.ip_header.ip_dst_readable ; end
15
+ def ip_frag; self.ip_header.ip_frag ; end
16
+ def ip_frag=(v); self.ip_header.ip_frag= v; end
17
+ def ip_hl; self.ip_header.ip_hl ; end
18
+ def ip_hl=(v); self.ip_header.ip_hl= v; end
19
+ def ip_hlen; self.ip_header.ip_hlen ; end
20
+ def ip_id; self.ip_header.ip_id ; end
21
+ def ip_id=(v); self.ip_header.ip_id= v; end
22
+ def ip_id_readable; self.ip_header.ip_id_readable ; end
23
+ def ip_len; self.ip_header.ip_len ; end
24
+ def ip_len=(v); self.ip_header.ip_len= v; end
25
+ def ip_proto; self.ip_header.ip_proto ; end
26
+ def ip_proto=(v); self.ip_header.ip_proto= v; end
27
+ def ip_recalc(*args); self.ip_header.ip_recalc(*args) ; end
28
+ def ip_saddr; self.ip_header.ip_saddr ; end
29
+ def ip_saddr=(v); self.ip_header.ip_saddr= v; end
30
+ def ip_src; self.ip_header.ip_src ; end
31
+ def ip_src=(v); self.ip_header.ip_src= v; end
32
+ def ip_src_readable; self.ip_header.ip_src_readable ; end
33
+ def ip_sum; self.ip_header.ip_sum ; end
34
+ def ip_sum=(v); self.ip_header.ip_sum= v; end
35
+ def ip_sum_readable; self.ip_header.ip_sum_readable ; end
36
+ def ip_tos; self.ip_header.ip_tos ; end
37
+ def ip_tos=(v); self.ip_header.ip_tos= v; end
38
+ def ip_ttl; self.ip_header.ip_ttl ; end
39
+ def ip_ttl=(v); self.ip_header.ip_ttl= v; end
40
+ def ip_v; self.ip_header.ip_v ; end
41
+ def ip_v=(v); self.ip_header.ip_v= v; end
42
+ end
43
+ end
@@ -1,194 +1,10 @@
1
- module PacketFu
2
-
3
- # AddrIpv6 handles addressing for IPv6Header
4
- #
5
- # ==== Header Definition
6
- #
7
- # Int32 :a1
8
- # Int32 :a2
9
- # Int32 :a3
10
- # Int32 :a4
11
- class AddrIpv6 < Struct.new(:a1, :a2, :a3, :a4)
1
+ require 'packetfu/protos/eth/header'
2
+ require 'packetfu/protos/eth/mixin'
12
3
 
13
- include StructFu
14
-
15
- def initialize(args={})
16
- super(
17
- Int32.new(args[:a1]),
18
- Int32.new(args[:a2]),
19
- Int32.new(args[:a3]),
20
- Int32.new(args[:a4]))
21
- end
22
-
23
- # Returns the address in string format.
24
- def to_s
25
- self.to_a.map {|x| x.to_s}.join
26
- end
27
-
28
- # Returns the address as a fairly ginormous integer.
29
- def to_i
30
- (a1.to_i << 96) + (a2.to_i << 64) + (a3.to_i << 32) + a4.to_i
31
- end
32
-
33
- # Returns the address as a colon-delimited hex string.
34
- def to_x
35
- IPAddr.new(self.to_i, Socket::AF_INET6).to_s
36
- end
37
-
38
- # Reads in a string and casts it as an IPv6 address
39
- def read(str)
40
- force_binary(str)
41
- return self if str.nil?
42
- self[:a1].read str[0,4]
43
- self[:a2].read str[4,4]
44
- self[:a3].read str[8,4]
45
- self[:a4].read str[12,4]
46
- self
47
- end
48
-
49
- # Reads in a colon-delimited hex string and casts it as an IPv6 address.
50
- def read_x(str)
51
- addr = IPAddr.new(str).to_i
52
- self[:a1]=Int32.new(addr >> 96)
53
- self[:a2]=Int32.new((addr & 0x00000000ffffffff0000000000000000) >> 64)
54
- self[:a3]=Int32.new((addr & 0x0000000000000000ffffffff00000000) >> 32)
55
- self[:a4]=Int32.new(addr & 0x000000000000000000000000ffffffff)
56
- self
57
- end
58
-
59
- end
60
-
61
- # IPv6Header is complete IPv6 struct, used in IPv6Packet.
62
- #
63
- # ==== Header Definition
64
- #
65
- # Fixnum (4 bits) :ipv6_v Default: 6 # Versiom
66
- # Fixnum (8 bits) :ipv6_class Defualt: 0 # Class
67
- # Fixnum (20 bits) :ipv6_label Defualt: 0 # Label
68
- # Int16 :ipv6_len Default: calc # Payload length
69
- # Int8 :ipv6_next # Next Header
70
- # Int8 :ipv6_hop Default: 0xff # Hop limit
71
- # AddrIpv6 :ipv6_src
72
- # AddrIpv6 :ipv6_dst
73
- # String :body
74
- class IPv6Header < Struct.new(:ipv6_v, :ipv6_class, :ipv6_label,
75
- :ipv6_len, :ipv6_next, :ipv6_hop,
76
- :ipv6_src, :ipv6_dst, :body)
77
- include StructFu
78
-
79
- def initialize(args={})
80
- super(
81
- (args[:ipv6_v] || 6),
82
- (args[:ipv6_class] || 0),
83
- (args[:ipv6_label] || 0),
84
- Int16.new(args[:ipv6_len]),
85
- Int8.new(args[:ipv6_next]),
86
- Int8.new(args[:ipv6_hop] || 0xff),
87
- AddrIpv6.new.read(args[:ipv6_src] || ("\x00" * 16)),
88
- AddrIpv6.new.read(args[:ipv6_dst] || ("\x00" * 16)),
89
- StructFu::String.new.read(args[:body])
90
- )
91
- end
92
-
93
- # Returns the object in string form.
94
- def to_s
95
- bytes_v_class_label = [(self.ipv6_v << 28) +
96
- (self.ipv6_class << 20) +
97
- self.ipv6_label].pack("N")
98
- bytes_v_class_label + (self.to_a[3,6].map {|x| x.to_s}.join)
99
- end
100
-
101
- # Reads a string to populate the object.
102
- def read(str)
103
- force_binary(str)
104
- return self if str.nil?
105
- self[:ipv6_v] = str[0,1].unpack("C").first >> 4
106
- self[:ipv6_class] = (str[0,2].unpack("n").first & 0x0ff0) >> 4
107
- self[:ipv6_label] = str[0,4].unpack("N").first & 0x000fffff
108
- self[:ipv6_len].read(str[4,2])
109
- self[:ipv6_next].read(str[6,1])
110
- self[:ipv6_hop].read(str[7,1])
111
- self[:ipv6_src].read(str[8,16])
112
- self[:ipv6_dst].read(str[24,16])
113
- self[:body].read(str[40,str.size]) if str.size > 40
114
- self
115
- end
116
-
117
- # Setter for the version (usually, 6).
118
- def ipv6_v=(i); self[:ip_v] = i.to_i; end
119
- # Getter for the version (usually, 6).
120
- def ipv6_v; self[:ipv6_v].to_i; end
121
- # Setter for the traffic class.
122
- def ipv6_class=(i); self[:ip_class] = i.to_i; end
123
- # Getter for the traffic class.
124
- def ipv6_class; self[:ipv6_class].to_i; end
125
- # Setter for the flow label.
126
- def ipv6_label=(i); self[:ip_label] = i.to_i; end
127
- # Getter for the flow label.
128
- def ipv6_label; self[:ipv6_label].to_i; end
129
- # Setter for the payload length.
130
- def ipv6_len=(i); typecast i; end
131
- # Getter for the payload length.
132
- def ipv6_len; self[:ipv6_len].to_i; end
133
- # Setter for the next protocol header.
134
- def ipv6_next=(i); typecast i; end
135
- # Getter for the next protocol header.
136
- def ipv6_next; self[:ipv6_next].to_i; end
137
- # Setter for the hop limit.
138
- def ipv6_hop=(i); typecast i; end
139
- # Getter for the hop limit.
140
- def ipv6_hop; self[:ipv6_hop].to_i; end
141
- # Setter for the source address.
142
- def ipv6_src=(i); typecast i; end
143
- # Getter for the source address.
144
- def ipv6_src; self[:ipv6_src].to_i; end
145
- # Setter for the destination address.
146
- def ipv6_dst=(i); typecast i; end
147
- # Getter for the destination address.
148
- def ipv6_dst; self[:ipv6_dst].to_i; end
149
-
150
- # Calculates the payload length.
151
- def ipv6_calc_len
152
- self[:ipv6_len] = body.to_s.length
153
- end
154
-
155
- # Recalculates the calculatable fields for this object.
156
- def ipv6_recalc(arg=:all)
157
- case arg
158
- when :ipv6_len
159
- ipv6_calc_len
160
- when :all
161
- ipv6_recalc(:len)
162
- end
163
- end
164
-
165
- # Get the source address in a more readable form.
166
- def ipv6_saddr
167
- self[:ipv6_src].to_x
168
- end
169
-
170
- # Set the source address in a more readable form.
171
- def ipv6_saddr=(str)
172
- self[:ipv6_src].read_x(str)
173
- end
174
-
175
- # Get the destination address in a more readable form.
176
- def ipv6_daddr
177
- self[:ipv6_dst].to_x
178
- end
179
-
180
- # Set the destination address in a more readable form.
181
- def ipv6_daddr=(str)
182
- self[:ipv6_dst].read_x(str)
183
- end
184
-
185
- # Readability aliases
186
-
187
- alias :ipv6_src_readable :ipv6_saddr
188
- alias :ipv6_dst_readable :ipv6_daddr
189
-
190
- end # class IPv6Header
4
+ require 'packetfu/protos/ipv6/header'
5
+ require 'packetfu/protos/ipv6/mixin'
191
6
 
7
+ module PacketFu
192
8
  # IPv6Packet is used to construct IPv6 Packets. They contain an EthHeader and an IPv6Header, and in
193
9
  # the distant, unknowable future, will take interesting IPv6ish payloads.
194
10
  #
@@ -205,6 +21,8 @@ module PacketFu
205
21
  # :config
206
22
  # A hash of return address details, often the output of Utils.whoami?
207
23
  class IPv6Packet < Packet
24
+ include ::PacketFu::EthHeaderMixin
25
+ include ::PacketFu::IPv6HeaderMixin
208
26
 
209
27
  attr_accessor :eth_header, :ipv6_header
210
28
 
@@ -218,8 +36,6 @@ module PacketFu
218
36
  def read(str=nil,args={})
219
37
  raise "Cannot parse `#{str}'" unless self.class.can_parse?(str)
220
38
  @eth_header.read(str)
221
- @ipv6_header.read(str[14,str.size])
222
- @eth_header.body = @ipv6_header
223
39
  super(args)
224
40
  self
225
41
  end