packetfu 1.1.10 → 1.1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -0
- data/.gitignore +3 -0
- data/.travis.yml +8 -0
- data/CONTRIBUTING.md +47 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +1 -1
- data/README.rdoc +35 -30
- data/Rakefile +4 -4
- data/bench/octets.rb +9 -9
- data/examples/100kpackets.rb +12 -12
- data/examples/ackscan.rb +16 -16
- data/examples/arp.rb +35 -35
- data/examples/arphood.rb +36 -36
- data/examples/dissect_thinger.rb +6 -6
- data/examples/new-simple-stats.rb +23 -23
- data/examples/packetfu-shell.rb +25 -25
- data/examples/simple-sniffer.rb +9 -9
- data/examples/simple-stats.rb +23 -23
- data/examples/slammer.rb +3 -3
- data/gem-public_cert.pem +21 -0
- data/lib/packetfu.rb +149 -127
- data/lib/packetfu/capture.rb +169 -169
- data/lib/packetfu/config.rb +52 -52
- data/lib/packetfu/inject.rb +56 -56
- data/lib/packetfu/packet.rb +531 -528
- data/lib/packetfu/pcap.rb +579 -579
- data/lib/packetfu/protos/arp.rb +90 -90
- data/lib/packetfu/protos/arp/header.rb +158 -158
- data/lib/packetfu/protos/arp/mixin.rb +36 -36
- data/lib/packetfu/protos/eth.rb +44 -44
- data/lib/packetfu/protos/eth/header.rb +243 -243
- data/lib/packetfu/protos/eth/mixin.rb +3 -3
- data/lib/packetfu/protos/hsrp.rb +69 -69
- data/lib/packetfu/protos/hsrp/header.rb +107 -107
- data/lib/packetfu/protos/hsrp/mixin.rb +29 -29
- data/lib/packetfu/protos/icmp.rb +71 -71
- data/lib/packetfu/protos/icmp/header.rb +82 -82
- data/lib/packetfu/protos/icmp/mixin.rb +14 -14
- data/lib/packetfu/protos/invalid.rb +49 -49
- data/lib/packetfu/protos/ip.rb +69 -69
- data/lib/packetfu/protos/ip/header.rb +291 -291
- data/lib/packetfu/protos/ip/mixin.rb +40 -40
- data/lib/packetfu/protos/ipv6.rb +50 -50
- data/lib/packetfu/protos/ipv6/header.rb +188 -188
- data/lib/packetfu/protos/ipv6/mixin.rb +29 -29
- data/lib/packetfu/protos/tcp.rb +176 -176
- data/lib/packetfu/protos/tcp/ecn.rb +35 -35
- data/lib/packetfu/protos/tcp/flags.rb +74 -74
- data/lib/packetfu/protos/tcp/header.rb +268 -268
- data/lib/packetfu/protos/tcp/hlen.rb +32 -32
- data/lib/packetfu/protos/tcp/mixin.rb +46 -46
- data/lib/packetfu/protos/tcp/option.rb +321 -321
- data/lib/packetfu/protos/tcp/options.rb +95 -95
- data/lib/packetfu/protos/tcp/reserved.rb +35 -35
- data/lib/packetfu/protos/udp.rb +159 -123
- data/lib/packetfu/protos/udp/header.rb +91 -91
- data/lib/packetfu/protos/udp/mixin.rb +3 -3
- data/lib/packetfu/structfu.rb +280 -280
- data/lib/packetfu/utils.rb +292 -225
- data/lib/packetfu/version.rb +41 -41
- data/packetfu.gemspec +14 -3
- data/spec/arp_spec.rb +191 -0
- data/spec/eth_spec.rb +148 -0
- data/spec/icmp_spec.rb +97 -0
- data/spec/ip_spec.rb +78 -0
- data/spec/ipv6_spec.rb +81 -0
- data/spec/packet_spec.rb +61 -59
- data/spec/packet_subclasses_spec.rb +9 -10
- data/spec/packetfu_spec.rb +55 -62
- data/spec/sample3.pcap +0 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/structfu_spec.rb +270 -271
- data/spec/tcp_spec.rb +76 -77
- data/spec/udp_spec.rb +32 -0
- data/spec/utils_spec.rb +95 -0
- data/test/all_tests.rb +14 -17
- data/test/func_lldp.rb +3 -3
- data/test/ptest.rb +2 -2
- data/test/test_capture.rb +45 -45
- data/test/test_eth.rb +70 -68
- data/test/test_hsrp.rb +9 -9
- data/test/test_inject.rb +18 -18
- data/test/test_invalid.rb +16 -16
- data/test/test_octets.rb +23 -21
- data/test/test_packet.rb +156 -154
- data/test/test_pcap.rb +172 -170
- data/test/test_structfu.rb +99 -97
- data/test/test_tcp.rb +322 -320
- data/test/test_udp.rb +78 -76
- metadata +108 -44
- metadata.gz.sig +2 -0
- data/spec/ethpacket_spec.rb +0 -74
- data/test/test_arp.rb +0 -135
- data/test/test_icmp.rb +0 -62
- data/test/test_ip.rb +0 -50
- data/test/test_ip6.rb +0 -68
data/spec/icmp_spec.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
include PacketFu
|
6
|
+
|
7
|
+
describe ICMPPacket, "when read from a pcap file" do
|
8
|
+
before :all do
|
9
|
+
parsed_packets = PcapFile.read_packets(File.join(File.dirname(__FILE__),"sample.pcap"))
|
10
|
+
@icmp_packet = parsed_packets[3]
|
11
|
+
|
12
|
+
parsed_packets3 = PcapFile.read_packets(File.join(File.dirname(__FILE__),"sample3.pcap"))
|
13
|
+
@icmp_packet2 = parsed_packets3[8] # contains 0x0A byte in payload
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should be recognized as an icmp packet" do
|
17
|
+
@icmp_packet.is_icmp?.should be true
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should report the right seq number" do
|
21
|
+
@icmp_packet.payload[2..3].unpack("H*")[0].should eq "0003"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should be recognized as an icmp reply packet" do
|
25
|
+
@icmp_packet.icmp_type.should eq 0
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have the right checksum" do
|
29
|
+
@icmp_packet.icmp_sum.to_s(16).should eq @icmp_packet.icmp_calc_sum.to_s(16)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should have the right checksum even with 0xOA byte in payload" do
|
33
|
+
@icmp_packet2.icmp_sum.to_s(16).should eq @icmp_packet2.icmp_calc_sum.to_s(16)
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when initializing ICMPHeader from scratch" do
|
37
|
+
before :each do
|
38
|
+
@icmp_header = ICMPHeader.new
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have the right instance variables" do
|
42
|
+
expect(@icmp_header.to_s).to eql("\x00\x00\xff\xff")
|
43
|
+
expect(@icmp_header.icmp_type).to eql(0)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should allow setting of the type" do
|
47
|
+
@icmp_header.icmp_type = 1
|
48
|
+
expect(@icmp_header.icmp_type).to eql(1)
|
49
|
+
@icmp_header.icmp_recalc
|
50
|
+
expect(@icmp_header.to_s).to eql("\x01\x00\xfe\xff")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when initializing ICMPPacket from scratch" do
|
55
|
+
before :each do
|
56
|
+
@icmp_packet = ICMPPacket.new
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should support peak functionality" do
|
60
|
+
@icmp_packet.ip_saddr = "10.20.30.40"
|
61
|
+
@icmp_packet.ip_daddr = "50.60.70.80"
|
62
|
+
@icmp_packet.payload = "abcdefghijklmnopqrstuvwxyz"
|
63
|
+
@icmp_packet.recalc
|
64
|
+
expect(@icmp_packet.peek).to match(/IC 64\s+10.20.30.40:pong\s+->\s+50.60.70.80\s+I:[a-z0-9]{4}/)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "when reading/writing ICMPPacket to disk" do
|
69
|
+
before :each do
|
70
|
+
@icmp_packet = ICMPPacket.new
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should write a PCAP file to disk" do
|
74
|
+
@icmp_packet.ip_saddr = "10.20.30.40"
|
75
|
+
@icmp_packet.ip_daddr = "50.60.70.80"
|
76
|
+
@icmp_packet.payload = "abcdefghijklmnopqrstuvwxyz"
|
77
|
+
@icmp_packet.recalc
|
78
|
+
|
79
|
+
icmp_pcap_file = Tempfile.new('icmp_pcap')
|
80
|
+
expect(icmp_pcap_file.read).to eql("")
|
81
|
+
|
82
|
+
@icmp_packet.to_f(icmp_pcap_file, 'a')
|
83
|
+
expect(File.exists?('icmp_pcap'))
|
84
|
+
expect(icmp_pcap_file.read.size).to be >= 79
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should read a PCAP file from disk" do
|
88
|
+
sample_packet = PcapFile.new.file_to_array(:f => './test/sample.pcap')[2]
|
89
|
+
pkt = Packet.parse(sample_packet)
|
90
|
+
|
91
|
+
expect(pkt.is_icmp?).to be true
|
92
|
+
expect(pkt.class).to eql(PacketFu::ICMPPacket)
|
93
|
+
expect(pkt.icmp_sum.to_i).to eql(0x4d58)
|
94
|
+
expect(pkt.icmp_type.to_i).to eql(8)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/spec/ip_spec.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
include PacketFu
|
5
|
+
|
6
|
+
describe IPHeader do
|
7
|
+
context "when initializing" do
|
8
|
+
before :each do
|
9
|
+
@ip_header = IPHeader.new
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should have sane defaults" do
|
13
|
+
expect(@ip_header.ip_v).to eql(4)
|
14
|
+
expect(@ip_header.ip_hl).to eql(5)
|
15
|
+
expect(@ip_header.ip_tos).to eql(0)
|
16
|
+
expect(@ip_header.ip_len).to eql(20)
|
17
|
+
expect(@ip_header.ip_id).to be_kind_of(Fixnum)
|
18
|
+
expect(@ip_header.ip_frag).to eql(0)
|
19
|
+
expect(@ip_header.ip_proto).to eql(0)
|
20
|
+
expect(@ip_header.ip_sum).to eql(65535)
|
21
|
+
expect(@ip_header.ip_src).to eql(0)
|
22
|
+
expect(@ip_header.ip_dst).to eql(0)
|
23
|
+
expect(@ip_header.body).to eql("")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe IPPacket do
|
29
|
+
context "when initializing" do
|
30
|
+
before :each do
|
31
|
+
@ip_packet = IPPacket.new
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should have sane defaults" do
|
35
|
+
expect(@ip_packet.ip_v).to eql(4)
|
36
|
+
expect(@ip_packet.ip_hl).to eql(5)
|
37
|
+
expect(@ip_packet.ip_tos).to eql(0)
|
38
|
+
expect(@ip_packet.ip_len).to eql(20)
|
39
|
+
expect(@ip_packet.ip_id).to be_kind_of(Fixnum)
|
40
|
+
expect(@ip_packet.ip_frag).to eql(0)
|
41
|
+
expect(@ip_packet.ip_proto).to eql(0)
|
42
|
+
expect(@ip_packet.ip_sum).to eql(65535)
|
43
|
+
expect(@ip_packet.ip_src).to eql(0)
|
44
|
+
expect(@ip_packet.ip_dst).to eql(0)
|
45
|
+
expect(@ip_packet.payload).to eql("")
|
46
|
+
expect(@ip_packet.is_ip?).to be true
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should support peek functionality" do
|
50
|
+
@ip_packet.ip_saddr = "1.2.3.4"
|
51
|
+
@ip_packet.ip_daddr = "5.6.7.8"
|
52
|
+
@ip_packet.ip_proto = 94
|
53
|
+
@ip_packet.payload = '\x00' * 30
|
54
|
+
@ip_packet.recalc
|
55
|
+
|
56
|
+
expect(@ip_packet.peek).to match(/I\s+154\s+1\.2\.3\.4\s+\->\s+5\.6\.7\.8\s+I:[0-9a-z]{4}/)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when writing a PCAP file to disk" do
|
61
|
+
before :each do
|
62
|
+
@ip_packet = IPPacket.new
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should write a PCAP file to disk" do
|
66
|
+
@ip_packet.ip_saddr = "10.20.30.40"
|
67
|
+
@ip_packet.ip_daddr = "50.60.70.80"
|
68
|
+
@ip_packet.recalc
|
69
|
+
|
70
|
+
ip_pcap_file = Tempfile.new('ip_pcap')
|
71
|
+
expect(ip_pcap_file.read).to eql("")
|
72
|
+
|
73
|
+
@ip_packet.to_f(ip_pcap_file, 'a')
|
74
|
+
expect(File.exists?('ip_pcap'))
|
75
|
+
expect(ip_pcap_file.read.size).to be >= 50
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/spec/ipv6_spec.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
include PacketFu
|
4
|
+
|
5
|
+
describe IPv6Header do
|
6
|
+
context "when initializing an IPv6Header" do
|
7
|
+
before :each do
|
8
|
+
@ipv6_header = IPv6Header.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should contain sane defaults" do
|
12
|
+
expect(@ipv6_header.ipv6_v).to eql(6)
|
13
|
+
expect(@ipv6_header.ipv6_len).to eql(0)
|
14
|
+
expect(@ipv6_header.ipv6_src).to eql(0)
|
15
|
+
expect(@ipv6_header.ipv6_dst).to eql(0)
|
16
|
+
expect(@ipv6_header.ipv6_hop).to eql(255)
|
17
|
+
expect(@ipv6_header.ipv6_next).to eql(0)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe AddrIpv6 do
|
23
|
+
context "when parsing IPv6 from wire" do
|
24
|
+
before :each do
|
25
|
+
@address_ipv6 = AddrIpv6.new
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should parse an IPv6 address from string i/o" do
|
29
|
+
raw_addr_ipv6 = "\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x1a\xc5\xff\xfe\x00\x01\x52"
|
30
|
+
@address_ipv6.read(raw_addr_ipv6)
|
31
|
+
|
32
|
+
expect(@address_ipv6.to_i).to eql(338288524927261089654170548082086773074)
|
33
|
+
expect(@address_ipv6.to_x).to eql("fe80::21a:c5ff:fe00:152")
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should parse an IPv6 address from octet string" do
|
37
|
+
ipv6_string = "fe80::21a:c5ff:fe00:152"
|
38
|
+
@address_ipv6.read_x(ipv6_string)
|
39
|
+
|
40
|
+
expect(@address_ipv6.to_x).to eql(ipv6_string)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe IPv6Packet do
|
46
|
+
context "when initializing an IPv6Packet" do
|
47
|
+
before :each do
|
48
|
+
@ipv6_packet = IPv6Packet.new
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should contain sane defaults" do
|
52
|
+
expect(@ipv6_packet.ipv6_v).to eql(6)
|
53
|
+
expect(@ipv6_packet.payload).to eql("")
|
54
|
+
expect(@ipv6_packet.is_ipv6?).to be true
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should support peek functionality" do
|
58
|
+
expect(@ipv6_packet.peek).to match(/6\s+54\s+::\s+\->\s+::\s+N:0/)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should set payload size on #recalc' do
|
62
|
+
@ipv6_packet.payload = "\0" * 14
|
63
|
+
@ipv6_packet.recalc
|
64
|
+
expect(@ipv6_packet.ipv6_len).to eq(14)
|
65
|
+
|
66
|
+
@ipv6_packet.payload = "\0" * 255
|
67
|
+
@ipv6_packet.recalc(:ipv6)
|
68
|
+
expect(@ipv6_packet.ipv6_len).to eq(255)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should set payload size on #ipv6_recalc' do
|
72
|
+
@ipv6_packet.payload = "\0" * 3
|
73
|
+
@ipv6_packet.ipv6_recalc
|
74
|
+
expect(@ipv6_packet.ipv6_len).to eq(3)
|
75
|
+
|
76
|
+
@ipv6_packet.payload = "\xff" * 12
|
77
|
+
@ipv6_packet.ipv6_recalc(:ipv6_len)
|
78
|
+
expect(@ipv6_packet.ipv6_len).to eq(12)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/spec/packet_spec.rb
CHANGED
@@ -1,73 +1,75 @@
|
|
1
|
-
|
2
|
-
require 'packetfu'
|
1
|
+
require 'spec_helper'
|
3
2
|
|
4
3
|
describe PacketFu::Packet, "abstract packet class behavior" do
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
5
|
+
before(:all) do
|
6
|
+
add_fake_packets
|
7
|
+
end
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
after(:all) do
|
10
|
+
remove_fake_packets
|
11
|
+
end
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
13
|
+
it "should not be instantiated" do
|
14
|
+
expect { PacketFu::Packet.new }.to raise_error(NoMethodError)
|
15
|
+
end
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
it "should allow subclasses to instantiate" do
|
18
|
+
expect(PacketFu::FooPacket.new).to be
|
19
|
+
PacketFu.packet_classes.include?(PacketFu::FooPacket).should be true
|
20
|
+
end
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
}.to raise_error
|
30
|
-
PacketFu.packet_classes.include?(PacketFu::PacketNot).should be_false
|
31
|
-
PacketFu.packet_classes {should_not include(PacketNot) }
|
32
|
-
end
|
22
|
+
it "should register packet classes with PacketFu" do
|
23
|
+
PacketFu.packet_classes {should include(FooPacket) }
|
24
|
+
PacketFu.packet_classes {should include(BarPacket) }
|
25
|
+
end
|
33
26
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
27
|
+
it "should disallow badly named subclasses" do
|
28
|
+
expect {
|
29
|
+
class PacketFu::PacketNot < PacketFu::Packet
|
30
|
+
end
|
31
|
+
}.to raise_error(RuntimeError, "Packet classes should be named 'ProtoPacket'")
|
32
|
+
PacketFu.packet_classes.include?(PacketFu::PacketNot).should be false
|
33
|
+
PacketFu.packet_classes {should_not include(PacketNot) }
|
34
|
+
end
|
38
35
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
p2.headers[1].object_id.should == @tcp_packet.headers[1].object_id
|
44
|
-
end
|
36
|
+
before(:each) do
|
37
|
+
@tcp_packet = PacketFu::TCPPacket.new
|
38
|
+
@tcp_packet.ip_saddr = "10.10.10.10"
|
39
|
+
end
|
45
40
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
41
|
+
it "should shallow copy with dup()" do
|
42
|
+
p2 = @tcp_packet.dup
|
43
|
+
p2.ip_saddr = "20.20.20.20"
|
44
|
+
p2.ip_saddr.should == @tcp_packet.ip_saddr
|
45
|
+
p2.headers[1].object_id.should == @tcp_packet.headers[1].object_id
|
46
|
+
end
|
52
47
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
48
|
+
it "should deep copy with clone()" do
|
49
|
+
p3 = @tcp_packet.clone
|
50
|
+
p3.ip_saddr = "30.30.30.30"
|
51
|
+
p3.ip_saddr.should_not == @tcp_packet.ip_saddr
|
52
|
+
p3.headers[1].object_id.should_not == @tcp_packet.headers[1].object_id
|
53
|
+
end
|
59
54
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
55
|
+
it "should have senisble equality" do
|
56
|
+
p4 = @tcp_packet.dup
|
57
|
+
p4.should == @tcp_packet
|
58
|
+
p5 = @tcp_packet.clone
|
59
|
+
p5.should == @tcp_packet
|
60
|
+
end
|
61
|
+
|
62
|
+
# It's actually kinda hard to manually create identical TCP packets
|
63
|
+
it "should be possible to manually create identical packets" do
|
64
|
+
p6 = @tcp_packet.clone
|
65
|
+
p6.should == @tcp_packet
|
66
|
+
p7 = PacketFu::TCPPacket.new
|
67
|
+
p7.ip_saddr = p6.ip_saddr
|
68
|
+
p7.ip_id = p6.ip_id
|
69
|
+
p7.tcp_seq = p6.tcp_seq
|
70
|
+
p7.tcp_src = p6.tcp_src
|
71
|
+
p7.tcp_sum = p6.tcp_sum
|
72
|
+
p7.should == p6
|
73
|
+
end
|
72
74
|
|
73
75
|
end
|
@@ -1,13 +1,12 @@
|
|
1
|
-
|
2
|
-
require 'packetfu'
|
1
|
+
require 'spec_helper'
|
3
2
|
|
4
3
|
PacketFu.packet_classes.each do |pclass|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
4
|
+
describe pclass, "peek format" do
|
5
|
+
it "will display sensible peek information" do
|
6
|
+
p = pclass.new
|
7
|
+
p.respond_to?(:peek).should be true
|
8
|
+
p.peek.size.should be <= 80, p.peek.inspect
|
9
|
+
p.peek.should match(/^[A-Z0-9?]../)
|
10
|
+
end
|
11
|
+
end
|
13
12
|
end
|
data/spec/packetfu_spec.rb
CHANGED
@@ -1,85 +1,78 @@
|
|
1
|
-
|
2
|
-
require 'packetfu'
|
1
|
+
require 'spec_helper'
|
3
2
|
|
4
3
|
describe PacketFu, "version information" do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
it "reports a version number" do
|
5
|
+
PacketFu::VERSION.should match /^1\.[0-9]+\.[0-9]+$/
|
6
|
+
end
|
7
|
+
its(:version) {should eq PacketFu::VERSION}
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
it "can compare version strings" do
|
10
|
+
PacketFu.binarize_version("1.2.3").should == 0x010203
|
11
|
+
PacketFu.binarize_version("3.0").should == 0x030000
|
12
|
+
PacketFu.at_least?("1.0").should be true
|
13
|
+
PacketFu.at_least?("4.0").should be false
|
14
|
+
PacketFu.older_than?("4.0").should be true
|
15
|
+
PacketFu.newer_than?("1.0").should be true
|
16
|
+
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
it "can handle .pre versions" do
|
19
|
+
PacketFu.binarize_version("1.7.6.pre").should == 0x010706
|
20
|
+
PacketFu.at_least?("0.9.0.pre").should be true
|
21
|
+
end
|
23
22
|
end
|
24
23
|
|
25
24
|
describe PacketFu, "instance variables" do
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
it "should have a bunch of instance variables" do
|
26
|
+
PacketFu.instance_variable_get(:@byte_order).should == :little
|
27
|
+
PacketFu.instance_variable_get(:@pcaprub_loaded).should_not be_nil
|
28
|
+
end
|
30
29
|
end
|
31
30
|
|
32
31
|
describe PacketFu, "pcaprub deps" do
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
32
|
+
it "should check for pcaprub" do
|
33
|
+
begin
|
34
|
+
has_pcap = false
|
35
|
+
require 'pcaprub'
|
36
|
+
has_pcap = true
|
37
|
+
rescue LoadError
|
38
|
+
end
|
39
|
+
if has_pcap
|
40
|
+
PacketFu.instance_variable_get(:@pcaprub_loaded).should be true
|
41
|
+
else
|
42
|
+
PacketFu.instance_variable_get(:@pcaprub_loaded).should be false
|
43
|
+
end
|
44
|
+
end
|
46
45
|
end
|
47
46
|
|
48
47
|
describe PacketFu, "protocol requires" do
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
48
|
+
it "should have some protocols defined" do
|
49
|
+
PacketFu::EthPacket.should_not be_nil
|
50
|
+
PacketFu::IPPacket.should_not be_nil
|
51
|
+
PacketFu::TCPPacket.should_not be_nil
|
52
|
+
expect { PacketFu::FakePacket }.to raise_error(NameError, "uninitialized constant PacketFu::FakePacket")
|
53
|
+
end
|
55
54
|
end
|
56
55
|
|
57
56
|
describe PacketFu, "packet class list management" do
|
58
57
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
58
|
+
it "should allow packet class registration" do
|
59
|
+
PacketFu.add_packet_class(PacketFu::FooPacket).should be_kind_of Array
|
60
|
+
PacketFu.add_packet_class(PacketFu::BarPacket).should be_kind_of Array
|
61
|
+
end
|
64
62
|
|
65
|
-
|
66
|
-
PacketFu.add_packet_class(PacketFu::FooPacket).should be_kind_of Array
|
67
|
-
PacketFu.add_packet_class(PacketFu::BarPacket).should be_kind_of Array
|
68
|
-
end
|
63
|
+
its(:packet_classes) {should include(PacketFu::FooPacket)}
|
69
64
|
|
70
|
-
|
65
|
+
it "should disallow non-classes as packet classes" do
|
66
|
+
expect { PacketFu.add_packet_class("A String") }.to raise_error(RuntimeError, "Need a class")
|
67
|
+
end
|
71
68
|
|
72
|
-
|
73
|
-
expect { PacketFu.add_packet_class("A String") }.to raise_error
|
74
|
-
end
|
69
|
+
its(:packet_prefixes) {should include("bar")}
|
75
70
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
PacketFu.add_packet_class(PacketFu::BarPacket)
|
83
|
-
end
|
71
|
+
# Don't really have much utility for this right now.
|
72
|
+
it "should allow packet class deregistration" do
|
73
|
+
PacketFu.remove_packet_class(PacketFu::BarPacket)
|
74
|
+
PacketFu.packet_prefixes.should_not include("bar")
|
75
|
+
PacketFu.add_packet_class(PacketFu::BarPacket)
|
76
|
+
end
|
84
77
|
|
85
78
|
end
|