packetfu 1.1.10 → 1.1.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -0
  4. data/.gitignore +3 -0
  5. data/.travis.yml +8 -0
  6. data/CONTRIBUTING.md +47 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +1 -1
  9. data/README.rdoc +35 -30
  10. data/Rakefile +4 -4
  11. data/bench/octets.rb +9 -9
  12. data/examples/100kpackets.rb +12 -12
  13. data/examples/ackscan.rb +16 -16
  14. data/examples/arp.rb +35 -35
  15. data/examples/arphood.rb +36 -36
  16. data/examples/dissect_thinger.rb +6 -6
  17. data/examples/new-simple-stats.rb +23 -23
  18. data/examples/packetfu-shell.rb +25 -25
  19. data/examples/simple-sniffer.rb +9 -9
  20. data/examples/simple-stats.rb +23 -23
  21. data/examples/slammer.rb +3 -3
  22. data/gem-public_cert.pem +21 -0
  23. data/lib/packetfu.rb +149 -127
  24. data/lib/packetfu/capture.rb +169 -169
  25. data/lib/packetfu/config.rb +52 -52
  26. data/lib/packetfu/inject.rb +56 -56
  27. data/lib/packetfu/packet.rb +531 -528
  28. data/lib/packetfu/pcap.rb +579 -579
  29. data/lib/packetfu/protos/arp.rb +90 -90
  30. data/lib/packetfu/protos/arp/header.rb +158 -158
  31. data/lib/packetfu/protos/arp/mixin.rb +36 -36
  32. data/lib/packetfu/protos/eth.rb +44 -44
  33. data/lib/packetfu/protos/eth/header.rb +243 -243
  34. data/lib/packetfu/protos/eth/mixin.rb +3 -3
  35. data/lib/packetfu/protos/hsrp.rb +69 -69
  36. data/lib/packetfu/protos/hsrp/header.rb +107 -107
  37. data/lib/packetfu/protos/hsrp/mixin.rb +29 -29
  38. data/lib/packetfu/protos/icmp.rb +71 -71
  39. data/lib/packetfu/protos/icmp/header.rb +82 -82
  40. data/lib/packetfu/protos/icmp/mixin.rb +14 -14
  41. data/lib/packetfu/protos/invalid.rb +49 -49
  42. data/lib/packetfu/protos/ip.rb +69 -69
  43. data/lib/packetfu/protos/ip/header.rb +291 -291
  44. data/lib/packetfu/protos/ip/mixin.rb +40 -40
  45. data/lib/packetfu/protos/ipv6.rb +50 -50
  46. data/lib/packetfu/protos/ipv6/header.rb +188 -188
  47. data/lib/packetfu/protos/ipv6/mixin.rb +29 -29
  48. data/lib/packetfu/protos/tcp.rb +176 -176
  49. data/lib/packetfu/protos/tcp/ecn.rb +35 -35
  50. data/lib/packetfu/protos/tcp/flags.rb +74 -74
  51. data/lib/packetfu/protos/tcp/header.rb +268 -268
  52. data/lib/packetfu/protos/tcp/hlen.rb +32 -32
  53. data/lib/packetfu/protos/tcp/mixin.rb +46 -46
  54. data/lib/packetfu/protos/tcp/option.rb +321 -321
  55. data/lib/packetfu/protos/tcp/options.rb +95 -95
  56. data/lib/packetfu/protos/tcp/reserved.rb +35 -35
  57. data/lib/packetfu/protos/udp.rb +159 -123
  58. data/lib/packetfu/protos/udp/header.rb +91 -91
  59. data/lib/packetfu/protos/udp/mixin.rb +3 -3
  60. data/lib/packetfu/structfu.rb +280 -280
  61. data/lib/packetfu/utils.rb +292 -225
  62. data/lib/packetfu/version.rb +41 -41
  63. data/packetfu.gemspec +14 -3
  64. data/spec/arp_spec.rb +191 -0
  65. data/spec/eth_spec.rb +148 -0
  66. data/spec/icmp_spec.rb +97 -0
  67. data/spec/ip_spec.rb +78 -0
  68. data/spec/ipv6_spec.rb +81 -0
  69. data/spec/packet_spec.rb +61 -59
  70. data/spec/packet_subclasses_spec.rb +9 -10
  71. data/spec/packetfu_spec.rb +55 -62
  72. data/spec/sample3.pcap +0 -0
  73. data/spec/spec_helper.rb +44 -0
  74. data/spec/structfu_spec.rb +270 -271
  75. data/spec/tcp_spec.rb +76 -77
  76. data/spec/udp_spec.rb +32 -0
  77. data/spec/utils_spec.rb +95 -0
  78. data/test/all_tests.rb +14 -17
  79. data/test/func_lldp.rb +3 -3
  80. data/test/ptest.rb +2 -2
  81. data/test/test_capture.rb +45 -45
  82. data/test/test_eth.rb +70 -68
  83. data/test/test_hsrp.rb +9 -9
  84. data/test/test_inject.rb +18 -18
  85. data/test/test_invalid.rb +16 -16
  86. data/test/test_octets.rb +23 -21
  87. data/test/test_packet.rb +156 -154
  88. data/test/test_pcap.rb +172 -170
  89. data/test/test_structfu.rb +99 -97
  90. data/test/test_tcp.rb +322 -320
  91. data/test/test_udp.rb +78 -76
  92. metadata +108 -44
  93. metadata.gz.sig +2 -0
  94. data/spec/ethpacket_spec.rb +0 -74
  95. data/test/test_arp.rb +0 -135
  96. data/test/test_icmp.rb +0 -62
  97. data/test/test_ip.rb +0 -50
  98. data/test/test_ip6.rb +0 -68
