logstash-codec-sflow 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/logstash/codecs/sflow.rb +6 -18
- data/lib/logstash/codecs/sflow/counter_record.rb +7 -0
- data/lib/logstash/codecs/sflow/datagram.rb +3 -2
- data/lib/logstash/codecs/sflow/flow_record.rb +6 -0
- data/lib/logstash/codecs/sflow/packet_header.rb +25 -7
- data/lib/logstash/codecs/sflow/sample.rb +16 -14
- data/lib/logstash/codecs/sflow/util.rb +6 -3
- data/logstash-codec-sflow.gemspec +1 -1
- data/spec/codecs/sflow/packet_header_spec.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd2eaaabdcac4aa04d07417a080f816d3ca10312
|
4
|
+
data.tar.gz: ed4a423a37954b8d3828da46f46b721c3970f208
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4a26572a0c3cd25e870f3858be947ef83489932b20f097a5d8e7032954db83c3980e169acb1f3a96d9b562e1398fb6e02e4dfa2eb1650b9325ed07eaa164c56
|
7
|
+
data.tar.gz: 9ecbdf91625700f3a3396ff712b9a89bd2d5ba26858660d36be61a570ee479b9da8067bc58d5f1b4191e6301b674fc5358773dfd4d2aa243c13c66abc83f26f1
|
@@ -7,31 +7,21 @@ class LogStash::Codecs::Sflow < LogStash::Codecs::Base
|
|
7
7
|
config_name 'sflow'
|
8
8
|
|
9
9
|
# Specify which sflow must not be send in the event
|
10
|
-
config :optional_removed_field, :validate => :array, :default =>
|
11
|
-
'ip_header_length', 'ip_dscp', 'ip_ecn',
|
12
|
-
'ip_total_length', 'ip_identification', 'ip_flags',
|
13
|
-
'ip_fragment_offset', 'ip_ttl', 'ip_checksum',
|
14
|
-
'ip_options', 'tcp_seq_number', 'tcp_ack_number',
|
15
|
-
'tcp_header_length', 'tcp_reserved', 'tcp_is_nonce',
|
16
|
-
'tcp_is_cwr', 'tcp_is_ecn_echo', 'tcp_is_urgent',
|
17
|
-
'tcp_is_ack', 'tcp_is_push', 'tcp_is_reset',
|
18
|
-
'tcp_is_syn', 'tcp_is_fin', 'tcp_window_size',
|
19
|
-
'tcp_checksum', 'tcp_urgent_pointer', 'tcp_options']
|
10
|
+
config :optional_removed_field, :validate => :array, :default => %w(sflow_version ip_version header_size ip_header_length ip_dscp ip_ecn ip_total_length ip_identification ip_flags ip_fragment_offset ip_ttl ip_checksum ip_options tcp_seq_number tcp_ack_number tcp_header_length tcp_reserved tcp_is_nonce tcp_is_cwr tcp_is_ecn_echo tcp_is_urgent tcp_is_ack tcp_is_push tcp_is_reset tcp_is_syn tcp_is_fin tcp_window_size tcp_checksum tcp_urgent_pointer tcp_options)
|
20
11
|
|
21
12
|
|
22
13
|
def initialize(params = {})
|
23
14
|
super(params)
|
24
15
|
@threadsafe = false
|
25
|
-
|
26
|
-
|
27
|
-
'tcp_nbits', 'ip_nbits'] | @optional_removed_field
|
16
|
+
# noinspection RubyResolve
|
17
|
+
@removed_field = %w(record_length record_count record_entreprise record_format sample_entreprise sample_format sample_length sample_count sample_header layer3 layer4 layer4_data header udata) | @optional_removed_field
|
28
18
|
end
|
29
19
|
|
30
20
|
# def initialize
|
31
21
|
|
32
22
|
public
|
33
23
|
def register
|
34
|
-
require
|
24
|
+
require 'logstash/codecs/sflow/datagram'
|
35
25
|
end
|
36
26
|
|
37
27
|
# def register
|
@@ -100,15 +90,13 @@ class LogStash::Codecs::Sflow < LogStash::Codecs::Base
|
|
100
90
|
end
|
101
91
|
end
|
102
92
|
|
103
|
-
if record['record_data']['sample_header'].has_key?(
|
93
|
+
if record['record_data']['sample_header'].has_key?('layer3')
|
104
94
|
record['record_data']['sample_header']['layer3']['header'].each_pair do |k, v|
|
105
95
|
unless k.to_s.eql? 'record_data' or @removed_field.include? k.to_s
|
106
96
|
event["#{k}"] = v
|
107
97
|
end
|
108
98
|
end
|
109
|
-
end
|
110
99
|
|
111
|
-
unless record['record_data']['sample_header']['layer3']['header']['layer4'].to_s.eql? ''
|
112
100
|
record['record_data']['sample_header']['layer3']['header']['layer4'].each_pair do |k, v|
|
113
101
|
unless k.to_s.eql? 'record_data' or @removed_field.include? k.to_s
|
114
102
|
event["#{k}"] = v
|
@@ -171,4 +159,4 @@ class LogStash::Codecs::Sflow < LogStash::Codecs::Base
|
|
171
159
|
yield event
|
172
160
|
end
|
173
161
|
end # def decode
|
174
|
-
end # class LogStash::Filters::Sflow
|
162
|
+
end # class LogStash::Filters::Sflow
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'bindata'
|
4
4
|
|
5
|
+
# noinspection RubyResolve
|
5
6
|
class GenericInterface < BinData::Record
|
6
7
|
endian :big
|
7
8
|
uint32 :interface_index
|
@@ -25,6 +26,7 @@ class GenericInterface < BinData::Record
|
|
25
26
|
uint32 :promiscous_mode
|
26
27
|
end
|
27
28
|
|
29
|
+
# noinspection RubyResolve
|
28
30
|
class EthernetInterfaces < BinData::Record
|
29
31
|
endian :big
|
30
32
|
uint32 :dot3StatsAlignmentErrors
|
@@ -42,6 +44,7 @@ class EthernetInterfaces < BinData::Record
|
|
42
44
|
uint32 :dot3StatsSymbolErrors
|
43
45
|
end
|
44
46
|
|
47
|
+
# noinspection RubyResolve
|
45
48
|
class TokenRing < BinData::Record
|
46
49
|
endian :big
|
47
50
|
uint32 :dot5StatsLineErrors
|
@@ -64,6 +67,7 @@ class TokenRing < BinData::Record
|
|
64
67
|
uint32 :dot5StatsFreqErrors
|
65
68
|
end
|
66
69
|
|
70
|
+
# noinspection RubyResolve
|
67
71
|
class HundredBaseVG < BinData::Record
|
68
72
|
endian :big
|
69
73
|
uint32 :dot12InHighPriorityFrames
|
@@ -82,6 +86,7 @@ class HundredBaseVG < BinData::Record
|
|
82
86
|
uint64 :dot12HCOutHighPriorityOctets
|
83
87
|
end
|
84
88
|
|
89
|
+
# noinspection RubyResolve
|
85
90
|
class Vlan < BinData::Record
|
86
91
|
endian :big
|
87
92
|
uint32 :vlan_id
|
@@ -93,6 +98,7 @@ class Vlan < BinData::Record
|
|
93
98
|
end
|
94
99
|
|
95
100
|
|
101
|
+
# noinspection RubyResolve
|
96
102
|
class ProcessorInformation < BinData::Record
|
97
103
|
endian :big
|
98
104
|
uint32 :five_sec_cpu_percent
|
@@ -102,6 +108,7 @@ class ProcessorInformation < BinData::Record
|
|
102
108
|
uint64 :free_memory
|
103
109
|
end
|
104
110
|
|
111
|
+
# noinspection RubyResolve
|
105
112
|
class HttpCounters < BinData::Record
|
106
113
|
endian :big
|
107
114
|
uint32 :method_option_count
|
@@ -4,6 +4,7 @@ require 'bindata'
|
|
4
4
|
require 'logstash/codecs/sflow/util'
|
5
5
|
require 'logstash/codecs/sflow/sample'
|
6
6
|
|
7
|
+
# noinspection RubyResolve
|
7
8
|
class SFlow < BinData::Record
|
8
9
|
endian :big
|
9
10
|
uint32 :sflow_version
|
@@ -21,8 +22,8 @@ class SFlow < BinData::Record
|
|
21
22
|
bit12 :sample_format
|
22
23
|
uint32 :sample_length
|
23
24
|
choice :sample_data, :selection => lambda { "#{sample_entreprise}-#{sample_format}" } do
|
24
|
-
flow_sample
|
25
|
-
counter_sample
|
25
|
+
flow_sample '0-1'
|
26
|
+
counter_sample '0-2'
|
26
27
|
skip :default, :length => :sample_length
|
27
28
|
end
|
28
29
|
end
|
@@ -4,6 +4,7 @@ require 'bindata'
|
|
4
4
|
require 'logstash/codecs/sflow/util'
|
5
5
|
require 'logstash/codecs/sflow/packet_header'
|
6
6
|
|
7
|
+
# noinspection RubyResolve
|
7
8
|
class RawPacketHeader < BinData::Record
|
8
9
|
endian :big
|
9
10
|
uint32 :protocol
|
@@ -17,6 +18,7 @@ class RawPacketHeader < BinData::Record
|
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
21
|
+
# noinspection RubyResolve
|
20
22
|
class EthernetFrameData < BinData::Record
|
21
23
|
endian :big
|
22
24
|
uint32 :packet_length
|
@@ -27,6 +29,7 @@ class EthernetFrameData < BinData::Record
|
|
27
29
|
uint32 :type
|
28
30
|
end
|
29
31
|
|
32
|
+
# noinspection RubyResolve
|
30
33
|
class IP4Data < BinData::Record
|
31
34
|
endian :big
|
32
35
|
uint32 :ip_packet_length
|
@@ -39,6 +42,7 @@ class IP4Data < BinData::Record
|
|
39
42
|
uint32 :type
|
40
43
|
end
|
41
44
|
|
45
|
+
# noinspection RubyResolve
|
42
46
|
class IP6Data < BinData::Record
|
43
47
|
endian :big
|
44
48
|
uint32 :ip_packet_length
|
@@ -51,6 +55,7 @@ class IP6Data < BinData::Record
|
|
51
55
|
uint32 :ip_priority
|
52
56
|
end
|
53
57
|
|
58
|
+
# noinspection RubyResolve
|
54
59
|
class ExtendedSwitchData < BinData::Record
|
55
60
|
endian :big
|
56
61
|
uint32 :src_vlan
|
@@ -59,6 +64,7 @@ class ExtendedSwitchData < BinData::Record
|
|
59
64
|
uint32 :dst_priority
|
60
65
|
end
|
61
66
|
|
67
|
+
# noinspection RubyResolve
|
62
68
|
class ExtendedRouterData < BinData::Record
|
63
69
|
endian :big
|
64
70
|
uint32 :ip_version
|
@@ -4,6 +4,16 @@ require 'bindata'
|
|
4
4
|
require 'logstash/codecs/sflow/util'
|
5
5
|
|
6
6
|
|
7
|
+
# noinspection RubyResolve
|
8
|
+
class UnknownHeader < BinData::Record
|
9
|
+
mandatory_parameter :size_header
|
10
|
+
|
11
|
+
endian :big
|
12
|
+
bit :udata, :nbits => :size_header
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
# noinspection RubyResolve,RubyResolve
|
7
17
|
class TcpHeader < BinData::Record
|
8
18
|
mandatory_parameter :size_header
|
9
19
|
|
@@ -29,22 +39,27 @@ class TcpHeader < BinData::Record
|
|
29
39
|
array :tcp_options, :initial_length => lambda { (((tcp_header_length * 4) - 20)/4).ceil }, :onlyif => :is_options? do
|
30
40
|
string :tcp_option, :length => 4, :pad_byte => "\0"
|
31
41
|
end
|
32
|
-
bit :nbits => lambda { size_header - (tcp_header_length * 4 * 8) }
|
42
|
+
bit :layer4_data, :nbits => lambda { size_header - (tcp_header_length * 4 * 8) }
|
33
43
|
|
34
44
|
def is_options?
|
35
45
|
tcp_header_length.to_i > 5
|
36
46
|
end
|
37
47
|
end
|
38
48
|
|
49
|
+
# noinspection RubyResolve
|
39
50
|
class UdpHeader < BinData::Record
|
51
|
+
mandatory_parameter :size_header
|
52
|
+
|
40
53
|
endian :big
|
41
54
|
uint16 :src_port
|
42
55
|
uint16 :dst_port
|
43
56
|
uint16 :udp_length
|
44
57
|
uint16 :udp_checksum
|
45
|
-
skip :length => lambda { udp_length - 64 } #skip udp data
|
58
|
+
#skip :length => lambda { udp_length - 64 } #skip udp data
|
59
|
+
bit :layer4_data, :nbits => lambda { size_header - 64 } #skip udp data
|
46
60
|
end
|
47
61
|
|
62
|
+
# noinspection RubyResolve,RubyResolve
|
48
63
|
class IPV4Header < BinData::Record
|
49
64
|
mandatory_parameter :size_header
|
50
65
|
|
@@ -66,8 +81,8 @@ class IPV4Header < BinData::Record
|
|
66
81
|
end
|
67
82
|
choice :layer4, :selection => :ip_protocol do
|
68
83
|
tcp_header 6, :size_header => lambda { size_header - (ip_header_length * 4 * 8) }
|
69
|
-
udp_header 17
|
70
|
-
|
84
|
+
udp_header 17, :size_header => lambda { size_header - (ip_header_length * 4 * 8) }
|
85
|
+
unknown_header :default, :size_header => lambda { size_header - (ip_header_length * 4 * 8) }
|
71
86
|
end
|
72
87
|
|
73
88
|
def is_options?
|
@@ -75,6 +90,8 @@ class IPV4Header < BinData::Record
|
|
75
90
|
end
|
76
91
|
end
|
77
92
|
|
93
|
+
|
94
|
+
# noinspection RubyResolve
|
78
95
|
class IPHeader < BinData::Record
|
79
96
|
mandatory_parameter :size_header
|
80
97
|
|
@@ -82,10 +99,11 @@ class IPHeader < BinData::Record
|
|
82
99
|
bit4 :ip_version
|
83
100
|
choice :header, :selection => :ip_version do
|
84
101
|
ipv4_header 4, :size_header => :size_header
|
85
|
-
|
102
|
+
unknown_header :default, :size_header => lambda { size_header - 4 }
|
86
103
|
end
|
87
104
|
end
|
88
105
|
|
106
|
+
# noinspection RubyResolve
|
89
107
|
class EthernetHeader < BinData::Record
|
90
108
|
mandatory_parameter :size_header
|
91
109
|
|
@@ -95,6 +113,6 @@ class EthernetHeader < BinData::Record
|
|
95
113
|
uint16 :eth_type
|
96
114
|
choice :layer3, :selection => :eth_type do
|
97
115
|
ip_header 2048, :size_header => lambda { size_header - (14 * 8) }
|
98
|
-
|
116
|
+
unknown_header :default, :size_header => lambda { size_header - (14 * 8) }
|
99
117
|
end
|
100
|
-
end
|
118
|
+
end
|
@@ -4,9 +4,10 @@ require 'bindata'
|
|
4
4
|
require 'logstash/codecs/sflow/flow_record'
|
5
5
|
require 'logstash/codecs/sflow/counter_record'
|
6
6
|
|
7
|
+
# noinspection RubyResolve
|
7
8
|
class FlowSample < BinData::Record
|
8
9
|
endian :big
|
9
|
-
uint32 :
|
10
|
+
uint32 :flow_sequence_number
|
10
11
|
uint8 :source_id_type
|
11
12
|
uint24 :source_id_index
|
12
13
|
uint32 :sampling_rate
|
@@ -20,17 +21,18 @@ class FlowSample < BinData::Record
|
|
20
21
|
bit12 :record_format
|
21
22
|
uint32 :record_length
|
22
23
|
choice :record_data, :selection => lambda { "#{record_entreprise}-#{record_format}" } do
|
23
|
-
raw_packet_header
|
24
|
-
ethernet_frame_data
|
25
|
-
ip4_data
|
26
|
-
ip6_data
|
27
|
-
extended_switch_data
|
28
|
-
extended_router_data
|
24
|
+
raw_packet_header '0-1'
|
25
|
+
ethernet_frame_data '0-2'
|
26
|
+
ip4_data '0-3'
|
27
|
+
ip6_data '0-4'
|
28
|
+
extended_switch_data '0-1001'
|
29
|
+
extended_router_data '0-1002'
|
29
30
|
skip :default, :length => :record_length
|
30
31
|
end
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
35
|
+
# noinspection RubyResolve
|
34
36
|
class CounterSample < BinData::Record
|
35
37
|
endian :big
|
36
38
|
uint32 :sample_seq_number
|
@@ -42,13 +44,13 @@ class CounterSample < BinData::Record
|
|
42
44
|
bit12 :record_format
|
43
45
|
uint32 :record_length
|
44
46
|
choice :record_data, :selection => lambda { "#{record_entreprise}-#{record_format}" } do
|
45
|
-
generic_interface
|
46
|
-
ethernet_interfaces
|
47
|
-
token_ring
|
48
|
-
hundred_base_vg
|
49
|
-
vlan
|
50
|
-
processor_information
|
51
|
-
http_counters
|
47
|
+
generic_interface '0-1'
|
48
|
+
ethernet_interfaces '0-2'
|
49
|
+
token_ring '0-3'
|
50
|
+
hundred_base_vg '0-4'
|
51
|
+
vlan '0-5'
|
52
|
+
processor_information '0-1001'
|
53
|
+
http_counters '0-2201'
|
52
54
|
skip :default, :length => :record_length
|
53
55
|
end
|
54
56
|
#processor_information :record_data
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'bindata'
|
4
4
|
require 'ipaddr'
|
5
5
|
|
6
|
+
# noinspection RubyResolve
|
6
7
|
class MacAddress < BinData::Primitive
|
7
8
|
array :bytes, :type => :uint8, :initial_length => 6
|
8
9
|
|
@@ -12,17 +13,18 @@ class MacAddress < BinData::Primitive
|
|
12
13
|
end
|
13
14
|
|
14
15
|
def get
|
15
|
-
self.bytes.collect { |byte| byte.value.to_s(16).rjust(2, '0') }.join(
|
16
|
+
self.bytes.collect { |byte| byte.value.to_s(16).rjust(2, '0') }.join(':')
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
20
|
+
# noinspection RubyResolve,RubyResolve,RubyResolve
|
19
21
|
class IP4Addr < BinData::Primitive
|
20
22
|
endian :big
|
21
23
|
uint32 :storage
|
22
24
|
|
23
25
|
def set(val)
|
24
26
|
ip = IPAddr.new(val)
|
25
|
-
|
27
|
+
unless ip.ipv4?
|
26
28
|
raise ArgumentError, "invalid IPv4 address '#{val}'"
|
27
29
|
end
|
28
30
|
self.storage = ip.to_i
|
@@ -33,13 +35,14 @@ class IP4Addr < BinData::Primitive
|
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
38
|
+
# noinspection RubyResolve
|
36
39
|
class IP6Addr < BinData::Primitive
|
37
40
|
endian :big
|
38
41
|
uint128 :storage
|
39
42
|
|
40
43
|
def set(val)
|
41
44
|
ip = IPAddr.new(val)
|
42
|
-
|
45
|
+
unless ip.ipv6?
|
43
46
|
raise ArgumentError, "invalid IPv6 address `#{val}'"
|
44
47
|
end
|
45
48
|
self.storage = ip.to_i
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-codec-sflow'
|
4
|
-
s.version = '0.
|
4
|
+
s.version = '0.3.0'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "The sflow codec is for decoding SFlow v5 flows."
|
7
7
|
s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
|
@@ -6,7 +6,7 @@ require "logstash/codecs/sflow/packet_header"
|
|
6
6
|
describe UdpHeader do
|
7
7
|
it "should decode udp header" do
|
8
8
|
payload = IO.read(File.join(File.dirname(__FILE__), "udp.dat"), :mode => "rb")
|
9
|
-
decoded = UdpHeader.read(payload)
|
9
|
+
decoded = UdpHeader.new(:size_header => payload.bytesize * 8).read(payload)
|
10
10
|
|
11
11
|
decoded["src_port"].to_s.should eq("20665")
|
12
12
|
decoded["dst_port"].to_s.should eq("514")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-codec-sflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicolas Fraison
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|