packetfu 1.1.2 → 1.1.3
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/.gitignore +3 -0
- data/INSTALL.rdoc +40 -0
- data/LICENSE.txt +25 -0
- data/examples/100kpackets.rb +41 -0
- data/examples/ackscan.rb +38 -0
- data/examples/arp.rb +60 -0
- data/examples/arphood.rb +59 -0
- data/examples/dissect_thinger.rb +22 -0
- data/examples/ethernet.rb +10 -0
- data/examples/examples.rb +3 -0
- data/examples/ids.rb +4 -0
- data/examples/idsv2.rb +6 -0
- data/examples/new-simple-stats.rb +52 -0
- data/examples/oui.txt +84177 -0
- data/examples/packetfu-shell.rb +113 -0
- data/examples/simple-sniffer.rb +40 -0
- data/examples/simple-stats.rb +50 -0
- data/examples/slammer.rb +33 -0
- data/examples/uniqpcap.rb +15 -0
- data/lib/packetfu.rb +147 -0
- data/lib/packetfu/capture.rb +169 -0
- data/lib/packetfu/config.rb +58 -0
- data/lib/packetfu/inject.rb +65 -0
- data/lib/packetfu/packet.rb +533 -0
- data/lib/packetfu/pcap.rb +594 -0
- data/lib/packetfu/protos/arp.rb +268 -0
- data/lib/packetfu/protos/eth.rb +296 -0
- data/lib/packetfu/protos/hsrp.rb +206 -0
- data/lib/packetfu/protos/icmp.rb +179 -0
- data/lib/packetfu/protos/invalid.rb +55 -0
- data/lib/packetfu/protos/ip.rb +378 -0
- data/lib/packetfu/protos/ipv6.rb +250 -0
- data/lib/packetfu/protos/tcp.rb +1127 -0
- data/lib/packetfu/protos/udp.rb +240 -0
- data/lib/packetfu/structfu.rb +294 -0
- data/lib/packetfu/utils.rb +194 -0
- data/lib/packetfu/version.rb +50 -0
- data/packetfu.gemspec +21 -0
- data/setup.rb +1586 -0
- data/test/all_tests.rb +41 -0
- data/test/ethpacket_spec.rb +74 -0
- data/test/packet_spec.rb +73 -0
- data/test/packet_subclasses_spec.rb +13 -0
- data/test/packetfu_spec.rb +90 -0
- data/test/ptest.rb +16 -0
- data/test/sample-ipv6.pcap +0 -0
- data/test/sample.pcap +0 -0
- data/test/sample2.pcap +0 -0
- data/test/sample_hsrp_pcapr.cap +0 -0
- data/test/structfu_spec.rb +335 -0
- data/test/tcp_spec.rb +101 -0
- data/test/test_arp.rb +135 -0
- data/test/test_eth.rb +91 -0
- data/test/test_hsrp.rb +20 -0
- data/test/test_icmp.rb +54 -0
- data/test/test_inject.rb +31 -0
- data/test/test_invalid.rb +28 -0
- data/test/test_ip.rb +69 -0
- data/test/test_ip6.rb +68 -0
- data/test/test_octets.rb +37 -0
- data/test/test_packet.rb +174 -0
- data/test/test_pcap.rb +209 -0
- data/test/test_structfu.rb +112 -0
- data/test/test_tcp.rb +327 -0
- data/test/test_udp.rb +73 -0
- data/test/vlan-pcapr.cap +0 -0
- metadata +85 -6
data/test/all_tests.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Tested on:
|
4
|
+
#
|
5
|
+
# ruby-1.9.3-head [ x86_64 ]
|
6
|
+
# ruby-1.9.1-p378 [ x86_64 ]
|
7
|
+
# ruby-1.8.6-p399 [ x86_64 ]
|
8
|
+
# ruby-1.8.7-p334 [ x86_64 ]
|
9
|
+
# ruby-1.9.2-p180 [ x86_64 ]
|
10
|
+
|
11
|
+
# Okay so the regular test/unit stuff screws up some of my
|
12
|
+
# meta magic. I need to move these over to spec and see
|
13
|
+
# if they're any better. In the meantime, behold my
|
14
|
+
# ghetto test exec()'er. It all passes with this,
|
15
|
+
# so I'm just going to go ahead and assume the testing
|
16
|
+
# methodolgy is flawed. TODO: rewrite all this for spec
|
17
|
+
# and incidentally get the gem to test like it's supposed
|
18
|
+
# to.
|
19
|
+
|
20
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
21
|
+
require 'packetfu'
|
22
|
+
puts "Testing PacketFu v#{PacketFu::VERSION}"
|
23
|
+
dir = Dir.new(File.dirname(__FILE__))
|
24
|
+
|
25
|
+
dir.each { |file|
|
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
|
+
}
|
40
|
+
|
41
|
+
# vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
|
@@ -0,0 +1,74 @@
|
|
1
|
+
$:.unshift File.join(File.expand_path(File.dirname(__FILE__)), "..", "lib")
|
2
|
+
require 'packetfu'
|
3
|
+
|
4
|
+
include PacketFu
|
5
|
+
|
6
|
+
describe EthPacket, "when read from a pcap file" do
|
7
|
+
|
8
|
+
before :all do
|
9
|
+
parsed_packets = PcapFile.read_packets(File.join(".","sample.pcap"))
|
10
|
+
@eth_packet = parsed_packets.first
|
11
|
+
end
|
12
|
+
|
13
|
+
context "is a regular ethernet packet" do
|
14
|
+
|
15
|
+
subject { @eth_packet }
|
16
|
+
|
17
|
+
it "should be an EthPacket kind of packet" do
|
18
|
+
subject.should be_kind_of EthPacket
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have a dest mac address" do
|
22
|
+
subject.eth_daddr.should == "00:03:2f:1a:74:de"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have a source mac address" do
|
26
|
+
subject.eth_saddr.should == "00:1b:11:51:b7:ce"
|
27
|
+
end
|
28
|
+
|
29
|
+
its(:size) { should == 78 }
|
30
|
+
|
31
|
+
it "should have a payload in its first header" do
|
32
|
+
subject.headers.first.body.should_not be_nil
|
33
|
+
end
|
34
|
+
|
35
|
+
context "an EthPacket's first header" do
|
36
|
+
|
37
|
+
subject { @eth_packet.headers.first }
|
38
|
+
|
39
|
+
it "should be 64 bytes" do
|
40
|
+
subject.body.sz.should == 64
|
41
|
+
end
|
42
|
+
|
43
|
+
context "EthHeader struct members" do
|
44
|
+
if RUBY_VERSION =~ /^1\.8/
|
45
|
+
its(:members) { should include :eth_dst.to_s }
|
46
|
+
its(:members) { should include :eth_src.to_s }
|
47
|
+
its(:members) { should include :eth_proto.to_s }
|
48
|
+
its(:members) { should include :body.to_s }
|
49
|
+
else
|
50
|
+
its(:members) { should include :eth_dst }
|
51
|
+
its(:members) { should include :eth_src }
|
52
|
+
its(:members) { should include :eth_proto }
|
53
|
+
its(:members) { should include :body }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
context "isn't a regular Ethernet packet" do
|
62
|
+
|
63
|
+
subject {
|
64
|
+
parsed_packets = PcapFile.read_packets(File.join(".","vlan-pcapr.cap"))
|
65
|
+
parsed_packets.first
|
66
|
+
}
|
67
|
+
|
68
|
+
it "should not be an EthPacket" do
|
69
|
+
subject.should_not be_kind_of EthPacket
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
data/test/packet_spec.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
$:.unshift File.join(File.expand_path(File.dirname(__FILE__)), "..", "lib")
|
2
|
+
require 'packetfu'
|
3
|
+
|
4
|
+
describe PacketFu::Packet, "abstract packet class behavior" do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
class PacketFu::FooPacket < PacketFu::Packet; end
|
8
|
+
class PacketFu::BarPacket < PacketFu::Packet; end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should not be instantiated" do
|
12
|
+
expect { PacketFu::Packet.new }.to raise_error(NoMethodError)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should allow subclasses to instantiate" do
|
16
|
+
expect { PacketFu::FooPacket.new }. to be
|
17
|
+
PacketFu.packet_classes.include?(PacketFu::FooPacket).should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should register packet classes with PacketFu" do
|
21
|
+
PacketFu.packet_classes {should include(FooPacket) }
|
22
|
+
PacketFu.packet_classes {should include(BarPacket) }
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should disallow badly named subclasses" do
|
26
|
+
expect {
|
27
|
+
class PacketFu::PacketNot < PacketFu::Packet
|
28
|
+
end
|
29
|
+
}.to raise_error
|
30
|
+
PacketFu.packet_classes.include?(PacketFu::PacketNot).should be_false
|
31
|
+
PacketFu.packet_classes {should_not include(PacketNot) }
|
32
|
+
end
|
33
|
+
|
34
|
+
before(:each) do
|
35
|
+
@tcp_packet = PacketFu::TCPPacket.new
|
36
|
+
@tcp_packet.ip_saddr = "10.10.10.10"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should shallow copy with dup()" do
|
40
|
+
p2 = @tcp_packet.dup
|
41
|
+
p2.ip_saddr = "20.20.20.20"
|
42
|
+
p2.ip_saddr.should == @tcp_packet.ip_saddr
|
43
|
+
p2.headers[1].object_id.should == @tcp_packet.headers[1].object_id
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should deep copy with clone()" do
|
47
|
+
p3 = @tcp_packet.clone
|
48
|
+
p3.ip_saddr = "30.30.30.30"
|
49
|
+
p3.ip_saddr.should_not == @tcp_packet.ip_saddr
|
50
|
+
p3.headers[1].object_id.should_not == @tcp_packet.headers[1].object_id
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should have senisble equality" do
|
54
|
+
p4 = @tcp_packet.dup
|
55
|
+
p4.should == @tcp_packet
|
56
|
+
p5 = @tcp_packet.clone
|
57
|
+
p5.should == @tcp_packet
|
58
|
+
end
|
59
|
+
|
60
|
+
# It's actually kinda hard to manually create identical TCP packets
|
61
|
+
it "should be possible to manually create identical packets" do
|
62
|
+
p6 = @tcp_packet.clone
|
63
|
+
p6.should == @tcp_packet
|
64
|
+
p7 = PacketFu::TCPPacket.new
|
65
|
+
p7.ip_saddr = p6.ip_saddr
|
66
|
+
p7.ip_id = p6.ip_id
|
67
|
+
p7.tcp_seq = p6.tcp_seq
|
68
|
+
p7.tcp_src = p6.tcp_src
|
69
|
+
p7.tcp_sum = p6.tcp_sum
|
70
|
+
p7.should == p6
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
$:.unshift File.join(File.expand_path(File.dirname(__FILE__)), "..", "lib")
|
2
|
+
require 'packetfu'
|
3
|
+
|
4
|
+
PacketFu.packet_classes.each do |pclass|
|
5
|
+
describe pclass, "peek format" do
|
6
|
+
it "will display sensible peek information" do
|
7
|
+
p = pclass.new
|
8
|
+
p.respond_to?(:peek).should be_true
|
9
|
+
p.peek.size.should be_<=(80), p.peek.inspect
|
10
|
+
p.peek.should match(/^[A-Z0-9?]../)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
$:.unshift File.join(File.expand_path(File.dirname(__FILE__)), "..", "lib")
|
2
|
+
require 'packetfu'
|
3
|
+
|
4
|
+
unless %x{#{$0} --version} =~ /^2\.6/
|
5
|
+
puts "PacketFu needs rspec 2.6 or so."
|
6
|
+
exit 1
|
7
|
+
end
|
8
|
+
|
9
|
+
describe PacketFu, "version information" do
|
10
|
+
it "reports a version number" do
|
11
|
+
PacketFu::VERSION.should match /^1\.[0-9]\.[0-9]$/
|
12
|
+
end
|
13
|
+
its(:version) {should eq PacketFu::VERSION}
|
14
|
+
|
15
|
+
it "can compare version strings" do
|
16
|
+
PacketFu.binarize_version("1.2.3").should == 0x010203
|
17
|
+
PacketFu.binarize_version("3.0").should == 0x030000
|
18
|
+
PacketFu.at_least?("1.0").should be_true
|
19
|
+
PacketFu.at_least?("4.0").should be_false
|
20
|
+
PacketFu.older_than?("4.0").should be_true
|
21
|
+
PacketFu.newer_than?("1.0").should be_true
|
22
|
+
end
|
23
|
+
|
24
|
+
it "can handle .pre versions" do
|
25
|
+
PacketFu.binarize_version("1.7.6.pre").should == 0x010706
|
26
|
+
PacketFu.at_least?("0.9.0.pre").should be_true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe PacketFu, "instance variables" do
|
31
|
+
it "should have a bunch of instance variables" do
|
32
|
+
PacketFu.instance_variable_get(:@byte_order).should == :little
|
33
|
+
PacketFu.instance_variable_get(:@pcaprub_loaded).should_not be_nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe PacketFu, "pcaprub deps" do
|
38
|
+
it "should check for pcaprub" do
|
39
|
+
begin
|
40
|
+
has_pcap = false
|
41
|
+
require 'pcaprub'
|
42
|
+
has_pcap = true
|
43
|
+
rescue LoadError
|
44
|
+
end
|
45
|
+
if has_pcap
|
46
|
+
PacketFu.instance_variable_get(:@pcaprub_loaded).should be_true
|
47
|
+
else
|
48
|
+
PacketFu.instance_variable_get(:@pcaprub_loaded).should be_false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe PacketFu, "protocol requires" do
|
54
|
+
it "should have some protocols defined" do
|
55
|
+
PacketFu::EthPacket.should_not be_nil
|
56
|
+
PacketFu::IPPacket.should_not be_nil
|
57
|
+
PacketFu::TCPPacket.should_not be_nil
|
58
|
+
expect { PacketFu::FakePacket }.to raise_error
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe PacketFu, "packet class list management" do
|
63
|
+
|
64
|
+
before(:all) do
|
65
|
+
class PacketFu::FooPacket < PacketFu::Packet; end
|
66
|
+
class PacketFu::BarPacket < PacketFu::Packet; end
|
67
|
+
class PacketFu::PacketBaz; end
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should allow packet class registration" do
|
71
|
+
PacketFu.add_packet_class(PacketFu::FooPacket).should be_kind_of Array
|
72
|
+
PacketFu.add_packet_class(PacketFu::BarPacket).should be_kind_of Array
|
73
|
+
end
|
74
|
+
|
75
|
+
its(:packet_classes) {should include(PacketFu::FooPacket)}
|
76
|
+
|
77
|
+
it "should disallow non-classes as packet classes" do
|
78
|
+
expect { PacketFu.add_packet_class("A String") }.to raise_error
|
79
|
+
end
|
80
|
+
|
81
|
+
its(:packet_prefixes) {should include("bar")}
|
82
|
+
|
83
|
+
# Don't really have much utility for this right now.
|
84
|
+
it "should allow packet class deregistration" do
|
85
|
+
PacketFu.remove_packet_class(PacketFu::BarPacket)
|
86
|
+
PacketFu.packet_prefixes.should_not include("bar")
|
87
|
+
PacketFu.add_packet_class(PacketFu::BarPacket)
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
data/test/ptest.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
3
|
+
require 'pcaprub'
|
4
|
+
require 'packetfu'
|
5
|
+
include PacketFu
|
6
|
+
|
7
|
+
if Process.euid.zero?
|
8
|
+
puts ">> Interface: " << Pcap.lookupdev
|
9
|
+
else
|
10
|
+
puts ">> No interface access"
|
11
|
+
end
|
12
|
+
puts ">> Version: " << PacketFu.version
|
13
|
+
|
14
|
+
# vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
|
15
|
+
|
16
|
+
|
Binary file
|
data/test/sample.pcap
ADDED
Binary file
|
data/test/sample2.pcap
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,335 @@
|
|
1
|
+
$:.unshift File.join(File.expand_path(File.dirname(__FILE__)), "..", "lib")
|
2
|
+
require 'packetfu'
|
3
|
+
|
4
|
+
describe StructFu, "mixin methods" do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
class StructClass
|
8
|
+
include StructFu
|
9
|
+
end
|
10
|
+
@sc = StructClass.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should provide the basic StructFu methods" do
|
14
|
+
@sc.respond_to?(:sz).should be_true
|
15
|
+
@sc.respond_to?(:len).should be_true
|
16
|
+
@sc.respond_to?(:typecast).should be_true
|
17
|
+
@sc.respond_to?(:body=).should be_true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe StructFu::Int, "basic Int class" do
|
22
|
+
|
23
|
+
before :each do
|
24
|
+
@int = StructFu::Int.new(8)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should have an initial state" do
|
28
|
+
new_int = StructFu::Int.new
|
29
|
+
new_int.value.should be_nil
|
30
|
+
new_int.endian.should be_nil
|
31
|
+
new_int.width.should be_nil
|
32
|
+
new_int.default.should == 0
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should raise when to_s'ed directly" do
|
36
|
+
expect { @int.to_s}.to raise_error
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should have a value of 8" do
|
40
|
+
@int.value.should == 8
|
41
|
+
@int.to_i.should == 8
|
42
|
+
@int.to_f.to_s.should == "8.0"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should read an integer" do
|
46
|
+
@int.read(7)
|
47
|
+
@int.to_i.should == 7
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe StructFu::Int8, "one byte value" do
|
53
|
+
|
54
|
+
before :each do
|
55
|
+
@int = StructFu::Int8.new(11)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should have an initial state" do
|
59
|
+
new_int = StructFu::Int8.new
|
60
|
+
new_int.value.should be_nil
|
61
|
+
new_int.endian.should be_nil
|
62
|
+
new_int.width.should == 1
|
63
|
+
new_int.default.should == 0
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should print a one character packed string" do
|
67
|
+
@int.to_s.should == "\x0b"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should have a value of 11" do
|
71
|
+
@int.value.should == 11
|
72
|
+
@int.to_i.should == 11
|
73
|
+
@int.to_f.to_s.should == "11.0"
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should reset with a new integer" do
|
77
|
+
@int.read(2)
|
78
|
+
@int.to_i.should == 2
|
79
|
+
@int.to_s.should == "\x02"
|
80
|
+
@int.read(254)
|
81
|
+
@int.to_i.should == 254
|
82
|
+
@int.to_s.should == "\xfe"
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
describe StructFu::Int16, "two byte value" do
|
88
|
+
|
89
|
+
before :each do
|
90
|
+
@int = StructFu::Int16.new(11)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should have an initial state" do
|
94
|
+
new_int = StructFu::Int16.new
|
95
|
+
new_int.value.should be_nil
|
96
|
+
new_int.endian.should == :big
|
97
|
+
new_int.width.should == 2
|
98
|
+
new_int.default.should == 0
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should print a two character packed string" do
|
102
|
+
@int.to_s.should == "\x00\x0b"
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should have a value of 11" do
|
106
|
+
@int.value.should == 11
|
107
|
+
@int.to_i.should == 11
|
108
|
+
@int.to_f.to_s.should == "11.0"
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should reset with a new integer" do
|
112
|
+
@int.read(2)
|
113
|
+
@int.to_i.should == 2
|
114
|
+
@int.to_s.should == "\x00\x02"
|
115
|
+
@int.read(254)
|
116
|
+
@int.to_i.should == 254
|
117
|
+
@int.to_s.should == "\x00\xfe"
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should be able to set endianness" do
|
121
|
+
int_be = StructFu::Int16.new(11,:big)
|
122
|
+
int_be.to_s.should == "\x00\x0b"
|
123
|
+
int_le = StructFu::Int16.new(11,:little)
|
124
|
+
int_le.to_s.should == "\x0b\x00"
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should be able to switch endianness" do
|
128
|
+
@int.endian.should == :big
|
129
|
+
@int.to_s.should == "\x00\x0b"
|
130
|
+
@int.endian = :little
|
131
|
+
@int.endian.should == :little
|
132
|
+
@int.read(11)
|
133
|
+
@int.to_s.should == "\x0b\x00"
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
describe StructFu::Int16le, "2 byte little-endian value" do
|
139
|
+
|
140
|
+
before :each do
|
141
|
+
@int = StructFu::Int16le.new(11)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should behave pretty much like any other 16 bit int" do
|
145
|
+
@int.to_s.should == "\x0b\x00"
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should raise when you try to change endianness" do
|
149
|
+
expect { @int.endian = :big }.to raise_error
|
150
|
+
expect { @int.endian = :little }.to raise_error
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
describe StructFu::Int16be, "2 byte big-endian value" do
|
156
|
+
|
157
|
+
before :each do
|
158
|
+
@int = StructFu::Int16be.new(11)
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should behave pretty much like any other 16 bit int" do
|
162
|
+
@int.to_s.should == "\x00\x0b"
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should raise when you try to change endianness" do
|
166
|
+
expect { @int.endian = :big }.to raise_error
|
167
|
+
expect { @int.endian = :little }.to raise_error
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
describe StructFu::Int32, "four byte value" do
|
173
|
+
|
174
|
+
before :each do
|
175
|
+
@int = StructFu::Int32.new(11)
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should have an initial state" do
|
179
|
+
new_int = StructFu::Int32.new
|
180
|
+
new_int.value.should be_nil
|
181
|
+
new_int.endian.should == :big
|
182
|
+
new_int.width.should == 4
|
183
|
+
new_int.default.should == 0
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should print a four character packed string" do
|
187
|
+
@int.to_s.should == "\x00\x00\x00\x0b"
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should have a value of 11" do
|
191
|
+
@int.value.should == 11
|
192
|
+
@int.to_i.should == 11
|
193
|
+
@int.to_f.to_s.should == "11.0"
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should reset with a new integer" do
|
197
|
+
@int.read(2)
|
198
|
+
@int.to_i.should == 2
|
199
|
+
@int.to_s.should == "\x00\x00\x00\x02"
|
200
|
+
@int.read(254)
|
201
|
+
@int.to_i.should == 254
|
202
|
+
@int.to_s.should == "\x00\x00\x00\xfe"
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should be able to set endianness" do
|
206
|
+
int_be = StructFu::Int32.new(11,:big)
|
207
|
+
int_be.to_s.should == "\x00\x00\x00\x0b"
|
208
|
+
int_le = StructFu::Int32.new(11,:little)
|
209
|
+
int_le.to_s.should == "\x0b\x00\x00\x00"
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should be able to switch endianness" do
|
213
|
+
@int.endian.should == :big
|
214
|
+
@int.to_s.should == "\x00\x00\x00\x0b"
|
215
|
+
@int.endian = :little
|
216
|
+
@int.endian.should == :little
|
217
|
+
@int.read(11)
|
218
|
+
@int.to_s.should == "\x0b\x00\x00\x00"
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
describe StructFu::Int32le, "4 byte little-endian value" do
|
224
|
+
|
225
|
+
before :each do
|
226
|
+
@int = StructFu::Int32le.new(11)
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should behave pretty much like any other 32 bit int" do
|
230
|
+
@int.to_s.should == "\x0b\x00\x00\x00"
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should raise when you try to change endianness" do
|
234
|
+
expect { @int.endian = :big }.to raise_error
|
235
|
+
expect { @int.endian = :little }.to raise_error
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
239
|
+
|
240
|
+
describe StructFu::Int32be, "4 byte big-endian value" do
|
241
|
+
|
242
|
+
before :each do
|
243
|
+
@int = StructFu::Int32be.new(11)
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should behave pretty much like any other 32 bit int" do
|
247
|
+
@int.to_s.should == "\x00\x00\x00\x0b"
|
248
|
+
end
|
249
|
+
|
250
|
+
it "should raise when you try to change endianness" do
|
251
|
+
expect { @int.endian = :big }.to raise_error
|
252
|
+
expect { @int.endian = :little }.to raise_error
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
256
|
+
|
257
|
+
describe StructFu::String, "a sligtly more special String" do
|
258
|
+
|
259
|
+
before :each do
|
260
|
+
@str = StructFu::String.new("Oi, a string")
|
261
|
+
end
|
262
|
+
|
263
|
+
it "should behave pretty much like a string" do
|
264
|
+
@str.should be_kind_of(String)
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should have a read method" do
|
268
|
+
@str.should respond_to(:read)
|
269
|
+
end
|
270
|
+
|
271
|
+
it "should read data like other StructFu things" do
|
272
|
+
@str.read("hello")
|
273
|
+
@str.should == "hello"
|
274
|
+
end
|
275
|
+
|
276
|
+
end
|
277
|
+
|
278
|
+
describe StructFu::IntString do
|
279
|
+
|
280
|
+
it "should be" do
|
281
|
+
StructFu::IntString.should be
|
282
|
+
end
|
283
|
+
|
284
|
+
it "should have a length and value" do
|
285
|
+
istr = StructFu::IntString.new("Avast!")
|
286
|
+
istr.to_s.should == "\x06Avast!"
|
287
|
+
end
|
288
|
+
|
289
|
+
it "should have a 16-bit length and a value" do
|
290
|
+
istr = StructFu::IntString.new("Avast!",StructFu::Int16)
|
291
|
+
istr.to_s.should == "\x00\x06Avast!"
|
292
|
+
end
|
293
|
+
|
294
|
+
it "should have a 32-bit length and a value" do
|
295
|
+
istr = StructFu::IntString.new("Avast!",StructFu::Int32)
|
296
|
+
istr.to_s.should == "\x00\x00\x00\x06Avast!"
|
297
|
+
end
|
298
|
+
|
299
|
+
before :each do
|
300
|
+
@istr = StructFu::IntString.new("Avast!",StructFu::Int32)
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should report the correct length with a new string" do
|
304
|
+
@istr.to_s.should == "\x00\x00\x00\x06Avast!"
|
305
|
+
@istr.string = "Ahoy!"
|
306
|
+
@istr.to_s.should == "\x00\x00\x00\x05Ahoy!"
|
307
|
+
end
|
308
|
+
|
309
|
+
it "should report the correct length with a new string" do
|
310
|
+
@istr.string = "Ahoy!"
|
311
|
+
@istr.to_s.should == "\x00\x00\x00\x05Ahoy!"
|
312
|
+
end
|
313
|
+
|
314
|
+
it "should keep the old length with a new string" do
|
315
|
+
@istr[:string] = "Ahoy!"
|
316
|
+
@istr.to_s.should == "\x00\x00\x00\x06Ahoy!"
|
317
|
+
end
|
318
|
+
|
319
|
+
it "should allow for adjusting the length manually" do
|
320
|
+
@istr.len = 16
|
321
|
+
@istr.to_s.should == "\x00\x00\x00\x10Avast!"
|
322
|
+
end
|
323
|
+
|
324
|
+
it "should read in an expected string" do
|
325
|
+
data = "\x00\x00\x00\x09Yo ho ho!"
|
326
|
+
@istr.read(data)
|
327
|
+
@istr.to_s.should == data
|
328
|
+
end
|
329
|
+
|
330
|
+
it "should raise when a string is too short" do
|
331
|
+
data = "\x01A"
|
332
|
+
expect { @istr.read(data) }.to raise_error
|
333
|
+
end
|
334
|
+
|
335
|
+
end
|