@@ -1,51 +1,51 @@
1
1
  # -*- coding: binary -*-
2
2
  module PacketFu
3
3
 
4
- # Check the repo's for version release histories
5
- VERSION = "1.1.10"
4
+ # Check the repo's for version release histories
5
+ VERSION = "1.1.11"
6
6
 
7
- # Returns PacketFu::VERSION
8
- def self.version
9
- VERSION
10
- end
7
+ # Returns PacketFu::VERSION
8
+ def self.version
9
+ VERSION
10
+ end
11
11
 
12
- # Returns a version string in a binary format for easy comparisons.
13
- def self.binarize_version(str)
14
- if(str.respond_to?(:split) && str =~ /^[0-9]+(\.([0-9]+)(\.[0-9]+)?)?\..+$/)
15
- bin_major,bin_minor,bin_teeny = str.split(/\x2e/).map {|x| x.to_i}
16
- bin_version = (bin_major.to_i << 16) + (bin_minor.to_i << 8) + bin_teeny.to_i
17
- else
18
- raise ArgumentError, "Compare version malformed. Should be \x22x.y.z\x22"
19
- end
20
- end
12
+ # Returns a version string in a binary format for easy comparisons.
13
+ def self.binarize_version(str)
14
+ if(str.respond_to?(:split) && str =~ /^[0-9]+(\.([0-9]+)(\.[0-9]+)?)?\..+$/)
15
+ bin_major,bin_minor,bin_teeny = str.split(/\x2e/).map {|x| x.to_i}
16
+ bin_version = (bin_major.to_i << 16) + (bin_minor.to_i << 8) + bin_teeny.to_i
17
+ else
18
+ raise ArgumentError, "Compare version malformed. Should be \x22x.y.z\x22"
19
+ end
20
+ end
21
21
 
