├── .github
└── workflows
│ └── test-linux.yaml
├── .gitignore
├── .pre-commit-config.yaml
├── Gemfile
├── LICENSE.txt
├── README.md
├── Rakefile
├── bin
├── console
└── setup
├── commitlint.config.js
├── example
└── fluentd.conf
├── ext
└── sflowtool
│ ├── extconf.rb
│ ├── fluent-plugin-sflow.c
│ ├── sflow.h
│ ├── sflow_v2v4.h
│ └── sflowtool.c
├── fluent-plugin-sflow.gemspec
├── lib
├── fluent
│ └── plugin
│ │ ├── in_sflow.rb
│ │ └── parser_sflow.rb
└── sflowtool.rb
└── test
├── dump
├── sflow.v5.counters.dump
└── sflow.v5.ipv4_without_vlan.dump
└── test_parser_sflow5.rb
/.github/workflows/test-linux.yaml:
--------------------------------------------------------------------------------
1 | name: Test on Ubuntu
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | test:
7 | runs-on: ${{ matrix.os }}
8 | continue-on-error: ${{ matrix.experimental }}
9 | strategy:
10 | fail-fast: false
11 | matrix:
12 | ruby-version: ['3.0', '2.7', '2.6']
13 | os: [ubuntu-latest]
14 | experimental: [false]
15 | include:
16 | - ruby-version: head
17 | os: ubuntu-latest
18 | experimental: true
19 |
20 | name: Test with ruby ${{ matrix.ruby-version }} on ${{ matrix.os }}
21 | steps:
22 | - uses: actions/checkout@v2
23 | - name: Set up Ruby
24 | uses: ruby/setup-ruby@v1
25 | with:
26 | ruby-version: ${{ matrix.ruby-version }}
27 | - name: Install dev tools
28 | run: sudo apt-get install gcc make
29 | - name: Install dependencies
30 | run: bundle install
31 | - name: Run tests
32 | run: bundle exec rake
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.bundle/
2 | /.yardoc
3 | /Gemfile.lock
4 | /_yardoc/
5 | /coverage/
6 | /doc/
7 | /pkg/
8 | /spec/reports/
9 | /tmp/
10 |
11 | # Editors
12 | /.idea/
13 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
3 | rev: v5.0.0
4 | hooks:
5 | - id: commitlint
6 | stages: [commit-msg]
7 | additional_dependencies: ['@commitlint/config-conventional']
8 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # Specify your gem's dependencies in fluent-plugin-sflow.gemspec
4 | gemspec
5 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017-2021 Shintaro Kojima
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 all
13 | 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 THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # fluent-plugin-sflow
2 |
3 | [](https://github.com/codeout/fluent-plugin-sflow/actions/workflows/test-linux.yaml)
4 |
5 | ## This branch is valid for Fluentd 0.14.x or later
6 |
7 | See [0.12.x branch](https://github.com/codeout/fluent-plugin-sflow/tree/fluentd-0.12) for Fluentd 0.12.x.
8 |
9 | ## Overview
10 |
11 | [Fluentd](http://fluentd.org/) input plugin that acts as sFlow v2/v4/v5 collector.
12 |
13 | Including a ruby wrapper of [sflowtool](http://www.inmon.com/technology/sflowTools.php) which processes sFlow datagrams to report in JSON format.
14 |
15 |
16 | ## Features
17 |
18 | fluent-plugin-sflow supports many packet formats below. Basically, it can process anything sflowtool can do. :sparkles:
19 |
20 | See [sflowtool document](http://www.inmon.com/technology/sflowTools.php) for more details.
21 |
22 | ### Sample Type
23 |
24 | * Flow Sample
25 | * Counter Sample
26 |
27 | ### Address Family
28 |
29 | * IPv4
30 | * IPv6
31 |
32 | ### Extended Data Type
33 |
34 | * Switch
35 | * Router
36 | * Gateway_v2
37 | * Gateway
38 | * User
39 | * Url
40 | * mplsLabelStack
41 | * Mpls
42 | * Nat
43 | * NatPort
44 | * MplsTunnel
45 | * MplsVC
46 | * MplsFTN
47 | * MplsLDP_FEC
48 | * VlanTunnel
49 | * WifiPayload
50 | * WifiRx
51 | * WifiTx
52 | * Aggregation
53 | * Socket4
54 | * ProxySocket4
55 | * Socket6
56 | * ProxySocket6
57 | * Decap
58 | * VNI
59 | * TCPInfo
60 |
61 | ### Counter Data Type
62 |
63 | * ethernet
64 | * tokenring
65 | * vg
66 | * vlan
67 | * 80211
68 | * processor
69 | * radio
70 | * OFPort
71 | * portName
72 | * OVSDP
73 | * host_hid
74 | * adaptors
75 | * host_parent
76 | * host_cpu
77 | * host_mem
78 | * host_dsk
79 | * host_nio
80 | * host_ip
81 | * host_icmp
82 | * host_tcp
83 | * host_udp
84 | * host_vnode
85 | * host_vcpu
86 | * host_vmem
87 | * host_vdsk
88 | * host_vnio
89 | * host_gpu_nvml
90 | * bcm_tables
91 | * memcache
92 | * memcache2
93 | * http
94 | * JVM
95 | * JMX
96 | * APP
97 | * APP_RESOURCE
98 | * APP_WORKERS
99 | * VDI
100 | * LACP
101 | * SFP
102 |
103 |
104 | ## Requirement
105 |
106 | * Fluentd: 0.14.x or lator
107 | * See [fluentd-0.12 branch](https://github.com/codeout/fluent-plugin-sflow) for Fluentd 0.12.x.
108 | * `gcc` and `make`
109 | * Ruby dev package
110 |
111 | ## Install
112 |
113 | You need to install development tools beforehand.
114 |
115 | :memo: If you see any problem on other platforms rather than Debian, Ubuntu, or CentOS, please [open a new issue](https://github.com/codeout/fluent-plugin-sflow/issues/new).
116 |
117 | ### Debian Linux or Ubuntu Linux
118 |
119 | ```shell
120 | $ sudo apt install -y gcc make
121 | ```
122 |
123 | If you're using ruby installed by `apt`, install `ruby-dev`.
124 | ( Skip if your `ruby` is installed by `rbenv` )
125 |
126 | ```shell
127 | $ sudo apt install -y ruby-dev
128 | ```
129 |
130 | ### CentOS Linux
131 |
132 | ```shell
133 | $ sudo dnf install -y redhat-rpm-config gcc make
134 | ```
135 |
136 | If you're using ruby installed by `dnf` ( or `yum` ), install `ruby-devel`.
137 | ( Skip if your `ruby` is installed by `rbenv` )
138 |
139 | ```shell
140 | $ sudo dnf install -y ruby-devel
141 | ```
142 |
143 | ### fluent-plugin-sflow
144 |
145 | ``` shell
146 | $ gem install fluent-plugin-sflow
147 | ```
148 |
149 | You can also use ```fluent-gem``` or ```td-agent-gem``` instead of ```gem``` command.
150 |
151 |
152 | ## Configuration
153 |
154 | ```
155 |
156 | @type sflow
157 | tag example.sflow
158 |
159 | bind 0.0.0.0
160 | port 6343
161 |
162 | ```
163 |
164 | **bind**
165 |
166 | IP address on which this plugin will accept sFlow.
167 | (Default: '0.0.0.0')
168 |
169 | **port**
170 |
171 | UDP port number on which this plugin will accept sFlow.
172 | (Default: 6343)
173 |
174 |
175 | ## Record Example
176 |
177 | ### Flow Sample
178 |
179 | ``` javascript
180 | {
181 | "datagram_source_ip": "10.1.2.1",
182 | "datagram_size": 240,
183 | "unix_seconds_utc": 1502113217,
184 | "datagram_version": 5,
185 | "agent_sub_id": 0,
186 | "agent": "10.1.2.1",
187 | "packet_sequence_no": 53,
188 | "sys_up_time": 3808877,
189 | "samples_in_packet": 1,
190 | "sample_type_tag": "0:1",
191 | "sample_type": "flow_sample",
192 | "sample_sequence_no": 44,
193 | "source_id": "0:513",
194 | "mean_skip_count": 5,
195 | "sample_pool": 225,
196 | "drop_events": 0,
197 | "input_port": 513,
198 | "output_port": 512,
199 | "flow_block_tag": "0:1002",
200 | "header_protocol": 1,
201 | "sampled_packet_size": 102,
202 | "stripped_bytes": 4,
203 | "header_len": 98,
204 | "header_bytes": "02-05-86-71-7D-03-08-00-27-12-99-09-08-00-45-00-00-54-B0-61-40-00-40-01-79-44-0A-01-02-02-01-00-04-01-08-00-DF-97-04-12-03-AD-D2-1A-87-59-00-00-00-00-F6-61-02-00-00-00-00-00-10-11-12-13-14-15-16-17-18-19-1A-1B-1C-1D-1E-1F-20-21-22-23-24-25-26-27-28-29-2A-2B-2C-2D-2E-2F-30-31-32-33-34-35-36-37",
205 | "dst_mac": "020586717d03",
206 | "src_mac": "080027129909",
207 | "ip_size": 84,
208 | "ip_tot_len": 84,
209 | "src_ip": "10.1.2.2",
210 | "dst_ip": "1.0.4.1",
211 | "ip_protocol": 1,
212 | "ip_tos": 0,
213 | "ip_ttl": 64,
214 | "ip_id": 25008,
215 | "icmp_type": 8,
216 | "icmp_code": 0,
217 | "in_vlan": 0,
218 | "in_priority": 0,
219 | "out_vlan": 0,
220 | "out_priority": 0,
221 | "next_hop": "202.249.2.169",
222 | "src_subnet_mask": 32,
223 | "dst_subnet_mask": 22
224 | }
225 | ```
226 |
227 | ### Counters Sample
228 |
229 | ``` javascript
230 | {
231 | "datagram_source_ip": "10.1.2.1",
232 | "datagram_size": 204,
233 | "unix_seconds_utc": 1502113415,
234 | "datagram_version": 5,
235 | "agent_sub_id": 0,
236 | "agent": "10.1.2.1",
237 | "packet_sequence_no": 54,
238 | "sys_up_time": 3810403,
239 | "samples_in_packet": 1,
240 | "sample_type_tag": "0:2",
241 | "sample_type": "counters_sample",
242 | "sample_sequence_no": 5,
243 | "source_id": "0:512",
244 | "counter_block_tag": "0:2",
245 | "if_index": 512,
246 | "network_type": 6,
247 | "if_speed": 10000000000,
248 | "if_direction": 1,
249 | "if_status": 3,
250 | "if_in_octets": 0,
251 | "if_in_ucast_pkts": 8,
252 | "if_in_multicast_pkts": 121,
253 | "if_in_broadcast_pkts": 0,
254 | "if_in_discards": 0,
255 | "if_in_errors": 0,
256 | "if_in_unknown_protos": 0,
257 | "if_out_octets": 130454,
258 | "if_out_ucast_pkts": 1060,
259 | "if_out_multicast_pkts": 0,
260 | "if_out_broadcast_pkts": 95,
261 | "if_out_discards": 0,
262 | "if_out_errors": 0,
263 | "if_promiscuous_mode": 0,
264 | "dot3_stats_alignment_errors": 0,
265 | "dot3_stats_fcserrors": 0,
266 | "dot3_stats_single_collision_frames": 0,
267 | "dot3_stats_multiple_collision_frames": 0,
268 | "dot3_stats_sqetest_errors": 0,
269 | "dot3_stats_deferred_transmissions": 0,
270 | "dot3_stats_late_collisions": 0,
271 | "dot3_stats_excessive_collisions": 0,
272 | "dot3_stats_internal_mac_transmit_errors": 0,
273 | "dot3_stats_carrier_sense_errors": 0,
274 | "dot3_stats_frame_too_longs": 0,
275 | "dot3_stats_internal_mac_receive_errors": 0,
276 | "dot3_stats_symbol_errors": 0
277 | }
278 | ```
279 |
280 | ## Benchmark
281 |
282 | Here is a quick benchmark on Macbook Pro Mid 2015:
283 |
284 | * sFlow v5 flow samples, 5.88 samples per packet in average
285 | * Fluentd v0.14.17
286 | * 13161 sFlow v5 records/s
287 |
288 |
289 | ## TODO
290 |
291 | * Add more tests
292 | * Please send me the sFlow pcap file if your device is not supported. :cyclone:
293 | 1. Archive your pcap in .zip or .gz
294 | 2. [Open a new issue](https://github.com/codeout/fluent-plugin-sflow/issues/new)
295 | 3. Attach the archive
296 |
297 |
298 | ## Contributing
299 |
300 | Please report issues or enhancement requests to [GitHub issues](https://github.com/codeout/fluent-plugin-sflow/issues).
301 | For questions or feedbacks write to my twitter @codeout.
302 |
303 | Or send a pull request to fix.
304 |
305 |
306 | ## Copyright and License
307 |
308 | Copyright (c) 2017-2021 Shintaro Kojima. Code released under the [MIT license](LICENSE.txt).
309 |
310 | Code includes a part of [sflowtool](http://www.inmon.com/technology/sflowTools.php) which is distributed in the [InMon sFlow License](http://www.inmon.com/technology/sflowlicense.txt).
311 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require "bundler/gem_tasks"
2 | require "rake/extensiontask"
3 | require "rake/testtask"
4 |
5 | task :build => :compile
6 |
7 | Rake::ExtensionTask.new("sflowtool") do |ext|
8 | ext.lib_dir = "lib/sflowtool"
9 | end
10 |
11 | Rake::TestTask.new do |t|
12 | t.verbose = true
13 | end
14 |
15 | task :default => [:compile, :test]
16 |
--------------------------------------------------------------------------------
/bin/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require "bundler/setup"
4 | require "fluent/plugin/sflow"
5 |
6 | # You can add fixtures and/or initialization code here to make experimenting
7 | # with your gem easier. You can also use a different console, if you like.
8 |
9 | # (If you use this, don't forget to add pry to your Gemfile!)
10 | # require "pry"
11 | # Pry.start
12 |
13 | require "irb"
14 | IRB.start(__FILE__)
15 |
--------------------------------------------------------------------------------
/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -euo pipefail
3 | IFS=$'\n\t'
4 | set -vx
5 |
6 | bundle install
7 |
8 | # Do any other automated setup that you need to do here
9 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ["@commitlint/config-conventional"],
3 | rules: {
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/example/fluentd.conf:
--------------------------------------------------------------------------------
1 |
2 | @type sflow
3 | tag example.sflow
4 |
5 | bind 127.0.0.1
6 | port 6343
7 |
8 |
9 |
10 | @type stdout
11 |
12 |
--------------------------------------------------------------------------------
/ext/sflowtool/extconf.rb:
--------------------------------------------------------------------------------
1 | require 'mkmf'
2 |
3 | SFLOWTOOL_VERSION = 3.41
4 |
5 |
6 | have_header('sflow.h')
7 | %w(fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h unistd.h).each do |h|
8 | have_header h
9 | end
10 |
11 | %w(ruby.h alpa/socket.h).each do |h|
12 | have_header h
13 | end
14 |
15 |
16 | %w(getaddrinfo memset select socket strdup strerror strspn strtol).each do |f|
17 | have_func f
18 | end
19 |
20 |
21 | create_header('config.h')
22 | File.open('config.h', 'ab') do |f|
23 | f.puts %(#define VERSION "#{SFLOWTOOL_VERSION}")
24 | end
25 |
26 |
27 | create_makefile('sflowtool/sflowtool')
28 |
--------------------------------------------------------------------------------
/ext/sflowtool/fluent-plugin-sflow.c:
--------------------------------------------------------------------------------
1 | #include "ruby.h"
2 | #include "sflow.h"
3 | #include "arpa/inet.h"
4 |
5 | #include
6 |
7 |
8 | void receiveSFlowDatagram();
9 | void detectAddressFamily(char *addr, SFSample *sample);
10 |
11 |
12 | VALUE wrap_receiveSFlowDatagram(self, data, exporter)
13 | VALUE self, data, exporter;
14 | {
15 | SFSample sample;
16 | char *addr;
17 |
18 | memset(&sample, 0, sizeof(sample));
19 | sample.json = rb_str_new(0, 0);
20 |
21 | sample.rawSample = (uint8_t *)StringValuePtr(data);
22 | sample.rawSampleLen = (int)RSTRING_LEN(data);
23 |
24 | addr = StringValuePtr(exporter);
25 | detectAddressFamily(addr, &sample);
26 |
27 | receiveSFlowDatagram(&sample);
28 |
29 | return sample.json;
30 | }
31 |
32 | void detectAddressFamily(char *addr, SFSample *sample)
33 | {
34 | unsigned char buf[sizeof(struct in6_addr)];
35 |
36 | /* NOTE: See static void receivePacket(int soc) */
37 | if(inet_pton(AF_INET, addr, buf)) {
38 | sample->sourceIP.type = SFLADDRESSTYPE_IP_V4;
39 | memcpy(&sample->sourceIP.address.ip_v4, buf, 4);
40 | } else if(inet_pton(AF_INET6, addr, buf)) {
41 | sample->sourceIP.type = SFLADDRESSTYPE_IP_V6;
42 | memcpy(&sample->sourceIP.address.ip_v6.addr, buf, 16);
43 | }
44 | }
45 |
46 | void Init_sflowtool()
47 | {
48 | VALUE module;
49 |
50 | module = rb_define_module("Sflowtool");
51 | rb_define_module_function(module, "receive_sflow_datagram", wrap_receiveSFlowDatagram, 2);
52 | }
53 |
--------------------------------------------------------------------------------
/ext/sflowtool/sflow.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2002-2011 InMon Corp. Licensed under the terms of the InMon sFlow licence: */
2 | /* http://www.inmon.com/technology/sflowlicense.txt */
3 |
4 | /*
5 | /////////////////////////////////////////////////////////////////////////////////
6 | /////////////////////// sFlow Sampling Packet Data Types ////////////////////////
7 | /////////////////////////////////////////////////////////////////////////////////
8 | */
9 |
10 | #include
11 | #include "ruby.h"
12 |
13 | #ifndef SFLOW_H
14 | #define SFLOW_H 1
15 |
16 | #if defined(__cplusplus)
17 | extern "C" {
18 | #endif
19 |
20 | typedef struct {
21 | uint32_t addr;
22 | } SFLIPv4;
23 |
24 | typedef struct {
25 | uint8_t addr[16];
26 | } SFLIPv6;
27 |
28 | typedef union _SFLAddress_value {
29 | SFLIPv4 ip_v4;
30 | SFLIPv6 ip_v6;
31 | } SFLAddress_value;
32 |
33 | enum SFLAddress_type {
34 | SFLADDRESSTYPE_UNDEFINED = 0,
35 | SFLADDRESSTYPE_IP_V4 = 1,
36 | SFLADDRESSTYPE_IP_V6 = 2
37 | };
38 |
39 | typedef struct _SFLAddress {
40 | uint32_t type; /* enum SFLAddress_type */
41 | SFLAddress_value address;
42 | } SFLAddress;
43 |
44 | /* Packet header data */
45 |
46 | #define SFL_DEFAULT_HEADER_SIZE 128
47 | #define SFL_DEFAULT_COLLECTOR_PORT 6343
48 | #define SFL_DEFAULT_SAMPLING_RATE 400
49 |
50 | /* The header protocol describes the format of the sampled header */
51 | enum SFLHeader_protocol {
52 | SFLHEADER_ETHERNET_ISO8023 = 1,
53 | SFLHEADER_ISO88024_TOKENBUS = 2,
54 | SFLHEADER_ISO88025_TOKENRING = 3,
55 | SFLHEADER_FDDI = 4,
56 | SFLHEADER_FRAME_RELAY = 5,
57 | SFLHEADER_X25 = 6,
58 | SFLHEADER_PPP = 7,
59 | SFLHEADER_SMDS = 8,
60 | SFLHEADER_AAL5 = 9,
61 | SFLHEADER_AAL5_IP = 10, /* e.g. Cisco AAL5 mux */
62 | SFLHEADER_IPv4 = 11,
63 | SFLHEADER_IPv6 = 12,
64 | SFLHEADER_MPLS = 13,
65 | SFLHEADER_POS = 14,
66 | SFLHEADER_IEEE80211MAC = 15,
67 | SFLHEADER_IEEE80211_AMPDU = 16,
68 | SFLHEADER_IEEE80211_AMSDU_SUBFRAME = 17
69 | };
70 |
71 | /* raw sampled header */
72 |
73 | typedef struct _SFLSampled_header {
74 | uint32_t header_protocol; /* (enum SFLHeader_protocol) */
75 | uint32_t frame_length; /* Original length of packet before sampling */
76 | uint32_t stripped; /* header/trailer bytes stripped by sender */
77 | uint32_t header_length; /* length of sampled header bytes to follow */
78 | uint8_t *header_bytes; /* Header bytes */
79 | } SFLSampled_header;
80 |
81 | /* decoded ethernet header */
82 |
83 | typedef struct _SFLSampled_ethernet {
84 | uint32_t eth_len; /* The length of the MAC packet excluding
85 | lower layer encapsulations */
86 | uint8_t src_mac[8]; /* 6 bytes + 2 pad */
87 | uint8_t dst_mac[8];
88 | uint32_t eth_type;
89 | } SFLSampled_ethernet;
90 |
91 | /* decoded IP version 4 header */
92 |
93 | typedef struct _SFLSampled_ipv4 {
94 | uint32_t length; /* The length of the IP packet
95 | excluding lower layer encapsulations */
96 | uint32_t protocol; /* IP Protocol type (for example, TCP = 6, UDP = 17) */
97 | SFLIPv4 src_ip; /* Source IP Address */
98 | SFLIPv4 dst_ip; /* Destination IP Address */
99 | uint32_t src_port; /* TCP/UDP source port number or equivalent */
100 | uint32_t dst_port; /* TCP/UDP destination port number or equivalent */
101 | uint32_t tcp_flags; /* TCP flags */
102 | uint32_t tos; /* IP type of service */
103 | } SFLSampled_ipv4;
104 |
105 | /* decoded IP version 6 data */
106 |
107 | typedef struct _SFLSampled_ipv6 {
108 | uint32_t length; /* The length of the IP packet
109 | excluding lower layer encapsulations */
110 | uint32_t protocol; /* IP Protocol type (for example, TCP = 6, UDP = 17) */
111 | SFLIPv6 src_ip; /* Source IP Address */
112 | SFLIPv6 dst_ip; /* Destination IP Address */
113 | uint32_t src_port; /* TCP/UDP source port number or equivalent */
114 | uint32_t dst_port; /* TCP/UDP destination port number or equivalent */
115 | uint32_t tcp_flags; /* TCP flags */
116 | uint32_t priority; /* IP priority */
117 | } SFLSampled_ipv6;
118 |
119 | /* Extended data types */
120 |
121 | /* Extended switch data */
122 |
123 | typedef struct _SFLExtended_switch {
124 | uint32_t src_vlan; /* The 802.1Q VLAN id of incomming frame */
125 | uint32_t src_priority; /* The 802.1p priority */
126 | uint32_t dst_vlan; /* The 802.1Q VLAN id of outgoing frame */
127 | uint32_t dst_priority; /* The 802.1p priority */
128 | } SFLExtended_switch;
129 |
130 | /* Extended router data */
131 |
132 | typedef struct _SFLExtended_router {
133 | SFLAddress nexthop; /* IP address of next hop router */
134 | uint32_t src_mask; /* Source address prefix mask bits */
135 | uint32_t dst_mask; /* Destination address prefix mask bits */
136 | } SFLExtended_router;
137 |
138 | /* Extended gateway data */
139 | enum SFLExtended_as_path_segment_type {
140 | SFLEXTENDED_AS_SET = 1, /* Unordered set of ASs */
141 | SFLEXTENDED_AS_SEQUENCE = 2 /* Ordered sequence of ASs */
142 | };
143 |
144 | typedef struct _SFLExtended_as_path_segment {
145 | uint32_t type; /* enum SFLExtended_as_path_segment_type */
146 | uint32_t length; /* number of AS numbers in set/sequence */
147 | union {
148 | uint32_t *set;
149 | uint32_t *seq;
150 | } as;
151 | } SFLExtended_as_path_segment;
152 |
153 | typedef struct _SFLExtended_gateway {
154 | SFLAddress nexthop; /* Address of the border router that should
155 | be used for the destination network */
156 | uint32_t as; /* AS number for this gateway */
157 | uint32_t src_as; /* AS number of source (origin) */
158 | uint32_t src_peer_as; /* AS number of source peer */
159 | uint32_t dst_as_path_segments; /* number of segments in path */
160 | SFLExtended_as_path_segment *dst_as_path; /* list of seqs or sets */
161 | uint32_t communities_length; /* number of communities */
162 | uint32_t *communities; /* set of communities */
163 | uint32_t localpref; /* LocalPref associated with this route */
164 | } SFLExtended_gateway;
165 |
166 | typedef struct _SFLString {
167 | uint32_t len;
168 | char *str;
169 | } SFLString;
170 |
171 | /* Extended user data */
172 |
173 | typedef struct _SFLExtended_user {
174 | uint32_t src_charset; /* MIBEnum value of character set used to encode a string - See RFC 2978
175 | Where possible UTF-8 encoding (MIBEnum=106) should be used. A value
176 | of zero indicates an unknown encoding. */
177 | SFLString src_user;
178 | uint32_t dst_charset;
179 | SFLString dst_user;
180 | } SFLExtended_user;
181 |
182 | /* Extended URL data */
183 |
184 | enum SFLExtended_url_direction {
185 | SFLEXTENDED_URL_SRC = 1, /* URL is associated with source address */
186 | SFLEXTENDED_URL_DST = 2 /* URL is associated with destination address */
187 | };
188 |
189 | typedef struct _SFLExtended_url {
190 | uint32_t direction; /* enum SFLExtended_url_direction */
191 | SFLString url; /* URL associated with the packet flow.
192 | Must be URL encoded */
193 | SFLString host; /* The host field from the HTTP header */
194 | } SFLExtended_url;
195 |
196 | /* Extended MPLS data */
197 |
198 | typedef struct _SFLLabelStack {
199 | uint32_t depth;
200 | uint32_t *stack; /* first entry is top of stack - see RFC 3032 for encoding */
201 | } SFLLabelStack;
202 |
203 | typedef struct _SFLExtended_mpls {
204 | SFLAddress nextHop; /* Address of the next hop */
205 | SFLLabelStack in_stack;
206 | SFLLabelStack out_stack;
207 | } SFLExtended_mpls;
208 |
209 | /* Extended NAT data
210 | Packet header records report addresses as seen at the sFlowDataSource.
211 | The extended_nat structure reports on translated source and/or destination
212 | addesses for this packet. If an address was not translated it should
213 | be equal to that reported for the header. */
214 |
215 | typedef struct _SFLExtended_nat {
216 | SFLAddress src; /* Source address */
217 | SFLAddress dst; /* Destination address */
218 | } SFLExtended_nat;
219 |
220 | typedef struct _SFLExtended_nat_port {
221 | uint32_t src_port;
222 | uint32_t dst_port;
223 | } SFLExtended_nat_port;
224 |
225 | /* additional Extended MPLS stucts */
226 |
227 | typedef struct _SFLExtended_mpls_tunnel {
228 | SFLString tunnel_lsp_name; /* Tunnel name */
229 | uint32_t tunnel_id; /* Tunnel ID */
230 | uint32_t tunnel_cos; /* Tunnel COS value */
231 | } SFLExtended_mpls_tunnel;
232 |
233 | typedef struct _SFLExtended_mpls_vc {
234 | SFLString vc_instance_name; /* VC instance name */
235 | uint32_t vll_vc_id; /* VLL/VC instance ID */
236 | uint32_t vc_label_cos; /* VC Label COS value */
237 | } SFLExtended_mpls_vc;
238 |
239 | /* Extended MPLS FEC
240 | - Definitions from MPLS-FTN-STD-MIB mplsFTNTable */
241 |
242 | typedef struct _SFLExtended_mpls_FTN {
243 | SFLString mplsFTNDescr;
244 | uint32_t mplsFTNMask;
245 | } SFLExtended_mpls_FTN;
246 |
247 | /* Extended MPLS LVP FEC
248 | - Definition from MPLS-LDP-STD-MIB mplsFecTable
249 | Note: mplsFecAddrType, mplsFecAddr information available
250 | from packet header */
251 |
252 | typedef struct _SFLExtended_mpls_LDP_FEC {
253 | uint32_t mplsFecAddrPrefixLength;
254 | } SFLExtended_mpls_LDP_FEC;
255 |
256 | /* Extended VLAN tunnel information
257 | Record outer VLAN encapsulations that have
258 | been stripped. extended_vlantunnel information
259 | should only be reported if all the following conditions are satisfied:
260 | 1. The packet has nested vlan tags, AND
261 | 2. The reporting device is VLAN aware, AND
262 | 3. One or more VLAN tags have been stripped, either
263 | because they represent proprietary encapsulations, or
264 | because switch hardware automatically strips the outer VLAN
265 | encapsulation.
266 | Reporting extended_vlantunnel information is not a substitute for
267 | reporting extended_switch information. extended_switch data must
268 | always be reported to describe the ingress/egress VLAN information
269 | for the packet. The extended_vlantunnel information only applies to
270 | nested VLAN tags, and then only when one or more tags has been
271 | stripped. */
272 |
273 | typedef SFLLabelStack SFLVlanStack;
274 | typedef struct _SFLExtended_vlan_tunnel {
275 | SFLVlanStack stack; /* List of stripped 802.1Q TPID/TCI layers. Each
276 | TPID,TCI pair is represented as a single 32 bit
277 | integer. Layers listed from outermost to
278 | innermost. */
279 | } SFLExtended_vlan_tunnel;
280 |
281 | /*
282 | ////////////////// IEEE 802.11 Extension structs ////////////////////
283 |
284 | The 4-byte cipher_suite identifier follows the format of the cipher suite
285 | selector value from the 802.11i (TKIP/CCMP amendment to 802.11i)
286 | The most significant three bytes contain the OUI and the least significant
287 | byte contains the Suite Type.
288 |
289 | The currently assigned values are:
290 |
291 | OUI |Suite type |Meaning
292 | ----------------------------------------------------
293 | 00-0F-AC | 0 | Use group cipher suite
294 | 00-0F-AC | 1 | WEP-40
295 | 00-0F-AC | 2 | TKIP
296 | 00-0F-AC | 3 | Reserved
297 | 00-0F-AC | 4 | CCMP
298 | 00-0F-AC | 5 | WEP-104
299 | 00-0F-AC | 6-255 | Reserved
300 | Vendor OUI | Other | Vendor specific
301 | Other | Any | Reserved
302 | ----------------------------------------------------
303 | */
304 |
305 | typedef uint32_t SFLCipherSuite;
306 |
307 | /* Extended wifi Payload
308 | Used to provide unencrypted version of 802.11 MAC data. If the
309 | MAC data is not encrypted then the agent must not include an
310 | extended_wifi_payload structure.
311 | If 802.11 MAC data is encrypted then the sampled_header structure
312 | should only contain the MAC header (since encrypted data cannot
313 | be decoded by the sFlow receiver). If the sFlow agent has access to
314 | the unencrypted payload, it should add an extended_wifi_payload
315 | structure containing the unencrypted data bytes from the sampled
316 | packet header, starting at the beginning of the 802.2 LLC and not
317 | including any trailing encryption footers. */
318 | /* opaque = flow_data; enterprise = 0; format = 1013 */
319 |
320 | typedef struct _SFLExtended_wifi_payload {
321 | SFLCipherSuite cipherSuite;
322 | SFLSampled_header header;
323 | } SFLExtended_wifi_payload;
324 |
325 | typedef enum {
326 | IEEE80211_A=1,
327 | IEEE80211_B=2,
328 | IEEE80211_G=3,
329 | IEEE80211_N=4,
330 | } SFL_IEEE80211_version;
331 |
332 | /* opaque = flow_data; enterprise = 0; format = 1014 */
333 |
334 | #define SFL_MAX_SSID_LEN 256
335 |
336 | typedef struct _SFLExtended_wifi_rx {
337 | uint32_t ssid_len;
338 | char *ssid;
339 | char bssid[6]; /* BSSID */
340 | SFL_IEEE80211_version version; /* version */
341 | uint32_t channel; /* channel number */
342 | uint64_t speed;
343 | uint32_t rsni; /* received signal to noise ratio, see dot11FrameRprtRSNI */
344 | uint32_t rcpi; /* received channel power, see dot11FrameRprtLastRCPI */
345 | uint32_t packet_duration_us; /* amount of time that the successfully received pkt occupied RF medium.*/
346 | } SFLExtended_wifi_rx;
347 |
348 | /* opaque = flow_data; enterprise = 0; format = 1015 */
349 |
350 | typedef struct _SFLExtended_wifi_tx {
351 | uint32_t ssid_len;
352 | char *ssid; /* SSID string */
353 | char bssid[6]; /* BSSID */
354 | SFL_IEEE80211_version version; /* version */
355 | uint32_t transmissions; /* number of transmissions for sampled
356 | packet.
357 | 0 = unkown
358 | 1 = packet was successfully transmitted
359 | on first attempt
360 | n > 1 = n - 1 retransmissions */
361 | uint32_t packet_duration_us; /* amount of time that the successfully
362 | transmitted packet occupied the
363 | RF medium */
364 | uint32_t retrans_duration_us; /* amount of time that failed transmission
365 | attempts occupied the RF medium */
366 | uint32_t channel; /* channel number */
367 | uint64_t speed;
368 | uint32_t power_mw; /* transmit power in mW. */
369 | } SFLExtended_wifi_tx;
370 |
371 | /* Extended 802.11 Aggregation Data */
372 | /* A flow_sample of an aggregated frame would consist of a packet
373 | header for the whole frame + any other extended structures that
374 | apply (e.g. 80211_tx/rx etc.) + an extended_wifi_aggregation
375 | structure which would contain an array of pdu structures (one
376 | for each PDU in the aggregate). A pdu is simply an array of
377 | flow records, in the simplest case a packet header for each PDU,
378 | but extended structures could be included as well. */
379 |
380 | /* opaque = flow_data; enterprise = 0; format = 1016 */
381 |
382 | struct _SFLFlow_Pdu; /* forward decl */
383 |
384 | typedef struct _SFLExtended_aggregation {
385 | uint32_t num_pdus;
386 | struct _SFFlow_Pdu *pdus;
387 | } SFLExtended_aggregation;
388 | /* TCP connection state */
389 | /* Based on struct tcp_info in /usr/include/linux/tcp.h */
390 | /* opaque = flow_data; enterprise=0; format=2209 */
391 |
392 | typedef enum {
393 | PKTDIR_unknown = 0,
394 | PKTDIR_received = 1,
395 | PKTDIR_sent = 2
396 | } EnumPktDirection;
397 |
398 | typedef struct _SFLExtended_TCP_info {
399 | uint32_t dirn; /* EnumPktDirection: Sampled packet direction */
400 | uint32_t snd_mss; /* Cached effective mss, not including SACKS */
401 | uint32_t rcv_mss; /* Max. recv. segment size */
402 | uint32_t unacked; /* Packets which are "in flight" */
403 | uint32_t lost; /* Lost packets */
404 | uint32_t retrans; /* Retransmitted packets */
405 | uint32_t pmtu; /* Last pmtu seen by socket */
406 | uint32_t rtt; /* smoothed RTT (microseconds) */
407 | uint32_t rttvar; /* RTT variance (microseconds) */
408 | uint32_t snd_cwnd; /* Sending congestion window */
409 | uint32_t reordering; /* Reordering */
410 | uint32_t min_rtt; /* Minimum RTT (microseconds) */
411 | } SFLExtended_TCP_info;
412 |
413 | #define XDRSIZ_SFLEXTENDED_TCP_INFO 48
414 |
415 | /* Extended socket information,
416 | Must be filled in for all application transactions associated with a network socket
417 | Omit if transaction associated with non-network IPC */
418 |
419 | /* IPv4 Socket */
420 | /* opaque = flow_data; enterprise = 0; format = 2100 */
421 | typedef struct _SFLExtended_socket_ipv4 {
422 | uint32_t protocol; /* IP Protocol (e.g. TCP = 6, UDP = 17) */
423 | SFLIPv4 local_ip; /* local IP address */
424 | SFLIPv4 remote_ip; /* remote IP address */
425 | uint32_t local_port; /* TCP/UDP local port number or equivalent */
426 | uint32_t remote_port; /* TCP/UDP remote port number of equivalent */
427 | } SFLExtended_socket_ipv4;
428 |
429 | #define XDRSIZ_SFLEXTENDED_SOCKET4 20
430 |
431 | /* IPv6 Socket */
432 | /* opaque = flow_data; enterprise = 0; format = 2101 */
433 | typedef struct _SFLExtended_socket_ipv6 {
434 | uint32_t protocol; /* IP Protocol (e.g. TCP = 6, UDP = 17) */
435 | SFLIPv6 local_ip; /* local IP address */
436 | SFLIPv6 remote_ip; /* remote IP address */
437 | uint32_t local_port; /* TCP/UDP local port number or equivalent */
438 | uint32_t remote_port; /* TCP/UDP remote port number of equivalent */
439 | } SFLExtended_socket_ipv6;
440 |
441 | #define XDRSIZ_SFLEXTENDED_SOCKET6 44
442 |
443 | typedef enum {
444 | MEMCACHE_PROT_OTHER = 0,
445 | MEMCACHE_PROT_ASCII = 1,
446 | MEMCACHE_PROT_BINARY = 2
447 | } SFLMemcache_prot;
448 |
449 | typedef enum {
450 | MEMCACHE_CMD_OTHER = 0,
451 | MEMCACHE_CMD_SET = 1,
452 | MEMCACHE_CMD_ADD = 2,
453 | MEMCACHE_CMD_REPLACE = 3,
454 | MEMCACHE_CMD_APPEND = 4,
455 | MEMCACHE_CMD_PREPEND = 5,
456 | MEMCACHE_CMD_CAS = 6,
457 | MEMCACHE_CMD_GET = 7,
458 | MEMCACHE_CMD_GETS = 8,
459 | MEMCACHE_CMD_INCR = 9,
460 | MEMCACHE_CMD_DECR = 10,
461 | MEMCACHE_CMD_DELETE = 11,
462 | MEMCACHE_CMD_STATS = 12,
463 | MEMCACHE_CMD_FLUSH = 13,
464 | MEMCACHE_CMD_VERSION = 14,
465 | MEMCACHE_CMD_QUIT = 15,
466 | MEMCACHE_CMD_TOUCH = 16
467 | } SFLMemcache_cmd;
468 |
469 | enum SFLMemcache_operation_status {
470 | MEMCACHE_OP_UNKNOWN = 0,
471 | MEMCACHE_OP_OK = 1,
472 | MEMCACHE_OP_ERROR = 2,
473 | MEMCACHE_OP_CLIENT_ERROR = 3,
474 | MEMCACHE_OP_SERVER_ERROR = 4,
475 | MEMCACHE_OP_STORED = 5,
476 | MEMCACHE_OP_NOT_STORED = 6,
477 | MEMCACHE_OP_EXISTS = 7,
478 | MEMCACHE_OP_NOT_FOUND = 8,
479 | MEMCACHE_OP_DELETED = 9
480 | };
481 |
482 | #define SFL_MAX_MEMCACHE_KEY 255
483 |
484 | typedef struct _SFLSampled_memcache {
485 | uint32_t protocol; /* SFLMemcache_prot */
486 | uint32_t command; /* SFLMemcache_cmd */
487 | SFLString key; /* up to 255 chars */
488 | uint32_t nkeys;
489 | uint32_t value_bytes;
490 | uint32_t duration_uS;
491 | uint32_t status; /* SFLMemcache_operation_status */
492 | } SFLSampled_memcache;
493 |
494 | typedef enum {
495 | SFHTTP_OTHER = 0,
496 | SFHTTP_OPTIONS = 1,
497 | SFHTTP_GET = 2,
498 | SFHTTP_HEAD = 3,
499 | SFHTTP_POST = 4,
500 | SFHTTP_PUT = 5,
501 | SFHTTP_DELETE = 6,
502 | SFHTTP_TRACE = 7,
503 | SFHTTP_CONNECT = 8
504 | } SFLHTTP_method;
505 |
506 | #define SFL_MAX_HTTP_URI 255
507 | #define SFL_MAX_HTTP_HOST 64
508 | #define SFL_MAX_HTTP_REFERRER 255
509 | #define SFL_MAX_HTTP_USERAGENT 128
510 | #define SFL_MAX_HTTP_XFF 64
511 | #define SFL_MAX_HTTP_AUTHUSER 32
512 | #define SFL_MAX_HTTP_MIMETYPE 64
513 |
514 | typedef struct _SFLSampled_http {
515 | SFLHTTP_method method;
516 | uint32_t protocol; /* 1.1=1001 */
517 | SFLString uri; /* URI exactly as it came from the client (up to 255 bytes) */
518 | SFLString host; /* Host value from request header (<= 64 bytes) */
519 | SFLString referrer; /* Referer value from request header (<=255 bytes) */
520 | SFLString useragent; /* User-Agent value from request header (<= 128 bytes)*/
521 | SFLString xff; /* X-Forwarded-For value from request header (<= 64 bytes)*/
522 | SFLString authuser; /* RFC 1413 identity of user (<=32 bytes)*/
523 | SFLString mimetype; /* Mime-Type (<=64 bytes) */
524 | uint64_t req_bytes; /* Content-Length of request */
525 | uint64_t resp_bytes; /* Content-Length of response */
526 | uint32_t uS; /* duration of the operation (microseconds) */
527 | uint32_t status; /* HTTP status code */
528 | } SFLSampled_http;
529 |
530 |
531 | typedef enum {
532 | SFLAPP_SUCCESS = 0,
533 | SFLAPP_OTHER = 1,
534 | SFLAPP_TIMEOUT = 2,
535 | SFLAPP_INTERNAL_ERROR = 3,
536 | SFLAPP_BAD_REQUEST = 4,
537 | SFLAPP_FORBIDDEN = 5,
538 | SFLAPP_TOO_LARGE = 6,
539 | SFLAPP_NOT_IMPLEMENTED = 7,
540 | SFLAPP_NOT_FOUND = 8,
541 | SFLAPP_UNAVAILABLE = 9,
542 | SFLAPP_UNAUTHORIZED = 10,
543 | SFLAPP_NUM_STATUS_CODES
544 | } EnumSFLAPPStatus;
545 |
546 | static const char *SFL_APP_STATUS_names[] = { "SUCCESS",
547 | "OTHER",
548 | "TIMEOUT",
549 | "INTERNAL_ERROR",
550 | "BAD_REQUEST",
551 | "FORBIDDEN",
552 | "TOO_LARGE",
553 | "NOT_IMPLEMENTED",
554 | "NOT_FOUND",
555 | "UNAVAILABLE",
556 | "UNATHORIZED" };
557 |
558 | /* Operation context */
559 | typedef struct {
560 | SFLString application;
561 | SFLString operation; /* type of operation (e.g. authorization, payment) */
562 | SFLString attributes; /* specific attributes associated operation */
563 | } SFLSampled_APP_CTXT;
564 |
565 | #define SFLAPP_MAX_APPLICATION_LEN 32
566 | #define SFLAPP_MAX_OPERATION_LEN 32
567 | #define SFLAPP_MAX_ATTRIBUTES_LEN 255
568 |
569 | /* Sampled Enterprise Operation */
570 | /* opaque = flow_data; enterprise = 0; format = 2202 */
571 | typedef struct {
572 | SFLSampled_APP_CTXT context; /* attributes describing the operation */
573 | SFLString status_descr; /* additional text describing status (e.g. "unknown client") */
574 | uint64_t req_bytes; /* size of request body (exclude headers) */
575 | uint64_t resp_bytes; /* size of response body (exclude headers) */
576 | uint32_t duration_uS; /* duration of the operation (microseconds) */
577 | EnumSFLAPPStatus status; /* status code */
578 | } SFLSampled_APP;
579 |
580 | #define SFLAPP_MAX_STATUS_LEN 32
581 |
582 | typedef struct {
583 | SFLString actor;
584 | } SFLSampled_APP_ACTOR;
585 |
586 | #define SFLAPP_MAX_ACTOR_LEN 64
587 |
588 | typedef struct _SFLExtended_vni {
589 | uint32_t vni; /* virtual network identifier */
590 | } SFLExtended_vni;
591 |
592 | typedef struct _SFLExtended_decap {
593 | uint32_t innerHeaderOffset;
594 | } SFLExtended_decap;
595 |
596 | enum SFLFlow_type_tag {
597 | /* enterprise = 0, format = ... */
598 | SFLFLOW_HEADER = 1, /* Packet headers are sampled */
599 | SFLFLOW_ETHERNET = 2, /* MAC layer information */
600 | SFLFLOW_IPV4 = 3, /* IP version 4 data */
601 | SFLFLOW_IPV6 = 4, /* IP version 6 data */
602 | SFLFLOW_EX_SWITCH = 1001, /* Extended switch information */
603 | SFLFLOW_EX_ROUTER = 1002, /* Extended router information */
604 | SFLFLOW_EX_GATEWAY = 1003, /* Extended gateway router information */
605 | SFLFLOW_EX_USER = 1004, /* Extended TACAS/RADIUS user information */
606 | SFLFLOW_EX_URL = 1005, /* Extended URL information */
607 | SFLFLOW_EX_MPLS = 1006, /* Extended MPLS information */
608 | SFLFLOW_EX_NAT = 1007, /* Extended NAT information */
609 | SFLFLOW_EX_MPLS_TUNNEL = 1008, /* additional MPLS information */
610 | SFLFLOW_EX_MPLS_VC = 1009,
611 | SFLFLOW_EX_MPLS_FTN = 1010,
612 | SFLFLOW_EX_MPLS_LDP_FEC = 1011,
613 | SFLFLOW_EX_VLAN_TUNNEL = 1012, /* VLAN stack */
614 | SFLFLOW_EX_80211_PAYLOAD = 1013,
615 | SFLFLOW_EX_80211_RX = 1014,
616 | SFLFLOW_EX_80211_TX = 1015,
617 | SFLFLOW_EX_AGGREGATION = 1016,
618 | SFLFLOW_EX_NAT_PORT = 1020, /* Extended NAT port information */
619 | SFLFLOW_EX_L2_TUNNEL_OUT = 1021, /* http://sflow.org/sflow_tunnels.txt */
620 | SFLFLOW_EX_L2_TUNNEL_IN = 1022,
621 | SFLFLOW_EX_IPV4_TUNNEL_OUT = 1023,
622 | SFLFLOW_EX_IPV4_TUNNEL_IN = 1024,
623 | SFLFLOW_EX_IPV6_TUNNEL_OUT = 1025,
624 | SFLFLOW_EX_IPV6_TUNNEL_IN = 1026,
625 | SFLFLOW_EX_DECAP_OUT = 1027,
626 | SFLFLOW_EX_DECAP_IN = 1028,
627 | SFLFLOW_EX_VNI_OUT = 1029,
628 | SFLFLOW_EX_VNI_IN = 1030,
629 | SFLFLOW_EX_SOCKET4 = 2100,
630 | SFLFLOW_EX_SOCKET6 = 2101,
631 | SFLFLOW_EX_PROXYSOCKET4 = 2102,
632 | SFLFLOW_EX_PROXYSOCKET6 = 2103,
633 | SFLFLOW_MEMCACHE = 2200,
634 | SFLFLOW_HTTP = 2201,
635 | SFLFLOW_APP = 2202, /* transaction sample */
636 | SFLFLOW_APP_CTXT = 2203, /* enclosing server context */
637 | SFLFLOW_APP_ACTOR_INIT = 2204, /* initiator */
638 | SFLFLOW_APP_ACTOR_TGT = 2205, /* target */
639 | SFLFLOW_HTTP2 = 2206,
640 | SFLFLOW_EX_TCP_INFO = 2209,
641 | };
642 |
643 | typedef union _SFLFlow_type {
644 | SFLSampled_header header;
645 | SFLSampled_ethernet ethernet;
646 | SFLSampled_ipv4 ipv4;
647 | SFLSampled_ipv6 ipv6;
648 | SFLSampled_memcache memcache;
649 | SFLSampled_http http;
650 | SFLSampled_APP app;
651 | SFLSampled_APP_CTXT appCtxt;
652 | SFLSampled_APP_ACTOR appActor;
653 | SFLExtended_switch sw;
654 | SFLExtended_router router;
655 | SFLExtended_gateway gateway;
656 | SFLExtended_user user;
657 | SFLExtended_url url;
658 | SFLExtended_mpls mpls;
659 | SFLExtended_nat nat;
660 | SFLExtended_nat_port nat_port;
661 | SFLExtended_mpls_tunnel mpls_tunnel;
662 | SFLExtended_mpls_vc mpls_vc;
663 | SFLExtended_mpls_FTN mpls_ftn;
664 | SFLExtended_mpls_LDP_FEC mpls_ldp_fec;
665 | SFLExtended_vlan_tunnel vlan_tunnel;
666 | SFLExtended_wifi_payload wifi_payload;
667 | SFLExtended_wifi_rx wifi_rx;
668 | SFLExtended_wifi_tx wifi_tx;
669 | SFLExtended_aggregation aggregation;
670 | SFLExtended_socket_ipv4 socket4;
671 | SFLExtended_socket_ipv6 socket6;
672 | SFLExtended_vni tunnel_vni;
673 | SFLExtended_decap tunnel_decap;
674 | } SFLFlow_type;
675 |
676 | typedef struct _SFLFlow_sample_element {
677 | struct _SFLFlow_sample_element *nxt;
678 | uint32_t tag; /* SFLFlow_type_tag */
679 | uint32_t length;
680 | SFLFlow_type flowType;
681 | } SFLFlow_sample_element;
682 |
683 | enum SFL_sample_tag {
684 | SFLFLOW_SAMPLE = 1, /* enterprise = 0 : format = 1 */
685 | SFLCOUNTERS_SAMPLE = 2, /* enterprise = 0 : format = 2 */
686 | SFLFLOW_SAMPLE_EXPANDED = 3, /* enterprise = 0 : format = 3 */
687 | SFLCOUNTERS_SAMPLE_EXPANDED = 4, /* enterprise = 0 : format = 4 */
688 | SFLRTMETRIC = ((4300 << 12) + 1002),
689 | SFLRTFLOW = ((4300 << 12) + 1003)
690 | };
691 |
692 | typedef struct _SFLFlow_Pdu {
693 | struct _SFLFlow_Pdu *nxt;
694 | uint32_t num_elements;
695 | SFLFlow_sample_element *elements;
696 | } SFLFlow_Pdu;
697 |
698 |
699 | /* Format of a single flow sample */
700 |
701 | typedef struct _SFLFlow_sample {
702 | /* uint32_t tag; */ /* SFL_sample_tag -- enterprise = 0 : format = 1 */
703 | /* uint32_t length; */
704 | uint32_t sequence_number; /* Incremented with each flow sample
705 | generated */
706 | uint32_t source_id; /* fsSourceId */
707 | uint32_t sampling_rate; /* fsPacketSamplingRate */
708 | uint32_t sample_pool; /* Total number of packets that could have been
709 | sampled (i.e. packets skipped by sampling
710 | process + total number of samples) */
711 | uint32_t drops; /* Number of times a packet was dropped due to
712 | lack of resources */
713 | uint32_t input; /* SNMP ifIndex of input interface.
714 | 0 if interface is not known. */
715 | uint32_t output; /* SNMP ifIndex of output interface,
716 | 0 if interface is not known.
717 | Set most significant bit to indicate
718 | multiple destination interfaces
719 | (i.e. in case of broadcast or multicast)
720 | and set lower order bits to indicate
721 | number of destination interfaces.
722 | Examples:
723 | 0x00000002 indicates ifIndex = 2
724 | 0x00000000 ifIndex unknown.
725 | 0x80000007 indicates a packet sent
726 | to 7 interfaces.
727 | 0x80000000 indicates a packet sent to
728 | an unknown number of
729 | interfaces greater than 1.*/
730 | uint32_t num_elements;
731 | SFLFlow_sample_element *elements;
732 | } SFLFlow_sample;
733 |
734 | /* same thing, but the expanded version (for full 32-bit ifIndex numbers) */
735 |
736 | typedef struct _SFLFlow_sample_expanded {
737 | /* uint32_t tag; */ /* SFL_sample_tag -- enterprise = 0 : format = 1 */
738 | /* uint32_t length; */
739 | uint32_t sequence_number; /* Incremented with each flow sample
740 | generated */
741 | uint32_t ds_class; /* EXPANDED */
742 | uint32_t ds_index; /* EXPANDED */
743 | uint32_t sampling_rate; /* fsPacketSamplingRate */
744 | uint32_t sample_pool; /* Total number of packets that could have been
745 | sampled (i.e. packets skipped by sampling
746 | process + total number of samples) */
747 | uint32_t drops; /* Number of times a packet was dropped due to
748 | lack of resources */
749 | uint32_t inputFormat; /* EXPANDED */
750 | uint32_t input; /* SNMP ifIndex of input interface.
751 | 0 if interface is not known. */
752 | uint32_t outputFormat; /* EXPANDED */
753 | uint32_t output; /* SNMP ifIndex of output interface,
754 | 0 if interface is not known. */
755 | uint32_t num_elements;
756 | SFLFlow_sample_element *elements;
757 | } SFLFlow_sample_expanded;
758 |
759 | /* Counter types */
760 |
761 | /* Generic interface counters - see RFC 1573, 2233 */
762 |
763 | typedef struct _SFLIf_counters {
764 | uint32_t ifIndex;
765 | uint32_t ifType;
766 | uint64_t ifSpeed;
767 | uint32_t ifDirection; /* Derived from MAU MIB (RFC 2668)
768 | 0 = unknown, 1 = full-duplex,
769 | 2 = half-duplex, 3 = in, 4 = out */
770 | uint32_t ifStatus; /* bit field with the following bits assigned:
771 | bit 0 = ifAdminStatus (0 = down, 1 = up)
772 | bit 1 = ifOperStatus (0 = down, 1 = up) */
773 | uint64_t ifInOctets;
774 | uint32_t ifInUcastPkts;
775 | uint32_t ifInMulticastPkts;
776 | uint32_t ifInBroadcastPkts;
777 | uint32_t ifInDiscards;
778 | uint32_t ifInErrors;
779 | uint32_t ifInUnknownProtos;
780 | uint64_t ifOutOctets;
781 | uint32_t ifOutUcastPkts;
782 | uint32_t ifOutMulticastPkts;
783 | uint32_t ifOutBroadcastPkts;
784 | uint32_t ifOutDiscards;
785 | uint32_t ifOutErrors;
786 | uint32_t ifPromiscuousMode;
787 | } SFLIf_counters;
788 |
789 | /* Ethernet interface counters - see RFC 2358 */
790 | typedef struct _SFLEthernet_counters {
791 | uint32_t dot3StatsAlignmentErrors;
792 | uint32_t dot3StatsFCSErrors;
793 | uint32_t dot3StatsSingleCollisionFrames;
794 | uint32_t dot3StatsMultipleCollisionFrames;
795 | uint32_t dot3StatsSQETestErrors;
796 | uint32_t dot3StatsDeferredTransmissions;
797 | uint32_t dot3StatsLateCollisions;
798 | uint32_t dot3StatsExcessiveCollisions;
799 | uint32_t dot3StatsInternalMacTransmitErrors;
800 | uint32_t dot3StatsCarrierSenseErrors;
801 | uint32_t dot3StatsFrameTooLongs;
802 | uint32_t dot3StatsInternalMacReceiveErrors;
803 | uint32_t dot3StatsSymbolErrors;
804 | } SFLEthernet_counters;
805 |
806 | /* Token ring counters - see RFC 1748 */
807 |
808 | typedef struct _SFLTokenring_counters {
809 | uint32_t dot5StatsLineErrors;
810 | uint32_t dot5StatsBurstErrors;
811 | uint32_t dot5StatsACErrors;
812 | uint32_t dot5StatsAbortTransErrors;
813 | uint32_t dot5StatsInternalErrors;
814 | uint32_t dot5StatsLostFrameErrors;
815 | uint32_t dot5StatsReceiveCongestions;
816 | uint32_t dot5StatsFrameCopiedErrors;
817 | uint32_t dot5StatsTokenErrors;
818 | uint32_t dot5StatsSoftErrors;
819 | uint32_t dot5StatsHardErrors;
820 | uint32_t dot5StatsSignalLoss;
821 | uint32_t dot5StatsTransmitBeacons;
822 | uint32_t dot5StatsRecoverys;
823 | uint32_t dot5StatsLobeWires;
824 | uint32_t dot5StatsRemoves;
825 | uint32_t dot5StatsSingles;
826 | uint32_t dot5StatsFreqErrors;
827 | } SFLTokenring_counters;
828 |
829 | /* 100 BaseVG interface counters - see RFC 2020 */
830 |
831 | typedef struct _SFLVg_counters {
832 | uint32_t dot12InHighPriorityFrames;
833 | uint64_t dot12InHighPriorityOctets;
834 | uint32_t dot12InNormPriorityFrames;
835 | uint64_t dot12InNormPriorityOctets;
836 | uint32_t dot12InIPMErrors;
837 | uint32_t dot12InOversizeFrameErrors;
838 | uint32_t dot12InDataErrors;
839 | uint32_t dot12InNullAddressedFrames;
840 | uint32_t dot12OutHighPriorityFrames;
841 | uint64_t dot12OutHighPriorityOctets;
842 | uint32_t dot12TransitionIntoTrainings;
843 | uint64_t dot12HCInHighPriorityOctets;
844 | uint64_t dot12HCInNormPriorityOctets;
845 | uint64_t dot12HCOutHighPriorityOctets;
846 | } SFLVg_counters;
847 |
848 | typedef struct _SFLVlan_counters {
849 | uint32_t vlan_id;
850 | uint64_t octets;
851 | uint32_t ucastPkts;
852 | uint32_t multicastPkts;
853 | uint32_t broadcastPkts;
854 | uint32_t discards;
855 | } SFLVlan_counters;
856 |
857 | typedef struct _SFLWifi_counters {
858 | uint32_t dot11TransmittedFragmentCount;
859 | uint32_t dot11MulticastTransmittedFrameCount;
860 | uint32_t dot11FailedCount;
861 | uint32_t dot11RetryCount;
862 | uint32_t dot11MultipleRetryCount;
863 | uint32_t dot11FrameDuplicateCount;
864 | uint32_t dot11RTSSuccessCount;
865 | uint32_t dot11RTSFailureCount;
866 | uint32_t dot11ACKFailureCount;
867 | uint32_t dot11ReceivedFragmentCount;
868 | uint32_t dot11MulticastReceivedFrameCount;
869 | uint32_t dot11FCSErrorCount;
870 | uint32_t dot11TransmittedFrameCount;
871 | uint32_t dot11WEPUndecryptableCount;
872 | uint32_t dot11QoSDiscardedFragmentCount;
873 | uint32_t dot11AssociatedStationCount;
874 | uint32_t dot11QoSCFPollsReceivedCount;
875 | uint32_t dot11QoSCFPollsUnusedCount;
876 | uint32_t dot11QoSCFPollsUnusableCount;
877 | uint32_t dot11QoSCFPollsLostCount;
878 | } SFLWifi_counters;
879 |
880 | /* Processor Information */
881 | /* opaque = counter_data; enterprise = 0; format = 1001 */
882 |
883 | typedef struct _SFLProcessor_counters {
884 | uint32_t five_sec_cpu; /* 5 second average CPU utilization */
885 | uint32_t one_min_cpu; /* 1 minute average CPU utilization */
886 | uint32_t five_min_cpu; /* 5 minute average CPU utilization */
887 | uint64_t total_memory; /* total memory (in bytes) */
888 | uint64_t free_memory; /* free memory (in bytes) */
889 | } SFLProcessor_counters;
890 |
891 | typedef struct _SFLRadio_counters {
892 | uint32_t elapsed_time; /* elapsed time in ms */
893 | uint32_t on_channel_time; /* time in ms spent on channel */
894 | uint32_t on_channel_busy_time; /* time in ms spent on channel and busy */
895 | } SFLRadio_counters;
896 |
897 | /* host sflow */
898 |
899 | enum SFLMachine_type {
900 | SFLMT_unknown = 0,
901 | SFLMT_other = 1,
902 | SFLMT_x86 = 2,
903 | SFLMT_x86_64 = 3,
904 | SFLMT_ia64 = 4,
905 | SFLMT_sparc = 5,
906 | SFLMT_alpha = 6,
907 | SFLMT_powerpc = 7,
908 | SFLMT_m68k = 8,
909 | SFLMT_mips = 9,
910 | SFLMT_arm = 10,
911 | SFLMT_hppa = 11,
912 | SFLMT_s390 = 12
913 | };
914 |
915 | enum SFLOS_name {
916 | SFLOS_unknown = 0,
917 | SFLOS_other = 1,
918 | SFLOS_linux = 2,
919 | SFLOS_windows = 3,
920 | SFLOS_darwin = 4,
921 | SFLOS_hpux = 5,
922 | SFLOS_aix = 6,
923 | SFLOS_dragonfly = 7,
924 | SFLOS_freebsd = 8,
925 | SFLOS_netbsd = 9,
926 | SFLOS_openbsd = 10,
927 | SFLOS_osf = 11,
928 | SFLOS_solaris = 12
929 | };
930 |
931 | typedef struct _SFLMacAddress {
932 | uint8_t mac[8];
933 | } SFLMacAddress;
934 |
935 | typedef struct _SFLAdaptor {
936 | uint32_t ifIndex;
937 | uint32_t num_macs;
938 | SFLMacAddress macs[1];
939 | } SFLAdaptor;
940 |
941 | typedef struct _SFLAdaptorList {
942 | uint32_t capacity;
943 | uint32_t num_adaptors;
944 | SFLAdaptor **adaptors;
945 | } SFLAdaptorList;
946 |
947 | typedef struct _SFLHost_parent {
948 | uint32_t dsClass; /* sFlowDataSource class */
949 | uint32_t dsIndex; /* sFlowDataSource index */
950 | } SFLHost_parent;
951 |
952 |
953 | #define SFL_MAX_HOSTNAME_LEN 64
954 | #define SFL_MAX_OSRELEASE_LEN 32
955 |
956 | typedef struct _SFLHostId {
957 | SFLString hostname;
958 | uint8_t uuid[16];
959 | uint32_t machine_type; /* enum SFLMachine_type */
960 | uint32_t os_name; /* enum SFLOS_name */
961 | SFLString os_release; /* max len 32 bytes */
962 | } SFLHostId;
963 |
964 | typedef struct _SFLHost_nio_counters {
965 | uint64_t bytes_in;
966 | uint32_t pkts_in;
967 | uint32_t errs_in;
968 | uint32_t drops_in;
969 | uint64_t bytes_out;
970 | uint32_t pkts_out;
971 | uint32_t errs_out;
972 | uint32_t drops_out;
973 | } SFLHost_nio_counters;
974 |
975 | typedef struct _SFLHost_cpu_counters {
976 | float load_one; /* 1 minute load avg. */
977 | float load_five; /* 5 minute load avg. */
978 | float load_fifteen; /* 15 minute load avg. */
979 | uint32_t proc_run; /* running threads */
980 | uint32_t proc_total; /* total threads */
981 | uint32_t cpu_num; /* # CPU cores */
982 | uint32_t cpu_speed; /* speed in MHz of CPU */
983 | uint32_t uptime; /* seconds since last reboot */
984 | uint32_t cpu_user; /* time executing in user mode processes (ms) */
985 | uint32_t cpu_nice; /* time executing niced processs (ms) */
986 | uint32_t cpu_system; /* time executing kernel mode processes (ms) */
987 | uint32_t cpu_idle; /* idle time (ms) */
988 | uint32_t cpu_wio; /* time waiting for I/O to complete (ms) */
989 | uint32_t cpu_intr; /* time servicing interrupts (ms) */
990 | uint32_t cpu_sintr; /* time servicing softirqs (ms) */
991 | uint32_t interrupts; /* interrupt count */
992 | uint32_t contexts; /* context switch count */
993 | uint32_t cpu_steal; /* time spent in other OS instances (virtual env) (ms) */
994 | uint32_t cpu_guest; /* time spent running vcpu for guest OS */
995 | uint32_t cpu_guest_nice; /* time spent running vcpu for "niced" guest OS */
996 | } SFLHost_cpu_counters;
997 |
998 | typedef struct _SFLHost_mem_counters {
999 | uint64_t mem_total; /* total bytes */
1000 | uint64_t mem_free; /* free bytes */
1001 | uint64_t mem_shared; /* shared bytes */
1002 | uint64_t mem_buffers; /* buffers bytes */
1003 | uint64_t mem_cached; /* cached bytes */
1004 | uint64_t swap_total; /* swap total bytes */
1005 | uint64_t swap_free; /* swap free bytes */
1006 | uint32_t page_in; /* page in count */
1007 | uint32_t page_out; /* page out count */
1008 | uint32_t swap_in; /* swap in count */
1009 | uint32_t swap_out; /* swap out count */
1010 | } SFLHost_mem_counters;
1011 |
1012 | typedef struct _SFLHost_dsk_counters {
1013 | uint64_t disk_total;
1014 | uint64_t disk_free;
1015 | uint32_t part_max_used; /* as percent * 100, so 100==1% */
1016 | uint32_t reads; /* reads issued */
1017 | uint64_t bytes_read; /* bytes read */
1018 | uint32_t read_time; /* read time (ms) */
1019 | uint32_t writes; /* writes completed */
1020 | uint64_t bytes_written; /* bytes written */
1021 | uint32_t write_time; /* write time (ms) */
1022 | } SFLHost_dsk_counters;
1023 |
1024 | /* Virtual Node Statistics */
1025 | /* opaque = counter_data; enterprise = 0; format = 2100 */
1026 |
1027 | typedef struct _SFLHost_vrt_node_counters {
1028 | uint32_t mhz; /* expected CPU frequency */
1029 | uint32_t cpus; /* the number of active CPUs */
1030 | uint64_t memory; /* memory size in bytes */
1031 | uint64_t memory_free; /* unassigned memory in bytes */
1032 | uint32_t num_domains; /* number of active domains */
1033 | } SFLHost_vrt_node_counters;
1034 |
1035 | /* Virtual Domain Statistics */
1036 | /* opaque = counter_data; enterprise = 0; format = 2101 */
1037 |
1038 | /* virDomainState imported from libvirt.h */
1039 | enum SFLVirDomainState {
1040 | SFL_VIR_DOMAIN_NOSTATE = 0, /* no state */
1041 | SFL_VIR_DOMAIN_RUNNING = 1, /* the domain is running */
1042 | SFL_VIR_DOMAIN_BLOCKED = 2, /* the domain is blocked on resource */
1043 | SFL_VIR_DOMAIN_PAUSED = 3, /* the domain is paused by user */
1044 | SFL_VIR_DOMAIN_SHUTDOWN= 4, /* the domain is being shut down */
1045 | SFL_VIR_DOMAIN_SHUTOFF = 5, /* the domain is shut off */
1046 | SFL_VIR_DOMAIN_CRASHED = 6 /* the domain is crashed */
1047 | };
1048 |
1049 | typedef struct _SFLHost_vrt_cpu_counters {
1050 | uint32_t state; /* virtDomainState */
1051 | uint32_t cpuTime; /* the CPU time used in mS */
1052 | uint32_t cpuCount; /* number of virtual CPUs for the domain */
1053 | } SFLHost_vrt_cpu_counters;
1054 |
1055 | /* Virtual Domain Memory statistics */
1056 | /* opaque = counter_data; enterprise = 0; format = 2102 */
1057 |
1058 | typedef struct _SFLHost_vrt_mem_counters {
1059 | uint64_t memory; /* memory in bytes used by domain */
1060 | uint64_t maxMemory; /* memory in bytes allowed */
1061 | } SFLHost_vrt_mem_counters;
1062 |
1063 | /* Virtual Domain Disk statistics */
1064 | /* opaque = counter_data; enterprise = 0; format = 2103 */
1065 |
1066 | typedef struct _SFLHost_vrt_dsk_counters {
1067 | uint64_t capacity; /* logical size in bytes */
1068 | uint64_t allocation; /* current allocation in bytes */
1069 | uint64_t available; /* remaining free bytes */
1070 | uint32_t rd_req; /* number of read requests */
1071 | uint64_t rd_bytes; /* number of read bytes */
1072 | uint32_t wr_req; /* number of write requests */
1073 | uint64_t wr_bytes; /* number of written bytes */
1074 | uint32_t errs; /* read/write errors */
1075 | } SFLHost_vrt_dsk_counters;
1076 |
1077 | /* Virtual Domain Network statistics */
1078 | /* opaque = counter_data; enterprise = 0; format = 2104 */
1079 |
1080 | typedef struct _SFLHost_vrt_nio_counters {
1081 | uint64_t bytes_in;
1082 | uint32_t pkts_in;
1083 | uint32_t errs_in;
1084 | uint32_t drops_in;
1085 | uint64_t bytes_out;
1086 | uint32_t pkts_out;
1087 | uint32_t errs_out;
1088 | uint32_t drops_out;
1089 | } SFLHost_vrt_nio_counters;
1090 |
1091 | /* NVML statistics */
1092 | /* opaque = counter_data; enterprise = 5703, format=1 */
1093 | typedef struct _SFLHost_gpu_nvml {
1094 | uint32_t device_count; /* see nvmlGetDeviceCount */
1095 | uint32_t processes; /* see nvmlDeviceGetComputeRunningProcesses */
1096 | uint32_t gpu_time; /* total milliseconds in which one or more kernels was executing on GPU */
1097 | uint32_t mem_time; /* total milliseconds during which global device memory was being read/written */
1098 | uint64_t mem_total; /* bytes. see nvmlDeviceGetMemoryInfo */
1099 | uint64_t mem_free; /* bytes. see nvmlDeviceGetMemoryInfo */
1100 | uint32_t ecc_errors; /* see nvmlDeviceGetTotalEccErrors */
1101 | uint32_t energy; /* mJ. see nvmlDeviceGetPowerUsage */
1102 | uint32_t temperature; /* C. maximum across devices - see nvmlDeviceGetTemperature */
1103 | uint32_t fan_speed; /* %. maximum across devices - see nvmlDeviceGetFanSpeed */
1104 | } SFLHost_gpu_nvml;
1105 |
1106 | /* Broadcom switch ASIC table utilizations */
1107 | /* opaque = counter_data; enterprise = 4413 (Broadcom); format = 3 */
1108 | typedef struct {
1109 | uint32_t bcm_host_entries;
1110 | uint32_t bcm_host_entries_max;
1111 | uint32_t bcm_ipv4_entries;
1112 | uint32_t bcm_ipv4_entries_max;
1113 | uint32_t bcm_ipv6_entries;
1114 | uint32_t bcm_ipv6_entries_max;
1115 | uint32_t bcm_ipv4_ipv6_entries;
1116 | uint32_t bcm_ipv4_ipv6_entries_max;
1117 | uint32_t bcm_long_ipv6_entries;
1118 | uint32_t bcm_long_ipv6_entries_max;
1119 | uint32_t bcm_total_routes;
1120 | uint32_t bcm_total_routes_max;
1121 | uint32_t bcm_ecmp_nexthops;
1122 | uint32_t bcm_ecmp_nexthops_max;
1123 | uint32_t bcm_mac_entries;
1124 | uint32_t bcm_mac_entries_max;
1125 | uint32_t bcm_ipv4_neighbors;
1126 | uint32_t bcm_ipv6_neighbors;
1127 | uint32_t bcm_ipv4_routes;
1128 | uint32_t bcm_ipv6_routes;
1129 | uint32_t bcm_acl_ingress_entries;
1130 | uint32_t bcm_acl_ingress_entries_max;
1131 | uint32_t bcm_acl_ingress_counters;
1132 | uint32_t bcm_acl_ingress_counters_max;
1133 | uint32_t bcm_acl_ingress_meters;
1134 | uint32_t bcm_acl_ingress_meters_max;
1135 | uint32_t bcm_acl_ingress_slices;
1136 | uint32_t bcm_acl_ingress_slices_max;
1137 | uint32_t bcm_acl_egress_entries;
1138 | uint32_t bcm_acl_egress_entries_max;
1139 | uint32_t bcm_acl_egress_counters;
1140 | uint32_t bcm_acl_egress_counters_max;
1141 | uint32_t bcm_acl_egress_meters;
1142 | uint32_t bcm_acl_egress_meters_max;
1143 | uint32_t bcm_acl_egress_slices;
1144 | uint32_t bcm_acl_egress_slices_max;
1145 | } SFLBCM_tables;
1146 |
1147 | ///////////// TCP/UDP/ICMP from MIB-II ///////////////////////
1148 |
1149 | /* IP Group - see MIB-II */
1150 | /* opaque = counter_data; enterprise = 0; format = 2007 */
1151 |
1152 | typedef struct _SFLHost_IP_counters {
1153 | uint32_t ipForwarding;
1154 | uint32_t ipDefaultTTL;
1155 | uint32_t ipInReceives;
1156 | uint32_t ipInHdrErrors;
1157 | uint32_t ipInAddrErrors;
1158 | uint32_t ipForwDatagrams;
1159 | uint32_t ipInUnknownProtos;
1160 | uint32_t ipInDiscards;
1161 | uint32_t ipInDelivers;
1162 | uint32_t ipOutRequests;
1163 | uint32_t ipOutDiscards;
1164 | uint32_t ipOutNoRoutes;
1165 | uint32_t ipReasmTimeout;
1166 | uint32_t ipReasmReqds;
1167 | uint32_t ipReasmOKs;
1168 | uint32_t ipReasmFails;
1169 | uint32_t ipFragOKs;
1170 | uint32_t ipFragFails;
1171 | uint32_t ipFragCreates;
1172 | } SFLHost_IP_counters;
1173 |
1174 | /* ICMP Group - see MIB-II */
1175 | /* opaque = counter_data; enterprise = 0; format = 2008 */
1176 |
1177 | typedef struct _SFLHost_ICMP_counters {
1178 | uint32_t icmpInMsgs;
1179 | uint32_t icmpInErrors;
1180 | uint32_t icmpInDestUnreachs;
1181 | uint32_t icmpInTimeExcds;
1182 | uint32_t icmpInParamProbs;
1183 | uint32_t icmpInSrcQuenchs;
1184 | uint32_t icmpInRedirects;
1185 | uint32_t icmpInEchos;
1186 | uint32_t icmpInEchoReps;
1187 | uint32_t icmpInTimestamps;
1188 | uint32_t icmpInAddrMasks;
1189 | uint32_t icmpInAddrMaskReps;
1190 | uint32_t icmpOutMsgs;
1191 | uint32_t icmpOutErrors;
1192 | uint32_t icmpOutDestUnreachs;
1193 | uint32_t icmpOutTimeExcds;
1194 | uint32_t icmpOutParamProbs;
1195 | uint32_t icmpOutSrcQuenchs;
1196 | uint32_t icmpOutRedirects;
1197 | uint32_t icmpOutEchos;
1198 | uint32_t icmpOutEchoReps;
1199 | uint32_t icmpOutTimestamps;
1200 | uint32_t icmpOutTimestampReps;
1201 | uint32_t icmpOutAddrMasks;
1202 | uint32_t icmpOutAddrMaskReps;
1203 | } SFLHost_ICMP_counters;
1204 |
1205 | /* TCP Group - see MIB-II */
1206 | /* opaque = counter_data; enterprise = 0; format = 2009 */
1207 |
1208 | typedef struct _SFLHost_TCP_counters {
1209 | uint32_t tcpRtoAlgorithm;
1210 | uint32_t tcpRtoMin;
1211 | uint32_t tcpRtoMax;
1212 | uint32_t tcpMaxConn;
1213 | uint32_t tcpActiveOpens;
1214 | uint32_t tcpPassiveOpens;
1215 | uint32_t tcpAttemptFails;
1216 | uint32_t tcpEstabResets;
1217 | uint32_t tcpCurrEstab;
1218 | uint32_t tcpInSegs;
1219 | uint32_t tcpOutSegs;
1220 | uint32_t tcpRetransSegs;
1221 | uint32_t tcpInErrs;
1222 | uint32_t tcpOutRsts;
1223 | uint32_t tcpInCsumErrors;
1224 | } SFLHost_TCP_counters;
1225 |
1226 | /* UDP Group - see MIB-II */
1227 | /* opaque = counter_data; enterprise = 0; format = 2010 */
1228 |
1229 | typedef struct _SFLHost_UDP_counters {
1230 | uint32_t udpInDatagrams;
1231 | uint32_t udpNoPorts;
1232 | uint32_t udpInErrors;
1233 | uint32_t udpOutDatagrams;
1234 | uint32_t udpRcvbufErrors;
1235 | uint32_t udpSndbufErrors;
1236 | uint32_t udpInCsumErrors;
1237 | } SFLHost_UDP_counters;
1238 |
1239 | /* memcache */
1240 | /* opaque = counter_data; enterprise = 0; format = 2204 */
1241 |
1242 | typedef struct _SFLMemcache_counters {
1243 | uint32_t uptime; /* not in 2204 */
1244 | uint32_t rusage_user; /* not in 2204 */
1245 | uint32_t rusage_system; /* not in 2204 */
1246 | uint32_t cmd_get; /* not in 2204 */
1247 | uint32_t accepting_conns; /* not in 2204 */
1248 | uint32_t cmd_set;
1249 | uint32_t cmd_touch; /* added for 2204 */
1250 | uint32_t cmd_flush;
1251 | uint32_t get_hits;
1252 | uint32_t get_misses;
1253 | uint32_t delete_hits;
1254 | uint32_t delete_misses;
1255 | uint32_t incr_hits;
1256 | uint32_t incr_misses;
1257 | uint32_t decr_hits;
1258 | uint32_t decr_misses;
1259 | uint32_t cas_hits;
1260 | uint32_t cas_misses;
1261 | uint32_t cas_badval;
1262 | uint32_t auth_cmds;
1263 | uint32_t auth_errors;
1264 | uint32_t threads;
1265 | uint32_t conn_yields;
1266 | uint32_t listen_disabled_num;
1267 | uint32_t curr_connections;
1268 | uint32_t rejected_connections; /* added for 2204 */
1269 | uint32_t total_connections;
1270 | uint32_t connection_structures;
1271 | uint32_t evictions;
1272 | uint32_t reclaimed; /* added for 2204 */
1273 | uint32_t curr_items;
1274 | uint32_t total_items;
1275 | uint64_t bytes_read;
1276 | uint64_t bytes_written;
1277 | uint64_t bytes;
1278 | uint64_t limit_maxbytes; /* converted to 64-bit for structure 2204 */
1279 | } SFLMemcache_counters;
1280 |
1281 | /* http */
1282 | /* opaque = counter_data; enterprise = 0; format = 2201 */
1283 |
1284 | typedef struct _SFLHTTP_counters {
1285 | uint32_t method_option_count;
1286 | uint32_t method_get_count;
1287 | uint32_t method_head_count;
1288 | uint32_t method_post_count;
1289 | uint32_t method_put_count;
1290 | uint32_t method_delete_count;
1291 | uint32_t method_trace_count;
1292 | uint32_t methd_connect_count;
1293 | uint32_t method_other_count;
1294 | uint32_t status_1XX_count;
1295 | uint32_t status_2XX_count;
1296 | uint32_t status_3XX_count;
1297 | uint32_t status_4XX_count;
1298 | uint32_t status_5XX_count;
1299 | uint32_t status_other_count;
1300 | } SFLHTTP_counters;
1301 |
1302 |
1303 | /* Enterprise counters */
1304 | /* opaque = counter_data; enterprise = 0; format = 2202 */
1305 | typedef struct _SFLAPP_counters {
1306 | SFLString application;
1307 | uint32_t status_OK;
1308 | uint32_t errors_OTHER;
1309 | uint32_t errors_TIMEOUT;
1310 | uint32_t errors_INTERNAL_ERROR;
1311 | uint32_t errors_BAD_REQUEST;
1312 | uint32_t errors_FORBIDDEN;
1313 | uint32_t errors_TOO_LARGE;
1314 | uint32_t errors_NOT_IMPLEMENTED;
1315 | uint32_t errors_NOT_FOUND;
1316 | uint32_t errors_UNAVAILABLE;
1317 | uint32_t errors_UNAUTHORIZED;
1318 | } SFLAPP_counters;
1319 |
1320 | /* Enterprise resource counters */
1321 | /* opaque = counter_data; enterprise = 0; format = 2203 */
1322 | typedef struct {
1323 | uint32_t user_time; /* in milliseconds */
1324 | uint32_t system_time; /* in milliseconds */
1325 | uint64_t mem_used;
1326 | uint64_t mem_max;
1327 | uint32_t fd_open;
1328 | uint32_t fd_max;
1329 | uint32_t conn_open;
1330 | uint32_t conn_max;
1331 | } SFLAPP_resources;
1332 |
1333 | /* Enterprise application workers */
1334 | /* opaque = counter_data; enterprise = 0; format = 2206 */
1335 |
1336 | typedef struct {
1337 | uint32_t workers_active;
1338 | uint32_t workers_idle;
1339 | uint32_t workers_max;
1340 | uint32_t req_delayed;
1341 | uint32_t req_dropped;
1342 | } SFLAPP_workers;
1343 |
1344 | typedef struct _SFLJVM_ID {
1345 | SFLString vm_name;
1346 | SFLString vm_vendor;
1347 | SFLString vm_version;
1348 | } SFLJVM_ID;
1349 |
1350 | #define SFLJVM_MAX_VMNAME_LEN 64
1351 | #define SFLJVM_MAX_VENDOR_LEN 32
1352 | #define SFLJVM_MAX_VERSION_LEN 32
1353 |
1354 | typedef struct _SFLJMX_counters {
1355 | uint64_t hmem_initial;
1356 | uint64_t hmem_used;
1357 | uint64_t hmem_committed;
1358 | uint64_t hmem_max;
1359 | uint64_t nhmem_initial;
1360 | uint64_t nhmem_used;
1361 | uint64_t nhmem_committed;
1362 | uint64_t nhmem_max;
1363 | uint32_t gc_count;
1364 | uint32_t gc_ms;
1365 | uint32_t cls_loaded;
1366 | uint32_t cls_total;
1367 | uint32_t cls_unloaded;
1368 | uint32_t comp_ms;
1369 | uint32_t thread_live;
1370 | uint32_t thread_daemon;
1371 | uint32_t thread_started;
1372 | uint32_t fds_open;
1373 | uint32_t fds_max;
1374 | } SFLJMX_counters;
1375 |
1376 | #define XDRSIZ_JMX_COUNTERS 108
1377 |
1378 | typedef struct _SFLVdi_counters {
1379 | uint32_t sessions_current; /* number of current sessions */
1380 | uint32_t sessions_total; /* total sessions started */
1381 | uint32_t sessions_duration; /* cumulative session time (in seconds)
1382 | across all sessions, such that average
1383 | session duration = sessions_duration
1384 | / sessions_total */
1385 | uint32_t rx_bytes; /* total bytes received */
1386 | uint32_t tx_bytes; /* total bytes sent */
1387 | uint32_t rx_packets; /* total packet received */
1388 | uint32_t tx_packets; /* total packets sent */
1389 | uint32_t rx_packets_lost; /* total received packets lost */
1390 | uint32_t tx_packets_lost; /* total sent packets lost */
1391 | uint32_t rtt_min_ms; /* minimum round trip latency with client
1392 | across all current sessions
1393 | measured in milliseconds */
1394 | uint32_t rtt_max_ms; /* maximum round trip latency with client
1395 | across all current sessions
1396 | measured in millisecond */
1397 | uint32_t rtt_avg_ms; /* average round trip latency with client
1398 | across all current sessions
1399 | measured in milliseconds */
1400 | uint32_t audio_rx_bytes; /* total bytes of audio data received */
1401 | uint32_t audio_tx_bytes; /* total bytes of audio data sent */
1402 | uint32_t audio_tx_limit; /* administrative limit on audio transmission
1403 | bandwidth (in bits per second) */
1404 | uint32_t img_rx_bytes; /* total bytes of imaging data recieved */
1405 | uint32_t img_tx_bytes; /* total bytes of imaging data sent */
1406 | uint32_t img_frames; /* total image frames encoded */
1407 | uint32_t img_qual_min; /* minimum image encoding quality across
1408 | current sessions, on a scale of 0 to 100 */
1409 | uint32_t img_qual_max; /* best image encoding quality across
1410 | current sessions, on a scale of 0 to 100 */
1411 | uint32_t img_qual_avg; /* average image encoding quality across
1412 | current sessions, on a scale of 0 to 100 */
1413 | uint32_t usb_rx_bytes; /* total bytes of usb data received */
1414 | uint32_t usb_tx_bytes; /* total bytes of usb data sent */
1415 | } SFLVdi_counters;
1416 |
1417 | /* LAG Port Statistics - see IEEE8023-LAG-MIB */
1418 | /* opaque = counter_data; enterprise = 0; format = 7 */
1419 | typedef union _SFLLACP_portState {
1420 | uint32_t all;
1421 | struct {
1422 | uint8_t actorAdmin;
1423 | uint8_t actorOper;
1424 | uint8_t partnerAdmin;
1425 | uint8_t partnerOper;
1426 | } v;
1427 | } SFLLACP_portState;
1428 |
1429 | typedef struct _SFLLACP_counters {
1430 | uint8_t actorSystemID[8]; /* 6 bytes + 2 pad */
1431 | uint8_t partnerSystemID[8]; /* 6 bytes + 2 pad */
1432 | uint32_t attachedAggID;
1433 | SFLLACP_portState portState;
1434 | uint32_t LACPDUsRx;
1435 | uint32_t markerPDUsRx;
1436 | uint32_t markerResponsePDUsRx;
1437 | uint32_t unknownRx;
1438 | uint32_t illegalRx;
1439 | uint32_t LACPDUsTx;
1440 | uint32_t markerPDUsTx;
1441 | uint32_t markerResponsePDUsTx;
1442 | } SFLLACP_counters;
1443 |
1444 | #define XDRSIZ_LACP_COUNTERS 56
1445 |
1446 | /* openflow port */
1447 | /* opaque = counter_data; enterprise = 0; format = 1004 */
1448 | typedef struct {
1449 | uint64_t datapath_id;
1450 | uint32_t port_no;
1451 | } SFLOFPort;
1452 |
1453 | #define XDRSIZ_OFPORT 12
1454 |
1455 | /* port name */
1456 | /* opaque = counter_data; enterprise = 0; format = 1005 */
1457 | typedef struct {
1458 | SFLString portName;
1459 | } SFLPortName;
1460 |
1461 | #define SFL_MAX_PORTNAME_LEN 255
1462 |
1463 | /* OVS datapath stats */
1464 | typedef struct _SFLOVSDP_counters {
1465 | uint32_t n_hit;
1466 | uint32_t n_missed;
1467 | uint32_t n_lost;
1468 | uint32_t n_mask_hit;
1469 | uint32_t n_flows;
1470 | uint32_t n_masks;
1471 | } SFLOVSDP_counters;
1472 |
1473 | #define XDRSIZE_OVSDP 24
1474 |
1475 | /* Optical SFP/QSFP metrics */
1476 | /* opaque = counter_data; enterprise = 0; format = 10 */
1477 |
1478 | typedef struct {
1479 | uint32_t lane_index; /* index of lane in module - starting from 1 */
1480 | uint32_t tx_bias_current; /* microamps */
1481 | uint32_t tx_power; /* microwatts */
1482 | uint32_t tx_power_min; /* microwatts */
1483 | uint32_t tx_power_max; /* microwatts */
1484 | uint32_t tx_wavelength; /* nanometers */
1485 | uint32_t rx_power; /* microwatts */
1486 | uint32_t rx_power_min; /* microwatts */
1487 | uint32_t rx_power_max; /* microwatts */
1488 | uint32_t rx_wavelength; /* nanometers */
1489 | } SFLLane;
1490 |
1491 | #define XDRSIZ_LANE_COUNTERS 40
1492 |
1493 | typedef struct {
1494 | uint32_t module_id;
1495 | uint32_t module_total_lanes; /* total lanes in module */
1496 | uint32_t module_supply_voltage; /* millivolts */
1497 | int32_t module_temperature; /* signed - in oC / 1000 */
1498 | uint32_t num_lanes; /* number of active lane structs to come */
1499 | SFLLane *lanes;
1500 | } SFLSFP_counters;
1501 |
1502 | /* Counters data */
1503 |
1504 | enum SFLCounters_type_tag {
1505 | /* enterprise = 0, format = ... */
1506 | SFLCOUNTERS_GENERIC = 1,
1507 | SFLCOUNTERS_ETHERNET = 2,
1508 | SFLCOUNTERS_TOKENRING = 3,
1509 | SFLCOUNTERS_VG = 4,
1510 | SFLCOUNTERS_VLAN = 5,
1511 | SFLCOUNTERS_80211 = 6,
1512 | SFLCOUNTERS_LACP = 7,
1513 | SFLCOUNTERS_SFP = 10,
1514 | SFLCOUNTERS_PROCESSOR = 1001,
1515 | SFLCOUNTERS_RADIO = 1002,
1516 | SFLCOUNTERS_OFPORT = 1004,
1517 | SFLCOUNTERS_PORTNAME = 1005,
1518 | SFLCOUNTERS_HOST_HID = 2000, /* host id */
1519 | SFLCOUNTERS_ADAPTORS = 2001, /* host adaptors */
1520 | SFLCOUNTERS_HOST_PAR = 2002, /* host parent */
1521 | SFLCOUNTERS_HOST_CPU = 2003, /* host cpu */
1522 | SFLCOUNTERS_HOST_MEM = 2004, /* host memory */
1523 | SFLCOUNTERS_HOST_DSK = 2005, /* host storage I/O */
1524 | SFLCOUNTERS_HOST_NIO = 2006, /* host network I/O */
1525 | SFLCOUNTERS_HOST_IP = 2007,
1526 | SFLCOUNTERS_HOST_ICMP = 2008,
1527 | SFLCOUNTERS_HOST_TCP = 2009,
1528 | SFLCOUNTERS_HOST_UDP = 2010,
1529 | SFLCOUNTERS_HOST_VRT_NODE = 2100, /* host virt node */
1530 | SFLCOUNTERS_HOST_VRT_CPU = 2101, /* host virt cpu */
1531 | SFLCOUNTERS_HOST_VRT_MEM = 2102, /* host virt mem */
1532 | SFLCOUNTERS_HOST_VRT_DSK = 2103, /* host virt storage */
1533 | SFLCOUNTERS_HOST_VRT_NIO = 2104, /* host virt network I/O */
1534 | SFLCOUNTERS_JVM = 2105, /* java runtime */
1535 | SFLCOUNTERS_JMX = 2106, /* java JMX stats */
1536 | SFLCOUNTERS_MEMCACHE = 2200, /* memcached (deprecated) */
1537 | SFLCOUNTERS_HTTP = 2201, /* http */
1538 | SFLCOUNTERS_APP = 2202,
1539 | SFLCOUNTERS_APP_RESOURCE = 2203,
1540 | SFLCOUNTERS_MEMCACHE2 = 2204, /* memcached */
1541 | SFLCOUNTERS_VDI = 2205,
1542 | SFLCOUNTERS_APP_WORKERS = 2206,
1543 | SFLCOUNTERS_OVSDP = 2207,
1544 | SFLCOUNTERS_HOST_GPU_NVML = (5703 << 12) + 1, /* = 23359489 */
1545 | SFLCOUNTERS_BCM_TABLES = (4413 << 12) + 3,
1546 | };
1547 |
1548 | typedef union _SFLCounters_type {
1549 | SFLIf_counters generic;
1550 | SFLEthernet_counters ethernet;
1551 | SFLTokenring_counters tokenring;
1552 | SFLVg_counters vg;
1553 | SFLVlan_counters vlan;
1554 | SFLWifi_counters wifi;
1555 | SFLProcessor_counters processor;
1556 | SFLRadio_counters radio;
1557 | SFLHostId hostId;
1558 | SFLAdaptorList *adaptors;
1559 | SFLHost_parent host_par;
1560 | SFLHost_cpu_counters host_cpu;
1561 | SFLHost_mem_counters host_mem;
1562 | SFLHost_dsk_counters host_dsk;
1563 | SFLHost_nio_counters host_nio;
1564 | SFLHost_IP_counters host_ip;
1565 | SFLHost_ICMP_counters host_icmp;
1566 | SFLHost_TCP_counters host_tcp;
1567 | SFLHost_UDP_counters host_udp;
1568 | SFLHost_vrt_node_counters host_vrt_node;
1569 | SFLHost_vrt_cpu_counters host_vrt_cpu;
1570 | SFLHost_vrt_mem_counters host_vrt_mem;
1571 | SFLHost_vrt_dsk_counters host_vrt_dsk;
1572 | SFLHost_vrt_nio_counters host_vrt_nio;
1573 | SFLHost_gpu_nvml host_gpu_nvml;
1574 | SFLBCM_tables bcm_tables;
1575 | SFLMemcache_counters memcache;
1576 | SFLHTTP_counters http;
1577 | SFLJVM_ID jvm;
1578 | SFLJMX_counters jmx;
1579 | SFLAPP_counters app;
1580 | SFLAPP_resources appResources;
1581 | SFLAPP_workers appWorkers;
1582 | SFLVdi_counters vdi;
1583 | SFLLACP_counters lacp;
1584 | SFLPortName portName;
1585 | SFLSFP_counters sfp;
1586 | SFLOVSDP_counters ovsdp;
1587 | } SFLCounters_type;
1588 |
1589 | typedef struct _SFLCounters_sample_element {
1590 | struct _SFLCounters_sample_element *nxt; /* linked list */
1591 | uint32_t tag; /* SFLCounters_type_tag */
1592 | uint32_t length;
1593 | SFLCounters_type counterBlock;
1594 | } SFLCounters_sample_element;
1595 |
1596 | typedef struct _SFLCounters_sample {
1597 | /* uint32_t tag; */ /* SFL_sample_tag -- enterprise = 0 : format = 2 */
1598 | /* uint32_t length; */
1599 | uint32_t sequence_number; /* Incremented with each counters sample
1600 | generated by this source_id */
1601 | uint32_t source_id; /* fsSourceId */
1602 | uint32_t num_elements;
1603 | SFLCounters_sample_element *elements;
1604 | } SFLCounters_sample;
1605 |
1606 | /* same thing, but the expanded version, so ds_index can be a full 32 bits */
1607 | typedef struct _SFLCounters_sample_expanded {
1608 | /* uint32_t tag; */ /* SFL_sample_tag -- enterprise = 0 : format = 2 */
1609 | /* uint32_t length; */
1610 | uint32_t sequence_number; /* Incremented with each counters sample
1611 | generated by this source_id */
1612 | uint32_t ds_class; /* EXPANDED */
1613 | uint32_t ds_index; /* EXPANDED */
1614 | uint32_t num_elements;
1615 | SFLCounters_sample_element *elements;
1616 | } SFLCounters_sample_expanded;
1617 |
1618 | #define SFLADD_ELEMENT(_sm, _el) do { (_el)->nxt = (_sm)->elements; (_sm)->elements = (_el); } while(0)
1619 |
1620 | /* Format of a sample datagram */
1621 |
1622 | enum SFLDatagram_version {
1623 | SFLDATAGRAM_VERSION2 = 2,
1624 | SFLDATAGRAM_VERSION4 = 4,
1625 | SFLDATAGRAM_VERSION5 = 5
1626 | };
1627 |
1628 | typedef struct _SFLSample_datagram_hdr {
1629 | uint32_t datagram_version; /* (enum SFLDatagram_version) = VERSION5 = 5 */
1630 | SFLAddress agent_address; /* IP address of sampling agent */
1631 | uint32_t sub_agent_id; /* Used to distinguishing between datagram
1632 | streams from separate agent sub entities
1633 | within an device. */
1634 | uint32_t sequence_number; /* Incremented with each sample datagram
1635 | generated */
1636 | uint32_t uptime; /* Current time (in milliseconds since device
1637 | last booted). Should be set as close to
1638 | datagram transmission time as possible.*/
1639 | uint32_t num_records; /* Number of tag-len-val flow/counter records to follow */
1640 | } SFLSample_datagram_hdr;
1641 |
1642 | typedef struct _SFSample {
1643 | SFLAddress sourceIP;
1644 | SFLAddress agent_addr;
1645 | uint32_t agentSubId;
1646 |
1647 | /* the raw pdu */
1648 | uint8_t *rawSample;
1649 | uint32_t rawSampleLen;
1650 | uint8_t *endp;
1651 | time_t pcapTimestamp;
1652 | time_t readTimestamp;
1653 |
1654 | /* decode cursor */
1655 | uint32_t *datap;
1656 |
1657 | uint32_t datagramVersion;
1658 | uint32_t sampleType;
1659 | uint32_t elementType;
1660 | uint32_t ds_class;
1661 | uint32_t ds_index;
1662 |
1663 | /* generic interface counter sample */
1664 | SFLIf_counters ifCounters;
1665 |
1666 | /* sample stream info */
1667 | uint32_t sysUpTime;
1668 | uint32_t sequenceNo;
1669 | uint32_t sampledPacketSize;
1670 | uint32_t samplesGenerated;
1671 | uint32_t meanSkipCount;
1672 | uint32_t samplePool;
1673 | uint32_t dropEvents;
1674 |
1675 | /* the sampled header */
1676 | uint32_t packet_data_tag;
1677 | uint32_t headerProtocol;
1678 | uint8_t *header;
1679 | uint32_t headerLen;
1680 | uint32_t stripped;
1681 |
1682 | /* header decode */
1683 | int gotIPV4;
1684 | int gotIPV4Struct;
1685 | int offsetToIPV4;
1686 | int gotIPV6;
1687 | int gotIPV6Struct;
1688 | int offsetToIPV6;
1689 | int offsetToPayload;
1690 | SFLAddress ipsrc;
1691 | SFLAddress ipdst;
1692 | uint32_t dcd_ipProtocol;
1693 | uint32_t dcd_ipTos;
1694 | uint32_t dcd_ipTTL;
1695 | uint32_t dcd_sport;
1696 | uint32_t dcd_dport;
1697 | uint32_t dcd_tcpFlags;
1698 | uint32_t ip_fragmentOffset;
1699 | uint32_t udp_pduLen;
1700 |
1701 | /* ports */
1702 | uint32_t inputPortFormat;
1703 | uint32_t outputPortFormat;
1704 | uint32_t inputPort;
1705 | uint32_t outputPort;
1706 |
1707 | /* ethernet */
1708 | uint32_t eth_type;
1709 | uint32_t eth_len;
1710 | uint8_t eth_src[8];
1711 | uint8_t eth_dst[8];
1712 |
1713 | /* vlan */
1714 | uint32_t in_vlan;
1715 | uint32_t in_priority;
1716 | uint32_t internalPriority;
1717 | uint32_t out_vlan;
1718 | uint32_t out_priority;
1719 | int vlanFilterReject;
1720 |
1721 | /* extended data fields */
1722 | uint32_t num_extended;
1723 | uint32_t extended_data_tag;
1724 | #define SASAMPLE_EXTENDED_DATA_SWITCH 1
1725 | #define SASAMPLE_EXTENDED_DATA_ROUTER 4
1726 | #define SASAMPLE_EXTENDED_DATA_GATEWAY 8
1727 | #define SASAMPLE_EXTENDED_DATA_USER 16
1728 | #define SASAMPLE_EXTENDED_DATA_URL 32
1729 | #define SASAMPLE_EXTENDED_DATA_MPLS 64
1730 | #define SASAMPLE_EXTENDED_DATA_NAT 128
1731 | #define SASAMPLE_EXTENDED_DATA_MPLS_TUNNEL 256
1732 | #define SASAMPLE_EXTENDED_DATA_MPLS_VC 512
1733 | #define SASAMPLE_EXTENDED_DATA_MPLS_FTN 1024
1734 | #define SASAMPLE_EXTENDED_DATA_MPLS_LDP_FEC 2048
1735 | #define SASAMPLE_EXTENDED_DATA_VLAN_TUNNEL 4096
1736 | #define SASAMPLE_EXTENDED_DATA_NAT_PORT 8192
1737 |
1738 | /* IP forwarding info */
1739 | SFLAddress nextHop;
1740 | uint32_t srcMask;
1741 | uint32_t dstMask;
1742 |
1743 | /* BGP info */
1744 | SFLAddress bgp_nextHop;
1745 | uint32_t my_as;
1746 | uint32_t src_as;
1747 | uint32_t src_peer_as;
1748 | uint32_t dst_as_path_len;
1749 | uint32_t *dst_as_path;
1750 | /* note: version 4 dst as path segments just get printed, not stored here, however
1751 | * the dst_peer and dst_as are filled in, since those are used for netflow encoding
1752 | */
1753 | uint32_t dst_peer_as;
1754 | uint32_t dst_as;
1755 |
1756 | uint32_t communities_len;
1757 | uint32_t *communities;
1758 | uint32_t localpref;
1759 |
1760 | /* user id */
1761 | #define SA_MAX_EXTENDED_USER_LEN 200
1762 | uint32_t src_user_charset;
1763 | uint32_t src_user_len;
1764 | char src_user[SA_MAX_EXTENDED_USER_LEN+1];
1765 | uint32_t dst_user_charset;
1766 | uint32_t dst_user_len;
1767 | char dst_user[SA_MAX_EXTENDED_USER_LEN+1];
1768 |
1769 | /* url */
1770 | #define SA_MAX_EXTENDED_URL_LEN 200
1771 | #define SA_MAX_EXTENDED_HOST_LEN 200
1772 | uint32_t url_direction;
1773 | uint32_t url_len;
1774 | char url[SA_MAX_EXTENDED_URL_LEN+1];
1775 | uint32_t host_len;
1776 | char host[SA_MAX_EXTENDED_HOST_LEN+1];
1777 |
1778 | /* mpls */
1779 | SFLAddress mpls_nextHop;
1780 |
1781 | /* nat */
1782 | SFLAddress nat_src;
1783 | SFLAddress nat_dst;
1784 |
1785 | /* counter blocks */
1786 | uint32_t statsSamplingInterval;
1787 | uint32_t counterBlockVersion;
1788 |
1789 | /* exception handler context */
1790 | jmp_buf env;
1791 |
1792 | #define ERROUT stderr
1793 |
1794 | #ifdef DEBUG
1795 | # define SFABORT(s, r) abort()
1796 | # undef ERROUT
1797 | # define ERROUT stdout
1798 | #else
1799 | # define SFABORT(s, r) longjmp((s)->env, (r))
1800 | #endif
1801 |
1802 | #define SF_ABORT_EOS 1
1803 | #define SF_ABORT_DECODE_ERROR 2
1804 | #define SF_ABORT_LENGTH_ERROR 3
1805 |
1806 | /* Flow samples in json */
1807 | VALUE json;
1808 |
1809 | } SFSample;
1810 |
1811 | #define SFL_MAX_DATAGRAM_SIZE 1500
1812 | #define SFL_MIN_DATAGRAM_SIZE 200
1813 | #define SFL_DEFAULT_DATAGRAM_SIZE 1400
1814 |
1815 | #define SFL_DATA_PAD 400
1816 |
1817 | #if defined(__cplusplus)
1818 | } /* extern "C" */
1819 | #endif
1820 |
1821 | #endif /* SFLOW_H */
1822 |
--------------------------------------------------------------------------------
/ext/sflowtool/sflow_v2v4.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2002-2011 InMon Corp. Licensed under the terms of the InMon sFlow licence: */
2 | /* http://www.inmon.com/technology/sflowlicense.txt */
3 |
4 | #ifndef SFLOW_V2V4_H
5 | #define SFLOW_V2V4_H 1
6 |
7 | #if defined(__cplusplus)
8 | extern "C" {
9 | #endif
10 |
11 | enum INMAddress_type {
12 | INMADDRESSTYPE_IP_V4 = 1,
13 | INMADDRESSTYPE_IP_V6 = 2
14 | };
15 |
16 | typedef union _INMAddress_value {
17 | SFLIPv4 ip_v4;
18 | SFLIPv6 ip_v6;
19 | } INMAddress_value;
20 |
21 | typedef struct _INMAddress {
22 | uint32_t type; /* enum INMAddress_type */
23 | INMAddress_value address;
24 | } INMAddress;
25 |
26 | /* Packet header data */
27 |
28 | #define INM_MAX_HEADER_SIZE 256 /* The maximum sampled header size. */
29 | #define INM_DEFAULT_HEADER_SIZE 128
30 | #define INM_DEFAULT_COLLECTOR_PORT 6343
31 | #define INM_DEFAULT_SAMPLING_RATE 400
32 |
33 | /* The header protocol describes the format of the sampled header */
34 | enum INMHeader_protocol {
35 | INMHEADER_ETHERNET_ISO8023 = 1,
36 | INMHEADER_ISO88024_TOKENBUS = 2,
37 | INMHEADER_ISO88025_TOKENRING = 3,
38 | INMHEADER_FDDI = 4,
39 | INMHEADER_FRAME_RELAY = 5,
40 | INMHEADER_X25 = 6,
41 | INMHEADER_PPP = 7,
42 | INMHEADER_SMDS = 8,
43 | INMHEADER_AAL5 = 9,
44 | INMHEADER_AAL5_IP = 10, /* e.g. Cisco AAL5 mux */
45 | INMHEADER_IPv4 = 11,
46 | INMHEADER_IPv6 = 12
47 | };
48 |
49 | typedef struct _INMSampled_header {
50 | uint32_t header_protocol; /* (enum INMHeader_protocol) */
51 | uint32_t frame_length; /* Original length of packet before sampling */
52 | uint32_t header_length; /* length of sampled header bytes to follow */
53 | uint8_t header[INM_MAX_HEADER_SIZE]; /* Header bytes */
54 | } INMSampled_header;
55 |
56 | /* Packet IP version 4 data */
57 |
58 | typedef struct _INMSampled_ipv4 {
59 | uint32_t length; /* The length of the IP packet
60 | excluding lower layer encapsulations */
61 | uint32_t protocol; /* IP Protocol type (for example, TCP = 6, UDP = 17) */
62 | SFLIPv4 src_ip; /* Source IP Address */
63 | SFLIPv4 dst_ip; /* Destination IP Address */
64 | uint32_t src_port; /* TCP/UDP source port number or equivalent */
65 | uint32_t dst_port; /* TCP/UDP destination port number or equivalent */
66 | uint32_t tcp_flags; /* TCP flags */
67 | uint32_t tos; /* IP type of service */
68 | } INMSampled_ipv4;
69 |
70 | /* Packet IP version 6 data */
71 |
72 | typedef struct _INMSampled_ipv6 {
73 | uint32_t length; /* The length of the IP packet
74 | excluding lower layer encapsulations */
75 | uint32_t protocol; /* IP Protocol type (for example, TCP = 6, UDP = 17) */
76 | SFLIPv6 src_ip; /* Source IP Address */
77 | SFLIPv6 dst_ip; /* Destination IP Address */
78 | uint32_t src_port; /* TCP/UDP source port number or equivalent */
79 | uint32_t dst_port; /* TCP/UDP destination port number or equivalent */
80 | uint32_t tcp_flags; /* TCP flags */
81 | uint32_t tos; /* IP type of service */
82 | } INMSampled_ipv6;
83 |
84 |
85 | /* Packet data */
86 |
87 | enum INMPacket_information_type {
88 | INMPACKETTYPE_HEADER = 1, /* Packet headers are sampled */
89 | INMPACKETTYPE_IPV4 = 2, /* IP version 4 data */
90 | INMPACKETTYPE_IPV6 = 3 /* IP version 4 data */
91 | };
92 |
93 | typedef union _INMPacket_data_type {
94 | INMSampled_header header;
95 | INMSampled_ipv4 ipv4;
96 | INMSampled_ipv6 ipv6;
97 | } INMPacket_data_type;
98 |
99 | /* Extended data types */
100 |
101 | /* Extended switch data */
102 |
103 | typedef struct _INMExtended_switch {
104 | uint32_t src_vlan; /* The 802.1Q VLAN id of incomming frame */
105 | uint32_t src_priority; /* The 802.1p priority */
106 | uint32_t dst_vlan; /* The 802.1Q VLAN id of outgoing frame */
107 | uint32_t dst_priority; /* The 802.1p priority */
108 | } INMExtended_switch;
109 |
110 | /* Extended router data */
111 |
112 | typedef struct _INMExtended_router {
113 | INMAddress nexthop; /* IP address of next hop router */
114 | uint32_t src_mask; /* Source address prefix mask bits */
115 | uint32_t dst_mask; /* Destination address prefix mask bits */
116 | } INMExtended_router;
117 |
118 | /* Extended gateway data */
119 |
120 | enum INMExtended_as_path_segment_type {
121 | INMEXTENDED_AS_SET = 1, /* Unordered set of ASs */
122 | INMEXTENDED_AS_SEQUENCE = 2 /* Ordered sequence of ASs */
123 | };
124 |
125 | typedef struct _INMExtended_as_path_segment {
126 | uint32_t type; /* enum INMExtended_as_path_segment_type */
127 | uint32_t length; /* number of AS numbers in set/sequence */
128 | union {
129 | uint32_t *set;
130 | uint32_t *seq;
131 | } as;
132 | } INMExtended_as_path_segment;
133 |
134 | /* note: the INMExtended_gateway structure has changed between v2 and v4.
135 | Here is the old version first... */
136 |
137 | typedef struct _INMExtended_gateway_v2 {
138 | uint32_t as; /* AS number for this gateway */
139 | uint32_t src_as; /* AS number of source (origin) */
140 | uint32_t src_peer_as; /* AS number of source peer */
141 | uint32_t dst_as_path_length; /* number of AS numbers in path */
142 | uint32_t *dst_as_path;
143 | } INMExtended_gateway_v2;
144 |
145 | /* now here is the new version... */
146 |
147 | typedef struct _INMExtended_gateway_v4 {
148 | uint32_t as; /* AS number for this gateway */
149 | uint32_t src_as; /* AS number of source (origin) */
150 | uint32_t src_peer_as; /* AS number of source peer */
151 | uint32_t dst_as_path_segments; /* number of segments in path */
152 | INMExtended_as_path_segment *dst_as_path; /* list of seqs or sets */
153 | uint32_t communities_length; /* number of communities */
154 | uint32_t *communities; /* set of communities */
155 | uint32_t localpref; /* LocalPref associated with this route */
156 | } INMExtended_gateway_v4;
157 |
158 | /* Extended user data */
159 | typedef struct _INMExtended_user {
160 | uint32_t src_user_len;
161 | char *src_user;
162 | uint32_t dst_user_len;
163 | char *dst_user;
164 | } INMExtended_user;
165 | enum INMExtended_url_direction {
166 | INMEXTENDED_URL_SRC = 1, /* URL is associated with source address */
167 | INMEXTENDED_URL_DST = 2 /* URL is associated with destination address */
168 | };
169 |
170 | typedef struct _INMExtended_url {
171 | uint32_t direction; /* enum INMExtended_url_direction */
172 | uint32_t url_len;
173 | char *url;
174 | } INMExtended_url;
175 |
176 | /* Extended data */
177 |
178 | enum INMExtended_information_type {
179 | INMEXTENDED_SWITCH = 1, /* Extended switch information */
180 | INMEXTENDED_ROUTER = 2, /* Extended router information */
181 | INMEXTENDED_GATEWAY = 3, /* Extended gateway router information */
182 | INMEXTENDED_USER = 4, /* Extended TACAS/RADIUS user information */
183 | INMEXTENDED_URL = 5 /* Extended URL information */
184 | };
185 |
186 | /* Format of a single sample */
187 |
188 | typedef struct _INMFlow_sample {
189 | uint32_t sequence_number; /* Incremented with each flow sample
190 | generated */
191 | uint32_t source_id; /* fsSourceId */
192 | uint32_t sampling_rate; /* fsPacketSamplingRate */
193 | uint32_t sample_pool; /* Total number of packets that could have been
194 | sampled (i.e. packets skipped by sampling
195 | process + total number of samples) */
196 | uint32_t drops; /* Number of times a packet was dropped due to
197 | lack of resources */
198 | uint32_t input; /* SNMP ifIndex of input interface.
199 | 0 if interface is not known. */
200 | uint32_t output; /* SNMP ifIndex of output interface,
201 | 0 if interface is not known.
202 | Set most significant bit to indicate
203 | multiple destination interfaces
204 | (i.e. in case of broadcast or multicast)
205 | and set lower order bits to indicate
206 | number of destination interfaces.
207 | Examples:
208 | 0x00000002 indicates ifIndex = 2
209 | 0x00000000 ifIndex unknown.
210 | 0x80000007 indicates a packet sent
211 | to 7 interfaces.
212 | 0x80000000 indicates a packet sent to
213 | an unknown number of
214 | interfaces greater than 1.*/
215 | uint32_t packet_data_tag; /* enum INMPacket_information_type */
216 | INMPacket_data_type packet_data; /* Information about sampled packet */
217 |
218 | /* in the sFlow packet spec the next field is the number of extended objects
219 | followed by the data for each one (tagged with the type). Here we just
220 | provide space for each one, and flags to enable them. The correct format
221 | is then put together by the serialization code */
222 | int gotSwitch;
223 | INMExtended_switch switchDevice;
224 | int gotRouter;
225 | INMExtended_router router;
226 | int gotGateway;
227 | union {
228 | INMExtended_gateway_v2 v2; /* make the version explicit so that there is */
229 | INMExtended_gateway_v4 v4; /* less danger of mistakes when upgrading code */
230 | } gateway;
231 | int gotUser;
232 | INMExtended_user user;
233 | int gotUrl;
234 | INMExtended_url url;
235 | } INMFlow_sample;
236 |
237 | /* Counter types */
238 |
239 | /* Generic interface counters - see RFC 1573, 2233 */
240 |
241 | typedef struct _INMIf_counters {
242 | uint32_t ifIndex;
243 | uint32_t ifType;
244 | uint64_t ifSpeed;
245 | uint32_t ifDirection; /* Derived from MAU MIB (RFC 2239)
246 | 0 = unknown, 1 = full-duplex,
247 | 2 = half-duplex, 3 = in, 4 = out */
248 | uint32_t ifStatus; /* bit field with the following bits assigned:
249 | bit 0 = ifAdminStatus (0 = down, 1 = up)
250 | bit 1 = ifOperStatus (0 = down, 1 = up) */
251 | uint64_t ifInOctets;
252 | uint32_t ifInUcastPkts;
253 | uint32_t ifInMulticastPkts;
254 | uint32_t ifInBroadcastPkts;
255 | uint32_t ifInDiscards;
256 | uint32_t ifInErrors;
257 | uint32_t ifInUnknownProtos;
258 | uint64_t ifOutOctets;
259 | uint32_t ifOutUcastPkts;
260 | uint32_t ifOutMulticastPkts;
261 | uint32_t ifOutBroadcastPkts;
262 | uint32_t ifOutDiscards;
263 | uint32_t ifOutErrors;
264 | uint32_t ifPromiscuousMode;
265 | } INMIf_counters;
266 |
267 | /* Ethernet interface counters - see RFC 2358 */
268 | typedef struct _INMEthernet_specific_counters {
269 | uint32_t dot3StatsAlignmentErrors;
270 | uint32_t dot3StatsFCSErrors;
271 | uint32_t dot3StatsSingleCollisionFrames;
272 | uint32_t dot3StatsMultipleCollisionFrames;
273 | uint32_t dot3StatsSQETestErrors;
274 | uint32_t dot3StatsDeferredTransmissions;
275 | uint32_t dot3StatsLateCollisions;
276 | uint32_t dot3StatsExcessiveCollisions;
277 | uint32_t dot3StatsInternalMacTransmitErrors;
278 | uint32_t dot3StatsCarrierSenseErrors;
279 | uint32_t dot3StatsFrameTooLongs;
280 | uint32_t dot3StatsInternalMacReceiveErrors;
281 | uint32_t dot3StatsSymbolErrors;
282 | } INMEthernet_specific_counters;
283 |
284 | typedef struct _INMEthernet_counters {
285 | INMIf_counters generic;
286 | INMEthernet_specific_counters ethernet;
287 | } INMEthernet_counters;
288 |
289 | /* FDDI interface counters - see RFC 1512 */
290 | typedef struct _INMFddi_counters {
291 | INMIf_counters generic;
292 | } INMFddi_counters;
293 |
294 | /* Token ring counters - see RFC 1748 */
295 |
296 | typedef struct _INMTokenring_specific_counters {
297 | uint32_t dot5StatsLineErrors;
298 | uint32_t dot5StatsBurstErrors;
299 | uint32_t dot5StatsACErrors;
300 | uint32_t dot5StatsAbortTransErrors;
301 | uint32_t dot5StatsInternalErrors;
302 | uint32_t dot5StatsLostFrameErrors;
303 | uint32_t dot5StatsReceiveCongestions;
304 | uint32_t dot5StatsFrameCopiedErrors;
305 | uint32_t dot5StatsTokenErrors;
306 | uint32_t dot5StatsSoftErrors;
307 | uint32_t dot5StatsHardErrors;
308 | uint32_t dot5StatsSignalLoss;
309 | uint32_t dot5StatsTransmitBeacons;
310 | uint32_t dot5StatsRecoverys;
311 | uint32_t dot5StatsLobeWires;
312 | uint32_t dot5StatsRemoves;
313 | uint32_t dot5StatsSingles;
314 | uint32_t dot5StatsFreqErrors;
315 | } INMTokenring_specific_counters;
316 |
317 | typedef struct _INMTokenring_counters {
318 | INMIf_counters generic;
319 | INMTokenring_specific_counters tokenring;
320 | } INMTokenring_counters;
321 |
322 | /* 100 BaseVG interface counters - see RFC 2020 */
323 |
324 | typedef struct _INMVg_specific_counters {
325 | uint32_t dot12InHighPriorityFrames;
326 | uint64_t dot12InHighPriorityOctets;
327 | uint32_t dot12InNormPriorityFrames;
328 | uint64_t dot12InNormPriorityOctets;
329 | uint32_t dot12InIPMErrors;
330 | uint32_t dot12InOversizeFrameErrors;
331 | uint32_t dot12InDataErrors;
332 | uint32_t dot12InNullAddressedFrames;
333 | uint32_t dot12OutHighPriorityFrames;
334 | uint64_t dot12OutHighPriorityOctets;
335 | uint32_t dot12TransitionIntoTrainings;
336 | uint64_t dot12HCInHighPriorityOctets;
337 | uint64_t dot12HCInNormPriorityOctets;
338 | uint64_t dot12HCOutHighPriorityOctets;
339 | } INMVg_specific_counters;
340 |
341 | typedef struct _INMVg_counters {
342 | INMIf_counters generic;
343 | INMVg_specific_counters vg;
344 | } INMVg_counters;
345 |
346 | /* WAN counters */
347 |
348 | typedef struct _INMWan_counters {
349 | INMIf_counters generic;
350 | } INMWan_counters;
351 |
352 | typedef struct _INMVlan_counters {
353 | uint32_t vlan_id;
354 | uint64_t octets;
355 | uint32_t ucastPkts;
356 | uint32_t multicastPkts;
357 | uint32_t broadcastPkts;
358 | uint32_t discards;
359 | } INMVlan_counters;
360 |
361 | /* Counters data */
362 |
363 | enum INMCounters_version {
364 | INMCOUNTERSVERSION_GENERIC = 1,
365 | INMCOUNTERSVERSION_ETHERNET = 2,
366 | INMCOUNTERSVERSION_TOKENRING = 3,
367 | INMCOUNTERSVERSION_FDDI = 4,
368 | INMCOUNTERSVERSION_VG = 5,
369 | INMCOUNTERSVERSION_WAN = 6,
370 | INMCOUNTERSVERSION_VLAN = 7
371 | };
372 |
373 | typedef union _INMCounters_type {
374 | INMIf_counters generic;
375 | INMEthernet_counters ethernet;
376 | INMTokenring_counters tokenring;
377 | INMFddi_counters fddi;
378 | INMVg_counters vg;
379 | INMWan_counters wan;
380 | INMVlan_counters vlan;
381 | } INMCounters_type;
382 |
383 | typedef struct _INMCounters_sample_hdr {
384 | uint32_t sequence_number; /* Incremented with each counters sample
385 | generated by this source_id */
386 | uint32_t source_id; /* fsSourceId */
387 | uint32_t sampling_interval; /* fsCounterSamplingInterval */
388 | } INMCounters_sample_hdr;
389 |
390 | typedef struct _INMCounters_sample {
391 | INMCounters_sample_hdr hdr;
392 | uint32_t counters_type_tag; /* Enum INMCounters_version */
393 | INMCounters_type counters; /* Counter set for this interface type */
394 | } INMCounters_sample;
395 |
396 | /* when I turn on optimisation with the Microsoft compiler it seems to change
397 | the values of these enumerated types and break the program - not sure why */
398 | enum INMSample_types {
399 | FLOWSAMPLE = 1,
400 | COUNTERSSAMPLE = 2
401 | };
402 |
403 | typedef union _INMSample_type {
404 | INMFlow_sample flowsample;
405 | INMCounters_sample counterssample;
406 | } INMSample_type;
407 |
408 | /* Format of a sample datagram */
409 |
410 | enum INMDatagram_version {
411 | INMDATAGRAM_VERSION2 = 2,
412 | INMDATAGRAM_VERSION4 = 4
413 | };
414 |
415 | typedef struct _INMSample_datagram_hdr {
416 | uint32_t datagram_version; /* (enum INMDatagram_version) = VERSION4 */
417 | INMAddress agent_address; /* IP address of sampling agent */
418 | uint32_t sequence_number; /* Incremented with each sample datagram
419 | generated */
420 | uint32_t uptime; /* Current time (in milliseconds since device
421 | last booted). Should be set as close to
422 | datagram transmission time as possible.*/
423 | uint32_t num_samples; /* Number of flow and counters samples to follow */
424 | } INMSample_datagram_hdr;
425 |
426 | #define INM_MAX_DATAGRAM_SIZE 1500
427 | #define INM_MIN_DATAGRAM_SIZE 200
428 | #define INM_DEFAULT_DATAGRAM_SIZE 1400
429 |
430 | #define INM_DATA_PAD 400
431 |
432 | #if defined(__cplusplus)
433 | } /* extern "C" */
434 | #endif
435 |
436 | #endif /* SFLOW_V2V4_H */
437 |
--------------------------------------------------------------------------------
/fluent-plugin-sflow.gemspec:
--------------------------------------------------------------------------------
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-sflow"
7 | spec.version = "0.3.3"
8 | spec.authors = ["Shintaro Kojima"]
9 | spec.email = ["goodies@codeout.net"]
10 |
11 | spec.summary = "sFlow plugin for Fluentd"
12 | spec.description = "sFlow v2 / v4 / v5 input plugin for Fluentd supporting many packet formats"
13 | spec.homepage = "https://github.com/codeout/fluent-plugin-sflow"
14 |
15 | spec.files = `git ls-files -z`.split("\x0").reject do |f|
16 | f.match(%r{^(test|spec|features)/})
17 | end
18 | spec.bindir = "exe"
19 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20 | spec.require_paths = ["lib"]
21 | spec.extensions = ["ext/sflowtool/extconf.rb"]
22 |
23 | spec.add_dependency "fluentd", ">=0.14.0", "< 2"
24 | spec.add_development_dependency "bundler"
25 | spec.add_development_dependency "rake"
26 | spec.add_development_dependency "rake-compiler"
27 | spec.add_development_dependency "test-unit"
28 |
29 | if RUBY_VERSION.to_i > 2
30 | spec.add_development_dependency "webrick"
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/lib/fluent/plugin/in_sflow.rb:
--------------------------------------------------------------------------------
1 | require 'fluent/plugin/input'
2 | require 'fluent/plugin/parser_sflow'
3 |
4 |
5 | module Fluent::Plugin
6 | class SflowInput < Input
7 | Fluent::Plugin.register_input('sflow', self)
8 |
9 | helpers :server
10 |
11 | config_param :bind, :string, default: '0.0.0.0'
12 | config_param :port, :integer, default: 6343
13 | config_param :tag, :string
14 | config_param :max_bytes, :integer, default: 2048
15 |
16 |
17 | def configure(conf)
18 | super
19 | @parser = Fluent::Plugin::SflowParser.new
20 | end
21 |
22 | def start
23 | super
24 | server_create(:in_sflow_server, @port, proto: :udp, bind: @bind, max_bytes: @max_bytes) do |data, sock|
25 | receive(data, sock.remote_host)
26 | end
27 | end
28 |
29 |
30 | protected
31 |
32 | def receive(raw, exporter)
33 | log.on_debug do
34 | log.debug 'received sflow datagram', raw: raw, exporter: exporter
35 | end
36 |
37 | @parser.parse(raw, exporter) do |time, record|
38 | if !time || !record
39 | log.warn 'Failed to parse', raw: raw, exporter: exporter
40 | return
41 | end
42 |
43 | router.emit(@tag, time, record)
44 | end
45 | rescue
46 | log.warn 'Unexpected error on parsing',
47 | raw: raw, exporter: exporter, error_class: $!.class, error: $!.message
48 | end
49 | end
50 | end
51 |
--------------------------------------------------------------------------------
/lib/fluent/plugin/parser_sflow.rb:
--------------------------------------------------------------------------------
1 | require 'fluent/plugin/parser'
2 | require 'fluent/time'
3 | require 'json'
4 | require 'sflowtool'
5 |
6 |
7 | module Fluent
8 | module Plugin
9 | class SflowParser < Parser
10 | Plugin.register_parser('sflow', self)
11 |
12 |
13 | def parse(raw, remote_host)
14 | data = JSON.load(Sflowtool.parse(raw, remote_host))
15 |
16 | # NOTE: sFlow datagram doesn't have timestamp field, but sysUpTime only
17 | time = Fluent::EventTime.new(data['header']['unix_seconds_utc'])
18 |
19 | data['samples'].each do |sample|
20 | yield time, data['header'].merge(sample)
21 | end
22 | end
23 | end
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/lib/sflowtool.rb:
--------------------------------------------------------------------------------
1 | require 'sflowtool/sflowtool'
2 |
3 | module Sflowtool
4 | class << self
5 | def parse(data, exporter)
6 | purge_trailing_commas(receive_sflow_datagram(data, exporter))
7 | end
8 |
9 | private
10 |
11 | def purge_trailing_commas(str)
12 | str.gsub! ',]', ']'
13 | str.gsub! ',}', '}'
14 | str
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/test/dump/sflow.v5.counters.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeout/fluent-plugin-sflow/cb0d019e421e79abb4e81d88a336526219cef094/test/dump/sflow.v5.counters.dump
--------------------------------------------------------------------------------
/test/dump/sflow.v5.ipv4_without_vlan.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeout/fluent-plugin-sflow/cb0d019e421e79abb4e81d88a336526219cef094/test/dump/sflow.v5.ipv4_without_vlan.dump
--------------------------------------------------------------------------------
/test/test_parser_sflow5.rb:
--------------------------------------------------------------------------------
1 | require 'fluent/test'
2 | require 'test/unit'
3 |
4 | require 'fluent/plugin/parser_sflow'
5 |
6 |
7 | class ParserSflow5Test < Test::Unit::TestCase
8 | def setup
9 | Fluent::Test.setup
10 | end
11 |
12 |
13 | def parser
14 | Fluent::Plugin::SflowParser.new
15 | end
16 |
17 |
18 | test 'parse sflow v5 flow sample of IPv4 packet without vlan' do
19 | data = File.binread(File.expand_path('../dump/sflow.v5.ipv4_without_vlan.dump', __FILE__))
20 |
21 | parsed = []
22 | parser.parse(data, '10.1.2.1') do |time, record|
23 | parsed << [time, record]
24 | end
25 |
26 | assert_equal 1, parsed.size
27 | assert parsed.first[0] - Time.now.to_i < 1
28 |
29 | {
30 | 'datagram_source_ip' => '10.1.2.1',
31 | 'unix_seconds_utc' => parsed.first[0],
32 | 'datagram_version' => 5,
33 | 'agent' => '10.1.2.1',
34 | 'samples_in_packet' => 1,
35 | 'sample_type' => 'flow_sample',
36 |
37 | 'input_port' => 513,
38 | 'output_port' => 512,
39 | 'dst_mac' => '020586717d03',
40 | 'src_mac' => '080027129909',
41 | 'ip_size' => 84,
42 | 'ip_tot_len' => 84,
43 | 'src_ip' => '10.1.2.2',
44 | 'dst_ip' => '1.0.4.1',
45 | 'ip_protocol' => 1,
46 | 'icmp_type' => 8,
47 | 'icmp_code' => 0,
48 | 'in_vlan' => 0,
49 | 'out_vlan' => 0,
50 | 'next_hop' => '202.249.2.169',
51 | 'src_subnet_mask' => 32,
52 | 'dst_subnet_mask' => 22
53 | }.each do |key, expected|
54 | assert_equal expected, parsed.first[1][key]
55 | end
56 | end
57 |
58 | test 'parse sflow v5 counters sample' do
59 | data = File.binread(File.expand_path('../dump/sflow.v5.counters.dump', __FILE__))
60 |
61 | parsed = []
62 | parser.parse(data, '10.1.2.1') do |time, record|
63 | parsed << [time, record]
64 | end
65 |
66 | assert_equal 1, parsed.size
67 | assert parsed.first[0] - Time.now.to_i < 1
68 |
69 | {
70 | 'datagram_source_ip' => '10.1.2.1',
71 | 'unix_seconds_utc' => parsed.first[0],
72 | 'datagram_version' => 5,
73 | 'agent' => '10.1.2.1',
74 | 'samples_in_packet' => 1,
75 | 'sample_type' => 'counters_sample',
76 |
77 | 'if_index' => 512,
78 | 'network_type' => 6,
79 | 'if_speed' => 10000000000,
80 | 'if_direction' => 1,
81 | 'if_status' => 3,
82 | 'if_in_octets' => 0,
83 | 'if_in_ucast_pkts' => 8,
84 | 'if_in_multicast_pkts' => 121,
85 | 'if_in_broadcast_pkts' => 0,
86 | 'if_in_discards' => 0,
87 | 'if_in_errors' => 0,
88 | 'if_in_unknown_protos' => 0,
89 | 'if_out_octets' => 130454,
90 | 'if_out_ucast_pkts' => 1060,
91 | 'if_out_multicast_pkts' => 0,
92 | 'if_out_broadcast_pkts' => 95,
93 | 'if_out_discards' => 0,
94 | 'if_out_errors' => 0,
95 | 'if_promiscuous_mode' => 0,
96 | 'dot3_stats_alignment_errors' => 0,
97 | 'dot3_stats_fcserrors' => 0,
98 | 'dot3_stats_single_collision_frames' => 0,
99 | 'dot3_stats_multiple_collision_frames' => 0,
100 | 'dot3_stats_sqetest_errors' => 0,
101 | 'dot3_stats_deferred_transmissions' => 0,
102 | 'dot3_stats_late_collisions' => 0,
103 | 'dot3_stats_excessive_collisions' => 0,
104 | 'dot3_stats_internal_mac_transmit_errors' => 0,
105 | 'dot3_stats_carrier_sense_errors' => 0,
106 | 'dot3_stats_frame_too_longs' => 0,
107 | 'dot3_stats_internal_mac_receive_errors' => 0,
108 | 'dot3_stats_symbol_errors' => 0
109 | }.each do |key, expected|
110 | assert_equal expected, parsed.first[1][key]
111 | end
112 | end
113 | end
114 |
--------------------------------------------------------------------------------