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 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
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.2.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in netlink_proc_events.gemspec
4
+ gemspec
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,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -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: []