22
- # Returns true if the version is equal to or greater than the compare version.
23
- # If the current version of PacketFu is "0.3.1" for example:
24
- #
25
- # PacketFu.at_least? "0" # => true
26
- # PacketFu.at_least? "0.2.9" # => true
27
- # PacketFu.at_least? "0.3" # => true
28
- # PacketFu.at_least? "1" # => true after 1.0's release
29
- # PacketFu.at_least? "1.12" # => false
30
- # PacketFu.at_least? "2" # => false
31
- def self.at_least?(str)
32
- this_version = binarize_version(self.version)
33
- ask_version = binarize_version(str)
34
- this_version >= ask_version
35
- end
22
+ # Returns true if the version is equal to or greater than the compare version.
23
+ # If the current version of PacketFu is "0.3.1" for example:
24
+ #
25
+ # PacketFu.at_least? "0" # => true
26
+ # PacketFu.at_least? "0.2.9" # => true
27
+ # PacketFu.at_least? "0.3" # => true
28
+ # PacketFu.at_least? "1" # => true after 1.0's release
29
+ # PacketFu.at_least? "1.12" # => false
30
+ # PacketFu.at_least? "2" # => false
31
+ def self.at_least?(str)
32
+ this_version = binarize_version(self.version)
33
+ ask_version = binarize_version(str)
34
+ this_version >= ask_version
35
+ end
36
36
 
37
- # Returns true if the current version is older than the compare version.
38
- def self.older_than?(str)
39
- return false if str == self.version
40
- this_version = binarize_version(self.version)
41
- ask_version = binarize_version(str)
42
- this_version < ask_version
43
- end
37
+ # Returns true if the current version is older than the compare version.
38
+ def self.older_than?(str)
39
+ return false if str == self.version
40
+ this_version = binarize_version(self.version)
41
+ ask_version = binarize_version(str)
42
+ this_version < ask_version
43
+ end
44
44
 
45
- # Returns true if the current version is newer than the compare version.
46
- def self.newer_than?(str)
47
- return false if str == self.version
48
- !self.older_than?(str)
49
- end
45
+ # Returns true if the current version is newer than the compare version.
46
+ def self.newer_than?(str)
47
+ return false if str == self.version
48
+ !self.older_than?(str)
49
+ end
50
50
 
51
51
  end
@@ -12,11 +12,22 @@ Gem::Specification.new do |s|
12
12
  s.files = `git ls-files`.split($/)
13
13
  s.license = 'BSD'
14
14
 
15
- s.add_development_dependency('pcaprub', '>= 0.9.2')
16
- s.add_development_dependency('rspec', '>= 2.6.2')
17
- s.add_development_dependency('sdoc', '>= 0.2.0')
15
+ s.add_dependency('network_interface', '~> 0.0')
16
+ s.add_dependency('pcaprub', '~> 0.12')
17
+ s.add_development_dependency('rake', '~> 10.3')
18
+ s.add_development_dependency('rspec', '~> 3.0')
19
+ s.add_development_dependency('rspec-its', '~> 1.2')
20
+ s.add_development_dependency('sdoc', '~> 0.4.1')
18
21
 
19
22
  s.extra_rdoc_files = %w[.document README.rdoc]
20
23
  s.test_files = (s.files & (Dir['spec/**/*_spec.rb'] + Dir['test/test_*.rb']) )
21
24
  s.rubyforge_project = 'packetfu'
25
+
26
+ cert = File.expand_path("~/.ssh/gem-private_key_todb.pem")
27
+
28
+ if File.exist?(cert) and File.readable?(cert)
29
+ s.signing_key = cert
30
+ s.cert_chain = ['gem-public_cert.pem']
31
+ end
32
+
22
33
  end
