fluent-plugin-netflow-enchanced 1.0.0.rc1
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.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/.travis.yml +18 -0
- data/Gemfile +3 -0
- data/README.md +180 -0
- data/Rakefile +14 -0
- data/VERSION +1 -0
- data/example/fluentd.conf +9 -0
- data/fluent-plugin-netflow.gemspec +24 -0
- data/lib/fluent/plugin/in_netflow.rb +80 -0
- data/lib/fluent/plugin/netflow_fields.yaml +302 -0
- data/lib/fluent/plugin/netflow_records.rb +160 -0
- data/lib/fluent/plugin/parser_netflow.rb +403 -0
- data/lib/fluent/plugin/vash.rb +75 -0
- data/test/dump/netflow.v5.dump +0 -0
- data/test/dump/netflow.v9.dump +0 -0
- data/test/dump/netflow.v9.flowStartMilliseconds.dump +0 -0
- data/test/dump/netflow.v9.mpls-data.dump +0 -0
- data/test/dump/netflow.v9.mpls-template.dump +0 -0
- data/test/dump/netflow.v9.sampler.dump +0 -0
- data/test/dump/netflow.v9.sampler_template.dump +0 -0
- data/test/dump/netflow.v9.template.as2.dump +0 -0
- data/test/dump/netflow.v9.template.dump +0 -0
- data/test/dump/netflow.v9.template.flowStartMilliseconds.dump +0 -0
- data/test/helper.rb +26 -0
- data/test/test_in_netflow.rb +34 -0
- data/test/test_parser_netflow.rb +380 -0
- data/test/test_parser_netflow9.rb +223 -0
- metadata +132 -0
@@ -0,0 +1,223 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class Netflow9ParserTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
Fluent::Test.setup
|
6
|
+
end
|
7
|
+
|
8
|
+
def create_parser(conf={})
|
9
|
+
parser = Fluent::Plugin::NetflowParser.new
|
10
|
+
parser.configure(Fluent::Config::Element.new('ROOT', '', conf, []))
|
11
|
+
parser
|
12
|
+
end
|
13
|
+
|
14
|
+
def raw_template
|
15
|
+
@raw_template ||= File.read(File.expand_path('../dump/netflow.v9.template.dump', __FILE__))
|
16
|
+
end
|
17
|
+
|
18
|
+
def raw_flowStartMilliseconds_template
|
19
|
+
@raw_flowStartMilliseconds_template ||= File.read(File.expand_path('../dump/netflow.v9.template.flowStartMilliseconds.dump', __FILE__))
|
20
|
+
end
|
21
|
+
|
22
|
+
def raw_mpls_template
|
23
|
+
@raw_mpls_template ||= File.read(File.expand_path('../dump/netflow.v9.mpls-template.dump', __FILE__))
|
24
|
+
end
|
25
|
+
|
26
|
+
def raw_data
|
27
|
+
@raw_data ||= File.read(File.expand_path('../dump/netflow.v9.dump', __FILE__))
|
28
|
+
end
|
29
|
+
|
30
|
+
def raw_flowStartMilliseconds_data
|
31
|
+
@raw_flowStartMilliseconds_data ||= File.read(File.expand_path('../dump/netflow.v9.flowStartMilliseconds.dump', __FILE__))
|
32
|
+
end
|
33
|
+
|
34
|
+
def raw_mpls_data
|
35
|
+
@raw_mpls_data ||= File.read(File.expand_path('../dump/netflow.v9.mpls-data.dump', __FILE__))
|
36
|
+
end
|
37
|
+
|
38
|
+
def raw_sampler_template
|
39
|
+
@raw_sampler_template ||= File.read(File.expand_path('../dump/netflow.v9.sampler_template.dump', __FILE__))
|
40
|
+
end
|
41
|
+
|
42
|
+
def raw_sampler_data
|
43
|
+
@raw_sampler_data ||= File.read(File.expand_path('../dump/netflow.v9.sampler.dump', __FILE__))
|
44
|
+
end
|
45
|
+
|
46
|
+
def raw_2byte_as_template
|
47
|
+
@raw_2byte_as_template ||= File.read(File.expand_path('../dump/netflow.v9.template.as2.dump', __FILE__))
|
48
|
+
end
|
49
|
+
|
50
|
+
DEFAULT_HOST = '127.0.0.1'
|
51
|
+
|
52
|
+
test 'parse netflow v9 binary data before loading corresponding template' do
|
53
|
+
parser = create_parser
|
54
|
+
|
55
|
+
assert_equal 92, raw_data.size
|
56
|
+
parser.call(raw_data, DEFAULT_HOST) do |time, record|
|
57
|
+
assert false, 'nothing emitted'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
test 'parse netflow v9 binary data' do
|
62
|
+
parser = create_parser
|
63
|
+
|
64
|
+
parsed = []
|
65
|
+
parser.call raw_template, DEFAULT_HOST
|
66
|
+
parser.call(raw_data, DEFAULT_HOST) do |time, record|
|
67
|
+
parsed << [time, record]
|
68
|
+
end
|
69
|
+
|
70
|
+
assert_equal 1, parsed.size
|
71
|
+
assert_equal Time.parse('2016-02-12T04:02:25Z').to_i, parsed.first[0]
|
72
|
+
expected_record = {
|
73
|
+
# header
|
74
|
+
'version' => 9,
|
75
|
+
'flow_seq_num' => 4645895,
|
76
|
+
'flowset_id' => 260,
|
77
|
+
|
78
|
+
# flowset
|
79
|
+
'in_pkts' => 1,
|
80
|
+
'in_bytes' => 60,
|
81
|
+
'ipv4_src_addr' => '192.168.0.1',
|
82
|
+
'ipv4_dst_addr' => '192.168.0.2',
|
83
|
+
'input_snmp' => 54,
|
84
|
+
'output_snmp' => 29,
|
85
|
+
'last_switched' => '2016-02-12T04:02:09.053Z',
|
86
|
+
'first_switched' => '2016-02-12T04:02:09.053Z',
|
87
|
+
'l4_src_port' => 80,
|
88
|
+
'l4_dst_port' => 32822,
|
89
|
+
'src_as' => 0,
|
90
|
+
'dst_as' => 65000,
|
91
|
+
'bgp_ipv4_next_hop' => '192.168.0.3',
|
92
|
+
'src_mask' => 24,
|
93
|
+
'dst_mask' => 24,
|
94
|
+
'protocol' => 6,
|
95
|
+
'tcp_flags' => 0x12,
|
96
|
+
'src_tos' => 0x0,
|
97
|
+
'direction' => 0,
|
98
|
+
'forwarding_status' => 0b01000000,
|
99
|
+
'flow_sampler_id' => 1,
|
100
|
+
'ingress_vrf_id' => 1610612736,
|
101
|
+
'egress_vrf_id' => 1610612736
|
102
|
+
}
|
103
|
+
assert_equal expected_record, parsed.first[1]
|
104
|
+
end
|
105
|
+
|
106
|
+
test 'parse netflow v9 binary data (flowStartMilliseconds)' do
|
107
|
+
parser = create_parser
|
108
|
+
|
109
|
+
parsed = []
|
110
|
+
parser.call raw_flowStartMilliseconds_template, DEFAULT_HOST
|
111
|
+
parser.call(raw_flowStartMilliseconds_data, DEFAULT_HOST) do |time, record|
|
112
|
+
parsed << [time, record]
|
113
|
+
end
|
114
|
+
|
115
|
+
assert_equal 1, parsed.size
|
116
|
+
assert_equal Time.parse('2016-02-12T04:02:25Z').to_i, parsed.first[0]
|
117
|
+
expected_record = {
|
118
|
+
# header
|
119
|
+
'version' => 9,
|
120
|
+
'flow_seq_num' => 4645895,
|
121
|
+
'flowset_id' => 261,
|
122
|
+
|
123
|
+
# flowset
|
124
|
+
'in_pkts' => 1,
|
125
|
+
'in_bytes' => 60,
|
126
|
+
'ipv4_src_addr' => '192.168.0.1',
|
127
|
+
'ipv4_dst_addr' => '192.168.0.2',
|
128
|
+
'input_snmp' => 54,
|
129
|
+
'output_snmp' => 29,
|
130
|
+
'flowEndMilliseconds' => '2016-02-12T04:02:09.053Z',
|
131
|
+
'flowStartMilliseconds' => '2016-02-12T04:02:09.053Z',
|
132
|
+
'l4_src_port' => 80,
|
133
|
+
'l4_dst_port' => 32822,
|
134
|
+
'src_as' => 0,
|
135
|
+
'dst_as' => 65000,
|
136
|
+
'bgp_ipv4_next_hop' => '192.168.0.3',
|
137
|
+
'src_mask' => 24,
|
138
|
+
'dst_mask' => 24,
|
139
|
+
'protocol' => 6,
|
140
|
+
'tcp_flags' => 0x12,
|
141
|
+
'src_tos' => 0x0,
|
142
|
+
'direction' => 0,
|
143
|
+
'forwarding_status' => 0b01000000,
|
144
|
+
'flow_sampler_id' => 1,
|
145
|
+
'ingress_vrf_id' => 1610612736,
|
146
|
+
'egress_vrf_id' => 1610612736
|
147
|
+
}
|
148
|
+
assert_equal expected_record, parsed.first[1]
|
149
|
+
end
|
150
|
+
|
151
|
+
test 'parse netflow v9 binary data after sampler data is cached' do
|
152
|
+
parser = create_parser
|
153
|
+
|
154
|
+
parsed = []
|
155
|
+
[raw_sampler_template, raw_sampler_data, raw_template].each {|raw| parser.call(raw, DEFAULT_HOST){} }
|
156
|
+
parser.call(raw_data, DEFAULT_HOST) do |time, record|
|
157
|
+
parsed << [time, record]
|
158
|
+
end
|
159
|
+
|
160
|
+
assert_equal 2, parsed.first[1]['sampling_algorithm']
|
161
|
+
assert_equal 5000, parsed.first[1]['sampling_interval']
|
162
|
+
end
|
163
|
+
|
164
|
+
test 'parse netflow v9 binary data with host-based template cache' do
|
165
|
+
parser = create_parser
|
166
|
+
another_host = DEFAULT_HOST.next
|
167
|
+
|
168
|
+
parsed = []
|
169
|
+
parser.call raw_template, DEFAULT_HOST
|
170
|
+
parser.call(raw_data, another_host) do |time, record|
|
171
|
+
assert false, 'nothing emitted'
|
172
|
+
end
|
173
|
+
parser.call raw_template, another_host
|
174
|
+
parser.call(raw_data, another_host) do |time, record|
|
175
|
+
parsed << [time, record]
|
176
|
+
end
|
177
|
+
|
178
|
+
assert_equal 1, parsed.size
|
179
|
+
end
|
180
|
+
|
181
|
+
test 'parse netflow v9 binary data with host-based sampler cache' do
|
182
|
+
parser = create_parser
|
183
|
+
another_host = DEFAULT_HOST.next
|
184
|
+
|
185
|
+
parsed = []
|
186
|
+
[raw_sampler_template, raw_sampler_data, raw_template].each {|raw| parser.call(raw, DEFAULT_HOST){} }
|
187
|
+
parser.call(raw_template, another_host){}
|
188
|
+
parser.call(raw_data, another_host) do |time, record|
|
189
|
+
parsed << [time, record]
|
190
|
+
end
|
191
|
+
|
192
|
+
assert_equal nil, parsed.first[1]['sampling_algorithm']
|
193
|
+
assert_equal nil, parsed.first[1]['sampling_interval']
|
194
|
+
end
|
195
|
+
|
196
|
+
test 'parse netflow v9 binary data with templates whose AS field length varies' do
|
197
|
+
parser = create_parser
|
198
|
+
|
199
|
+
parsed = []
|
200
|
+
[raw_2byte_as_template, raw_template].each {|raw| parser.call(raw, DEFAULT_HOST){} }
|
201
|
+
parser.call(raw_data, DEFAULT_HOST) do |time, record|
|
202
|
+
parsed << [time, record]
|
203
|
+
end
|
204
|
+
|
205
|
+
assert_equal 1, parsed.size
|
206
|
+
assert_equal 0, parsed.first[1]['src_as']
|
207
|
+
assert_equal 65000, parsed.first[1]['dst_as']
|
208
|
+
end
|
209
|
+
|
210
|
+
test 'parse netflow v9 binary data contains mpls information' do
|
211
|
+
parser = create_parser
|
212
|
+
|
213
|
+
parsed = []
|
214
|
+
[raw_sampler_template, raw_sampler_data, raw_mpls_template].each {|raw| parser.call(raw, DEFAULT_HOST){} }
|
215
|
+
parser.call(raw_mpls_data, DEFAULT_HOST) do |time, record|
|
216
|
+
parsed << [time, record]
|
217
|
+
end
|
218
|
+
|
219
|
+
assert_equal 24002, parsed.first[1]['mpls_label_1']
|
220
|
+
assert_equal '192.168.32.100', parsed.first[1]['ipv4_src_addr']
|
221
|
+
assert_equal '172.16.32.2', parsed.first[1]['ipv4_dst_addr']
|
222
|
+
end
|
223
|
+
end
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-netflow-enchanced
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.rc1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Masahiro Nakagawa
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-04-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fluentd
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.14.10
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.14.10
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: bindata
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.1'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '2.1'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.9.2
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 0.9.2
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: test-unit
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '3.0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '3.0'
|
75
|
+
description: Netflow plugin for Fluentd
|
76
|
+
email: repeatedly@gmail.com
|
77
|
+
executables: []
|
78
|
+
extensions: []
|
79
|
+
extra_rdoc_files: []
|
80
|
+
files:
|
81
|
+
- ".gitignore"
|
82
|
+
- ".travis.yml"
|
83
|
+
- Gemfile
|
84
|
+
- README.md
|
85
|
+
- Rakefile
|
86
|
+
- VERSION
|
87
|
+
- example/fluentd.conf
|
88
|
+
- fluent-plugin-netflow.gemspec
|
89
|
+
- lib/fluent/plugin/in_netflow.rb
|
90
|
+
- lib/fluent/plugin/netflow_fields.yaml
|
91
|
+
- lib/fluent/plugin/netflow_records.rb
|
92
|
+
- lib/fluent/plugin/parser_netflow.rb
|
93
|
+
- lib/fluent/plugin/vash.rb
|
94
|
+
- test/dump/netflow.v5.dump
|
95
|
+
- test/dump/netflow.v9.dump
|
96
|
+
- test/dump/netflow.v9.flowStartMilliseconds.dump
|
97
|
+
- test/dump/netflow.v9.mpls-data.dump
|
98
|
+
- test/dump/netflow.v9.mpls-template.dump
|
99
|
+
- test/dump/netflow.v9.sampler.dump
|
100
|
+
- test/dump/netflow.v9.sampler_template.dump
|
101
|
+
- test/dump/netflow.v9.template.as2.dump
|
102
|
+
- test/dump/netflow.v9.template.dump
|
103
|
+
- test/dump/netflow.v9.template.flowStartMilliseconds.dump
|
104
|
+
- test/helper.rb
|
105
|
+
- test/test_in_netflow.rb
|
106
|
+
- test/test_parser_netflow.rb
|
107
|
+
- test/test_parser_netflow9.rb
|
108
|
+
homepage: https://github.com/repeatedly/fluent-plugin-netflow
|
109
|
+
licenses:
|
110
|
+
- Apache License (2.0)
|
111
|
+
metadata: {}
|
112
|
+
post_install_message:
|
113
|
+
rdoc_options: []
|
114
|
+
require_paths:
|
115
|
+
- lib
|
116
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">"
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 1.3.1
|
126
|
+
requirements: []
|
127
|
+
rubyforge_project:
|
128
|
+
rubygems_version: 2.6.8
|
129
|
+
signing_key:
|
130
|
+
specification_version: 4
|
131
|
+
summary: Netflow plugin for Fluentd
|
132
|
+
test_files: []
|