├── .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 | [![Test on Ubuntu](https://github.com/codeout/fluent-plugin-sflow/actions/workflows/test-linux.yaml/badge.svg)](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 | --------------------------------------------------------------------------------