@@ -0,0 +1,191 @@
1
+ # -*- coding: binary -*-
2
+ require 'spec_helper'
3
+ require 'tempfile'
4
+
5
+ include PacketFu
6
+
7
+ describe ARPHeader do
8
+ context "when initializing ARPHeader" do
9
+ before :each do
10
+ @arp_header = ARPHeader.new
11
+ end
12
+
13
+ it "should have the correct classes for initialization values" do
14
+ expect(@arp_header).to be_kind_of(ARPHeader)
15
+ expect(@arp_header[:arp_hw]).to be_kind_of(StructFu::Int16)
16
+ expect(@arp_header.arp_hw).to be_kind_of(Fixnum)
17
+ expect(@arp_header[:arp_src_ip]).to be_kind_of(Octets)
18
+ expect(@arp_header.arp_src_ip).to be_kind_of(String)
19
+ expect(@arp_header[:arp_dst_mac]).to be_kind_of(EthMac)
20
+ expect(@arp_header.body).to be_kind_of(StructFu::String)
21
+ end
22
+ end
23
+
24
+ context "when parsing ARPHeader from the wire" do
25
+ before :each do
26
+ @arp_header = ARPHeader.new
27
+ end
28
+
29
+ it "should be able to parse an ARPHeader from string I/O" do
30
+ hexified_arp_header = "000108000604000200032f1a74dec0a80102001b1151b7cec0a80169"
31
+ raw_arp_header = hexified_arp_header.scan(/../).map {|x| x.to_i(16)}.pack("C*")
32
+
33
+ @arp_header.read(raw_arp_header)
34
+ expect(@arp_header.to_s).to eql(raw_arp_header)
35
+ expect(@arp_header.arp_daddr_ip).to eql("192.168.1.105")
36
+ expect(@arp_header.arp_saddr_ip).to eql("192.168.1.2")
37
+ expect(@arp_header.arp_daddr_mac).to eql("00:1b:11:51:b7:ce")
38
+ expect(@arp_header.arp_saddr_mac).to eql("00:03:2f:1a:74:de")
39
+ end
40
+ end
41
+ end
42
+
43
+ describe ARPPacket do
44
+ context "when initializing ARPPacket" do
45
+ before :each do
46
+ @arp_packet = ARPPacket.new
47
+ end
48
+
49
+ it "should have the correct values for initialization" do
50
+ expect(@arp_packet).to be_kind_of(ARPPacket)
51
+ expect(@arp_packet.arp_saddr_ip).to eql("0.0.0.0")
52
+ expect(@arp_packet.arp_daddr_ip).to eql("0.0.0.0")
53
+ expect(@arp_packet.arp_src_ip).to eql("\x00\x00\x00\x00")
54
+ expect(@arp_packet.arp_dst_ip).to eql("\x00\x00\x00\x00")
55
+ end
56
+
57
+ it "should allow setting values at initialization" do
58
+ opts_hash = {
59
+ :arp_hw => 1,
60
+ :arp_proto => 0x0800,
61
+ :arp_opcode => 2,
62
+ :arp_src_ip => "\xc0\xa8\x01\x02"
63
+ }
64
+ arp = ARPPacket.new(opts_hash)
65
+
66
+ expect(@arp_packet.arp_hw).to eql(opts_hash[:arp_hw])
67
+ expect(@arp_packet.arp_proto).to eql(opts_hash[:arp_proto])
68
+
69
+ # TODO: Fix the bug that is preventing these values from setting
70
+ #expect(@arp_packet.arp_opcode).to eql(opts_hash[:arp_opcode])
71
+ #expect(@arp_packet.arp_src_ip).to eql(opts_hash[:arp_src_ip])
72
+ end
73
+
74
+ it "should have the ability to set IP addresses" do
75
+ @arp_packet.arp_saddr_ip = "1.2.3.4"
76
+ @arp_packet.arp_daddr_ip = "5.6.7.8"
77
+
78
+ expect(@arp_packet.arp_saddr_ip).to eql("1.2.3.4")
79
+ expect(@arp_packet.arp_daddr_ip).to eql("5.6.7.8")
80
+ expect(@arp_packet.arp_src_ip).to eql("\x01\x02\x03\x04")
81
+ expect(@arp_packet.arp_dst_ip).to eql("\x05\x06\x07\x08")
82
+ end
83
+
84
+ it "should support peek formatting" do
85
+ expect(@arp_packet.peek).to match(/A\s+60\s+00:01:ac:00:00:00\(0.0.0.0\)\->00:01:ac:00:00:00\(0\.0\.0\.0\):Requ/)
86
+ end
87
+ end
88
+
89
+ context "when setting attributes on ARPPacket" do
90
+ before :each do
91
+ @arp_packet = ARPPacket.new
92
+ end
93
+
94
+ it "should allow the setting of IP addresses" do
95
+ @arp_packet.arp_saddr_ip = "1.2.3.4"
96
+ @arp_packet.arp_daddr_ip = "5.6.7.8"
97
+
98
+ expect(@arp_packet.arp_saddr_ip).to eql("1.2.3.4")
99
+ expect(@arp_packet.arp_daddr_ip).to eql("5.6.7.8")
100
+ expect(@arp_packet.arp_src_ip).to eql("\x01\x02\x03\x04")
101
+ expect(@arp_packet.arp_dst_ip).to eql("\x05\x06\x07\x08")
102
+ end
103
+
104
+ it "should allow the setting of MAC addresses" do
105
+ @arp_packet.arp_saddr_mac = "00:01:02:03:04:05"
106
+ @arp_packet.arp_daddr_mac = "00:06:07:08:09:0a"
107
+
108
+ expect(@arp_packet.arp_saddr_mac).to eql("00:01:02:03:04:05")
109
+ expect(@arp_packet.arp_daddr_mac).to eql("00:06:07:08:09:0a")
110
+ expect(@arp_packet.arp_src_mac).to eql("\x00\x01\x02\x03\x04\x05")
111
+ expect(@arp_packet.arp_dst_mac).to eql("\x00\x06\x07\x08\x09\x0a")
112
+ end
113
+
114
+ it "should allow the setting of all attributes" do
115
+ hexified_arp_packet = "000108000604000200032f1a74dec0a80102001b1151b7cec0a80169"
116
+ raw_arp_packet = hexified_arp_packet.scan(/../).map {|x| x.to_i(16)}.pack("C*")
117
+
118
+ @arp_packet.arp_hw = 1
119
+ @arp_packet.arp_proto = 0x0800
120
+ @arp_packet.arp_hw_len = 6
121
+ @arp_packet.arp_proto_len = 4
122
+ @arp_packet.arp_opcode = 2
123
+ @arp_packet.arp_src_mac = "\x00\x03\x2f\x1a\x74\xde"
124
+ @arp_packet.arp_src_ip = "\xc0\xa8\x01\x02"
125
+ @arp_packet.arp_dst_mac = "\x00\x1b\x11\x51\xb7\xce"
126
+ @arp_packet.arp_dst_ip = "\xc0\xa8\x01\x69"
127
+ @arp_packet.payload = ""
128
+ expect(@arp_packet.to_s[14,0xffff]).to eql(raw_arp_packet)
129
+ end
130
+
131
+ context "when setting arp flavors" do
132
+ before :each do
133
+ @arp_packet = ARPPacket.new
134
+ end
135
+
136
+ it "should have a sane default" do
137
+ expect(@arp_packet.payload).to eql("\x00" * 18)
138
+ end
139
+
140
+ it "should support a Windows flavor" do
141
+ @arp_packet = ARPPacket.new(:flavor => "Windows")
142
+ expect(@arp_packet.payload).to eql("\x00" * 64)
143
+ end
144
+
145
+ it "should support a Linux flavor" do
146
+ @arp_packet = ARPPacket.new(:flavor => "Linux")
147
+ expect(@arp_packet.payload.size).to eql(32)
148
+ end
149
+
150
+ it "should support a HP Deskjet flavor" do
151
+ @arp_packet = ARPPacket.new(:flavor => :hp_deskjet)
152
+ expect(@arp_packet.payload.size).to eql(18)
153
+ end
154
+ end
155
+ end
156
+
157
+ context "when parsing ARPPacket from the wire" do
158
+ before :each do
159
+ @arp_packet = ARPPacket.new
160
+ end
161
+
162
+ it "should be able to parse an ARPPacket from string I/O" do
163
+ hexified_arp_packet = "001b1151b7ce00032f1a74de0806000108000604000200032f1a74dec0a80102001b1151b7cec0a80169c0a80169"
164
+ raw_arp_packet = hexified_arp_packet.scan(/../).map {|x| x.to_i(16)}.pack("C*")
165
+
166
+ @arp_packet.read(raw_arp_packet)
167
+ expect(@arp_packet.to_s).to eql(raw_arp_packet)
168
+ expect(@arp_packet.payload).to eql("\xC0\xA8\x01i")
169
+ expect(@arp_packet.arp_daddr_ip).to eql("192.168.1.105")
170
+ expect(@arp_packet.arp_saddr_ip).to eql("192.168.1.2")
171
+ expect(@arp_packet.arp_daddr_mac).to eql("00:1b:11:51:b7:ce")
172
+ expect(@arp_packet.arp_saddr_mac).to eql("00:03:2f:1a:74:de")
173
+ end
174
+ end
175
+
176
+ context "when writing ARPPacket to PCAP" do
177
+ before :each do
178
+ @arp_packet = ARPPacket.new
179
+ end
180
+
181
+ it "should write a PCAP file to disk" do
182
+ @arp_packet.recalc
183
+ arp_pcap_file = Tempfile.new('arp_pcap')
184
+ expect(arp_pcap_file.read).to eql("")
185
+
186
+ @arp_packet.to_f(arp_pcap_file, 'a')
187
+ expect(File.exists?('arp_pcap'))
188
+ expect(arp_pcap_file.read.size).to be >= 76
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,148 @@
1
+ # -*- coding: binary -*-
2
+ require 'spec_helper'
3
+ require 'tempfile'
4
+
5
+ include PacketFu
6
+
7
+ describe EthMac do
8
+ context "when creating an object from scratch" do
9
+ before :each do
10
+ @eth_mac = EthMac.new
11
+ end
12
+
13
+ it "should have sane defaults" do
14
+ expect(@eth_mac.oui).to be_kind_of(EthOui)
15
+ expect(@eth_mac.oui.oui).to eql(428)
16
+ expect(@eth_mac.nic).to be_kind_of(EthNic)
17
+ expect(@eth_mac.nic.to_s).to eql("\x00\x00\x00")
18
+ end
19
+ end
20
+
21
+ context "when parsing EthMac from the wire" do
22
+ before :each do
23
+ @eth_mac = EthMac.new
24
+ end
25
+
26
+ it "should parse from string i/o (Example 1)" do
27
+ dst = "\x00\x03\x2f\x1a\x74\xde"
28
+ @eth_mac.read(dst)
29
+
30
+ expect(@eth_mac).to be_kind_of(EthMac)
31
+ expect(@eth_mac.to_s).to eql(dst)
32
+ expect(@eth_mac.oui.oui).to eql(0x32f)
33
+ expect(@eth_mac.nic.to_s).to eql("\x1At\xDE".force_encoding('binary'))
34
+ expect(@eth_mac.nic.n2).to eql(222)
35
+ end
36
+
37
+ it "should parse from an ipad" do
38
+ dst = "\x7c\x6d\x62\x01\x02\x03"
39
+ @eth_mac.read(dst)
40
+
41
+ expect(@eth_mac).to be_kind_of(EthMac)
42
+ expect(@eth_mac.to_s).to eql(dst)
43
+ expect(@eth_mac.oui.oui).to eql(0x6d62)
44
+ end
45
+ end
46
+
47
+ end
48
+
49
+ describe EthHeader do
50
+ context "when creating an object from scratch" do
51
+ before :each do
52
+ @eth_header = EthHeader.new
53
+ end
54
+
55
+ it "should have sane defaults" do
56
+ expect(@eth_header).to be_kind_of(EthHeader)
57
+ expect(@eth_header.eth_src).to eql("\x00\x01\xAC\x00\x00\x00".force_encoding('binary'))
58
+ expect(@eth_header.eth_dst).to eql("\x00\x01\xAC\x00\x00\x00".force_encoding('binary'))
59
+ expect(@eth_header.eth_proto).to eql(2048)
60
+ end
61
+
62
+ it "should allow setting of the dstmac" do
63
+ dst = "\x00\x03\x2f\x1a\x74\xde"
64
+ dstmac = "00:03:2f:1a:74:de"
65
+
66
+ expect(EthHeader.str2mac(dst)).to eql(dstmac)
67
+ expect(EthHeader.mac2str(dstmac)).to eql(dst)
68
+ end
69
+ end
70
+ end
71
+
72
+ describe EthPacket do
73
+ context "when creating an object from scratch" do
74
+ before :each do
75
+ @eth_packet = EthPacket.new
76
+ end
77
+
78
+ it "should have sane defaults" do
79
+ expect(@eth_packet.eth_dst).to eql("\x00\x01\xAC\x00\x00\x00")
80
+ expect(@eth_packet.eth_src).to eql("\x00\x01\xAC\x00\x00\x00")
81
+ expect(@eth_packet.eth_proto).to eql(2048)
82
+ end
83
+
84
+ it "should be able to match a predefined eth_packet via string i/o" do
85
+ raw_header = "00032f1a74de001b1151b7ce0800".scan(/../).map { |x| x.to_i(16) }.pack("C*")
86
+
87
+ expect(@eth_packet).to be_kind_of(EthPacket)
88
+ expect(@eth_packet.headers[0]).to be_kind_of(EthHeader)
89
+ expect(@eth_packet.is_eth?).to be true
90
+ expect(@eth_packet.is_tcp?).to be false
91
+
92
+ @eth_packet.eth_dst = "\x00\x03\x2f\x1a\x74\xde"
93
+ @eth_packet.eth_src = "\x00\x1b\x11\x51\xb7\xce"
94
+ @eth_packet.eth_proto = 0x0800
95
+
96
+ expect(@eth_packet.to_s[0,14]).to eql(raw_header)
97
+ end
98
+
99
+ it "should be able to match a predefined eth_packet via opts" do
100
+ raw_header = "00032f1a74de001b1151b7ce0800".scan(/../).map { |x| x.to_i(16) }.pack("C*")
101
+
102
+ @eth_packet = EthPacket.new(
103
+ :eth_dst => "\x00\x03\x2f\x1a\x74\xde",
104
+ :eth_src => "\x00\x1b\x11\x51\xb7\xce",
105
+ :eth_proto => 0x0800
106
+ )
107
+
108
+ expect(@eth_packet.to_s[0,14]).to eql(raw_header)
109
+ end
110
+ end
111
+
112
+ context "when reading/writing PCAP to file" do
113
+ it "should write a pcap file to disk" do
114
+ @eth_packet = EthPacket.new(
115
+ :eth_dst => "\x00\x03\x2f\x1a\x74\xde",
116
+ :eth_src => "\x00\x1b\x11\x51\xb7\xce",
117
+ :eth_proto => 0x0800
118
+ )
119
+
120
+ @eth_packet.recalc
121
+ eth_pcap_file = Tempfile.new('eth_pcap')
122
+ expect(eth_pcap_file.read).to eql("")
123
+
124
+ @eth_packet.to_f(eth_pcap_file, 'a')
125
+ expect(File.exists?('eth_pcap'))
126
+ expect(eth_pcap_file.read.size).to be >= 30
127
+ end
128
+
129
+ it "should read a pcap file to create ethpacket" do
130
+ parsed_packets = PcapFile.read_packets("./test/sample.pcap")
131
+ @eth_packet = parsed_packets.first
132
+
133
+ expect(@eth_packet).to be_kind_of(EthPacket)
134
+ expect(@eth_packet.eth_daddr).to eql("00:03:2f:1a:74:de")
135
+ expect(@eth_packet.eth_saddr).to eql("00:1b:11:51:b7:ce")
136
+ expect(@eth_packet.size).to eql(78)
137
+ expect(@eth_packet.headers.first.body).to be_kind_of(PacketFu::IPHeader)
138
+ expect(@eth_packet.headers.first.members).to eql([:eth_dst, :eth_src, :eth_proto, :body])
139
+ end
140
+
141
+ it "should read a vlan encapsulated ethpacket as an invalid packet" do
142
+ parsed_packets = PcapFile.read_packets("./test/vlan-pcapr.cap")
143
+ @eth_packet = parsed_packets.first
144
+
145
+ expect(@eth_packet).to be_kind_of(InvalidPacket)
146
+ end
147
+ end
148
+ end