dakrone-pcap-ffi 0.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/.gitignore +6 -0
- data/History.txt +4 -0
- data/Manifest.txt +40 -0
- data/README.txt +41 -0
- data/Rakefile +24 -0
- data/VERSION +1 -0
- data/examples/print_bytes.rb +17 -0
- data/lib/pcap/addr.rb +37 -0
- data/lib/pcap/data_link.rb +53 -0
- data/lib/pcap/dumper.rb +39 -0
- data/lib/pcap/error_buffer.rb +26 -0
- data/lib/pcap/exceptions/read_error.rb +6 -0
- data/lib/pcap/exceptions.rb +1 -0
- data/lib/pcap/ffi.rb +78 -0
- data/lib/pcap/file_header.rb +17 -0
- data/lib/pcap/handler.rb +170 -0
- data/lib/pcap/if.rb +36 -0
- data/lib/pcap/in_addr.rb +13 -0
- data/lib/pcap/packet_header.rb +26 -0
- data/lib/pcap/packets/ethernet.rb +40 -0
- data/lib/pcap/packets/ip.rb +119 -0
- data/lib/pcap/packets/tcp.rb +172 -0
- data/lib/pcap/packets/typedefs.rb +7 -0
- data/lib/pcap/packets.rb +3 -0
- data/lib/pcap/pcap.rb +85 -0
- data/lib/pcap/sock_addr.rb +17 -0
- data/lib/pcap/sock_addr_in.rb +25 -0
- data/lib/pcap/stat.rb +23 -0
- data/lib/pcap/time_val.rb +29 -0
- data/lib/pcap/typedefs.rb +16 -0
- data/lib/pcap/version.rb +6 -0
- data/lib/pcap.rb +10 -0
- data/pcap-ffi.gemspec +86 -0
- data/spec/data_link_spec.rb +29 -0
- data/spec/dumps/simple_tcp.pcap +0 -0
- data/spec/error_buffer.rb +18 -0
- data/spec/handler_examples.rb +71 -0
- data/spec/handler_spec.rb +80 -0
- data/spec/helpers/dumps.rb +3 -0
- data/spec/pcap_spec.rb +51 -0
- data/spec/spec_helper.rb +8 -0
- data/tasks/spec.rb +9 -0
- metadata +101 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
Rakefile
|
4
|
+
README.txt
|
5
|
+
examples/print_bytes.rb
|
6
|
+
lib/pcap.rb
|
7
|
+
lib/pcap/exceptions.rb
|
8
|
+
lib/pcap/exceptions/read_error.rb
|
9
|
+
lib/pcap/typedefs.rb
|
10
|
+
lib/pcap/time_val.rb
|
11
|
+
lib/pcap/in_addr.rb
|
12
|
+
lib/pcap/sock_addr.rb
|
13
|
+
lib/pcap/sock_addr_in.rb
|
14
|
+
lib/pcap/if.rb
|
15
|
+
lib/pcap/addr.rb
|
16
|
+
lib/pcap/file_header.rb
|
17
|
+
lib/pcap/packet_header.rb
|
18
|
+
lib/pcap/packet.rb
|
19
|
+
lib/pcap/packets.rb
|
20
|
+
lib/pcap/packets/typedefs.rb
|
21
|
+
lib/pcap/packets/ethernet.rb
|
22
|
+
lib/pcap/packets/ip.rb
|
23
|
+
lib/pcap/packets/tcp.rb
|
24
|
+
lib/pcap/stat.rb
|
25
|
+
lib/pcap/data_link.rb
|
26
|
+
lib/pcap/error_buffer.rb
|
27
|
+
lib/pcap/handler.rb
|
28
|
+
lib/pcap/dumper.rb
|
29
|
+
lib/pcap/version.rb
|
30
|
+
lib/pcap/ffi.rb
|
31
|
+
lib/pcap/pcap.rb
|
32
|
+
tasks/spec.rb
|
33
|
+
spec/spec_helper.rb
|
34
|
+
spec/helpers/dumps.rb
|
35
|
+
spec/dumps/simple_tcp.pcap
|
36
|
+
spec/error_buffer.rb
|
37
|
+
spec/data_link_spec.rb
|
38
|
+
spec/handler_examples.rb
|
39
|
+
spec/handler_spec.rb
|
40
|
+
spec/pcap_spec.rb
|
data/README.txt
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
= pcap-ffi
|
2
|
+
|
3
|
+
* http://github.com/postmodern/pcap-ffi/
|
4
|
+
* Postmodern (postmodern.mod3 at gmail.com)
|
5
|
+
|
6
|
+
== DESCRIPTION:
|
7
|
+
|
8
|
+
Ruby FFI bindings for libpcap.
|
9
|
+
|
10
|
+
== FEATURES:
|
11
|
+
|
12
|
+
== EXAMPLES:
|
13
|
+
|
14
|
+
== INSTALL:
|
15
|
+
|
16
|
+
$ sudo gem install pcap-ffi
|
17
|
+
|
18
|
+
== LICENSE:
|
19
|
+
|
20
|
+
The MIT License
|
21
|
+
|
22
|
+
Copyright (c) 2009 Hal Brodigan
|
23
|
+
|
24
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
25
|
+
a copy of this software and associated documentation files (the
|
26
|
+
'Software'), to deal in the Software without restriction, including
|
27
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
28
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
29
|
+
permit persons to whom the Software is furnished to do so, subject to
|
30
|
+
the following conditions:
|
31
|
+
|
32
|
+
The above copyright notice and this permission notice shall be
|
33
|
+
included in all copies or substantial portions of the Software.
|
34
|
+
|
35
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
36
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
37
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
38
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
39
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
40
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
41
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require './lib/pcap/version.rb'
|
5
|
+
require './tasks/spec.rb'
|
6
|
+
|
7
|
+
# Generate a gem using jeweler
|
8
|
+
begin
|
9
|
+
require 'jeweler'
|
10
|
+
Jeweler::Tasks.new do |gemspec|
|
11
|
+
gemspec.rubyforge_project = 'pcap-ffi'
|
12
|
+
gemspec.name = "pcap-ffi"
|
13
|
+
gemspec.summary = "FFI bindings for libpcap"
|
14
|
+
gemspec.email = "postmodern.mod3@gmail.com"
|
15
|
+
gemspec.homepage = "http://github.com/postmodern/pcap-ffi"
|
16
|
+
gemspec.description = "Bindings to sniff packets using the FFI interface in Ruby."
|
17
|
+
gemspec.authors = ["Postmodern, Dakrone"]
|
18
|
+
end
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
# vim: syntax=Ruby
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'pcap'
|
5
|
+
|
6
|
+
include FFI
|
7
|
+
|
8
|
+
pcap = PCap.open_live(:device => ARGV[0]) do |user,header,bytes|
|
9
|
+
puts "#{header.timestamp}:"
|
10
|
+
|
11
|
+
header.captured.times { |i|
|
12
|
+
print ' %.2x' % bytes.get_uchar(i)
|
13
|
+
}
|
14
|
+
putc "\n"
|
15
|
+
end
|
16
|
+
|
17
|
+
pcap.loop
|
data/lib/pcap/addr.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'pcap/typedefs'
|
2
|
+
require 'pcap/sock_addr'
|
3
|
+
|
4
|
+
require 'ffi/struct'
|
5
|
+
|
6
|
+
module FFI
|
7
|
+
module PCap
|
8
|
+
class Addr < FFI::Struct
|
9
|
+
layout :next, :pointer,
|
10
|
+
:addr, :pointer,
|
11
|
+
:netmask, :pointer,
|
12
|
+
:broadaddr, :pointer,
|
13
|
+
:dstaddr, :pointer
|
14
|
+
|
15
|
+
def next
|
16
|
+
Addr.new(self[:next])
|
17
|
+
end
|
18
|
+
|
19
|
+
def addr
|
20
|
+
SockAddr.new(self[:addr])
|
21
|
+
end
|
22
|
+
|
23
|
+
def netmask
|
24
|
+
SockAddr.new(self[:netmask])
|
25
|
+
end
|
26
|
+
|
27
|
+
def broadcast
|
28
|
+
SockAddr.new(self[:broadaddr])
|
29
|
+
end
|
30
|
+
|
31
|
+
def dest_addr
|
32
|
+
SockAddr.new(self[:destaddr])
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module FFI
|
2
|
+
module PCap
|
3
|
+
class DataLink
|
4
|
+
|
5
|
+
# PCap datalink numeric value
|
6
|
+
attr_reader :value
|
7
|
+
|
8
|
+
# DataLink name
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
#
|
12
|
+
# Creates a new DataLink object with the specified _value_.
|
13
|
+
#
|
14
|
+
def initialize(value)
|
15
|
+
@value = value
|
16
|
+
@name = PCap.pcap_datalink_val_to_name(@value)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.[](name)
|
20
|
+
PCap.pcap_datalink_name_to_val(name.to_s.downcase)
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# Returns the description of the datalink.
|
25
|
+
#
|
26
|
+
def description
|
27
|
+
PCap.pcap_datalink_val_to_description(@value)
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Returns the numeric value of the datalink.
|
32
|
+
#
|
33
|
+
def to_i
|
34
|
+
@value
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# Returns the String form of the datalink.
|
39
|
+
#
|
40
|
+
def to_s
|
41
|
+
@name
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Inspects the datalink.
|
46
|
+
#
|
47
|
+
def inspect
|
48
|
+
"#<#{self.class}: #{@name}>"
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/pcap/dumper.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'pcap/ffi'
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
module FFI
|
6
|
+
module PCap
|
7
|
+
class Dumper < FFI::MemoryPointer
|
8
|
+
|
9
|
+
def initialize(dumper)
|
10
|
+
@dumper = dumper
|
11
|
+
end
|
12
|
+
|
13
|
+
def write(header,bytes)
|
14
|
+
PCap.pcap_dump(@dumper,header,bytes)
|
15
|
+
end
|
16
|
+
|
17
|
+
def tell
|
18
|
+
PCap.pcap_dump_ftell(@dumper)
|
19
|
+
end
|
20
|
+
|
21
|
+
def flush
|
22
|
+
PCap.pcap_dump_flush(@dumper)
|
23
|
+
end
|
24
|
+
|
25
|
+
def close
|
26
|
+
PCap.pcap_dump_close(@dumper)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_ptr
|
30
|
+
@dumper
|
31
|
+
end
|
32
|
+
|
33
|
+
def inspect
|
34
|
+
"#<#{self.class}: 0x#{@dumper.address.to_s(16)}>"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module FFI
|
4
|
+
module PCap
|
5
|
+
class ErrorBuffer < FFI::Buffer
|
6
|
+
|
7
|
+
# Size of the error buffers
|
8
|
+
SIZE = 256
|
9
|
+
|
10
|
+
#
|
11
|
+
# Creates a new ErrorBuffer object.
|
12
|
+
#
|
13
|
+
def initialize
|
14
|
+
super(SIZE)
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Returns the error message within the error buffer.
|
19
|
+
#
|
20
|
+
def to_s
|
21
|
+
get_string(SIZE)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'pcap/exceptions/read_error'
|
data/lib/pcap/ffi.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'pcap/typedefs'
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
module FFI
|
6
|
+
module PCap
|
7
|
+
extend FFI::Library
|
8
|
+
|
9
|
+
ffi_lib 'libpcap'
|
10
|
+
|
11
|
+
enum :pcap_direction, [
|
12
|
+
:pcap_d_inout,
|
13
|
+
:pcap_d_in,
|
14
|
+
:pcap_d_out
|
15
|
+
]
|
16
|
+
|
17
|
+
callback :pcap_handler, [:pointer, :pointer, :pointer], :void
|
18
|
+
|
19
|
+
attach_function :pcap_lookupdev, [:pointer], :string
|
20
|
+
attach_function :pcap_lookupnet, [:string, :pointer, :pointer, :pointer], :int
|
21
|
+
attach_function :pcap_open_live, [:string, :int, :int, :int, :pointer], :pointer
|
22
|
+
attach_function :pcap_open_dead, [:int, :int], :pointer
|
23
|
+
attach_function :pcap_open_offline, [:string, :pointer], :pointer
|
24
|
+
attach_function :pcap_fopen_offline, [:pointer, :string], :pointer
|
25
|
+
attach_function :pcap_close, [:pointer], :void
|
26
|
+
attach_function :pcap_loop, [:pointer, :int, :pcap_handler, :pointer], :int
|
27
|
+
attach_function :pcap_dispatch, [:pointer, :int, :pcap_handler, :pointer], :int
|
28
|
+
attach_function :pcap_next, [:pointer, :pointer], :pointer
|
29
|
+
attach_function :pcap_next_ex, [:pointer, :pointer, :pointer], :int
|
30
|
+
attach_function :pcap_breakloop, [:pointer], :void
|
31
|
+
attach_function :pcap_stats, [:pointer, :pointer], :int
|
32
|
+
attach_function :pcap_setfilter, [:pointer, :pointer], :int
|
33
|
+
attach_function :pcap_setdirection, [:pointer, :pcap_direction], :int
|
34
|
+
attach_function :pcap_getnonblock, [:pointer, :pointer], :int
|
35
|
+
attach_function :pcap_setnonblock, [:pointer, :int, :pointer], :int
|
36
|
+
attach_function :pcap_perror, [:pointer, :string], :void
|
37
|
+
attach_function :pcap_inject, [:pointer, :pointer, :int], :int
|
38
|
+
attach_function :pcap_sendpacket, [:pointer, :pointer, :int], :int
|
39
|
+
attach_function :pcap_strerror, [:int], :string
|
40
|
+
attach_function :pcap_geterr, [:pointer], :string
|
41
|
+
attach_function :pcap_compile, [:pointer, :pointer, :string, :int, :bpf_uint32], :int
|
42
|
+
attach_function :pcap_compile_nopcap, [:int, :int, :pointer, :string, :int, :bpf_uint32], :int
|
43
|
+
attach_function :pcap_freecode, [:pointer], :void
|
44
|
+
attach_function :pcap_datalink, [:pointer], :int
|
45
|
+
attach_function :pcap_list_datalinks, [:pointer, :pointer], :int
|
46
|
+
attach_function :pcap_set_datalink, [:pointer, :int], :int
|
47
|
+
attach_function :pcap_datalink_name_to_val, [:string], :int
|
48
|
+
attach_function :pcap_datalink_val_to_name, [:int], :string
|
49
|
+
attach_function :pcap_datalink_val_to_description, [:int], :string
|
50
|
+
attach_function :pcap_snapshot, [:pointer], :int
|
51
|
+
attach_function :pcap_is_swapped, [:pointer], :int
|
52
|
+
attach_function :pcap_major_version, [:pointer], :int
|
53
|
+
attach_function :pcap_minor_version, [:pointer], :int
|
54
|
+
|
55
|
+
attach_function :pcap_file, [:pointer], :pointer
|
56
|
+
attach_function :pcap_fileno, [:pointer], :int
|
57
|
+
|
58
|
+
attach_function :pcap_dump_open, [:pointer, :string], :pointer
|
59
|
+
attach_function :pcap_dump_fopen, [:pointer, :pointer], :pointer
|
60
|
+
attach_function :pcap_dump_file, [:pointer], :pointer
|
61
|
+
attach_function :pcap_dump_ftell, [:pointer], :long
|
62
|
+
attach_function :pcap_dump_flush, [:pointer], :int
|
63
|
+
attach_function :pcap_dump_close, [:pointer], :void
|
64
|
+
attach_function :pcap_dump, [:pointer, :pointer, :pointer], :void
|
65
|
+
|
66
|
+
attach_function :pcap_findalldevs, [:pointer, :pointer], :int
|
67
|
+
attach_function :pcap_freealldevs, [:pointer], :void
|
68
|
+
|
69
|
+
attach_function :pcap_lib_version, [], :string
|
70
|
+
|
71
|
+
attach_function :bpf_filter, [:pointer, :pointer, :uint, :uint], :uint
|
72
|
+
attach_function :bpf_validate, [:pointer, :int], :int
|
73
|
+
attach_function :bpf_image, [:pointer, :int], :string
|
74
|
+
attach_function :bpf_dump, [:pointer, :int], :void
|
75
|
+
|
76
|
+
# TODO: WIN32/MSDOS/UN*X specific definitions
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'pcap/typedefs'
|
2
|
+
|
3
|
+
require 'ffi/struct'
|
4
|
+
|
5
|
+
module FFI
|
6
|
+
module PCap
|
7
|
+
class FileHeader < FFI::Struct
|
8
|
+
layout :magic, :bpf_uint32,
|
9
|
+
:version_major, :ushort,
|
10
|
+
:version_minor, :ushort,
|
11
|
+
:thiszone, :bpf_int32,
|
12
|
+
:sigfigs, :bpf_uint32,
|
13
|
+
:snaplen, :bpf_uint32,
|
14
|
+
:linktype, :bpf_uint32
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/pcap/handler.rb
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
require 'pcap/exceptions/read_error'
|
2
|
+
require 'pcap/ffi'
|
3
|
+
require 'pcap/error_buffer'
|
4
|
+
require 'pcap/data_link'
|
5
|
+
require 'pcap/packet_header'
|
6
|
+
require 'pcap/stat'
|
7
|
+
|
8
|
+
require 'ffi'
|
9
|
+
|
10
|
+
module FFI
|
11
|
+
module PCap
|
12
|
+
class Handler
|
13
|
+
|
14
|
+
include Enumerable
|
15
|
+
|
16
|
+
# Default snaplen
|
17
|
+
SNAPLEN = 65535
|
18
|
+
|
19
|
+
# Pointer to the pcap opaque type
|
20
|
+
attr_reader :pcap
|
21
|
+
|
22
|
+
# Number of packets to sniff
|
23
|
+
attr_accessor :count
|
24
|
+
|
25
|
+
def initialize(pcap,options={},&block)
|
26
|
+
@pcap = pcap
|
27
|
+
@closed = false
|
28
|
+
|
29
|
+
# Default is to infinitely loop over packets.
|
30
|
+
@count = (options[:count] || -1)
|
31
|
+
|
32
|
+
if options[:direction]
|
33
|
+
self.direction = options[:direction]
|
34
|
+
end
|
35
|
+
|
36
|
+
@callback_wrapper = Proc.new do |user,header,bytes|
|
37
|
+
if @callback
|
38
|
+
@callback.call(user,PacketHeader.new(header),bytes)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
callback(&block)
|
43
|
+
|
44
|
+
trap('SIGINT') { self.close }
|
45
|
+
end
|
46
|
+
|
47
|
+
def datalink
|
48
|
+
DataLink.new(PCap.pcap_datalink(@pcap))
|
49
|
+
end
|
50
|
+
|
51
|
+
def callback(&block)
|
52
|
+
@callback = block
|
53
|
+
return @callback
|
54
|
+
end
|
55
|
+
|
56
|
+
def direction=(dir)
|
57
|
+
directions = PCap.enum_type(:pcap_direction)
|
58
|
+
|
59
|
+
return PCap.pcap_setdirection(@pcap,directions[:"pcap_d_#{dir}"])
|
60
|
+
end
|
61
|
+
|
62
|
+
def non_blocking=(mode)
|
63
|
+
errbuf = ErrorBuffer.new
|
64
|
+
mode = if mode
|
65
|
+
1
|
66
|
+
else
|
67
|
+
0
|
68
|
+
end
|
69
|
+
|
70
|
+
if PCap.pcap_setnonblock(@pcap,mode,errbuf) == -1
|
71
|
+
raise(RuntimeError,errbuf.to_s,caller)
|
72
|
+
end
|
73
|
+
|
74
|
+
return mode == 1
|
75
|
+
end
|
76
|
+
|
77
|
+
def non_blocking?
|
78
|
+
errbuf = ErrorBuffer.new
|
79
|
+
mode = PCap.pcap_getnonblock(@pcap,errbuf)
|
80
|
+
|
81
|
+
if mode == -1
|
82
|
+
raise(RuntimeError,errbuf.to_s,caller)
|
83
|
+
end
|
84
|
+
|
85
|
+
return mode == 1
|
86
|
+
end
|
87
|
+
|
88
|
+
def loop(data=nil,&block)
|
89
|
+
callback(&block) if block
|
90
|
+
|
91
|
+
PCap.pcap_loop(@pcap,@count,@callback_wrapper,data)
|
92
|
+
end
|
93
|
+
|
94
|
+
alias each loop
|
95
|
+
|
96
|
+
def dispatch(data=nil,&block)
|
97
|
+
callback(&block) if block
|
98
|
+
|
99
|
+
return PCap.pcap_dispatch(@pcap,@count,@callback_wrapper,data)
|
100
|
+
end
|
101
|
+
|
102
|
+
def next
|
103
|
+
header = PacketHeader.new
|
104
|
+
data = PCap.pcap_next(@pcap,header)
|
105
|
+
|
106
|
+
return [nil, nil] if data.null?
|
107
|
+
return [header, data]
|
108
|
+
end
|
109
|
+
|
110
|
+
def next_extra
|
111
|
+
header_ptr = MemoryPointer.new(:pointer)
|
112
|
+
data_ptr = MemoryPointer.new(:pointer)
|
113
|
+
|
114
|
+
case PCap.pcap_next_ex(@pcap,header_ptr,data_ptr)
|
115
|
+
when -1
|
116
|
+
raise(ReadError,"an error occurred while reading the packet",caller)
|
117
|
+
when -2
|
118
|
+
raise(ReadError,"the 'savefile' contains no more packets",caller)
|
119
|
+
end
|
120
|
+
|
121
|
+
return [header_ptr.get_pointer(0), data_ptr.get_pointer(0)]
|
122
|
+
end
|
123
|
+
|
124
|
+
def open_dump(path)
|
125
|
+
dump_ptr = PCap.pcap_dump_open(@pcap,File.expand_path(path))
|
126
|
+
|
127
|
+
if dump_ptr.null?
|
128
|
+
raise(RuntimeError,error,caller)
|
129
|
+
end
|
130
|
+
|
131
|
+
return Dumper.new(dump_ptr)
|
132
|
+
end
|
133
|
+
|
134
|
+
def stats
|
135
|
+
stats = Stat.new
|
136
|
+
|
137
|
+
PCap.pcap_stats(@pcap,stats)
|
138
|
+
return stats
|
139
|
+
end
|
140
|
+
|
141
|
+
def error
|
142
|
+
PCap.pcap_geterr(@pcap)
|
143
|
+
end
|
144
|
+
|
145
|
+
def stop
|
146
|
+
PCap.pcap_breakloop(@pcap)
|
147
|
+
end
|
148
|
+
|
149
|
+
def closed?
|
150
|
+
@closed == true
|
151
|
+
end
|
152
|
+
|
153
|
+
def close
|
154
|
+
unless @closed
|
155
|
+
@closed = true
|
156
|
+
PCap.pcap_close(@pcap)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def to_ptr
|
161
|
+
@pcap
|
162
|
+
end
|
163
|
+
|
164
|
+
def inspect
|
165
|
+
"#<#{self.class}: 0x#{@pcap.address.to_s(16)}>"
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
data/lib/pcap/if.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'pcap/typedefs'
|
2
|
+
require 'pcap/addr'
|
3
|
+
|
4
|
+
require 'ffi/struct'
|
5
|
+
|
6
|
+
module FFI
|
7
|
+
module PCap
|
8
|
+
class IF < FFI::Struct
|
9
|
+
# interface is loopback
|
10
|
+
LOOPBACK = 0x00000001
|
11
|
+
|
12
|
+
layout :next, :pointer,
|
13
|
+
:name, :string,
|
14
|
+
:description, :string,
|
15
|
+
:addresses, :pointer,
|
16
|
+
:flags, :bpf_uint32
|
17
|
+
|
18
|
+
def next
|
19
|
+
IF.new(self[:next])
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
self[:name]
|
24
|
+
end
|
25
|
+
|
26
|
+
def addresses
|
27
|
+
Addr.new(self[:addresses])
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
self[:name]
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/pcap/in_addr.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'pcap/typedefs'
|
2
|
+
require 'pcap/time_val'
|
3
|
+
|
4
|
+
require 'ffi/struct'
|
5
|
+
|
6
|
+
module FFI
|
7
|
+
module PCap
|
8
|
+
class PacketHeader < FFI::Struct
|
9
|
+
layout :ts, TimeVal,
|
10
|
+
:caplen, :bpf_uint32,
|
11
|
+
:len, :bpf_uint32
|
12
|
+
|
13
|
+
def timestamp
|
14
|
+
self[:ts]
|
15
|
+
end
|
16
|
+
|
17
|
+
def captured
|
18
|
+
self[:caplen]
|
19
|
+
end
|
20
|
+
|
21
|
+
def length
|
22
|
+
self[:len]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'pcap/packets/typedefs'
|
2
|
+
require 'pcap/packet'
|
3
|
+
|
4
|
+
require 'ffi'
|
5
|
+
|
6
|
+
module FFI
|
7
|
+
module PCap
|
8
|
+
module Packets
|
9
|
+
class Ethernet < FFI::Struct
|
10
|
+
|
11
|
+
include Packet
|
12
|
+
|
13
|
+
# Number of bytes for an ethernet address
|
14
|
+
ADDR_LEN = 6
|
15
|
+
|
16
|
+
# Size of an Ethernet header
|
17
|
+
SIZE = 14
|
18
|
+
|
19
|
+
layout :ether_dhost, [:uchar, ADDR_LEN],
|
20
|
+
:ether_shost, [:uchar, ADDR_LEN],
|
21
|
+
:ether_type, :ushort
|
22
|
+
|
23
|
+
#
|
24
|
+
# Returns the source MAC address.
|
25
|
+
#
|
26
|
+
def src_mac
|
27
|
+
self[:ether_shost]
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Returns the destination MAC address.
|
32
|
+
#
|
33
|
+
def dest_mac
|
34
|
+
self[:ether_dhost]
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|