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
@@ -1,24 +1,26 @@
|
|
1
1
|
module FFI
|
2
|
-
module PCap
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
2
|
+
module PCap
|
3
|
+
#
|
4
|
+
# Generic per-packet information, as supplied by libpcap. This structure
|
5
|
+
# is used to track only the libpcap header and just contains the
|
6
|
+
# timestamp and length information used by libpcap.
|
7
|
+
#
|
8
|
+
# See `pcap_pkthdr` struct in `pcap.h`.
|
9
|
+
#
|
10
|
+
class PacketHeader < FFI::Struct
|
10
11
|
|
11
|
-
|
12
|
-
struct :ts, ::FFI::PCap::TimeVal, :desc => 'time stamp'
|
13
|
-
field :caplen, :bpf_uint32, :desc => 'length of portion present'
|
14
|
-
field :len, :bpf_uint32, :desc => 'length of packet (off wire)'
|
15
|
-
end
|
12
|
+
include FFI::DRY::StructHelper
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
dsl_layout do
|
15
|
+
struct :ts, ::FFI::PCap::TimeVal, :desc => 'time stamp'
|
16
|
+
field :caplen, :bpf_uint32, :desc => 'length of portion present'
|
17
|
+
field :len, :bpf_uint32, :desc => 'length of packet (off wire)'
|
18
|
+
end
|
20
19
|
|
21
|
-
|
20
|
+
alias timestamp ts
|
21
|
+
alias captured caplen
|
22
|
+
alias length len
|
22
23
|
|
23
|
-
end
|
24
|
+
end
|
25
|
+
end
|
24
26
|
end
|
data/lib/ffi/pcap/pcap.rb
CHANGED
@@ -1,252 +1,309 @@
|
|
1
|
+
require 'ffi/pcap/bpf_instruction'
|
2
|
+
require 'ffi/pcap/bpf_program'
|
3
|
+
|
1
4
|
require 'enumerator'
|
2
5
|
|
3
6
|
module FFI
|
4
|
-
module PCap
|
5
|
-
DEFAULT_SNAPLEN = 65535 # Default snapshot length for packets
|
6
|
-
|
7
|
-
attach_function :pcap_lookupdev, [:pointer], :string
|
8
|
-
|
9
|
-
# Find the default device on which to capture.
|
10
|
-
#
|
11
|
-
# @return [String]
|
12
|
-
# Name of default device
|
13
|
-
#
|
14
|
-
# @raise [LibError]
|
15
|
-
# On failure, an exception is raised with the relevant error
|
16
|
-
# message from libpcap.
|
17
|
-
#
|
18
|
-
def PCap.lookupdev
|
19
|
-
e = ErrorBuffer.create()
|
20
|
-
unless name = FFI::PCap.pcap_lookupdev(e)
|
21
|
-
raise(LibError, "pcap_lookupdev(): #{e.to_s}")
|
22
|
-
end
|
23
|
-
return name
|
24
|
-
end
|
7
|
+
module PCap
|
25
8
|
|
9
|
+
DEFAULT_SNAPLEN = 65535 # Default snapshot length for packets
|
26
10
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
# @raise [LibError]
|
48
|
-
# On failure, an exception is raised with the relevant error message
|
49
|
-
# from libpcap.
|
50
|
-
#
|
51
|
-
def PCap.lookupnet(device)
|
52
|
-
netp = FFI::MemoryPointer.new(find_type(:bpf_uint32))
|
53
|
-
maskp = FFI::MemoryPointer.new(find_type(:bpf_uint32))
|
54
|
-
errbuf = ErrorBuffer.create()
|
55
|
-
unless FFI::PCap.pcap_lookupnet(device, netp, maskp, errbuf) == 0
|
56
|
-
raise(LibError, "pcap_lookupnet(): #{errbuf.to_s}")
|
57
|
-
end
|
58
|
-
if block_given?
|
59
|
-
yield(netp, maskp)
|
60
|
-
else
|
61
|
-
return( netp.get_array_of_uchar(0,4).join('.') << "/" <<
|
62
|
-
maskp.get_array_of_uchar(0,4).join('.') )
|
11
|
+
attach_function :pcap_lookupdev, [:pointer], :string
|
12
|
+
|
13
|
+
#
|
14
|
+
# Find the default device on which to capture.
|
15
|
+
#
|
16
|
+
# @return [String]
|
17
|
+
# Name of default device
|
18
|
+
#
|
19
|
+
# @raise [LibError]
|
20
|
+
# On failure, an exception is raised with the relevant error
|
21
|
+
# message from libpcap.
|
22
|
+
#
|
23
|
+
def PCap.lookupdev
|
24
|
+
e = ErrorBuffer.new
|
25
|
+
|
26
|
+
unless (name = PCap.pcap_lookupdev(e))
|
27
|
+
raise(LibError,"pcap_lookupdev(): #{e}",caller)
|
28
|
+
end
|
29
|
+
|
30
|
+
return name
|
63
31
|
end
|
64
|
-
end
|
65
|
-
|
66
|
-
|
67
|
-
# Opens a new Live device for capturing from the network. See Live.new()
|
68
|
-
# for arguments.
|
69
|
-
#
|
70
|
-
# If passed a block, the block is passed to Live.new() and the Live
|
71
|
-
# object is closed after completion of the block
|
72
|
-
def PCap.open_live(opts={},&block)
|
73
|
-
ret = Live.new(opts, &block)
|
74
|
-
return block_given? ? ret.close : ret
|
75
|
-
end
|
76
32
|
|
77
33
|
|
78
|
-
|
79
|
-
# a capture for output. See Dead.new() for arguments.
|
80
|
-
def PCap.open_dead(opts={}, &block)
|
81
|
-
ret = Dead.new(opts, &block)
|
82
|
-
return block_given? ? ret.close : ret
|
83
|
-
end
|
34
|
+
attach_function :pcap_lookupnet, [:string, :pointer, :pointer, :pointer], :int
|
84
35
|
|
36
|
+
#
|
37
|
+
# Determine the IPv4 network number and mask relevant with a network
|
38
|
+
# device.
|
39
|
+
#
|
40
|
+
# @param [String] device
|
41
|
+
# The name of the device to look up.
|
42
|
+
#
|
43
|
+
# @yield [netp, maskp]
|
44
|
+
#
|
45
|
+
# @yieldparam [FFI::MemoryPointer] netp
|
46
|
+
# A pointer to the network return value.
|
47
|
+
#
|
48
|
+
# @yieldparam [FFI::MemoryPointer] maskp
|
49
|
+
# A pointer to the netmask return value.
|
50
|
+
#
|
51
|
+
# @return [nil, String]
|
52
|
+
# The IPv4 network number and mask presented as `n.n.n.n/m.m.m.m`.
|
53
|
+
# `nil` is returned when a block is specified.
|
54
|
+
#
|
55
|
+
# @raise [LibError]
|
56
|
+
# On failure, an exception is raised with the relevant error message
|
57
|
+
# from libpcap.
|
58
|
+
#
|
59
|
+
def PCap.lookupnet(device)
|
60
|
+
netp = MemoryPointer.new(find_type(:bpf_uint32))
|
61
|
+
maskp = MemoryPointer.new(find_type(:bpf_uint32))
|
62
|
+
errbuf = ErrorBuffer.new
|
85
63
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
return block_given? ? ret.close : ret
|
90
|
-
end
|
64
|
+
unless PCap.pcap_lookupnet(device, netp, maskp, errbuf) == 0
|
65
|
+
raise(LibError, "pcap_lookupnet(): #{errbuf}",caller)
|
66
|
+
end
|
91
67
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
68
|
+
if block_given?
|
69
|
+
yield netp, maskp
|
70
|
+
else
|
71
|
+
net = netp.get_array_of_uchar(0,4).join('.')
|
72
|
+
net << '/'
|
73
|
+
net << maskp.get_array_of_uchar(0,4).join('.')
|
96
74
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
# List all capture devices and yield them each to a block
|
101
|
-
#
|
102
|
-
# @yield [dev]
|
103
|
-
#
|
104
|
-
# @yieldparam [Interface] dev
|
105
|
-
# An Interface structure for each device.
|
106
|
-
#
|
107
|
-
# @return [nil]
|
108
|
-
#
|
109
|
-
# @raise [LibError]
|
110
|
-
# On failure, an exception is raised with the relevant error
|
111
|
-
# message from libpcap.
|
112
|
-
#
|
113
|
-
def PCap.each_device
|
114
|
-
devices = ::FFI::MemoryPointer.new(:pointer)
|
115
|
-
errbuf = ErrorBuffer.create()
|
116
|
-
|
117
|
-
FFI::PCap.pcap_findalldevs(devices, errbuf)
|
118
|
-
node = devices.get_pointer(0)
|
119
|
-
|
120
|
-
if node.null?
|
121
|
-
raise(LibError, "pcap_findalldevs(): #{errbuf.to_s}")
|
75
|
+
return net
|
76
|
+
end
|
122
77
|
end
|
123
78
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
79
|
+
#
|
80
|
+
# Opens a new Live device for capturing from the network. See
|
81
|
+
# {Live#initialize} for arguments.
|
82
|
+
#
|
83
|
+
# If passed a block, the block is passed to {Live#initialize} and the
|
84
|
+
# {Live} object is closed after completion of the block
|
85
|
+
#
|
86
|
+
def PCap.open_live(opts={},&block)
|
87
|
+
ret = Live.new(opts, &block)
|
88
|
+
return block_given? ? ret.close : ret
|
129
89
|
end
|
130
90
|
|
131
|
-
|
132
|
-
|
133
|
-
|
91
|
+
#
|
92
|
+
# Opens a new Dead pcap interface for compiling filters or opening
|
93
|
+
# a capture for output.
|
94
|
+
#
|
95
|
+
# @see Dead#initialize
|
96
|
+
#
|
97
|
+
def PCap.open_dead(opts={}, &block)
|
98
|
+
ret = Dead.new(opts, &block)
|
99
|
+
return block_given? ? ret.close : ret
|
100
|
+
end
|
134
101
|
|
102
|
+
#
|
103
|
+
# Opens a saved capture file for reading.
|
104
|
+
#
|
105
|
+
# @see Offline#initialize
|
106
|
+
#
|
107
|
+
def PCap.open_offline(path, opts={}, &block)
|
108
|
+
ret = Offline.new(path, opts={}, &block)
|
109
|
+
return block_given? ? ret.close : ret
|
110
|
+
end
|
135
111
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
def PCap.dump_devices
|
142
|
-
FFI::PCap.enum_for(:each_device).map do |dev|
|
143
|
-
net = begin; FFI::PCap.lookupnet(dev.name); rescue LibError; end
|
144
|
-
[dev.name, net]
|
112
|
+
#
|
113
|
+
# @see Pcap.open_offline
|
114
|
+
#
|
115
|
+
def PCap.open_file(path, opts={}, &block)
|
116
|
+
open_offline(path, opts, &block)
|
145
117
|
end
|
146
|
-
end
|
147
118
|
|
119
|
+
attach_function :pcap_findalldevs, [:pointer, :pointer], :int
|
120
|
+
attach_function :pcap_freealldevs, [Interface], :void
|
148
121
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
122
|
+
#
|
123
|
+
# List all capture devices and yield them each to a block.
|
124
|
+
#
|
125
|
+
# @yield [dev]
|
126
|
+
#
|
127
|
+
# @yieldparam [Interface] dev
|
128
|
+
# An Interface structure for each device.
|
129
|
+
#
|
130
|
+
# @return [nil]
|
131
|
+
#
|
132
|
+
# @raise [LibError]
|
133
|
+
# On failure, an exception is raised with the relevant error
|
134
|
+
# message from libpcap.
|
135
|
+
#
|
136
|
+
def PCap.each_device
|
137
|
+
devices = FFI::MemoryPointer.new(:pointer)
|
138
|
+
errbuf = ErrorBuffer.new
|
153
139
|
|
154
|
-
|
140
|
+
PCap.pcap_findalldevs(devices, errbuf)
|
141
|
+
node = devices.get_pointer(0)
|
155
142
|
|
143
|
+
if node.null?
|
144
|
+
raise(LibError,"pcap_findalldevs(): #{errbuf}",caller)
|
145
|
+
end
|
156
146
|
|
157
|
-
|
158
|
-
#
|
159
|
-
# @return [String]
|
160
|
-
# Information about the version of the libpcap library being used;
|
161
|
-
# note that it contains more information than just a version number.
|
162
|
-
#
|
163
|
-
def PCap.lib_version
|
164
|
-
FFI::PCap.pcap_lib_version
|
165
|
-
end
|
147
|
+
device = Interface.new(node)
|
166
148
|
|
149
|
+
while device
|
150
|
+
yield(device)
|
167
151
|
|
168
|
-
|
169
|
-
|
170
|
-
# @return [String]
|
171
|
-
# Version number.
|
172
|
-
#
|
173
|
-
def PCap.lib_version_number
|
174
|
-
if lib_version() =~ /libpcap version (\d+\.\d+.\d+)/
|
175
|
-
return $1
|
176
|
-
end
|
177
|
-
end
|
152
|
+
device = device.next
|
153
|
+
end
|
178
154
|
|
155
|
+
PCap.pcap_freealldevs(node)
|
156
|
+
return nil
|
157
|
+
end
|
179
158
|
|
180
|
-
|
181
|
-
|
159
|
+
#
|
160
|
+
# Returns an array of device name and network/netmask pairs for
|
161
|
+
# each interface found on the system.
|
162
|
+
#
|
163
|
+
# If an interface does not have an address assigned, its network/netmask
|
164
|
+
# value is returned as a nil value.
|
165
|
+
#
|
166
|
+
def PCap.dump_devices
|
167
|
+
PCap.enum_for(:each_device).map do |dev|
|
168
|
+
net = begin
|
169
|
+
PCap.lookupnet(dev.name)
|
170
|
+
rescue LibError
|
171
|
+
end
|
172
|
+
|
173
|
+
[dev.name, net]
|
174
|
+
end
|
175
|
+
end
|
182
176
|
|
183
|
-
|
177
|
+
#
|
178
|
+
# Returns an array of device names for each interface found on the
|
179
|
+
# system.
|
180
|
+
#
|
181
|
+
def PCap.device_names
|
182
|
+
PCap.enum_for(:each_device).map { |dev| dev.name }
|
183
|
+
end
|
184
184
|
|
185
|
+
attach_function :pcap_lib_version, [], :string
|
185
186
|
|
186
|
-
# Drops privileges back to the uid of the SUDO_USER environment
|
187
|
-
# variable.
|
188
|
-
#
|
189
|
-
# Only available on Unix.
|
190
187
|
#
|
191
|
-
#
|
192
|
-
# ruby pcap program as root.
|
188
|
+
# Get the version information for libpcap.
|
193
189
|
#
|
194
|
-
#
|
195
|
-
#
|
196
|
-
#
|
197
|
-
#
|
198
|
-
|
190
|
+
# @return [String]
|
191
|
+
# Information about the version of the libpcap library being used;
|
192
|
+
# note that it contains more information than just a version number.
|
193
|
+
#
|
194
|
+
def PCap.lib_version
|
195
|
+
PCap.pcap_lib_version
|
196
|
+
end
|
197
|
+
|
199
198
|
#
|
200
|
-
#
|
201
|
-
# An error is raised if privileges cannot be dropped for
|
202
|
-
# some reason. This may be because the SUDO_USER environment
|
203
|
-
# variable is not set, because we already have a lower
|
204
|
-
# privilige and the SUDO_USER id is not the current uid,
|
205
|
-
# or because the SUDO_USER environment variable is not
|
206
|
-
# a valid user.
|
199
|
+
# Extract just the version number from the {PCap.lib_version} string.
|
207
200
|
#
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
return true if (
|
215
|
-
Process::Sys.getuid == pwent.uid and
|
216
|
-
Process::Sys.geteuid == pwent.uid and
|
217
|
-
Process::Sys.getgid == pwent.gid and
|
218
|
-
Process::Sys.getegid == pwent.gid )
|
201
|
+
# @return [String]
|
202
|
+
# Version number.
|
203
|
+
#
|
204
|
+
def PCap.lib_version_number
|
205
|
+
if (version = PCap.lib_version.match(/libpcap version (\d+\.\d+.\d+)/))
|
206
|
+
return version[1]
|
219
207
|
end
|
220
|
-
raise(StandardError, "Unable to drop privileges")
|
221
208
|
end
|
222
209
|
|
223
|
-
|
224
|
-
|
225
|
-
|
210
|
+
attach_function :pcap_compile_nopcap, [:int, :int, BPFProgram, :string, :int, :bpf_uint32], :int
|
211
|
+
|
212
|
+
attach_function :bpf_filter, [BPFInstruction, :pointer, :uint, :uint], :uint
|
213
|
+
attach_function :bpf_validate, [BPFInstruction, :int], :int
|
214
|
+
attach_function :bpf_image, [BPFInstruction, :int], :string
|
215
|
+
attach_function :bpf_dump, [BPFProgram, :int], :void
|
216
|
+
attach_function :pcap_freecode, [BPFProgram], :void
|
217
|
+
|
218
|
+
|
219
|
+
# Unix Only:
|
220
|
+
begin
|
221
|
+
attach_function :pcap_get_selectable_fd, [:pcap_t], :int
|
222
|
+
|
223
|
+
#
|
224
|
+
# Drops privileges back to the uid of the SUDO_USER environment
|
225
|
+
# variable.
|
226
|
+
#
|
227
|
+
# Only available on Unix.
|
228
|
+
#
|
229
|
+
# This is useful for the paranoid when sudo is used to run a
|
230
|
+
# ruby pcap program as root.
|
231
|
+
#
|
232
|
+
# This method can generally be called right after a call to
|
233
|
+
# open_live() has returned a pcap handle or another privileged
|
234
|
+
# call has completed. Note, however, that once privileges are
|
235
|
+
# dropped, pcap functions that a require higher privilege will
|
236
|
+
# no longer work.
|
237
|
+
#
|
238
|
+
# @raise [StandardError]
|
239
|
+
# An error is raised if privileges cannot be dropped for
|
240
|
+
# some reason. This may be because the SUDO_USER environment
|
241
|
+
# variable is not set, because we already have a lower
|
242
|
+
# privilige and the SUDO_USER id is not the current uid,
|
243
|
+
# or because the SUDO_USER environment variable is not
|
244
|
+
# a valid user.
|
245
|
+
#
|
246
|
+
def PCap.drop_sudo_privs
|
247
|
+
if ENV["SUDO_USER"]
|
248
|
+
if (pwent = Etc.getpwnam(ENV["SUDO_USER"]))
|
249
|
+
Process::Sys.setgid(pwent.gid)
|
250
|
+
Process::Sys.setegid(pwent.gid)
|
251
|
+
Process::Sys.setuid(pwent.uid)
|
252
|
+
Process::Sys.seteuid(pwent.uid)
|
253
|
+
|
254
|
+
return true if (
|
255
|
+
Process::Sys.getuid == pwent.uid and
|
256
|
+
Process::Sys.geteuid == pwent.uid and
|
257
|
+
Process::Sys.getgid == pwent.gid and
|
258
|
+
Process::Sys.getegid == pwent.gid
|
259
|
+
)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
raise(StandardError,"Unable to drop privileges",caller)
|
264
|
+
end
|
265
|
+
rescue FFI::NotFoundError
|
266
|
+
$pcap_not_unix = true
|
267
|
+
end
|
226
268
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
269
|
+
if $pcap_not_unix
|
270
|
+
# Win32 only:
|
271
|
+
begin
|
272
|
+
attach_function :pcap_setbuff, [:pcap_t, :int], :int
|
273
|
+
attach_function :pcap_setmode, [:pcap_t, :pcap_w32_modes_enum], :int
|
274
|
+
attach_function :pcap_setmintocopy, [:pcap_t, :int], :int
|
275
|
+
rescue FFI::NotFoundError
|
276
|
+
$pcap_not_win32 = true
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
if $pcap_not_win32
|
281
|
+
# MSDOS only???:
|
282
|
+
begin
|
283
|
+
attach_function :pcap_stats_ex, [:pcap_t, StatEx], :int
|
284
|
+
attach_function :pcap_set_wait, [:pcap_t, :pointer, :int], :void
|
285
|
+
attach_function :pcap_mac_packets, [], :ulong
|
286
|
+
rescue FFI::NotFoundError
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
attach_function :pcap_fileno, [:pcap_t], :int
|
291
|
+
|
292
|
+
|
293
|
+
### not sure if we want FILE stuff now or ever
|
294
|
+
|
295
|
+
#attach_function :pcap_fopen_offline, [:FILE, :pointer], :pcap_t
|
296
|
+
#attach_function :pcap_file, [:pcap_t], :FILE
|
297
|
+
#attach_function :pcap_dump_fopen, [:pcap_t, :FILE], :pcap_dumper_t
|
298
|
+
|
299
|
+
# MISC functions only in 1.0.0+
|
300
|
+
# They added a very different way of creating 'live' pcap handles
|
301
|
+
attach_optional_function :pcap_create, [:string, :pointer], :pcap_t
|
302
|
+
attach_optional_function :pcap_set_snaplen, [:pcap_t, :int], :int
|
303
|
+
attach_optional_function :pcap_set_promisc, [:pcap_t, :int], :int
|
304
|
+
attach_optional_function :pcap_can_set_rfmon, [:pcap_t, :int], :int
|
305
|
+
attach_optional_function :pcap_set_timeout, [:pcap_t, :int], :int
|
306
|
+
attach_optional_function :pcap_set_buffer_size, [:pcap_t, :int], :int
|
307
|
+
attach_optional_function :activate, [:pcap_t], :int
|
308
|
+
end
|
251
309
|
end
|
252
|
-
end
|