packetfu 1.1.5 → 1.1.6

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