ffi-pcap 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|