packetfu 1.0.0
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/.document +4 -0
- data/CHANGES +36 -0
- data/INSTALL +40 -0
- data/LICENSE +28 -0
- data/README +25 -0
- data/TODO +25 -0
- data/examples/ackscan.rb +38 -0
- data/examples/arp.rb +60 -0
- data/examples/arphood.rb +56 -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/oui.txt +84177 -0
- data/examples/packetfu-shell.rb +111 -0
- data/examples/simple-stats.rb +42 -0
- data/examples/slammer.rb +33 -0
- data/examples/uniqpcap.rb +15 -0
- data/lib/packetfu.rb +108 -0
- data/lib/packetfu/arp.rb +239 -0
- data/lib/packetfu/capture.rb +169 -0
- data/lib/packetfu/config.rb +55 -0
- data/lib/packetfu/eth.rb +264 -0
- data/lib/packetfu/icmp.rb +153 -0
- data/lib/packetfu/inject.rb +65 -0
- data/lib/packetfu/invalid.rb +41 -0
- data/lib/packetfu/ip.rb +318 -0
- data/lib/packetfu/ipv6.rb +230 -0
- data/lib/packetfu/packet.rb +492 -0
- data/lib/packetfu/pcap.rb +502 -0
- data/lib/packetfu/structfu.rb +274 -0
- data/lib/packetfu/tcp.rb +1061 -0
- data/lib/packetfu/udp.rb +210 -0
- data/lib/packetfu/utils.rb +182 -0
- data/test/all_tests.rb +37 -0
- data/test/ptest.rb +10 -0
- data/test/sample.pcap +0 -0
- data/test/sample2.pcap +0 -0
- data/test/test_arp.rb +135 -0
- data/test/test_eth.rb +90 -0
- data/test/test_icmp.rb +54 -0
- data/test/test_inject.rb +33 -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 +41 -0
- data/test/test_pcap.rb +210 -0
- data/test/test_structfu.rb +112 -0
- data/test/test_tcp.rb +327 -0
- data/test/test_udp.rb +73 -0
- metadata +144 -0
data/test/test_eth.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
4
|
+
require 'packetfu'
|
5
|
+
|
6
|
+
class EthTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_ethmac
|
9
|
+
dst = "\x00\x03\x2f\x1a\x74\xde"
|
10
|
+
e = PacketFu::EthMac.new
|
11
|
+
e.read dst
|
12
|
+
assert_equal(dst, e.to_s)
|
13
|
+
assert_equal(0x32f, e.oui.oui)
|
14
|
+
assert_equal("\x1a\x74\xde", e.nic.to_s)
|
15
|
+
assert_equal(222, e.nic.n2)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_ethmac_ipad
|
19
|
+
dst = "\x7c\x6d\x62\x01\x02\x03"
|
20
|
+
e = PacketFu::EthMac.new
|
21
|
+
e.read dst
|
22
|
+
assert_equal(dst, e.to_s)
|
23
|
+
assert_equal(0x6d62, e.oui.oui)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_ethmac_class
|
27
|
+
src = "\x00\x1b\x11\x51\xb7\xce"
|
28
|
+
e = PacketFu::EthMac.new
|
29
|
+
e.read src
|
30
|
+
assert_instance_of(PacketFu::EthMac, e)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_eth
|
34
|
+
header = "00032f1a74de001b1151b7ce0800".scan(/../).map { |x| x.to_i(16) }.pack("C*")
|
35
|
+
src = "\x00\x1b\x11\x51\xb7\xce"
|
36
|
+
dst = "\x00\x03\x2f\x1a\x74\xde"
|
37
|
+
e = PacketFu::EthHeader.new
|
38
|
+
e.eth_dst = dst
|
39
|
+
e.eth_src = src
|
40
|
+
e.eth_proto = "\x08\x00"
|
41
|
+
assert_equal(header, e.to_s)
|
42
|
+
assert_equal(header, PacketFu::EthHeader.new.read(header).to_s)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_macaddr
|
46
|
+
dst = "\x00\x03\x2f\x1a\x74\xde"
|
47
|
+
dstmac = "00:03:2f:1a:74:de"
|
48
|
+
assert_equal(dstmac,PacketFu::EthHeader.str2mac(dst))
|
49
|
+
assert_equal(dst, PacketFu::EthHeader.mac2str(dstmac))
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
class EthPacketTest < Test::Unit::TestCase
|
55
|
+
include PacketFu
|
56
|
+
|
57
|
+
def test_eth_create
|
58
|
+
sample_packet = PcapFile.new.file_to_array(:f => 'sample.pcap')[0]
|
59
|
+
e = EthPacket.new
|
60
|
+
header = "00032f1a74de001b1151b7ce0800".scan(/../).map { |x| x.to_i(16) }.pack("C*")
|
61
|
+
assert_kind_of EthPacket, e
|
62
|
+
assert_kind_of EthHeader, e.headers[0]
|
63
|
+
assert e.is_eth?
|
64
|
+
assert !e.is_tcp?
|
65
|
+
e.eth_dst = "\x00\x03\x2f\x1a\x74\xde"
|
66
|
+
e.eth_src = "\x00\x1b\x11\x51\xb7\xce"
|
67
|
+
e.eth_proto = 0x0800
|
68
|
+
assert_equal header, e.to_s[0,14]
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_eth_new
|
72
|
+
p = EthPacket.new(
|
73
|
+
:eth_dst => "\x00\x03\x2f\x1a\x74\xde",
|
74
|
+
:eth_src => "\x00\x1b\x11\x51\xb7\xce",
|
75
|
+
:eth_proto => 0x0800)
|
76
|
+
header = "00032f1a74de001b1151b7ce0800".scan(/../).map { |x| x.to_i(16) }.pack("C*")
|
77
|
+
assert_equal header, p.to_s[0,14]
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_eth_write
|
81
|
+
p = EthPacket.new(
|
82
|
+
:eth_dst => "\x00\x03\x2f\x1a\x74\xde",
|
83
|
+
:eth_src => "\x00\x1b\x11\x51\xb7\xce",
|
84
|
+
:eth_proto => 0x0800)
|
85
|
+
p.to_f('eth_test.pcap')
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
# vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
|
data/test/test_icmp.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
4
|
+
require 'packetfu'
|
5
|
+
|
6
|
+
class ICMPTest < Test::Unit::TestCase
|
7
|
+
include PacketFu
|
8
|
+
|
9
|
+
def test_icmp_header_new
|
10
|
+
i = ICMPHeader.new
|
11
|
+
assert_kind_of ICMPHeader, i
|
12
|
+
assert_equal("\x00\x00\xff\xff", i.to_s)
|
13
|
+
i.icmp_type = 1
|
14
|
+
i.icmp_recalc :icmp_sum
|
15
|
+
assert_equal("\x01\x00\xfe\xff", i.to_s)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_icmp_peek
|
19
|
+
i = ICMPPacket.new
|
20
|
+
i.ip_saddr = "10.20.30.40"
|
21
|
+
i.ip_daddr = "50.60.70.80"
|
22
|
+
i.payload = "abcdefghijklmnopqrstuvwxyz"
|
23
|
+
i.recalc
|
24
|
+
puts "\n"
|
25
|
+
puts "ICMP Peek format: "
|
26
|
+
puts i.peek
|
27
|
+
assert_equal 78,i.peek.size
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_icmp_pcap
|
31
|
+
i = ICMPPacket.new
|
32
|
+
assert_kind_of ICMPPacket, i
|
33
|
+
i.recalc
|
34
|
+
i.to_f('icmp_test.pcap')
|
35
|
+
i.ip_saddr = "10.20.30.40"
|
36
|
+
i.ip_daddr = "50.60.70.80"
|
37
|
+
i.payload = "\x00\x01\x00\01abcdefghijklmnopqrstuvwxyz"
|
38
|
+
i.icmp_code = 8
|
39
|
+
i.recalc
|
40
|
+
i.to_f('icmp_test.pcap','a')
|
41
|
+
assert File.exists?('icmp_test.pcap')
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_icmp_read
|
45
|
+
sample_packet = PcapFile.new.file_to_array(:f => 'sample.pcap')[2]
|
46
|
+
pkt = Packet.parse(sample_packet)
|
47
|
+
assert_kind_of ICMPPacket, pkt
|
48
|
+
assert_equal(0x4d58, pkt.icmp_sum.to_i)
|
49
|
+
assert_equal(8, pkt.icmp_type.to_i)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
# vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
|
data/test/test_inject.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
3
|
+
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
# Needed if you're using the gem version of pcaprub. Obviated in 1.9.
|
7
|
+
require 'packetfu'
|
8
|
+
|
9
|
+
class InjectTest < Test::Unit::TestCase
|
10
|
+
|
11
|
+
def test_cap
|
12
|
+
assert_nothing_raised { PacketFu::Capture }
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_whoami
|
16
|
+
assert_nothing_raised { PacketFu::Utils.whoami?(:iface => (ENV['IFACE'] || 'lo')) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_to_w
|
20
|
+
assert_equal(Process.euid, 0, "TEST FAIL: This test must be run as root")
|
21
|
+
conf = PacketFu::Utils.whoami?(:iface => (ENV['IFACE'] || 'lo'))
|
22
|
+
p = PacketFu::UDPPacket.new(:config => conf)
|
23
|
+
p.udp_dport = 12345
|
24
|
+
p.udp_sport = 12345
|
25
|
+
p.payload = "PacketFu test packet"
|
26
|
+
p.recalc
|
27
|
+
assert p.to_w
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
# vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
4
|
+
require 'packetfu'
|
5
|
+
|
6
|
+
class InvalidTest < Test::Unit::TestCase
|
7
|
+
include PacketFu
|
8
|
+
|
9
|
+
def test_create_invalid
|
10
|
+
p = InvalidPacket.new
|
11
|
+
assert_kind_of InvalidPacket, p
|
12
|
+
assert_kind_of Packet, p
|
13
|
+
assert p.is_invalid?
|
14
|
+
assert_equal false, p.is_eth?
|
15
|
+
assert_not_equal EthPacket, p.class
|
16
|
+
end
|
17
|
+
|
18
|
+
# Sadly, the only way to generate an "InvalidPacket" is
|
19
|
+
# to read a packet that's less than 14 bytes. Otherwise,
|
20
|
+
# it's presumed to be an EthPacket. TODO: Fix this assumption!
|
21
|
+
def test_parse_invalid
|
22
|
+
p = Packet.parse("A" * 13)
|
23
|
+
assert_kind_of InvalidPacket, p
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
# vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
|
data/test/test_ip.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
4
|
+
require 'packetfu'
|
5
|
+
|
6
|
+
class OctetsTest < Test::Unit::TestCase
|
7
|
+
include PacketFu
|
8
|
+
|
9
|
+
def test_octets_read
|
10
|
+
o = Octets.new
|
11
|
+
o.read("\x04\x03\x02\x01")
|
12
|
+
assert_equal("4.3.2.1", o.to_x)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_octets_read_quad
|
16
|
+
o = Octets.new
|
17
|
+
o.read_quad("1.2.3.4")
|
18
|
+
assert_equal("1.2.3.4", o.to_x)
|
19
|
+
assert_equal("\x01\x02\x03\x04", o.to_s)
|
20
|
+
assert_equal(0x01020304, o.to_i)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
class IPTest < Test::Unit::TestCase
|
26
|
+
include PacketFu
|
27
|
+
|
28
|
+
def test_ip_header_new
|
29
|
+
i = IPHeader.new
|
30
|
+
assert_kind_of IPHeader, i
|
31
|
+
i.ip_id = 0x1234
|
32
|
+
i.ip_recalc :ip_sum
|
33
|
+
assert_equal("E\000\000\024\0224\000\000 \000\210\267\000\000\000\000\000\000\000\000", i.to_s)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_ip_packet_new
|
37
|
+
i = IPPacket.new
|
38
|
+
assert i.is_ip?
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_ip_peek
|
42
|
+
i = IPPacket.new
|
43
|
+
i.ip_saddr = "1.2.3.4"
|
44
|
+
i.ip_daddr = "5.6.7.8"
|
45
|
+
i.ip_proto = 94
|
46
|
+
i.payload = '\x00' * 30
|
47
|
+
i.recalc
|
48
|
+
puts "\n"
|
49
|
+
puts "IP Peek format: "
|
50
|
+
puts i.peek
|
51
|
+
assert_equal 78,i.peek.size
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_ip_pcap
|
55
|
+
i = IPPacket.new
|
56
|
+
assert_kind_of IPPacket, i
|
57
|
+
i.recalc
|
58
|
+
i.to_f('ip_test.pcap')
|
59
|
+
i.ip_saddr = "1.2.3.4"
|
60
|
+
i.ip_daddr = "5.6.7.8"
|
61
|
+
i.ip_proto = 94
|
62
|
+
i.payload = "\x23" * 10
|
63
|
+
i.recalc
|
64
|
+
i.to_f('ip_test.pcap','a')
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
# vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
|
data/test/test_ip6.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
4
|
+
require 'packetfu'
|
5
|
+
|
6
|
+
class IPv6AddrTest < Test::Unit::TestCase
|
7
|
+
include PacketFu
|
8
|
+
|
9
|
+
def test_addr_read
|
10
|
+
a = AddrIpv6.new
|
11
|
+
addr = "\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x1a\xc5\xff\xfe\x00\x01\x52"
|
12
|
+
a.read(addr)
|
13
|
+
assert_equal(338288524927261089654170548082086773074, a.to_i)
|
14
|
+
assert_equal("fe80::21a:c5ff:fe00:152",a.to_x)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_octets_read_quad
|
18
|
+
a = AddrIpv6.new
|
19
|
+
addr = "fe80::21a:c5ff:fe00:152"
|
20
|
+
a.read_x(addr)
|
21
|
+
assert_equal(addr,a.to_x)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class IPv6Test < Test::Unit::TestCase
|
27
|
+
include PacketFu
|
28
|
+
|
29
|
+
def test_ipv6_header_new
|
30
|
+
i = IPv6Header.new
|
31
|
+
assert_kind_of IPv6Header, i
|
32
|
+
assert_equal("`\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", i.to_s)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_ipv6_packet_new
|
36
|
+
i = IPv6Packet.new
|
37
|
+
assert i.is_ipv6?
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_ipv6_peek
|
41
|
+
i = IPv6Packet.new
|
42
|
+
i.ipv6_saddr = "fe80::1"
|
43
|
+
i.ipv6_daddr = "fe80::2"
|
44
|
+
i.ipv6_next = 0x11
|
45
|
+
i.payload = '\x00' * 30
|
46
|
+
i.recalc
|
47
|
+
puts "\n"
|
48
|
+
puts "IPv6 Peek format: "
|
49
|
+
puts i.peek
|
50
|
+
assert_equal 78, i.peek.size
|
51
|
+
end
|
52
|
+
|
53
|
+
=begin
|
54
|
+
def test_ipv6_pcap
|
55
|
+
i = IPPacket.new
|
56
|
+
assert_kind_of IPPacket, i
|
57
|
+
i.recalc
|
58
|
+
i.to_f('ip_test.pcap')
|
59
|
+
i.ip_saddr = "1.2.3.4"
|
60
|
+
i.ip_daddr = "5.6.7.8"
|
61
|
+
i.ip_proto = 94
|
62
|
+
i.payload = "\x23" * 10
|
63
|
+
i.recalc
|
64
|
+
i.to_f('ip_test.pcap','a')
|
65
|
+
end
|
66
|
+
=end
|
67
|
+
end
|
68
|
+
# vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
|
data/test/test_octets.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
4
|
+
require 'packetfu'
|
5
|
+
|
6
|
+
class OctetTest < Test::Unit::TestCase
|
7
|
+
include PacketFu
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@o = Octets.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_create_octets
|
14
|
+
assert_kind_of Octets, @o
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_read
|
18
|
+
s = "\x0a\x0a\x0a\x0b"
|
19
|
+
@o.read s
|
20
|
+
assert_equal(s, @o.to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_dotted
|
24
|
+
s = "\x0a\x0a\x0a\x01"
|
25
|
+
@o.read s
|
26
|
+
assert_equal("10.10.10.1", @o.to_x)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_numerical
|
30
|
+
s = "\x00\x00\x00\x80"
|
31
|
+
@o.read s
|
32
|
+
assert_equal(128, @o.to_i)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
# vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
|
data/test/test_packet.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
4
|
+
require 'packetfu'
|
5
|
+
|
6
|
+
class EthPacketTest < Test::Unit::TestCase
|
7
|
+
include PacketFu
|
8
|
+
|
9
|
+
def test_parse_eth_packet
|
10
|
+
pcaps = PcapFile.new.file_to_array(:f => 'sample.pcap')
|
11
|
+
p = Packet.parse(pcaps[5]) # Really ARP.
|
12
|
+
assert_kind_of(Packet,p)
|
13
|
+
assert_kind_of(EthHeader, p.headers[0])
|
14
|
+
assert p.is_eth?
|
15
|
+
assert p.is_ethernet?
|
16
|
+
assert_equal(pcaps[5],p.to_s)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_parse_arp_request
|
20
|
+
pcaps = PcapFile.new.file_to_array(:f => 'sample.pcap')
|
21
|
+
p = Packet.parse(pcaps[5]) # Really ARP request.
|
22
|
+
assert p.is_eth?
|
23
|
+
assert_kind_of(ARPPacket,p)
|
24
|
+
assert p.is_arp?
|
25
|
+
assert_equal(p.to_s, pcaps[5])
|
26
|
+
assert_equal(1, p.arp_opcode.to_i)
|
27
|
+
assert_equal("\x00\x01", p.headers.last[:arp_opcode].to_s)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_parse_arp_reply
|
31
|
+
pcaps = PcapFile.new.file_to_array(:f => 'sample.pcap')
|
32
|
+
p = Packet.parse(pcaps[6]) # Really ARP reply.
|
33
|
+
assert_equal(p.to_s, pcaps[6])
|
34
|
+
assert_equal(2, p.arp_opcode.to_i)
|
35
|
+
assert_equal("\x00\x02", p.headers.last[:arp_opcode].to_s)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
# vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
|
data/test/test_pcap.rb
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
5
|
+
require 'packetfu'
|
6
|
+
|
7
|
+
class PcapHeaderTest < Test::Unit::TestCase
|
8
|
+
include PacketFu
|
9
|
+
def setup
|
10
|
+
@file = File.open('sample.pcap') {|f| f.read}
|
11
|
+
@file.force_encoding "binary" if @file.respond_to? :force_encoding
|
12
|
+
@file_magic = @file[0,4]
|
13
|
+
@file_header = @file[0,24]
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_header_size
|
17
|
+
assert_equal(24, PcapHeader.new.sz)
|
18
|
+
assert_equal(24, PcapHeader.new.sz)
|
19
|
+
end
|
20
|
+
|
21
|
+
# If this fails, the rest is pretty much for naught.
|
22
|
+
def test_read_file
|
23
|
+
assert_equal("\xd4\xc3\xb2\xa1", @file_magic) # yep, it's libpcap.
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_endian_magic
|
27
|
+
p = PcapHeader.new # usual case
|
28
|
+
assert_equal(@file_magic, p.to_s[0,4])
|
29
|
+
p = PcapHeader.new(:endian => :big)
|
30
|
+
assert_equal("\xa1\xb2\xc3\xd4", p.to_s[0,4])
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_header
|
34
|
+
p = PcapHeader.new
|
35
|
+
assert_equal(@file_header, p.to_s[0,24])
|
36
|
+
p = PcapHeader.new(:endian => :big)
|
37
|
+
assert_not_equal(@file_header, p.to_s[0,24])
|
38
|
+
# We want to ensure our endianness is little or big.
|
39
|
+
assert_raise(ArgumentError) {PcapHeader.new(:endian => :just_right)}
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_header_read
|
43
|
+
p = PcapHeader.new
|
44
|
+
p.read @file
|
45
|
+
assert_equal(@file_header,p.to_s)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
class TimestampTest < Test::Unit::TestCase
|
51
|
+
include PacketFu
|
52
|
+
def setup
|
53
|
+
@file = File.open('sample.pcap') {|f| f.read}
|
54
|
+
@ts = @file[24,8]
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_timestamp_size
|
58
|
+
assert_equal(3, Timestamp.new.size) # Number of elements
|
59
|
+
assert_equal(8, Timestamp.new.sz) # Length of the string (in PacketFu)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_timestamp_read
|
63
|
+
t = Timestamp.new
|
64
|
+
t.read(@ts)
|
65
|
+
assert_equal(@ts, t.to_s)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class PcapPacketTest < Test::Unit::TestCase
|
70
|
+
include PacketFu
|
71
|
+
def setup
|
72
|
+
@file = File.open('sample.pcap') {|f| f.read}
|
73
|
+
@file.force_encoding "binary" if @file.respond_to? :force_encoding
|
74
|
+
@header = @file[0,24]
|
75
|
+
@packet = @file[24,100] # pkt is 78 bytes + 16 bytes pcap hdr == 94
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_pcappacket_read
|
79
|
+
p = PcapPacket.new :endian => :little
|
80
|
+
p.read(@packet)
|
81
|
+
assert_equal(78,@packet[8,4].unpack("V").first)
|
82
|
+
assert_equal(@packet[8,4].unpack("V").first,p[:incl_len].to_i)
|
83
|
+
assert_equal(@packet[0,94],p.to_s)
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
class PcapPacketsTest < Test::Unit::TestCase
|
89
|
+
|
90
|
+
include PacketFu
|
91
|
+
def setup
|
92
|
+
@file = File.open('sample.pcap') {|f| f.read}
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_pcappackets_read
|
96
|
+
p = PcapPackets.new
|
97
|
+
p.read @file
|
98
|
+
assert_equal(11,p.size)
|
99
|
+
assert_equal(@file[24,@file.size],p.to_s)
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
class PcapFileTest < Test::Unit::TestCase
|
105
|
+
require 'digest/md5'
|
106
|
+
|
107
|
+
include PacketFu
|
108
|
+
def setup
|
109
|
+
@file = File.open('sample.pcap') {|f| f.read}
|
110
|
+
@md5 = '1be3b5082bb135c6f22de8801feb3495'
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_pcapfile_read
|
114
|
+
p = PcapFile.new
|
115
|
+
p.read @file
|
116
|
+
assert_equal(3,p.size)
|
117
|
+
assert_equal(@file.size, p.sz)
|
118
|
+
assert_equal(@file, p.to_s)
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_pcapfile_file_to_array
|
122
|
+
p = PcapFile.new.file_to_array(:filename => 'sample.pcap')
|
123
|
+
assert_equal(@md5.downcase, Digest::MD5.hexdigest(@file).downcase)
|
124
|
+
assert_instance_of(Array, p)
|
125
|
+
assert_instance_of(String, p[0])
|
126
|
+
assert_equal(11,p.size)
|
127
|
+
assert_equal(78,p[0].size)
|
128
|
+
assert_equal(94,p[1].size)
|
129
|
+
assert_equal(74,p[10].size)
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_pcapfile_read_and_write
|
133
|
+
File.unlink('out.pcap') if File.exists? 'out.pcap'
|
134
|
+
p = PcapFile.new
|
135
|
+
p.read @file
|
136
|
+
p.to_file(:filename => 'out.pcap')
|
137
|
+
@newfile = File.open('out.pcap') {|f| f.read(f.stat.size)}
|
138
|
+
@newfile.force_encoding "binary" if @newfile.respond_to? :force_encoding
|
139
|
+
assert_equal(@file, @newfile)
|
140
|
+
p.to_file(:filename => 'out.pcap', :append => true)
|
141
|
+
packet_array = PcapFile.new.f2a(:filename => 'out.pcap')
|
142
|
+
assert_equal(22, packet_array.size)
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_pcapfile_write_after_recalc
|
146
|
+
File.unlink('out.pcap') if File.exists? 'out.pcap'
|
147
|
+
pcaps = PcapFile.new.file_to_array(:filename => 'sample.pcap')
|
148
|
+
pcaps.each {|pkt|
|
149
|
+
p = Packet.parse pkt
|
150
|
+
p.recalc
|
151
|
+
p.to_f('out.pcap','a')
|
152
|
+
}
|
153
|
+
packet_array = PcapFile.new.f2a(:filename => 'out.pcap')
|
154
|
+
assert_equal(11, packet_array.size)
|
155
|
+
File.unlink('out.pcap')
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_pcapfile_read_and_write_timestamps
|
159
|
+
File.unlink('out.pcap') if File.exists? 'out.pcap'
|
160
|
+
pf = PcapFile.new
|
161
|
+
arr = pf.file_to_array(:filename => 'sample.pcap')
|
162
|
+
assert_equal(11, arr.size)
|
163
|
+
pf = PcapFile.new
|
164
|
+
pf.a2f(:array => arr, :f => 'out.pcap', :ts_inc => 4,
|
165
|
+
:timestamp => Time.now.to_i - 1_000_000)
|
166
|
+
diff_time = pf.body[0].timestamp.sec.to_i - pf.body[1].timestamp.sec.to_i
|
167
|
+
assert_equal(-4, diff_time)
|
168
|
+
File.unlink('out.pcap')
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
# Test the legacy Read objects.
|
174
|
+
class ReadTest < Test::Unit::TestCase
|
175
|
+
|
176
|
+
include PacketFu
|
177
|
+
|
178
|
+
def test_read_string
|
179
|
+
pkts = Read.file_to_array(:file => 'sample.pcap')
|
180
|
+
assert_kind_of Array, pkts
|
181
|
+
assert_equal 11, pkts.size
|
182
|
+
this_packet = Packet.parse pkts[0]
|
183
|
+
assert_kind_of UDPPacket, this_packet
|
184
|
+
that_packet = Packet.parse pkts[3]
|
185
|
+
assert_kind_of ICMPPacket, that_packet
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_read_hash
|
189
|
+
pkts = Read.file_to_array(:file => 'sample.pcap', :ts => true)
|
190
|
+
assert_kind_of Array, pkts
|
191
|
+
assert_equal 11, pkts.size
|
192
|
+
this_packet = Packet.parse pkts[0].values.first
|
193
|
+
assert_kind_of UDPPacket, this_packet
|
194
|
+
that_packet = Packet.parse pkts[3].values.first
|
195
|
+
assert_kind_of ICMPPacket, that_packet
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
class WriteTest < Test::Unit::TestCase
|
201
|
+
|
202
|
+
include PacketFu
|
203
|
+
|
204
|
+
def test_write
|
205
|
+
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
|
210
|
+
# vim: nowrap sw=2 sts=0 ts=2 ff=unix ft=ruby
|