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
data/.document CHANGED
@@ -1,4 +1,7 @@
1
1
  lib/packetfu.rb
2
2
  lib/packetfu/
3
- README
4
- LICENSE
3
+ -
4
+ LICENSE.txt
5
+ INSTALL.rdoc
6
+ README.rdoc
7
+ examples/*.rb
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  *.gem
2
2
  doc/
3
3
  pkg/
4
+ test/*test.pcap
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008-2011, Tod Beardsley
1
+ Copyright (c) 2008-2012, Tod Beardsley
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
@@ -0,0 +1,25 @@
1
+ Parsing a TCP Packet...
2
+ user system total real
3
+ PacketFu::Packet.parse() 1.670000 0.010000 1.680000 ( 1.664486)
4
+ PacketFu::EthPacket.new.read() 0.180000 0.000000 0.180000 ( 0.179386)
5
+ PacketFu::IPPacket.new.read() 0.410000 0.000000 0.410000 ( 0.415767)
6
+ PacketFu::TCPPacket.new.read() 1.380000 0.000000 1.380000 ( 1.375509)
7
+
8
+ Parsing a UDP Packet...
9
+ user system total real
10
+ PacketFu::Packet.parse() 1.750000 0.000000 1.750000 ( 1.757758)
11
+ PacketFu::EthPacket.new.read() 0.180000 0.000000 0.180000 ( 0.179951)
12
+ PacketFu::IPPacket.new.read() 0.420000 0.000000 0.420000 ( 0.416224)
13
+ PacketFu::UDPPacket.new.read() 0.720000 0.000000 0.720000 ( 0.715579)
14
+
15
+ Parsing a ARP Packet...
16
+ user system total real
17
+ PacketFu::Packet.parse() 0.820000 0.000000 0.820000 ( 0.823303)
18
+ PacketFu::EthPacket.new.read() 0.180000 0.000000 0.180000 ( 0.182247)
19
+ PacketFu::ARPPacket.new.read() 0.670000 0.000000 0.670000 ( 0.672712)
20
+
21
+ Parsing a IPv6 Packet...
22
+ user system total real
23
+ PacketFu::Packet.parse() 0.700000 0.000000 0.700000 ( 0.695721)
24
+ PacketFu::EthPacket.new.read() 0.180000 0.000000 0.180000 ( 0.180608)
25
+ PacketFu::IPv6Packet.new.read() 0.530000 0.000000 0.530000 ( 0.527124)
@@ -0,0 +1,25 @@
1
+ Parsing a TCP Packet...
2
+ user system total real
3
+ PacketFu::Packet.parse() 3.290000 0.000000 3.290000 ( 3.290771)
4
+ PacketFu::EthPacket.new.read() 0.180000 0.000000 0.180000 ( 0.181850)
5
+ PacketFu::IPPacket.new.read() 0.490000 0.000000 0.490000 ( 0.484150)
6
+ PacketFu::TCPPacket.new.read() 2.970000 0.000000 2.970000 ( 2.977186)
7
+
8
+ Parsing a UDP Packet...
9
+ user system total real
10
+ PacketFu::Packet.parse() 2.530000 0.010000 2.540000 ( 2.529333)
11
+ PacketFu::EthPacket.new.read() 0.180000 0.000000 0.180000 ( 0.179065)
12
+ PacketFu::IPPacket.new.read() 0.490000 0.000000 0.490000 ( 0.487412)
13
+ PacketFu::UDPPacket.new.read() 1.060000 0.000000 1.060000 ( 1.067339)
14
+
15
+ Parsing a ARP Packet...
16
+ user system total real
17
+ PacketFu::Packet.parse() 0.860000 0.000000 0.860000 ( 0.851042)
18
+ PacketFu::EthPacket.new.read() 0.180000 0.000000 0.180000 ( 0.183220)
19
+ PacketFu::ARPPacket.new.read() 0.720000 0.000000 0.720000 ( 0.718533)
20
+
21
+ Parsing a IPv6 Packet...
22
+ user system total real
23
+ PacketFu::Packet.parse() 0.750000 0.000000 0.750000 ( 0.753657)
24
+ PacketFu::EthPacket.new.read() 0.180000 0.000000 0.180000 ( 0.182015)
25
+ PacketFu::IPv6Packet.new.read() 0.610000 0.000000 0.610000 ( 0.611805)
data/bench/benchit.rb ADDED
@@ -0,0 +1,68 @@
1
+ $:.unshift File.join(File.expand_path(File.dirname(__FILE__)), "..", "lib")
2
+ require 'packetfu'
3
+ require 'benchmark'
4
+ class String
5
+ def bin
6
+ self.scan(/../).map {|x| x.to_i(16).chr}.join
7
+ end
8
+ end
9
+
10
+ file_pfx = ARGV.shift
11
+
12
+ IPV6_PACKET = "3333000000fb442a60c14d7b86dd60000000006611fffe80000000000000462a60fffec14d7bff0200000000000000000000000000fb14e914e900664ed1000000000002000000020000145542432d437573746f6d6572732d695061642d33056c6f63616c0000ff0001c00c00ff0001c00c001c0001000000780010fe80000000000000462a60fffec14d7bc00c0001000100000078000448d77827".bin
13
+
14
+ ARP_PACKET = "ffffffffffff001e6837bcf708060001080006040001001e6837bcf748d7780100000000000048d779f7000000000000000000000000000000000000".bin
15
+
16
+ UDP_PACKET = "01005e7ffffa100ba9eb63400800450000a12d7c0000011159b446a5fb7ceffffffacdf3076c008d516e4d2d534541524348202a20485454502f312e310d0a486f73743a3233392e3235352e3235352e3235303a313930300d0a53543a75726e3a736368656d61732d75706e702d6f72673a6465766963653a496e7465726e6574476174657761794465766963653a310d0a4d616e3a22737364703a646973636f766572220d0a4d583a330d0a0d0a".bin
17
+
18
+ TCP_PACKET = "e0f8472161a600254ba0760608004500004403554000400651d0c0a83207c0a832370224c1d22d94847f0b07c4ba8018ffff30ba00000101080a8731821433564b8c01027165000000000000200000000000".bin
19
+
20
+ iters = 5_000
21
+ data = []
22
+ data = []
23
+ data = []
24
+ data = []
25
+ puts "Parsing a TCP Packet..."
26
+ require 'pp'
27
+ Benchmark.bm do |bm|
28
+ data << bm.report("PacketFu::Packet.parse() ") { iters.times {PacketFu::Packet.parse(TCP_PACKET)} }
29
+ data << bm.report("PacketFu::EthPacket.new.read() ") { iters.times {PacketFu::EthPacket.new.read(TCP_PACKET)} }
30
+ data << bm.report("PacketFu::IPPacket.new.read() ") { iters.times {PacketFu::IPPacket.new.read(TCP_PACKET)} }
31
+ data << bm.report("PacketFu::TCPPacket.new.read() ") { iters.times {PacketFu::TCPPacket.new.read(TCP_PACKET)} }
32
+ nil
33
+ end
34
+
35
+ puts ""
36
+ puts "Parsing a UDP Packet..."
37
+ Benchmark.bm do |bm|
38
+ data << bm.report("PacketFu::Packet.parse() ") { iters.times {PacketFu::Packet.parse(UDP_PACKET)} }
39
+ data << bm.report("PacketFu::EthPacket.new.read() ") { iters.times {PacketFu::EthPacket.new.read(UDP_PACKET)} }
40
+ data << bm.report("PacketFu::IPPacket.new.read() ") { iters.times {PacketFu::IPPacket.new.read(UDP_PACKET)} }
41
+ data << bm.report("PacketFu::UDPPacket.new.read() ") { iters.times {PacketFu::UDPPacket.new.read(UDP_PACKET)} }
42
+ nil
43
+ end
44
+
45
+ puts ""
46
+ puts "Parsing a ARP Packet..."
47
+ Benchmark.bm do |bm|
48
+ data << bm.report("PacketFu::Packet.parse() ") { iters.times {PacketFu::Packet.parse(ARP_PACKET)} }
49
+ data << bm.report("PacketFu::EthPacket.new.read() ") { iters.times {PacketFu::EthPacket.new.read(ARP_PACKET)} }
50
+ data << bm.report("PacketFu::ARPPacket.new.read() ") { iters.times {PacketFu::ARPPacket.new.read(ARP_PACKET)} }
51
+ nil
52
+ end
53
+
54
+ puts ""
55
+ puts "Parsing a IPv6 Packet..."
56
+ Benchmark.bm do |bm|
57
+ data << bm.report("PacketFu::Packet.parse() ") { iters.times {PacketFu::Packet.parse(IPV6_PACKET)} }
58
+ data << bm.report("PacketFu::EthPacket.new.read() ") { iters.times {PacketFu::EthPacket.new.read(IPV6_PACKET)} }
59
+ data << bm.report("PacketFu::IPv6Packet.new.read() ") { iters.times {PacketFu::IPv6Packet.new.read(IPV6_PACKET)} }
60
+ nil
61
+ end
62
+ if file_pfx
63
+ filename = "#{file_pfx}.dat"
64
+ puts "dumping data to #{filename}"
65
+ fio = File.open(filename, "w")
66
+ Marshal.dump(data, fio)
67
+ fio.close
68
+ end
@@ -0,0 +1,17 @@
1
+ require 'benchmark'
2
+ require 'pp'
3
+
4
+ before = ARGV.shift
5
+ after = ARGV.shift
6
+
7
+ fio = File.open(before)
8
+ before_data = Marshal.load(fio)
9
+ fio.close
10
+
11
+ fio = File.open(after)
12
+ after_data = Marshal.load(fio)
13
+ fio.close
14
+
15
+ before_data.each_with_index do |data, i|
16
+ puts (data.total / after_data[i].total)
17
+ end
data/bench/octets.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'benchmark'
2
+ $:.unshift File.join(File.expand_path(File.dirname(__FILE__)), "..", "lib")
3
+ require 'packetfu'
4
+
5
+ IPV4_RAW = "\x01\x02\x03\x04"
6
+ IPV4_STR = "1.2.3.4"
7
+
8
+
9
+ iters = 50_000
10
+ Benchmark.bm do |bm|
11
+ bm.report("Octets.new.read(...) ") {iters.times {PacketFu::Octets.new.read(IPV4_RAW)}}
12
+ bm.report("Octets.new.read_quad(...) ") {iters.times {PacketFu::Octets.new.read_quad(IPV4_STR)}}
13
+
14
+ octets = PacketFu::Octets.new
15
+ bm.report("octets#read(...) ") {iters.times {octets.read(IPV4_RAW)}}
16
+ bm.report("octets#read_quad(...) ") {iters.times {octets.read_quad(IPV4_STR)}}
17
+
18
+ octets.read(IPV4_RAW)
19
+ bm.report("octets#to_x() ") {iters.times {octets.to_x}}
20
+ bm.report("octets#to_i() ") {iters.times {octets.to_i}}
21
+ bm.report("octets#to_s() ") {iters.times {octets.to_s}}
22
+ end
@@ -0,0 +1,8 @@
1
+ user system total real
2
+ Octets.new.read(...) 0.480000 0.000000 0.480000 ( 0.485710)
3
+ Octets.new.read_quad(...) 0.480000 0.000000 0.480000 ( 0.480071)
4
+ octets#read(...) 0.180000 0.000000 0.180000 ( 0.184558)
5
+ octets#read_quad(...) 0.180000 0.000000 0.180000 ( 0.175781)
6
+ octets#to_x() 0.120000 0.000000 0.120000 ( 0.120217)
7
+ octets#to_i() 0.040000 0.000000 0.040000 ( 0.043496)
8
+ octets#to_s() 0.100000 0.010000 0.110000 ( 0.093341)
@@ -0,0 +1,8 @@
1
+ user system total real
2
+ Octets.new.read(...) 0.200000 0.000000 0.200000 ( 0.207577)
3
+ Octets.new.read_quad(...) 0.290000 0.000000 0.290000 ( 0.285364)
4
+ octets#read(...) 0.080000 0.000000 0.080000 ( 0.074826)
5
+ octets#read_quad(...) 0.140000 0.000000 0.140000 ( 0.145170)
6
+ octets#to_x() 0.140000 0.000000 0.140000 ( 0.139427)
7
+ octets#to_i() 0.020000 0.000000 0.020000 ( 0.016444)
8
+ octets#to_s() 0.040000 0.000000 0.040000 ( 0.042925)
@@ -0,0 +1,8 @@
1
+ user system total real
2
+ Octets.new.read(...) 0.480000 0.000000 0.480000 ( 0.482913)
3
+ Octets.new.read_quad(...) 1.390000 0.460000 1.850000 ( 1.858652)
4
+ octets#read(...) 0.190000 0.000000 0.190000 ( 0.186785)
5
+ octets#read_quad(...) 1.030000 0.400000 1.430000 ( 1.435857)
6
+ octets#to_x() 1.010000 0.470000 1.480000 ( 1.480452)
7
+ octets#to_i() 0.830000 0.420000 1.250000 ( 1.250348)
8
+ octets#to_s() 0.150000 0.000000 0.150000 ( 0.157041)
data/lib/packetfu.rb CHANGED
@@ -27,7 +27,7 @@ module PacketFu
27
27
 
28
28
  # Deal with Ruby's encoding by ignoring it.
29
29
  def self.force_binary(str)
30
- str.force_encoding "binary" if str.respond_to? :force_encoding
30
+ str.force_encoding Encoding::BINARY if str.respond_to? :force_encoding
31
31
  end
32
32
 
33
33
  # Sets the expected byte order for a pcap file. See PacketFu::Read.set_byte_order
@@ -77,6 +77,7 @@ module PacketFu
77
77
  end
78
78
  @packet_classes ||= []
79
79
  @packet_classes << klass
80
+ @packet_classes_dirty = true
80
81
  @packet_classes.sort! {|x,y| x.name <=> y.name}
81
82
  end
82
83
 
@@ -85,6 +86,7 @@ module PacketFu
85
86
  raise "Need a class" unless klass.kind_of? Class
86
87
  @packet_classes ||= []
87
88
  @packet_classes.delete klass
89
+ @packet_classes_dirty = true
88
90
  @packet_classes
89
91
  end
90
92
 
@@ -95,8 +97,11 @@ module PacketFu
95
97
 
96
98
  # Returns an array of packet types by packet prefix.
97
99
  def self.packet_prefixes
98
- return [] unless @packet_classes
99
- @packet_classes.map {|p| p.to_s.split("::").last.to_s.downcase.gsub(/packet$/,"")}
100
+ return [] if @packet_classes.nil?
101
+ return @packet_class_prefixes if @packet_classes_dirty == false
102
+ @packet_classes_dirty = false
103
+ @packet_class_prefixes = @packet_classes.map {|p| p.to_s.split("::").last.to_s.downcase.gsub(/packet$/,"")}
104
+ return @packet_class_prefixes
100
105
  end
101
106
 
102
107
  # The current inspect style. One of :hex, :dissect, or :default
@@ -19,7 +19,7 @@ module PacketFu
19
19
 
20
20
  # Force strings into binary.
21
21
  def self.force_binary(str)
22
- str.force_encoding "binary" if str.respond_to? :force_encoding
22
+ str.force_encoding Encoding::BINARY if str.respond_to? :force_encoding
23
23
  end
24
24
 
25
25
  # Parse() creates the correct packet type based on the data, and returns the apporpiate
@@ -284,7 +284,7 @@ module PacketFu
284
284
 
285
285
  # Hexify provides a neatly-formatted dump of binary data, familar to hex readers.
286
286
  def hexify(str)
287
- str.force_encoding("ASCII-8BIT") if str.respond_to? :force_encoding
287
+ str.force_encoding(Encoding::BINARY) if str.respond_to? :force_encoding
288
288
  hexascii_lines = str.to_s.unpack("H*")[0].scan(/.{1,32}/)
289
289
  regex = Regexp.new('[\x00-\x1f\x7f-\xff]', nil, 'n')
290
290
  chars = str.to_s.gsub(regex,'.')
data/lib/packetfu/pcap.rb CHANGED
@@ -79,7 +79,7 @@ module PacketFu
79
79
  def read(str)
80
80
  force_binary(str)
81
81
  return self if str.nil?
82
- str.force_encoding("binary") if str.respond_to? :force_encoding
82
+ str.force_encoding(Encoding::BINARY) if str.respond_to? :force_encoding
83
83
  if str[0,4] == self[:magic].to_s
84
84
  self[:magic].read str[0,4]
85
85
  self[:ver_major].read str[4,2]
@@ -192,7 +192,7 @@ module PacketFu
192
192
  end
193
193
 
194
194
  def force_binary(str)
195
- str.force_encoding "binary" if str.respond_to? :force_encoding
195
+ str.force_encoding Encoding::BINARY if str.respond_to? :force_encoding
196
196
  end
197
197
 
198
198
  # Reads a string to populate the object. Note, this read takes in the
@@ -265,8 +265,11 @@ module PacketFu
265
265
  warn "Packet ##{packet_count} is corrupted: expected #{len.to_i}, got #{pcap_packet.data.size}. Exiting."
266
266
  break
267
267
  end
268
- pcap_packets << pcap_packet.clone
269
- yield pcap_packets.last if block
268
+ if block
269
+ yield pcap_packet
270
+ else
271
+ pcap_packets << pcap_packet.clone
272
+ end
270
273
  end
271
274
  ensure
272
275
  file_handle.close
@@ -317,6 +320,7 @@ module PacketFu
317
320
 
318
321
  def initialize(args={})
319
322
  init_fields(args)
323
+ @filename = args.delete :filename
320
324
  super(args[:endian], args[:head], args[:body])
321
325
  end
322
326
 
@@ -361,6 +365,18 @@ module PacketFu
361
365
  self.read! fdata
362
366
  end
363
367
 
368
+ # Calls the class method with this object's @filename
369
+ def read_packet_bytes(fname=@filename,&block)
370
+ raise ArgumentError, "Need a file" unless fname
371
+ return self.class.read_packet_bytes(fname, &block)
372
+ end
373
+
374
+ # Calls the class method with this object's @filename
375
+ def read_packets(fname=@filename,&block)
376
+ raise ArgumentError, "Need a file" unless fname
377
+ return self.class.read_packets(fname, &block)
378
+ end
379
+
364
380
  # file_to_array() translates a libpcap file into an array of packets.
365
381
  # Note that this strips out pcap timestamps -- if you'd like to retain
366
382
  # timestamps and other libpcap file information, you will want to
@@ -1,163 +1,10 @@
1
- module PacketFu
2
-
3
- # ARPHeader is a complete ARP struct, used in ARPPacket.
4
- #
5
- # ARP is used to discover the machine address of nearby devices.
6
- #
7
- # See http://www.networksorcery.com/enp/protocol/arp.htm for details.
8
- #
9
- # ==== Header Definition
10
- #
11
- # Int16 :arp_hw Default: 1 # Ethernet
12
- # Int16 :arp_proto, Default: 0x8000 # IP
13
- # Int8 :arp_hw_len, Default: 6
14
- # Int8 :arp_proto_len, Default: 4
15
- # Int16 :arp_opcode, Default: 1 # 1: Request, 2: Reply, 3: Request-Reverse, 4: Reply-Reverse
16
- # EthMac :arp_src_mac # From eth.rb
17
- # Octets :arp_src_ip # From ip.rb
18
- # EthMac :arp_dst_mac # From eth.rb
19
- # Octets :arp_dst_ip # From ip.rb
20
- # String :body
21
- class ARPHeader < Struct.new(:arp_hw, :arp_proto, :arp_hw_len,
22
- :arp_proto_len, :arp_opcode,
23
- :arp_src_mac, :arp_src_ip,
24
- :arp_dst_mac, :arp_dst_ip,
25
- :body)
26
- include StructFu
27
-
28
- def initialize(args={})
29
- src_mac = args[:arp_src_mac] || (args[:config][:eth_src] if args[:config])
30
- src_ip_bin = args[:arp_src_ip] || (args[:config][:ip_src_bin] if args[:config])
31
-
32
- super(
33
- Int16.new(args[:arp_hw] || 1),
34
- Int16.new(args[:arp_proto] ||0x0800),
35
- Int8.new(args[:arp_hw_len] || 6),
36
- Int8.new(args[:arp_proto_len] || 4),
37
- Int16.new(args[:arp_opcode] || 1),
38
- EthMac.new.read(src_mac),
39
- Octets.new.read(src_ip_bin),
40
- EthMac.new.read(args[:arp_dst_mac]),
41
- Octets.new.read(args[:arp_dst_ip]),
42
- StructFu::String.new.read(args[:body])
43
- )
44
- end
45
-
46
- # Returns the object in string form.
47
- def to_s
48
- self.to_a.map {|x| x.to_s}.join
49
- end
1
+ require 'packetfu/protos/eth/header'
2
+ require 'packetfu/protos/eth/mixin'
50
3
 
51
- # Reads a string to populate the object.
52
- def read(str)
53
- force_binary(str)
54
- return self if str.nil?
55
- self[:arp_hw].read(str[0,2])
56
- self[:arp_proto].read(str[2,2])
57
- self[:arp_hw_len].read(str[4,1])
58
- self[:arp_proto_len].read(str[5,1])
59
- self[:arp_opcode].read(str[6,2])
60
- self[:arp_src_mac].read(str[8,6])
61
- self[:arp_src_ip].read(str[14,4])
62
- self[:arp_dst_mac].read(str[18,6])
63
- self[:arp_dst_ip].read(str[24,4])
64
- self[:body].read(str[28,str.size])
65
- self
66
- end
4
+ require 'packetfu/protos/arp/header'
5
+ require 'packetfu/protos/arp/mixin'
67
6
 
68
- # Setter for the ARP hardware type.
69
- def arp_hw=(i); typecast i; end
70
- # Getter for the ARP hardware type.
71
- def arp_hw; self[:arp_hw].to_i; end
72
- # Setter for the ARP protocol.
73
- def arp_proto=(i); typecast i; end
74
- # Getter for the ARP protocol.
75
- def arp_proto; self[:arp_proto].to_i; end
76
- # Setter for the ARP hardware type length.
77
- def arp_hw_len=(i); typecast i; end
78
- # Getter for the ARP hardware type length.
79
- def arp_hw_len; self[:arp_hw_len].to_i; end
80
- # Setter for the ARP protocol length.
81
- def arp_proto_len=(i); typecast i; end
82
- # Getter for the ARP protocol length.
83
- def arp_proto_len; self[:arp_proto_len].to_i; end
84
- # Setter for the ARP opcode.
85
- def arp_opcode=(i); typecast i; end
86
- # Getter for the ARP opcode.
87
- def arp_opcode; self[:arp_opcode].to_i; end
88
- # Setter for the ARP source MAC address.
89
- def arp_src_mac=(i); typecast i; end
90
- # Getter for the ARP source MAC address.
91
- def arp_src_mac; self[:arp_src_mac].to_s; end
92
- # Getter for the ARP source IP address.
93
- def arp_src_ip=(i); typecast i; end
94
- # Setter for the ARP source IP address.
95
- def arp_src_ip; self[:arp_src_ip].to_s; end
96
- # Setter for the ARP destination MAC address.
97
- def arp_dst_mac=(i); typecast i; end
98
- # Setter for the ARP destination MAC address.
99
- def arp_dst_mac; self[:arp_dst_mac].to_s; end
100
- # Setter for the ARP destination IP address.
101
- def arp_dst_ip=(i); typecast i; end
102
- # Getter for the ARP destination IP address.
103
- def arp_dst_ip; self[:arp_dst_ip].to_s; end
104
-
105
- # Set the source MAC address in a more readable way.
106
- def arp_saddr_mac=(mac)
107
- mac = EthHeader.mac2str(mac)
108
- self[:arp_src_mac].read(mac)
109
- self.arp_src_mac
110
- end
111
-
112
- # Get a more readable source MAC address.
113
- def arp_saddr_mac
114
- EthHeader.str2mac(self[:arp_src_mac].to_s)
115
- end
116
-
117
- # Set the destination MAC address in a more readable way.
118
- def arp_daddr_mac=(mac)
119
- mac = EthHeader.mac2str(mac)
120
- self[:arp_dst_mac].read(mac)
121
- self.arp_dst_mac
122
- end
123
-
124
- # Get a more readable source MAC address.
125
- def arp_daddr_mac
126
- EthHeader.str2mac(self[:arp_dst_mac].to_s)
127
- end
128
-
129
- # Set a more readable source IP address.
130
- def arp_saddr_ip=(addr)
131
- self[:arp_src_ip].read_quad(addr)
132
- end
133
-
134
- # Get a more readable source IP address.
135
- def arp_saddr_ip
136
- self[:arp_src_ip].to_x
137
- end
138
-
139
- # Set a more readable destination IP address.
140
- def arp_daddr_ip=(addr)
141
- self[:arp_dst_ip].read_quad(addr)
142
- end
143
-
144
- # Get a more readable destination IP address.
145
- def arp_daddr_ip
146
- self[:arp_dst_ip].to_x
147
- end
148
-
149
- # Readability aliases
150
-
151
- alias :arp_src_mac_readable :arp_saddr_mac
152
- alias :arp_dst_mac_readable :arp_daddr_mac
153
- alias :arp_src_ip_readable :arp_saddr_ip
154
- alias :arp_dst_ip_readable :arp_daddr_ip
155
-
156
- def arp_proto_readable
157
- "0x%04x" % arp_proto
158
- end
159
-
160
- end # class ARPHeader
7
+ module PacketFu
161
8
 
162
9
  # ARPPacket is used to construct ARP packets. They contain an EthHeader and an ARPHeader.
163
10
  # == Example
@@ -184,6 +31,8 @@ module PacketFu
184
31
  # :config
185
32
  # A hash of return address details, often the output of Utils.whoami?
186
33
  class ARPPacket < Packet
34
+ include ::PacketFu::EthHeaderMixin
35
+ include ::PacketFu::ARPHeaderMixin
187
36
 
188
37
  attr_accessor :eth_header, :arp_header
189
38
 
@@ -197,8 +46,6 @@ module PacketFu
197
46
  def read(str=nil,args={})
198
47
  raise "Cannot parse `#{str}'" unless self.class.can_parse?(str)
199
48
  @eth_header.read(str)
200
- @arp_header.read(str[14,str.size])
201
- @eth_header.body = @arp_header
202
49
  super(args)
203
50
  self
204
51
  end