packetfu 1.1.8 → 1.1.9
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.
- data/README.rdoc +11 -12
- data/bench/octets.rb +9 -9
- data/examples/100kpackets.rb +13 -12
- data/examples/ackscan.rb +17 -16
- data/examples/arp.rb +36 -35
- data/examples/arphood.rb +37 -36
- data/examples/dissect_thinger.rb +7 -6
- data/examples/ethernet.rb +1 -0
- data/examples/examples.rb +1 -0
- data/examples/ifconfig.rb +1 -0
- data/examples/new-simple-stats.rb +24 -23
- data/examples/packetfu-shell.rb +26 -25
- data/examples/simple-sniffer.rb +10 -9
- data/examples/simple-stats.rb +24 -23
- data/examples/slammer.rb +4 -3
- data/lib/packetfu.rb +128 -127
- data/lib/packetfu/capture.rb +170 -169
- data/lib/packetfu/config.rb +53 -52
- data/lib/packetfu/inject.rb +57 -56
- data/lib/packetfu/packet.rb +529 -528
- data/lib/packetfu/pcap.rb +580 -579
- data/lib/packetfu/protos/arp.rb +91 -90
- data/lib/packetfu/protos/arp/header.rb +159 -158
- data/lib/packetfu/protos/arp/mixin.rb +37 -36
- data/lib/packetfu/protos/eth.rb +45 -44
- data/lib/packetfu/protos/eth/header.rb +244 -243
- data/lib/packetfu/protos/eth/mixin.rb +4 -3
- data/lib/packetfu/protos/hsrp.rb +70 -69
- data/lib/packetfu/protos/hsrp/header.rb +108 -107
- data/lib/packetfu/protos/hsrp/mixin.rb +30 -29
- data/lib/packetfu/protos/icmp.rb +72 -71
- data/lib/packetfu/protos/icmp/header.rb +83 -82
- data/lib/packetfu/protos/icmp/mixin.rb +15 -14
- data/lib/packetfu/protos/invalid.rb +50 -49
- data/lib/packetfu/protos/ip.rb +70 -69
- data/lib/packetfu/protos/ip/header.rb +292 -291
- data/lib/packetfu/protos/ip/mixin.rb +41 -40
- data/lib/packetfu/protos/ipv6.rb +51 -50
- data/lib/packetfu/protos/ipv6/header.rb +189 -188
- data/lib/packetfu/protos/ipv6/mixin.rb +30 -29
- data/lib/packetfu/protos/lldp.rb +3 -1
- data/lib/packetfu/protos/lldp/header.rb +1 -0
- data/lib/packetfu/protos/lldp/mixin.rb +1 -0
- data/lib/packetfu/protos/tcp.rb +177 -176
- data/lib/packetfu/protos/tcp/ecn.rb +36 -35
- data/lib/packetfu/protos/tcp/flags.rb +75 -74
- data/lib/packetfu/protos/tcp/header.rb +269 -268
- data/lib/packetfu/protos/tcp/hlen.rb +33 -32
- data/lib/packetfu/protos/tcp/mixin.rb +47 -46
- data/lib/packetfu/protos/tcp/option.rb +322 -321
- data/lib/packetfu/protos/tcp/options.rb +96 -95
- data/lib/packetfu/protos/tcp/reserved.rb +36 -35
- data/lib/packetfu/protos/udp.rb +117 -116
- data/lib/packetfu/protos/udp/header.rb +92 -91
- data/lib/packetfu/protos/udp/mixin.rb +4 -3
- data/lib/packetfu/structfu.rb +281 -280
- data/lib/packetfu/utils.rb +211 -208
- data/lib/packetfu/version.rb +42 -41
- data/packetfu.gemspec +1 -1
- data/spec/ethpacket_spec.rb +48 -48
- data/spec/packet_spec.rb +57 -57
- data/spec/packet_subclasses_spec.rb +8 -8
- data/spec/packetfu_spec.rb +59 -59
- data/spec/structfu_spec.rb +268 -268
- data/spec/tcp_spec.rb +75 -75
- data/test/all_tests.rb +13 -13
- data/test/func_lldp.rb +3 -3
- data/test/ptest.rb +2 -2
- data/test/test_arp.rb +116 -116
- data/test/test_capture.rb +45 -45
- data/test/test_eth.rb +68 -68
- data/test/test_hsrp.rb +9 -9
- data/test/test_icmp.rb +52 -52
- data/test/test_inject.rb +18 -18
- data/test/test_invalid.rb +16 -16
- data/test/test_ip.rb +36 -36
- data/test/test_ip6.rb +48 -48
- data/test/test_octets.rb +21 -21
- data/test/test_packet.rb +154 -154
- data/test/test_pcap.rb +170 -170
- data/test/test_structfu.rb +97 -97
- data/test/test_tcp.rb +320 -320
- data/test/test_udp.rb +76 -76
- metadata +2 -2
data/spec/tcp_spec.rb
CHANGED
@@ -4,98 +4,98 @@ require 'packetfu'
|
|
4
4
|
include PacketFu
|
5
5
|
|
6
6
|
def unusual_numeric_handling_headers(header,i)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
camelized_header = header.to_s.split("_").map {|x| x.capitalize}.join
|
8
|
+
header_class = PacketFu.const_get camelized_header
|
9
|
+
specify { subject.send(header).should == i }
|
10
|
+
specify { subject.send(header).should be_kind_of Integer }
|
11
|
+
specify { subject.headers.last[header].should be_kind_of header_class }
|
12
12
|
end
|
13
13
|
|
14
14
|
def tcp_hlen_numeric(i)
|
15
|
-
|
15
|
+
unusual_numeric_handling_headers(:tcp_hlen,i)
|
16
16
|
end
|
17
17
|
|
18
18
|
def tcp_reserved_numeric(i)
|
19
|
-
|
19
|
+
unusual_numeric_handling_headers(:tcp_reserved,i)
|
20
20
|
end
|
21
21
|
|
22
22
|
def tcp_ecn_numeric(i)
|
23
|
-
|
23
|
+
unusual_numeric_handling_headers(:tcp_ecn,i)
|
24
24
|
end
|
25
25
|
|
26
26
|
|
27
27
|
describe TCPPacket do
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
subject do
|
30
|
+
bytes = PcapFile.file_to_array(File.join(File.dirname(__FILE__), "sample2.pcap"))[2]
|
31
|
+
packet = Packet.parse(bytes)
|
32
|
+
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
34
|
+
context "TcpHlen reading and setting" do
|
35
|
+
context "TcpHlen set via #read" do
|
36
|
+
tcp_hlen_numeric(8)
|
37
|
+
end
|
38
|
+
context "TcpHlen set via an Integer for the setter" do
|
39
|
+
(0..15).each do |i|
|
40
|
+
context "i is #{i}" do
|
41
|
+
before { subject.tcp_hlen = i }
|
42
|
+
tcp_hlen_numeric(i)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
context "TcpHlen set via a String for the setter" do
|
47
|
+
before { subject.tcp_hlen = "\x60" }
|
48
|
+
tcp_hlen_numeric(6)
|
49
|
+
end
|
50
|
+
context "TcpHlen set via a TcpHlen for the setter" do
|
51
|
+
before { subject.tcp_hlen = TcpHlen.new(:hlen => 7) }
|
52
|
+
tcp_hlen_numeric(7)
|
53
|
+
end
|
54
|
+
end
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
56
|
+
context "TcpReserved reading and setting" do
|
57
|
+
context "TcpReserved set via #read" do
|
58
|
+
tcp_reserved_numeric(0)
|
59
|
+
end
|
60
|
+
context "TcpReserved set via an Integer for the setter" do
|
61
|
+
(0..7).each do |i|
|
62
|
+
context "i is #{i}" do
|
63
|
+
before { subject.tcp_reserved = i }
|
64
|
+
tcp_reserved_numeric(i)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
context "TcpReserved set via a String for the setter" do
|
69
|
+
before { subject.tcp_reserved = "\x03" }
|
70
|
+
tcp_reserved_numeric(3)
|
71
|
+
end
|
72
|
+
context "TcpReserved set via a TcpReserved for the setter" do
|
73
|
+
before { subject.tcp_reserved = TcpReserved.new(:r1 => 1, :r2 => 0, :r3 => 1) }
|
74
|
+
tcp_reserved_numeric(5)
|
75
|
+
end
|
76
|
+
end
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
78
|
+
context "TcpEcn reading and setting" do
|
79
|
+
context "TcpEcn set via #read" do
|
80
|
+
tcp_ecn_numeric(0)
|
81
|
+
end
|
82
|
+
context "TcpEcn set via an Integer for the setter" do
|
83
|
+
(0..7).each do |i|
|
84
|
+
context "i is #{i}" do
|
85
|
+
before { subject.tcp_ecn = i }
|
86
|
+
tcp_ecn_numeric(i)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
context "TcpEcn set via a String for the setter" do
|
91
|
+
before { subject.tcp_ecn = "\x00\xc0" }
|
92
|
+
tcp_ecn_numeric(3)
|
93
|
+
end
|
94
|
+
context "TcpEcn set via a TcpEcn for the setter" do
|
95
|
+
before { subject.tcp_ecn = TcpEcn.new(:n => 1, :c => 0, :e => 1) }
|
96
|
+
tcp_ecn_numeric(5)
|
97
|
+
end
|
98
|
+
end
|
99
99
|
|
100
100
|
end
|
101
101
|
|
data/test/all_tests.rb
CHANGED
@@ -23,19 +23,19 @@ puts "Testing PacketFu v#{PacketFu::VERSION}"
|
|
23
23
|
dir = Dir.new(File.dirname(__FILE__))
|
24
24
|
|
25
25
|
dir.each { |file|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
26
|
+
next unless File.file? file
|
27
|
+
next unless file[/^test_.*rb$/]
|
28
|
+
next if file == $0
|
29
|
+
puts "Running #{file}..."
|
30
|
+
cmd = %x{ruby #{file}}
|
31
|
+
if cmd[/ 0 failures/] && cmd[/ 0 errors/]
|
32
|
+
puts "#{file}: All passed"
|
33
|
+
else
|
34
|
+
puts "File: #{file} had failures or errors:"
|
35
|
+
puts "-" * 80
|
36
|
+
puts cmd
|
37
|
+
puts "-" * 80
|
38
|
+
end
|
39
39
|
}
|
40
40
|
|
41
41
|
# vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
|
data/test/func_lldp.rb
CHANGED
@@ -6,12 +6,12 @@ $:.unshift File.join(File.expand_path(File.dirname(__FILE__)), "..", "lib")
|
|
6
6
|
require 'packetfu'
|
7
7
|
|
8
8
|
def lldp_pcap
|
9
|
-
|
10
|
-
|
9
|
+
fname = "./sample_lldp.pcap"
|
10
|
+
fname if File.readable? fname
|
11
11
|
end
|
12
12
|
|
13
13
|
def lldp_test()
|
14
|
-
|
14
|
+
raise RuntimeError, "Need a sample_lldp.pcap to check!" unless lldp_pcap
|
15
15
|
cap = PacketFu::PcapFile.new.file_to_array(:filename => lldp_pcap)
|
16
16
|
cap.each do |p|
|
17
17
|
pkt = PacketFu::Packet.parse p
|
data/test/ptest.rb
CHANGED
@@ -5,9 +5,9 @@ require 'packetfu'
|
|
5
5
|
include PacketFu
|
6
6
|
|
7
7
|
if Process.euid.zero?
|
8
|
-
|
8
|
+
puts ">> Interface: " << Pcap.lookupdev
|
9
9
|
else
|
10
|
-
|
10
|
+
puts ">> No interface access"
|
11
11
|
end
|
12
12
|
puts ">> Version: " << PacketFu.version
|
13
13
|
|
data/test/test_arp.rb
CHANGED
@@ -3,132 +3,132 @@ require 'test/unit'
|
|
3
3
|
$:.unshift File.join(File.expand_path(File.dirname(__FILE__)), "..", "lib")
|
4
4
|
require 'packetfu'
|
5
5
|
class ArpTest < Test::Unit::TestCase
|
6
|
-
|
6
|
+
include PacketFu
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
8
|
+
def test_arp_header
|
9
|
+
a = ARPHeader.new
|
10
|
+
assert_kind_of ARPHeader, a
|
11
|
+
assert_kind_of StructFu::Int16, a[:arp_hw]
|
12
|
+
assert_kind_of Fixnum, a.arp_hw
|
13
|
+
assert_kind_of Octets, a[:arp_src_ip]
|
14
|
+
assert_kind_of String, a.arp_src_ip
|
15
|
+
assert_kind_of EthMac, a[:arp_dst_mac]
|
16
|
+
assert_kind_of String, a.arp_dst_mac
|
17
|
+
assert_kind_of StructFu::String, a.body
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
20
|
+
def test_read_header
|
21
|
+
a = ARPHeader.new
|
22
|
+
sample_arp = "000108000604000200032f1a74dec0a80102001b1151b7cec0a80169"
|
23
|
+
sample_arp = sample_arp.scan(/../).map {|x| x.to_i(16)}.pack("C*")
|
24
|
+
a.read(sample_arp)
|
25
|
+
assert_equal(sample_arp, a.to_s)
|
26
|
+
assert_equal("192.168.1.105", a.arp_daddr_ip)
|
27
|
+
assert_equal("192.168.1.2", a.arp_saddr_ip)
|
28
|
+
assert_equal("00:1b:11:51:b7:ce", a.arp_daddr_mac)
|
29
|
+
assert_equal("00:03:2f:1a:74:de", a.arp_saddr_mac)
|
30
|
+
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
32
|
+
def test_arp_read
|
33
|
+
a = ARPPacket.new
|
34
|
+
sample_arp = "001b1151b7ce00032f1a74de0806000108000604000200032f1a74dec0a80102001b1151b7cec0a80169c0a80169"
|
35
|
+
sample_arp = sample_arp.scan(/../).map {|x| x.to_i(16)}.pack("C*")
|
36
|
+
a.read(sample_arp)
|
37
|
+
assert_equal(sample_arp, a.to_s)
|
38
|
+
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
40
|
+
def test_write_ip
|
41
|
+
a = ARPPacket.new
|
42
|
+
a.arp_saddr_ip="1.2.3.4"
|
43
|
+
a.arp_daddr_ip="5.6.7.8"
|
44
|
+
assert_equal("1.2.3.4",a.arp_saddr_ip)
|
45
|
+
assert_equal("5.6.7.8",a.arp_daddr_ip)
|
46
|
+
assert_equal("\x01\x02\x03\x04",a.arp_src_ip)
|
47
|
+
assert_equal("\x05\x06\x07\x08",a.arp_dst_ip)
|
48
|
+
end
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
50
|
+
def test_write_mac
|
51
|
+
a = ARPPacket.new
|
52
|
+
a.arp_saddr_mac = "00:01:02:03:04:05"
|
53
|
+
a.arp_daddr_mac = "00:06:07:08:09:0a"
|
54
|
+
assert_equal("00:01:02:03:04:05",a.arp_saddr_mac)
|
55
|
+
assert_equal("00:06:07:08:09:0a",a.arp_daddr_mac)
|
56
|
+
assert_equal("\x00\x01\x02\x03\x04\x05",a.arp_src_mac)
|
57
|
+
assert_equal("\x00\x06\x07\x08\x09\x0a",a.arp_dst_mac)
|
58
|
+
end
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
60
|
+
def test_arp_flavors
|
61
|
+
a = ARPPacket.new(:flavor => "Windows")
|
62
|
+
assert_equal("\x00" * 64, a.payload)
|
63
|
+
a = ARPPacket.new(:flavor => "Linux")
|
64
|
+
assert_equal(32, a.payload.size)
|
65
|
+
a = ARPPacket.new(:flavor => :hp_deskjet)
|
66
|
+
assert_equal(18, a.payload.size)
|
67
|
+
a = ARPPacket.new
|
68
|
+
assert_equal("\x00" * 18, a.payload)
|
69
|
+
end
|
70
70
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
71
|
+
def test_arp_create
|
72
|
+
sample_arp = "000108000604000200032f1a74dec0a80102001b1151b7cec0a80169"
|
73
|
+
sample_arp = sample_arp.scan(/../).map {|x| x.to_i(16)}.pack("C*")
|
74
|
+
a = ARPPacket.new
|
75
|
+
assert_kind_of ARPPacket, a
|
76
|
+
a.arp_hw = 1
|
77
|
+
a.arp_proto = 0x0800
|
78
|
+
a.arp_hw_len = 6
|
79
|
+
a.arp_proto_len = 4
|
80
|
+
a.arp_opcode = 2
|
81
|
+
a.arp_src_mac = "\x00\x03\x2f\x1a\x74\xde"
|
82
|
+
a.arp_src_ip = "\xc0\xa8\x01\x02"
|
83
|
+
a.arp_dst_mac = "\x00\x1b\x11\x51\xb7\xce"
|
84
|
+
a.arp_dst_ip = "\xc0\xa8\x01\x69"
|
85
|
+
a.payload = ""
|
86
|
+
assert_equal(sample_arp,a.to_s[14,0xffff])
|
87
|
+
end
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
89
|
+
def test_arp_new
|
90
|
+
sample_arp = "000108000604000200032f1a74dec0a80102001b1151b7cec0a80169c0a80169"
|
91
|
+
sample_arp = sample_arp.scan(/../).map {|x| x.to_i(16)}.pack("C*")
|
92
|
+
arp = ARPPacket.new(:arp_hw => 1, :arp_proto => 0x0800,
|
93
|
+
:arp_opcode => 2, :arp_src_ip => "\xc0\xa8\x01\x02")
|
94
|
+
assert_kind_of ARPPacket, arp
|
95
|
+
arp.arp_hw_len = 6
|
96
|
+
arp.arp_proto_len = 4
|
97
|
+
arp.arp_src_mac = "\x00\x03\x2f\x1a\x74\xde"
|
98
|
+
arp.arp_dst_mac = "\x00\x1b\x11\x51\xb7\xce"
|
99
|
+
arp.arp_dst_ip = "\xc0\xa8\x01\x69"
|
100
|
+
arp.payload = "\xc0\xa8\x01\x69"
|
101
|
+
assert_equal(sample_arp,arp.to_s[14,0xffff])
|
102
|
+
end
|
103
103
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
104
|
+
def test_arp_peek
|
105
|
+
a = ARPPacket.new
|
106
|
+
puts "\n"
|
107
|
+
puts "ARP Peek format: "
|
108
|
+
puts a.peek
|
109
|
+
puts "\n"
|
110
|
+
assert(a.peek.size <= 80)
|
111
|
+
end
|
112
112
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
113
|
+
def test_arp_pcap
|
114
|
+
a = ARPPacket.new
|
115
|
+
assert_kind_of ARPPacket, a
|
116
|
+
a.to_f('arp_test.pcap','w')
|
117
|
+
a.arp_hw = 1
|
118
|
+
a.arp_proto = 0x0800
|
119
|
+
a.arp_hw_len = 6
|
120
|
+
a.arp_proto_len = 4
|
121
|
+
a.arp_opcode = 2
|
122
|
+
a.arp_src_mac = "\x00\x03\x2f\x1a\x74\xde"
|
123
|
+
a.arp_src_ip = "\xc0\xa8\x01\x02"
|
124
|
+
a.arp_dst_mac = "\x00\x1b\x11\x51\xb7\xce"
|
125
|
+
a.arp_dst_ip = "\xc0\xa8\x01\x69"
|
126
|
+
a.payload = ""
|
127
|
+
a.eth_daddr = "00:1b:11:51:b7:ce"
|
128
|
+
a.eth_saddr = "00:03:2f:1a:74:de"
|
129
|
+
a.to_f('arp_test.pcap','a')
|
130
|
+
end
|
131
|
+
|
132
132
|
end
|
133
133
|
|
134
134
|
|