ffi-pcap 0.2.0 → 0.2.1
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 +2 -1
- data/.pkg_ignore +25 -0
- data/.rspec +1 -0
- data/.specopts +1 -0
- data/.yardopts +1 -0
- data/{ChangeLog.rdoc → ChangeLog.md} +15 -5
- data/LICENSE.txt +1 -4
- data/README.md +92 -0
- data/Rakefile +30 -20
- data/examples/em_selectable_pcap.rb +38 -0
- data/examples/em_timer.rb +26 -0
- data/examples/ipfw_divert.rb +28 -8
- data/examples/print_bytes.rb +5 -1
- data/examples/replay.rb +11 -0
- data/examples/selectable_pcap.rb +29 -0
- data/ffi-pcap.gemspec +60 -0
- data/gemspec.yml +23 -0
- data/lib/ffi/pcap.rb +7 -13
- data/lib/ffi/pcap/addr.rb +16 -15
- data/lib/ffi/pcap/bpf_instruction.rb +25 -0
- data/lib/ffi/pcap/bpf_program.rb +85 -0
- data/lib/ffi/pcap/bsd.rb +9 -98
- data/lib/ffi/pcap/bsd/af.rb +18 -0
- data/lib/ffi/pcap/bsd/in6_addr.rb +16 -0
- data/lib/ffi/pcap/bsd/in_addr.rb +18 -0
- data/lib/ffi/pcap/bsd/sock_addr.rb +19 -0
- data/lib/ffi/pcap/bsd/sock_addr_dl.rb +24 -0
- data/lib/ffi/pcap/bsd/sock_addr_family.rb +19 -0
- data/lib/ffi/pcap/bsd/sock_addr_in.rb +21 -0
- data/lib/ffi/pcap/bsd/sock_addr_in6.rb +20 -0
- data/lib/ffi/pcap/bsd/typedefs.rb +7 -0
- data/lib/ffi/pcap/capture_wrapper.rb +296 -256
- data/lib/ffi/pcap/common_wrapper.rb +152 -127
- data/lib/ffi/pcap/copy_handler.rb +32 -32
- data/lib/ffi/pcap/crt.rb +7 -10
- data/lib/ffi/pcap/data_link.rb +178 -153
- data/lib/ffi/pcap/dead.rb +42 -29
- data/lib/ffi/pcap/dumper.rb +39 -41
- data/lib/ffi/pcap/error_buffer.rb +21 -36
- data/lib/ffi/pcap/exceptions.rb +21 -15
- data/lib/ffi/pcap/file_header.rb +24 -18
- data/lib/ffi/pcap/in_addr.rb +4 -4
- data/lib/ffi/pcap/interface.rb +22 -20
- data/lib/ffi/pcap/live.rb +296 -252
- data/lib/ffi/pcap/offline.rb +50 -43
- data/lib/ffi/pcap/packet.rb +186 -143
- data/lib/ffi/pcap/packet_header.rb +20 -18
- data/lib/ffi/pcap/pcap.rb +269 -212
- data/lib/ffi/pcap/stat.rb +19 -49
- data/lib/ffi/pcap/stat_ex.rb +42 -0
- data/lib/ffi/pcap/time_val.rb +52 -38
- data/lib/ffi/pcap/typedefs.rb +16 -20
- data/spec/data_link_spec.rb +39 -35
- data/spec/dead_spec.rb +0 -4
- data/spec/error_buffer_spec.rb +7 -9
- data/spec/file_header_spec.rb +17 -14
- data/spec/live_spec.rb +12 -5
- data/spec/offline_spec.rb +10 -11
- data/spec/packet_behaviors.rb +20 -6
- data/spec/packet_injection_spec.rb +9 -8
- data/spec/packet_spec.rb +22 -26
- data/spec/pcap_spec.rb +52 -40
- data/spec/spec_helper.rb +16 -5
- data/spec/wrapper_behaviors.rb +0 -3
- data/tasks/doc.rake +69 -0
- data/tasks/gem.rake +200 -0
- data/tasks/git.rake +40 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +286 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- metadata +142 -92
- data/README.rdoc +0 -30
- data/VERSION +0 -1
- data/lib/ffi/pcap/bpf.rb +0 -106
- data/lib/ffi/pcap/version.rb +0 -6
- data/tasks/rcov.rb +0 -6
- data/tasks/rdoc.rb +0 -17
- data/tasks/spec.rb +0 -9
- data/tasks/yard.rb +0 -21
data/lib/ffi/pcap/stat.rb
CHANGED
@@ -1,57 +1,27 @@
|
|
1
|
-
|
2
|
-
module PCap
|
3
|
-
# As returned by pcap_stats()
|
4
|
-
#
|
5
|
-
# See pcap_stat struct in pcap.h.
|
6
|
-
class Stat < FFI::Struct
|
7
|
-
include FFI::DRY::StructHelper
|
8
|
-
|
9
|
-
dsl_layout do
|
10
|
-
field :ps_recv, :uint, :desc => "number of packets received"
|
11
|
-
field :ps_drop, :uint, :desc => "numer of packets dropped"
|
12
|
-
field :ps_ifdrop, :uint, :desc => "drops by interface (not yet supported)"
|
13
|
-
# bs_capt field intentionally left off (WIN32 only)
|
14
|
-
end
|
15
|
-
|
16
|
-
alias received ps_recv
|
17
|
-
alias dropped ps_drop
|
18
|
-
alias interface_dropped ps_ifdrop
|
1
|
+
require 'ffi/pcap/stat_ex'
|
19
2
|
|
20
|
-
|
3
|
+
module FFI
|
4
|
+
module PCap
|
5
|
+
#
|
6
|
+
# As returned by `pcap_stats`.
|
7
|
+
#
|
8
|
+
# See `pcap_stat` struct in `pcap.h`.
|
9
|
+
#
|
10
|
+
class Stat < FFI::Struct
|
21
11
|
|
22
|
-
|
23
|
-
#
|
24
|
-
# See pcap_stat_ex struct in pcap.h
|
25
|
-
class StatEx < FFI::Struct
|
26
|
-
include FFI::DRY::StructHelper
|
12
|
+
include FFI::DRY::StructHelper
|
27
13
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
field :tx_errors, :ulong, :desc => "packet transmit problems"
|
35
|
-
field :rx_dropped, :ulong, :desc => "no space in Rx buffers"
|
36
|
-
field :tx_dropped, :ulong, :desc => "no space available for Tx"
|
37
|
-
field :multicast, :ulong, :desc => "multicast packets received"
|
38
|
-
field :collisions, :ulong
|
14
|
+
dsl_layout do
|
15
|
+
field :ps_recv, :uint, :desc => "number of packets received"
|
16
|
+
field :ps_drop, :uint, :desc => "numer of packets dropped"
|
17
|
+
field :ps_ifdrop, :uint, :desc => "drops by interface (not yet supported)"
|
18
|
+
# bs_capt field intentionally left off (WIN32 only)
|
19
|
+
end
|
39
20
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
field :rx_crc_errors, :ulong, :desc => "pkt with crc error"
|
44
|
-
field :rx_frame_errors, :ulong, :desc => "frame alignment errors"
|
45
|
-
field :rx_fifo_errors, :ulong, :desc => "fifo overrun"
|
46
|
-
field :rx_missed_errors, :ulong, :desc => "missed packet"
|
21
|
+
alias received ps_recv
|
22
|
+
alias dropped ps_drop
|
23
|
+
alias interface_dropped ps_ifdrop
|
47
24
|
|
48
|
-
# detailed tx_errors
|
49
|
-
field :tx_aborted_errors, :ulong
|
50
|
-
field :tx_carrier_errors, :ulong
|
51
|
-
field :tx_fifo_errors, :ulong
|
52
|
-
field :tx_heartbeat_errors, :ulong
|
53
|
-
field :tx_window_errors, :ulong
|
54
25
|
end
|
55
26
|
end
|
56
27
|
end
|
57
|
-
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module FFI
|
2
|
+
module PCap
|
3
|
+
#
|
4
|
+
# As returned by `pcap_stats_ex()` (MSDOS only).
|
5
|
+
#
|
6
|
+
# See `pcap_stat_ex` struct in `pcap.h`.
|
7
|
+
#
|
8
|
+
class StatEx < FFI::Struct
|
9
|
+
|
10
|
+
include FFI::DRY::StructHelper
|
11
|
+
|
12
|
+
dsl_layout do
|
13
|
+
field :rx_packets, :ulong, :desc => "total packets received"
|
14
|
+
field :tx_packets, :ulong, :desc => "total packets transmitted"
|
15
|
+
field :rx_bytes, :ulong, :desc => "total bytes received"
|
16
|
+
field :tx_bytes, :ulong, :desc => "total bytes transmitted"
|
17
|
+
field :rx_errors, :ulong, :desc => "bad packets received"
|
18
|
+
field :tx_errors, :ulong, :desc => "packet transmit problems"
|
19
|
+
field :rx_dropped, :ulong, :desc => "no space in Rx buffers"
|
20
|
+
field :tx_dropped, :ulong, :desc => "no space available for Tx"
|
21
|
+
field :multicast, :ulong, :desc => "multicast packets received"
|
22
|
+
field :collisions, :ulong
|
23
|
+
|
24
|
+
# detailed rx errors
|
25
|
+
field :rx_length_errors, :ulong
|
26
|
+
field :rx_over_errors, :ulong, :desc => "ring buff overflow"
|
27
|
+
field :rx_crc_errors, :ulong, :desc => "pkt with crc error"
|
28
|
+
field :rx_frame_errors, :ulong, :desc => "frame alignment errors"
|
29
|
+
field :rx_fifo_errors, :ulong, :desc => "fifo overrun"
|
30
|
+
field :rx_missed_errors, :ulong, :desc => "missed packet"
|
31
|
+
|
32
|
+
# detailed tx_errors
|
33
|
+
field :tx_aborted_errors, :ulong
|
34
|
+
field :tx_carrier_errors, :ulong
|
35
|
+
field :tx_fifo_errors, :ulong
|
36
|
+
field :tx_heartbeat_errors, :ulong
|
37
|
+
field :tx_window_errors, :ulong
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/ffi/pcap/time_val.rb
CHANGED
@@ -1,48 +1,62 @@
|
|
1
1
|
module FFI
|
2
|
-
module PCap
|
3
|
-
|
4
|
-
include FFI::DRY::StructHelper
|
2
|
+
module PCap
|
3
|
+
class TimeVal < FFI::Struct
|
5
4
|
|
6
|
-
|
7
|
-
field :tv_sec, :time_t
|
8
|
-
field :tv_usec, :suseconds_t
|
9
|
-
end
|
5
|
+
include FFI::DRY::StructHelper
|
10
6
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
else
|
15
|
-
super(*args)
|
7
|
+
dsl_layout do
|
8
|
+
field :tv_sec, :time_t
|
9
|
+
field :tv_usec, :suseconds_t
|
16
10
|
end
|
17
|
-
end
|
18
11
|
|
19
|
-
|
20
|
-
|
12
|
+
#
|
13
|
+
# Initializes the new {TimeVal}.
|
14
|
+
#
|
15
|
+
# @param [Time, FFI::Pointer] timeval
|
16
|
+
# A Time object or a pointer to another {TimeVal}.
|
17
|
+
#
|
18
|
+
def initialize(timeval=nil)
|
19
|
+
case timeval
|
20
|
+
when Time
|
21
|
+
super()
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
Time.at(self.tv_sec, self.tv_usec)
|
28
|
-
end
|
23
|
+
self.time = timeval
|
24
|
+
when Pointer then super(timeval)
|
25
|
+
else super()
|
26
|
+
end
|
27
|
+
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
self.tv_usec = t.tv_usec
|
43
|
-
return t
|
44
|
-
end
|
29
|
+
alias sec tv_sec
|
30
|
+
alias usec tv_usec
|
31
|
+
|
32
|
+
#
|
33
|
+
# Returns the time value as a ruby Time object.
|
34
|
+
#
|
35
|
+
# @return [Time]
|
36
|
+
# A ruby time object derived from this TimeVal.
|
37
|
+
#
|
38
|
+
def time
|
39
|
+
Time.at(self.tv_sec, self.tv_usec)
|
40
|
+
end
|
45
41
|
|
42
|
+
alias to_time time
|
43
|
+
|
44
|
+
#
|
45
|
+
# Sets the time value from a ruby Time object
|
46
|
+
#
|
47
|
+
# @param [Time] new_time
|
48
|
+
# A ruby time object from which to set the time.
|
49
|
+
#
|
50
|
+
# @return [Time]
|
51
|
+
# Returns the same Time object supplied per convention.
|
52
|
+
#
|
53
|
+
def time=(new_time)
|
54
|
+
self.tv_sec = new_time.tv_sec
|
55
|
+
self.tv_usec = new_time.tv_usec
|
56
|
+
|
57
|
+
return new_time
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
46
61
|
end
|
47
62
|
end
|
48
|
-
end
|
data/lib/ffi/pcap/typedefs.rb
CHANGED
@@ -1,27 +1,23 @@
|
|
1
1
|
module FFI
|
2
|
-
module PCap
|
3
|
-
|
2
|
+
module PCap
|
3
|
+
extend FFI::Library
|
4
4
|
|
5
|
-
|
6
|
-
typedef :uint, :bpf_uint32
|
5
|
+
typedef :pointer, :FILE
|
7
6
|
|
8
|
-
|
9
|
-
:
|
10
|
-
:pcap_d_in,
|
11
|
-
:pcap_d_out
|
12
|
-
]
|
7
|
+
typedef :int, :bpf_int32
|
8
|
+
typedef :uint, :bpf_uint32
|
13
9
|
|
14
|
-
|
15
|
-
|
10
|
+
enum :pcap_direction_t, [
|
11
|
+
:pcap_d_inout,
|
12
|
+
:pcap_d_in,
|
13
|
+
:pcap_d_out
|
14
|
+
]
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
typedef :pointer, :pcap_addr_t
|
16
|
+
# For Win32-only pcap_setmode()
|
17
|
+
enum :pcap_w32_modes_enum, [ :capt, :stat, :mon ]
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
19
|
+
typedef :pointer, :pcap_t
|
20
|
+
typedef :pointer, :pcap_dumper_t
|
21
|
+
typedef :pointer, :pcap_addr_t
|
22
|
+
end
|
27
23
|
end
|
data/spec/data_link_spec.rb
CHANGED
@@ -1,65 +1,69 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe DataLink do
|
4
|
-
|
5
|
-
@datalink = DataLink.new(0)
|
6
|
-
end
|
4
|
+
subject { described_class.new(0) }
|
7
5
|
|
8
6
|
it "should map datalink names to datalink layer type values" do
|
9
|
-
|
7
|
+
described_class.name_to_val(:en10mb).should == 1
|
10
8
|
end
|
11
9
|
|
12
10
|
it "should map datalink layer type values to datalink names" do
|
13
|
-
|
11
|
+
described_class.val_to_name(1).should == "EN10MB"
|
14
12
|
end
|
15
13
|
|
16
14
|
it "should be initialized from a pcap datalink value" do
|
17
|
-
|
15
|
+
subject.name.should == 'NULL'
|
18
16
|
end
|
19
17
|
|
20
|
-
it "should
|
21
|
-
|
22
|
-
DataLink.should === @datalink
|
18
|
+
it "should have a description" do
|
19
|
+
subject.description.should_not be_empty
|
23
20
|
end
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
22
|
+
describe "#initialize" do
|
23
|
+
it "should support initialization from a pcap datalink name Symbol" do
|
24
|
+
link = described_class.new(:null)
|
29
25
|
|
30
|
-
|
31
|
-
|
32
|
-
(@datalink == 1).should == false
|
33
|
-
end
|
26
|
+
link.name.should == 'NULL'
|
27
|
+
end
|
34
28
|
|
35
|
-
|
36
|
-
|
37
|
-
|
29
|
+
it "should support initialization from a pcap datalink name String" do
|
30
|
+
link = described_class.new('en10mb')
|
31
|
+
|
32
|
+
link.name.should == 'EN10MB'
|
33
|
+
end
|
38
34
|
end
|
39
35
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
36
|
+
describe "#==" do
|
37
|
+
it "should allow equality comparison against numeric values" do
|
38
|
+
(subject == 0).should == true
|
39
|
+
(subject == 1).should == false
|
40
|
+
end
|
44
41
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
42
|
+
it "should allow equality comparison against String names" do
|
43
|
+
(subject == "null").should == true
|
44
|
+
(subject == "en10mb").should == false
|
45
|
+
end
|
49
46
|
|
50
|
-
|
51
|
-
|
52
|
-
|
47
|
+
it "should allow equality comparison against Symbol names" do
|
48
|
+
(subject == :null).should == true
|
49
|
+
(subject == :en10mb).should == false
|
50
|
+
end
|
53
51
|
|
54
|
-
|
55
|
-
|
52
|
+
it "should allow comparison against another described_class" do
|
53
|
+
(subject == described_class.new(0)).should == true
|
54
|
+
(subject == described_class.new(1)).should == false
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should still compare correctly against any other object" do
|
58
|
+
(subject == Object.new).should == false
|
59
|
+
end
|
56
60
|
end
|
57
61
|
|
58
62
|
it "should convert to an Integer for the DLT value" do
|
59
|
-
|
63
|
+
subject.to_i.should == 0
|
60
64
|
end
|
61
65
|
|
62
66
|
it "should convert to a String for the DLT name" do
|
63
|
-
|
67
|
+
subject.to_s.should == 'NULL'
|
64
68
|
end
|
65
69
|
end
|
data/spec/dead_spec.rb
CHANGED
data/spec/error_buffer_spec.rb
CHANGED
@@ -1,17 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ErrorBuffer do
|
4
|
-
|
5
|
-
|
6
|
-
end
|
7
|
-
|
8
|
-
it "should have a size of 256" do
|
9
|
-
@errbuf.size.should == 256
|
4
|
+
it "should have a default size of 256" do
|
5
|
+
subject.size.should == 256
|
10
6
|
end
|
11
7
|
|
12
8
|
it "should return an error message with to_s" do
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
subject.to_s.should be_empty
|
10
|
+
|
11
|
+
PCap.pcap_open_offline("/this/file/wont/exist",subject)
|
12
|
+
|
13
|
+
subject.to_s.should_not be_empty
|
16
14
|
end
|
17
15
|
end
|
data/spec/file_header_spec.rb
CHANGED
@@ -1,28 +1,31 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe FileHeader do
|
4
|
-
|
5
|
-
|
4
|
+
let(:pcap_file) do
|
5
|
+
File.open(PCAP_TESTFILE,'rb') do |file|
|
6
|
+
file.read
|
7
|
+
end
|
6
8
|
end
|
7
9
|
|
10
|
+
subject { described_class.new(:raw => pcap_file) }
|
11
|
+
|
8
12
|
it "should parse a pcap file correctly" do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
subject.magic.should == 0xa1b2c3d4
|
14
|
+
subject.version_major.should == 2
|
15
|
+
subject.version_minor.should == 4
|
16
|
+
subject.thiszone.should == 0
|
17
|
+
subject.sigfigs.should == 0
|
18
|
+
subject.snaplen.should == 96
|
19
|
+
subject.linktype.should == 1
|
16
20
|
end
|
17
21
|
|
18
22
|
it "should return a file format version string" do
|
19
|
-
|
20
|
-
@file_header.version.should == "2.4"
|
23
|
+
subject.version.should == "2.4"
|
21
24
|
end
|
22
25
|
|
23
26
|
it "should return a DataLink for the linktype using datalink()" do
|
24
|
-
|
25
|
-
(@file_header.datalink == :en10mb).should == true
|
26
|
-
end
|
27
|
+
subject.datalink.should be_kind_of(DataLink)
|
27
28
|
|
29
|
+
(subject.datalink == :en10mb).should == true
|
30
|
+
end
|
28
31
|
end
|