fluent-plugin-pcapng 0.0.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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-pcapng.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 enukane
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,57 @@
1
+ # Fluent::Plugin::Pcapng
2
+
3
+ fluent-plugin-pcapng is an input plug-in for Fluentd.
4
+ It runs tshark with specified configuration and extract given packet fields.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'fluent-plugin-pcapng'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install fluent-plugin-pcapng
19
+
20
+ ## Usage
21
+
22
+ Add the following lines into your fluentd config.
23
+
24
+ simple case:
25
+
26
+ ```
27
+ <source>
28
+ type pcapng
29
+
30
+ interface eth0
31
+ fields frame.time,eth.dst,eth.src,eth.type
32
+ </source>
33
+ ```
34
+
35
+ advanced case:
36
+
37
+ ```
38
+ <source>
39
+ type pcapng
40
+
41
+ tag mypcap
42
+ interface eth0
43
+ fields frame.time,frame.time_epoch,ip.src,ip.dst,ip.proto
44
+ types time,double,string,string,long
45
+ convertdot __
46
+ </source>
47
+ ```
48
+
49
+ ## Configuration
50
+
51
+ |name|type|required?|default|description|
52
+ |:---|:---|:--------|:------|:----------|
53
+ | interface | string | required | "eth0" | interface to capture |
54
+ | fields | array | required | none | list of field to extract (-e on tshark) |
55
+ | types | array | optional | "string" for all | list of type for each field ("long", "double", "string", "time") |
56
+ | convertdot | string | optional | none | convert "." in field name (for outputing int DB who doesn't accept "dot" in schema) |
57
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -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
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "fluent-plugin-pcapng"
7
+ spec.version = "0.0.1"
8
+ spec.authors = ["enukane"]
9
+ spec.email = ["enukane@glenda9.org"]
10
+ spec.description = %q{Fluentd plugin for tshark (pcapng) monitoring from specified interface}
11
+ spec.summary = %q{Fluentd input plugin for monitoring packets received in specified interface}
12
+ spec.homepage = "https://github.com/enukane/fluent-plugin-pcapng"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "rake"
22
+ end
@@ -0,0 +1,165 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module Fluent
18
+ class PcapngInput < Input
19
+ Plugin.register_input('pcapng', self)
20
+
21
+ require 'open3'
22
+ require 'csv'
23
+ require 'time'
24
+
25
+ LONG="long"
26
+ DOUBLE="double"
27
+ STRING="string"
28
+ TIME="time"
29
+
30
+ def initialize
31
+ super
32
+ end
33
+
34
+ config_param :tag, :string, :default => "pcapng"
35
+ config_param :interface, :string, :default => 'ge0'
36
+ config_param :convertdot, :string, :default => nil
37
+ config_param :fields, :default => [] do |val|
38
+ val.split(',')
39
+ end
40
+ config_param :types, :default => [] do |val|
41
+ val.split(',')
42
+ end
43
+
44
+ def configure(conf)
45
+ super
46
+
47
+ if @fields != nil and @fields == []
48
+ raise ConfigError, "'fields' option is required on pcapng input"
49
+ end
50
+
51
+ if @types and @types.length != @fields.length
52
+ raise ConfigError, "'types' length must be equal to 'fields' length"
53
+ end
54
+ end
55
+
56
+ def start
57
+ super
58
+
59
+ @thread = Thread.new(&method(:run))
60
+ end
61
+
62
+ def shutdown
63
+ if @th_tshark and @th_tshark.alive?
64
+ Process.kill("INT", @th_tshark.pid)
65
+ end
66
+ @thread.join
67
+ rescue => e
68
+ log.error "pcapng failed to shutdown", :error => e.to_s,
69
+ :error_class => e.class.to_s
70
+ log.error_backtrace e.backtrace
71
+ end
72
+
73
+ def run
74
+ options = build_options(@fields)
75
+ cmdline = "tshark -i #{@interface} -T fields -E separator=\",\" -E quote=d #{options}"
76
+ print cmdline + "\n"
77
+ stdin, stdout, stderr, @th_tshark = *Open3.popen3(cmdline)
78
+
79
+ while @th_tshark.alive?
80
+ collect_tshark_output(stdout)
81
+ end
82
+ rescue => e
83
+ log.error "unexpected error", :error => e.to_s
84
+ log.error_backtrace e.backtrace
85
+ end
86
+
87
+ def build_options(fields)
88
+ options = ""
89
+ fields.each do |field|
90
+ options += "-e \"#{field}\" "
91
+ end
92
+ return options
93
+ end
94
+
95
+ def collect_tshark_output(stdout)
96
+ collected = []
97
+ begin
98
+ readlines_nonblock(stdout).each do |line|
99
+ array = CSV.parse(line).flatten
100
+ collected << array
101
+ end
102
+ rescue => e
103
+ log.error "pcapng failed to read or parse line", :error => e.to_s,
104
+ :error_class => e.class.to_s
105
+ end
106
+
107
+ collected.each do |ary|
108
+ router.emit(@tag, Engine.now, generate_record(ary))
109
+ end
110
+ rescue => e
111
+ log.error "pcapng failed to collect output from tshark",
112
+ :error => e.to_s,
113
+ :error_class => e.class.to_s
114
+ end
115
+
116
+ def readlines_nonblock(io)
117
+ @nbbuffer = "" if @nbbuffer == nil
118
+ @nbbuffer += io.read_nonblock(65535)
119
+ lines = []
120
+ while idx = @nbbuffer.index("\n")
121
+ lines << @nbbuffer[0..idx-1]
122
+ @nbbuffer = @nbbuffer[idx+1..-1]
123
+ end
124
+ return lines
125
+ rescue
126
+ return []
127
+ end
128
+
129
+ def generate_record(array)
130
+ fields = @fields
131
+ if fields.length != array.length
132
+ return {}
133
+ end
134
+ carray = convert_types(array)
135
+ if @convertdot
136
+ fields = fields.map{|field| field.gsub(".", @convertdot)}
137
+ end
138
+ return Hash[[fields, carray].transpose]
139
+ end
140
+
141
+ def convert_types(array)
142
+ return [array, @types].transpose.map{|val, type|
143
+ convert_type(val, type)
144
+ }
145
+ end
146
+
147
+ def convert_type val, type
148
+ v = val.to_s.gsub("\"", "")
149
+ v = "" if val == nil
150
+ case type
151
+ when LONG
152
+ if v.is_a?(String) and v.match(/^0x[0-9a-fA-F]+$/)
153
+ v = v.hex
154
+ else
155
+ v = v.to_i
156
+ end
157
+ when DOUBLE
158
+ v = v.to_f
159
+ when TIME
160
+ v = Time.parse(v)
161
+ end
162
+ return v
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,15 @@
1
+ <source>
2
+ type pcapng
3
+ id pcap_input
4
+
5
+ tag mypcap
6
+ interface wlan2
7
+ fields radiotap.channel.freq,wlan.fc.type_subtype,wlan.ta
8
+ types long,long,string
9
+ convertdot __
10
+ </source>
11
+
12
+ <match mypcap>
13
+ type stdout
14
+ id stdout_output
15
+ </match>
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-pcapng
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - enukane
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-10-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Fluentd plugin for tshark (pcapng) monitoring from specified interface
47
+ email:
48
+ - enukane@glenda9.org
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE.txt
56
+ - README.md
57
+ - Rakefile
58
+ - fluent-plugin-pcapng.gemspec
59
+ - lib/fluent/plugin/in_pcapng.rb
60
+ - sample/pcapng.conf.sample
61
+ homepage: https://github.com/enukane/fluent-plugin-pcapng
62
+ licenses:
63
+ - MIT
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ segments:
75
+ - 0
76
+ hash: 573394323
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ segments:
84
+ - 0
85
+ hash: 573394323
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 1.8.23
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Fluentd input plugin for monitoring packets received in specified interface
92
+ test_files: []