netlink_proc_event 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +43 -0
- data/Rakefile +2 -0
- data/lib/netlink_proc_event.rb +100 -0
- data/lib/netlink_proc_event/libnl.rb +88 -0
- data/lib/netlink_proc_event/version.rb +11 -0
- data/netlink_proc_event.gemspec +22 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6993edf72b9e1bd5c9c641ae36fbd13ed9719569
|
4
|
+
data.tar.gz: 9a61ff81f38b292eea069f87fb94d7212b0e866b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5b31950e7fe0789f195616d2fba80c1a028f5268026526460fc1b5fbdf5ca13648c87c005e931458982b2a60b89eee8ba537a4222513dbe6278e60aa2edc4f59
|
7
|
+
data.tar.gz: 73b583678cbb9982b67928875df86a715c18753d6b5abb921e088efccac7b5b4f54dac776717c7d989fe63492eafe53bf44e78b7d97543873fbc835056b4743e
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.0
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Christopher Aue
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# NetlinkProcEvent
|
2
|
+
|
3
|
+
Bindings for netlink to handle process events like fork, exec, etc.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'netlink_proc_events'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install netlink_proc_events
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
require 'netlink_proc_event'
|
25
|
+
|
26
|
+
NetlinkProcEvent.on :PROC_EVENT_FORK do |event|
|
27
|
+
puts "#{event[:pid]} forked"
|
28
|
+
end
|
29
|
+
|
30
|
+
NetlinkProcEvent.on :PROC_EVENT_EXEC do |event|
|
31
|
+
puts "#{event[:pid]} exec'd"
|
32
|
+
end
|
33
|
+
|
34
|
+
NetlinkProcEvent.on :PROC_EVENT_EXIT do |event|
|
35
|
+
puts "#{event[:pid]} killed"
|
36
|
+
end
|
37
|
+
|
38
|
+
loop do
|
39
|
+
Kernel.select([NetlinkProcEvent.socket]).each do |socket|
|
40
|
+
NetlinkProcEvent.handle_events
|
41
|
+
end
|
42
|
+
end
|
43
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015, Christopher Aue <mail@christopheraue.net>
|
3
|
+
#
|
4
|
+
# This file is part of the ruby netlink_proc_event gem. It is subject to the license terms in
|
5
|
+
# the LICENSE file found in the top-level directory of this distribution and at
|
6
|
+
# http://github.com/christopheraue/netlink_proc_event.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'netlink_proc_event/version'
|
10
|
+
require 'netlink_proc_event/libnl'
|
11
|
+
require 'socket'
|
12
|
+
|
13
|
+
module NetlinkProcEvent
|
14
|
+
class << self
|
15
|
+
attr_writer :logger
|
16
|
+
|
17
|
+
def socket
|
18
|
+
UNIXSocket.for_fd(Libnl.nl_socket_get_fd(nl_socket))
|
19
|
+
end
|
20
|
+
|
21
|
+
def handle_events
|
22
|
+
nl_sockaddr = FFI::MemoryPointer.new(32)
|
23
|
+
ptr_to_msg_ptr = FFI::MemoryPointer.new(:pointer)
|
24
|
+
|
25
|
+
msg_length = Libnl.nl_recv(nl_socket, nl_sockaddr, ptr_to_msg_ptr, nil)
|
26
|
+
msg_ptr = ptr_to_msg_ptr.read_pointer
|
27
|
+
msg_valid = Libnl.nlmsg_ok(msg_ptr, msg_length) > 0
|
28
|
+
|
29
|
+
if msg_length > 0 && msg_ptr && msg_valid
|
30
|
+
msg_payload_ptr = Libnl.nlmsg_data(msg_ptr)
|
31
|
+
msg_payload = Libnl::Cn_data_msg.new(msg_payload_ptr)
|
32
|
+
handle_event(msg_payload)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def on(event, &handler)
|
37
|
+
check_event(event)
|
38
|
+
subscribe_to_proc_events
|
39
|
+
event_handlers[event] ||= []
|
40
|
+
event_handlers[event] << handler
|
41
|
+
handler
|
42
|
+
end
|
43
|
+
|
44
|
+
def off(event, handler)
|
45
|
+
check_event(event)
|
46
|
+
return unless event_handlers[event]
|
47
|
+
event_handlers[event].delete(handler)
|
48
|
+
event_handlers.delete(event) if event_handlers[event].empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def nl_socket
|
54
|
+
@nl_socket ||= Libnl.nl_socket_alloc.tap do |socket|
|
55
|
+
Libnl.nl_socket_disable_seq_check(socket)
|
56
|
+
Libnl.nl_join_groups(socket, Libnl::CN_IDX_PROC)
|
57
|
+
Libnl.log(@logger, "Netlink connection attempt", Libnl.nl_connect(socket, Libnl::NETLINK_CONNECTOR))
|
58
|
+
Libnl.nl_socket_disable_auto_ack(socket)
|
59
|
+
Libnl.nl_socket_disable_seq_check(socket)
|
60
|
+
Libnl.nl_socket_enable_msg_peek(socket)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def event_handlers
|
65
|
+
@event_handlers ||= {}
|
66
|
+
end
|
67
|
+
|
68
|
+
def check_event(event)
|
69
|
+
Libnl::Event[event] || raise("Unknown event #{event}.")
|
70
|
+
end
|
71
|
+
|
72
|
+
def subscribe_to_proc_events
|
73
|
+
return if @subscribed_to_proc_events
|
74
|
+
|
75
|
+
msg = Libnl.nlmsg_alloc_simple(Libnl::NLMSG_DONE, 0)
|
76
|
+
data = Libnl.nlmsg_reserve(msg, 24, 4)
|
77
|
+
|
78
|
+
proc_message = Libnl::Cn_msg.new(data)
|
79
|
+
proc_message[:idx] = Libnl::CN_IDX_PROC
|
80
|
+
proc_message[:val] = Libnl::CN_VAL_PROC
|
81
|
+
proc_message[:data] = 1
|
82
|
+
proc_message[:len] = 4 # Contains an int
|
83
|
+
proc_message[:seq] = 0
|
84
|
+
proc_message[:ack] = 0
|
85
|
+
|
86
|
+
Libnl.log(@logger, "Netlink subscribed to proc events", Libnl.nl_send_auto(nl_socket, msg), 'Success')
|
87
|
+
|
88
|
+
@subscribed_to_proc_events = true
|
89
|
+
end
|
90
|
+
|
91
|
+
def handle_event(event)
|
92
|
+
if event_handlers[event[:what]]
|
93
|
+
event_handlers[event[:what]].each{ |handler| handler.call(event) }
|
94
|
+
true
|
95
|
+
else
|
96
|
+
false
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015, Christopher Aue <mail@christopheraue.net>
|
3
|
+
#
|
4
|
+
# This file is part of the ruby netlink_proc_event gem. It is subject to the license terms in
|
5
|
+
# the LICENSE file found in the top-level directory of this distribution and at
|
6
|
+
# http://github.com/christopheraue/netlink_proc_event.
|
7
|
+
#
|
8
|
+
|
9
|
+
# derived from https://github.com/cultureulterior/ruby-netlink-libnl3/blob/master/libnl3.rb
|
10
|
+
|
11
|
+
require 'ffi'
|
12
|
+
require 'ffi/tools/const_generator'
|
13
|
+
|
14
|
+
module NetlinkProcEvent
|
15
|
+
module Libnl
|
16
|
+
extend FFI::Library
|
17
|
+
ffi_lib 'libnl-3.so'
|
18
|
+
|
19
|
+
%w(CN_IDX_PROC CN_VAL_PROC NETLINK_CONNECTOR NLMSG_DONE).each do |const|
|
20
|
+
const_set(const,
|
21
|
+
FFI::ConstGenerator.new(nil, :required => true) do |gen|
|
22
|
+
gen.include 'linux/connector.h'
|
23
|
+
gen.include 'linux/netlink.h'
|
24
|
+
gen.const(const)
|
25
|
+
end[const].to_i
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
Event = enum(
|
30
|
+
:PROC_EVENT_NONE , 0x00000000,
|
31
|
+
:PROC_EVENT_FORK , 0x00000001,
|
32
|
+
:PROC_EVENT_EXEC , 0x00000002,
|
33
|
+
:PROC_EVENT_UID , 0x00000004,
|
34
|
+
:PROC_EVENT_GID , 0x00000040,
|
35
|
+
:PROC_EVENT_SID , 0x00000080,
|
36
|
+
:PROC_EVENT_PTRACE , 0x00000100,
|
37
|
+
:PROC_EVENT_COMM , 0x00000200,
|
38
|
+
:PROC_EVENT_EXIT , -0x80000000)
|
39
|
+
|
40
|
+
class Cn_data_msg < FFI::Struct
|
41
|
+
layout :idx, :uint32,
|
42
|
+
:val, :uint32,
|
43
|
+
:seq, :uint32,
|
44
|
+
:ack, :uint32,
|
45
|
+
:len, :uint16,
|
46
|
+
:flags, :uint16,
|
47
|
+
:what, Event,
|
48
|
+
:cpu, :uint32,
|
49
|
+
:timestamp_ns, :uint64,
|
50
|
+
:pid, :uint32,
|
51
|
+
:tid, :uint32
|
52
|
+
end
|
53
|
+
|
54
|
+
class Cn_msg < FFI::Struct
|
55
|
+
layout :idx, :uint32,
|
56
|
+
:val, :uint32,
|
57
|
+
:seq, :uint32,
|
58
|
+
:ack, :uint32,
|
59
|
+
:len, :uint16,
|
60
|
+
:flags, :uint16,
|
61
|
+
:data, :uint32
|
62
|
+
end
|
63
|
+
|
64
|
+
attach_function :nl_socket_alloc, [], :pointer
|
65
|
+
attach_function :nl_socket_get_fd, [:pointer], :int
|
66
|
+
attach_function :nl_connect, [:pointer,:int], :int
|
67
|
+
attach_function :nlmsg_data, [:pointer], :pointer
|
68
|
+
attach_function :nl_send_auto, [:pointer,:pointer], :int
|
69
|
+
attach_function :nl_geterror, [:int], :string
|
70
|
+
attach_function :nl_socket_disable_seq_check, [:pointer], :void
|
71
|
+
attach_function :nlmsg_alloc_simple, [:int, :int], :pointer
|
72
|
+
attach_function :nlmsg_reserve, [:pointer, :size_t, :int], :pointer
|
73
|
+
attach_function :nl_socket_disable_auto_ack, [:pointer], :void
|
74
|
+
attach_function :nl_join_groups, [:pointer, :int], :void
|
75
|
+
attach_function :nl_socket_enable_msg_peek, [:pointer], :void
|
76
|
+
attach_function :nl_recv, [:pointer, :pointer, :pointer, :pointer], :int
|
77
|
+
attach_function :nlmsg_ok, [:pointer, :int], :int
|
78
|
+
|
79
|
+
def self.log(logger, what, error, abovezero = nil)
|
80
|
+
return unless logger
|
81
|
+
if abovezero && error >= 0
|
82
|
+
logger.debug "#{what}: #{abovezero} (#{error})"
|
83
|
+
else
|
84
|
+
logger.debug "#{what}: #{nl_geterror(error)} (#{error})"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015, Christopher Aue <mail@christopheraue.net>
|
3
|
+
#
|
4
|
+
# This file is part of the ruby netlink_proc_event gem. It is subject to the license terms in
|
5
|
+
# the LICENSE file found in the top-level directory of this distribution and at
|
6
|
+
# http://github.com/christopheraue/netlink_proc_event.
|
7
|
+
#
|
8
|
+
|
9
|
+
module NetlinkProcEvent
|
10
|
+
VERSION = "0.1.0"
|
11
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'netlink_proc_event/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "netlink_proc_event"
|
8
|
+
spec.version = NetlinkProcEvent::VERSION
|
9
|
+
spec.authors = ["Christopher Aue"]
|
10
|
+
spec.email = ["mail@christopheraue.net"]
|
11
|
+
|
12
|
+
spec.summary = "Netlink bindings to subscribe to process events (exec, fork, etc.)."
|
13
|
+
spec.homepage = "https://github.com/christopheraue/ruby-netlink_proc_events"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_development_dependency "bundler", "~> 1.8"
|
20
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
21
|
+
spec.add_runtime_dependency 'ffi', '~> 1.9'
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: netlink_proc_event
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Christopher Aue
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.8'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ffi
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.9'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.9'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- mail@christopheraue.net
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".rspec"
|
64
|
+
- ".ruby-version"
|
65
|
+
- Gemfile
|
66
|
+
- LICENSE
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- lib/netlink_proc_event.rb
|
70
|
+
- lib/netlink_proc_event/libnl.rb
|
71
|
+
- lib/netlink_proc_event/version.rb
|
72
|
+
- netlink_proc_event.gemspec
|
73
|
+
homepage: https://github.com/christopheraue/ruby-netlink_proc_events
|
74
|
+
licenses:
|
75
|
+
- MIT
|
76
|
+
metadata: {}
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 2.4.5
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: Netlink bindings to subscribe to process events (exec, fork, etc.).
|
97
|
+
test_files: []
|