Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
208
plugins/inputs/netflow/README.md
Normal file
208
plugins/inputs/netflow/README.md
Normal file
|
@ -0,0 +1,208 @@
|
|||
# Netflow Input Plugin
|
||||
|
||||
This service plugin acts as a collector for Netflow v5, Netflow v9 and IPFIX
|
||||
flow information. The Layer 4 protocol numbers are gathered from the
|
||||
[official IANA assignments][IANA assignments].
|
||||
The internal field mappings for Netflow v5 fields are defined according to
|
||||
[Cisco's Netflow v5 documentation][CISCO NF5], Netflow v9 fields are defined
|
||||
according to [Cisco's Netflow v9 documentation][CISCO NF9] and the
|
||||
[ASA extensions][ASA extensions].
|
||||
Definitions for IPFIX are according to [IANA assignment document][IPFIX doc].
|
||||
|
||||
⭐ Telegraf v1.25.0
|
||||
🏷️ network
|
||||
💻 all
|
||||
|
||||
[IANA assignments]: https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
|
||||
[CISCO NF5]: https://www.cisco.com/c/en/us/td/docs/net_mgmt/netflow_collection_engine/3-6/user/guide/format.html#wp1006186
|
||||
[CISCO NF9]: https://www.cisco.com/en/US/technologies/tk648/tk362/technologies_white_paper09186a00800a3db9.html
|
||||
[ASA extensions]: https://www.cisco.com/c/en/us/td/docs/security/asa/special/netflow/asa_netflow.html
|
||||
[IPFIX doc]: https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-nat-type
|
||||
|
||||
## Service Input <!-- @/docs/includes/service_input.md -->
|
||||
|
||||
This plugin is a service input. Normal plugins gather metrics determined by the
|
||||
interval setting. Service plugins start a service to listen and wait for
|
||||
metrics or events to occur. Service plugins have two key differences from
|
||||
normal plugins:
|
||||
|
||||
1. The global or plugin specific `interval` setting may not apply
|
||||
2. The CLI options of `--test`, `--test-wait`, and `--once` may not produce
|
||||
output for this plugin
|
||||
|
||||
## Global configuration options <!-- @/docs/includes/plugin_config.md -->
|
||||
|
||||
In addition to the plugin-specific configuration settings, plugins support
|
||||
additional global and plugin configuration settings. These settings are used to
|
||||
modify metrics, tags, and field or create aliases and configure ordering, etc.
|
||||
See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||
|
||||
[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins
|
||||
|
||||
## Configuration
|
||||
|
||||
```toml @sample.conf
|
||||
# Netflow v5, Netflow v9 and IPFIX collector
|
||||
[[inputs.netflow]]
|
||||
## Address to listen for netflow,ipfix or sflow packets.
|
||||
## example: service_address = "udp://:2055"
|
||||
## service_address = "udp4://:2055"
|
||||
## service_address = "udp6://:2055"
|
||||
service_address = "udp://:2055"
|
||||
|
||||
## Set the size of the operating system's receive buffer.
|
||||
## example: read_buffer_size = "64KiB"
|
||||
## Uses the system's default if not set.
|
||||
# read_buffer_size = ""
|
||||
|
||||
## Protocol version to use for decoding.
|
||||
## Available options are
|
||||
## "ipfix" -- IPFIX / Netflow v10 protocol (also works for Netflow v9)
|
||||
## "netflow v5" -- Netflow v5 protocol
|
||||
## "netflow v9" -- Netflow v9 protocol (also works for IPFIX)
|
||||
## "sflow v5" -- sFlow v5 protocol
|
||||
# protocol = "ipfix"
|
||||
|
||||
## Private Enterprise Numbers (PEN) mappings for decoding
|
||||
## This option allows to specify vendor-specific mapping files to use during
|
||||
## decoding.
|
||||
# private_enterprise_number_files = []
|
||||
|
||||
## Log incoming packets for tracing issues
|
||||
# log_level = "trace"
|
||||
```
|
||||
|
||||
## Private Enterprise Number mapping
|
||||
|
||||
Using the `private_enterprise_number_files` option you can specify mappings for
|
||||
vendor-specific element-IDs with a PEN specification. The mapping has to be a
|
||||
comma-separated-file (CSV) containing the element's `ID`, its `name` and the
|
||||
`data-type`. A comma (`,`) is used as separator and comments are allowed using
|
||||
the hash (`#`) prefix.
|
||||
The element `ID` has the form `<pen-number>.<element-id>`, the `name` has to be
|
||||
a valid field-name and `data-type` denotes the mapping of the raw-byte value to
|
||||
the field's type. For example
|
||||
|
||||
```csv
|
||||
# PEN.ID, name, data type
|
||||
35632.349,in_src_osi_sap,hex
|
||||
35632.471,nprobe_ipv4_address,ip
|
||||
35632.1028,protocol_ntop,string
|
||||
35632.1036,l4_srv_port,uint
|
||||
```
|
||||
|
||||
specify four elements (`349`, `471`, `1028` and `1036`) for PEN `35632` (ntop)
|
||||
with the corresponding name and data-type.
|
||||
|
||||
Currently the following `data-type`s are supported:
|
||||
|
||||
- `uint` unsigned integer with 8, 16, 32 or 64 bit
|
||||
- `hex` hex-encoding of the raw byte sequence with `0x` prefix
|
||||
- `string` string interpretation of the raw byte sequence
|
||||
- `ip` IPv4 or IPv6 address
|
||||
- `proto` mapping of layer-4 protocol numbers to names
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### `Error template not found` warnings
|
||||
|
||||
Those warnings usually occur in cases where Telegraf is restarted or reloaded
|
||||
while the flow-device is already streaming data.
|
||||
As background, the Netflow and IPFIX protocols rely on templates sent by the
|
||||
flow-device to decode fields. Without those templates, it is not clear what the
|
||||
data-type and size of the payload is and this makes it impossible to correctly
|
||||
interpret the data. However, templates are sent by the flow-device, usually at
|
||||
the start of streaming and in regular intervals (configurable in the device) and
|
||||
Telegraf has no means to trigger sending of the templates. Therefore, we need to
|
||||
skip the packets until the templates are resent by the device.
|
||||
|
||||
## Metrics are missing at the output
|
||||
|
||||
The metrics produced by this plugin are not tagged in a connection specific
|
||||
manner, therefore outputs relying on unique series key (e.g. InfluxDB) require
|
||||
the metrics to contain tags for the protocol, the connection source and the
|
||||
connection destination. Otherwise, metrics might be overwritten and are thus
|
||||
missing.
|
||||
|
||||
The required tagging can be achieved using the `converter` processor
|
||||
|
||||
```toml
|
||||
[[processors.converter]]
|
||||
[processors.converter.fields]
|
||||
tag = ["protocol", "src", "src_port", "dst", "dst_port"]
|
||||
```
|
||||
|
||||
__Please be careful as this will produce metrics with high cardinality!__
|
||||
|
||||
## Metrics
|
||||
|
||||
Metrics depend on the format used as well as on the information provided
|
||||
by the exporter. Furthermore, proprietary information might be sent requiring
|
||||
further decoding information. Most exporters should provide at least the
|
||||
following information
|
||||
|
||||
- netflow
|
||||
- tags:
|
||||
- source (IP of the exporter sending the data)
|
||||
- version (flow protocol version)
|
||||
- fields:
|
||||
- src (IP address, address of the source of the packets)
|
||||
- src_mask (uint64, mask for the IP address in bits)
|
||||
- dst (IP address, address of the destination of the packets)
|
||||
- dst_mask (uint64, mask for the IP address in bits)
|
||||
- src_port (uint64, source port)
|
||||
- dst_port (uint64, destination port)
|
||||
- protocol (string, Layer 4 protocol name)
|
||||
- in_bytes (uint64, number of incoming bytes)
|
||||
- in_packets (uint64, number of incoming packets)
|
||||
- tcp_flags (string, TCP flags for the flow)
|
||||
|
||||
## Example Output
|
||||
|
||||
The specific fields vary for the different protocol versions, here are some
|
||||
examples
|
||||
|
||||
### IPFIX
|
||||
|
||||
```text
|
||||
netflow,source=127.0.0.1,version=IPFIX protocol="tcp",vlan_src=0u,src_tos="0x00",flow_end_ms=1666345513807u,src="192.168.119.100",dst="44.233.90.52",src_port=51008u,total_bytes_exported=0u,flow_end_reason="end of flow",flow_start_ms=1666345513807u,in_total_bytes=52u,in_total_packets=1u,dst_port=443u
|
||||
netflow,source=127.0.0.1,version=IPFIX src_tos="0x00",src_port=54330u,rev_total_bytes_exported=0u,last_switched=9u,vlan_src=0u,flow_start_ms=1666345513807u,in_total_packets=1u,flow_end_reason="end of flow",flow_end_ms=1666345513816u,in_total_bytes=40u,dst_port=443u,src="192.168.119.100",dst="104.17.240.92",total_bytes_exported=0u,protocol="tcp"
|
||||
netflow,source=127.0.0.1,version=IPFIX flow_start_ms=1666345513807u,flow_end_ms=1666345513977u,src="192.168.119.100",dst_port=443u,total_bytes_exported=0u,last_switched=170u,src_tos="0x00",in_total_bytes=40u,dst="44.233.90.52",src_port=51024u,protocol="tcp",flow_end_reason="end of flow",in_total_packets=1u,rev_total_bytes_exported=0u,vlan_src=0u
|
||||
netflow,source=127.0.0.1,version=IPFIX src_port=58246u,total_bytes_exported=1u,flow_start_ms=1666345513806u,flow_end_ms=1666345513806u,in_total_bytes=156u,src="192.168.119.100",rev_total_bytes_exported=0u,last_switched=0u,flow_end_reason="forced end",dst="192.168.119.17",dst_port=53u,protocol="udp",in_total_packets=2u,vlan_src=0u,src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=IPFIX protocol="udp",vlan_src=0u,src_port=58879u,dst_port=53u,flow_end_ms=1666345513832u,src_tos="0x00",src="192.168.119.100",total_bytes_exported=1u,rev_total_bytes_exported=0u,flow_end_reason="forced end",last_switched=33u,in_total_bytes=221u,in_total_packets=2u,flow_start_ms=1666345513799u,dst="192.168.119.17"
|
||||
```
|
||||
|
||||
### Netflow v5
|
||||
|
||||
```text
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="140.82.121.3",src_port=443u,dst="192.168.119.100",dst_port=55516u,flows=8u,in_bytes=87477u,in_packets=78u,first_switched=86400660u,last_switched=86403316u,tcp_flags="...PA...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="140.82.121.6",src_port=443u,dst="192.168.119.100",dst_port=36408u,flows=8u,in_bytes=5009u,in_packets=21u,first_switched=86400447u,last_switched=86403267u,tcp_flags="...PA...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="140.82.112.22",src_port=443u,dst="192.168.119.100",dst_port=39638u,flows=8u,in_bytes=925u,in_packets=6u,first_switched=86400324u,last_switched=86403214u,tcp_flags="...PA...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="140.82.114.26",src_port=443u,dst="192.168.119.100",dst_port=49398u,flows=8u,in_bytes=250u,in_packets=2u,first_switched=86403131u,last_switched=86403362u,tcp_flags="...PA...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="192.168.119.100",src_port=55516u,dst="140.82.121.3",dst_port=443u,flows=8u,in_bytes=4969u,in_packets=37u,first_switched=86400652u,last_switched=86403269u,tcp_flags="...PA...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="192.168.119.100",src_port=36408u,dst="140.82.121.6",dst_port=443u,flows=8u,in_bytes=2736u,in_packets=21u,first_switched=86400438u,last_switched=86403258u,tcp_flags="...PA...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="192.168.119.100",src_port=39638u,dst="140.82.112.22",dst_port=443u,flows=8u,in_bytes=1560u,in_packets=6u,first_switched=86400225u,last_switched=86403255u,tcp_flags="...PA...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="192.168.119.100",src_port=49398u,dst="140.82.114.26",dst_port=443u,flows=8u,in_bytes=697u,in_packets=4u,first_switched=86403030u,last_switched=86403362u,tcp_flags="...PA...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
```
|
||||
|
||||
### Netflow v9
|
||||
|
||||
```text
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="140.82.121.3",src_port=443u,dst="192.168.119.100",dst_port=55516u,in_bytes=87477u,in_packets=78u,flow_start_ms=1666350478660u,flow_end_ms=1666350481316u,tcp_flags="...PA...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="140.82.121.6",src_port=443u,dst="192.168.119.100",dst_port=36408u,in_bytes=5009u,in_packets=21u,flow_start_ms=1666350478447u,flow_end_ms=1666350481267u,tcp_flags="...PA...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="140.82.112.22",src_port=443u,dst="192.168.119.100",dst_port=39638u,in_bytes=925u,in_packets=6u,flow_start_ms=1666350478324u,flow_end_ms=1666350481214u,tcp_flags="...PA...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="140.82.114.26",src_port=443u,dst="192.168.119.100",dst_port=49398u,in_bytes=250u,in_packets=2u,flow_start_ms=1666350481131u,flow_end_ms=1666350481362u,tcp_flags="...PA...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="192.168.119.100",src_port=55516u,dst="140.82.121.3",dst_port=443u,in_bytes=4969u,in_packets=37u,flow_start_ms=1666350478652u,flow_end_ms=1666350481269u,tcp_flags="...PA...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="192.168.119.100",src_port=36408u,dst="140.82.121.6",dst_port=443u,in_bytes=2736u,in_packets=21u,flow_start_ms=1666350478438u,flow_end_ms=1666350481258u,tcp_flags="...PA...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="192.168.119.100",src_port=39638u,dst="140.82.112.22",dst_port=443u,in_bytes=1560u,in_packets=6u,flow_start_ms=1666350478225u,flow_end_ms=1666350481255u,tcp_flags="...PA...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="192.168.119.100",src_port=49398u,dst="140.82.114.26",dst_port=443u,in_bytes=697u,in_packets=4u,flow_start_ms=1666350481030u,flow_end_ms=1666350481362u,tcp_flags="...PA...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
```
|
||||
|
||||
### sFlow v5
|
||||
|
||||
```text
|
||||
netflow,source=127.0.0.1,version=sFlowV5 out_errors=0i,out_bytes=3946i,status="up",in_unknown_protocol=4294967295i,out_unicast_packets_total=29i,agent_subid=100000i,interface_type=6i,in_unicast_packets_total=28i,out_dropped_packets=0i,in_bytes=3910i,in_broadcast_packets_total=4294967295i,ip_version="IPv4",agent_ip="192.168.119.184",in_snmp=3i,in_errors=0i,promiscuous=0i,interface=3i,in_mcast_packets_total=4294967295i,in_dropped_packets=0i,sys_uptime=12414i,seq_number=2i,speed=1000000000i,out_mcast_packets_total=4294967295i,out_broadcast_packets_total=4294967295i 12414000000
|
||||
netflow,source=127.0.0.1,version=sFlowV5 sys_uptime=17214i,agent_ip="192.168.119.184",agent_subid=100000i,seq_number=2i,in_phy_interface=1i,ip_version="IPv4" 17214000000
|
||||
netflow,source=127.0.0.1,version=sFlowV5 in_errors=0i,out_unicast_packets_total=36i,interface=3i,in_broadcast_packets_total=4294967295i,ip_version="IPv4",speed=1000000000i,out_bytes=4408i,out_mcast_packets_total=4294967295i,status="up",in_snmp=3i,in_mcast_packets_total=4294967295i,out_broadcast_packets_total=4294967295i,promiscuous=0i,in_bytes=5568i,out_dropped_packets=0i,sys_uptime=22014i,agent_subid=100000i,in_unknown_protocol=4294967295i,interface_type=6i,in_dropped_packets=0i,in_unicast_packets_total=37i,out_errors=0i,agent_ip="192.168.119.184",seq_number=3i 22014000000
|
||||
|
||||
```
|
27
plugins/inputs/netflow/ipv4_options.csv
Normal file
27
plugins/inputs/netflow/ipv4_options.csv
Normal file
|
@ -0,0 +1,27 @@
|
|||
Number,Name
|
||||
0,EOOL
|
||||
1,NOP
|
||||
2,SEC
|
||||
3,LSR
|
||||
4,TS
|
||||
5,E-SEC
|
||||
6,CIPSO
|
||||
7,RR
|
||||
8,SID
|
||||
9,SSR
|
||||
10,ZSU
|
||||
11,MTUP
|
||||
12,MTUR
|
||||
13,FINN
|
||||
14,VISA
|
||||
15,ENCODE
|
||||
16,IMITD
|
||||
17,EIP
|
||||
18,TR
|
||||
19,ADDEXT
|
||||
20,RTRALT
|
||||
21,SDB
|
||||
23,DPS
|
||||
24,UMP
|
||||
25,QS
|
||||
30,EXP
|
|
151
plugins/inputs/netflow/layer4_protocol_numbers.csv
Normal file
151
plugins/inputs/netflow/layer4_protocol_numbers.csv
Normal file
|
@ -0,0 +1,151 @@
|
|||
Decimal,Keyword
|
||||
0,HOPOPT
|
||||
1,ICMP
|
||||
2,IGMP
|
||||
3,GGP
|
||||
4,IPv4
|
||||
5,ST
|
||||
6,TCP
|
||||
7,CBT
|
||||
8,EGP
|
||||
9,IGP
|
||||
10,BBN-RCC-MON
|
||||
11,NVP-II
|
||||
12,PUP
|
||||
13,ARGUS
|
||||
14,EMCON
|
||||
15,XNET
|
||||
16,CHAOS
|
||||
17,UDP
|
||||
18,MUX
|
||||
19,DCN-MEAS
|
||||
20,HMP
|
||||
21,PRM
|
||||
22,XNS-IDP
|
||||
23,TRUNK-1
|
||||
24,TRUNK-2
|
||||
25,LEAF-1
|
||||
26,LEAF-2
|
||||
27,RDP
|
||||
28,IRTP
|
||||
29,ISO-TP4
|
||||
30,NETBLT
|
||||
31,MFE-NSP
|
||||
32,MERIT-INP
|
||||
33,DCCP
|
||||
34,3PC
|
||||
35,IDPR
|
||||
36,XTP
|
||||
37,DDP
|
||||
38,IDPR-CMTP
|
||||
39,TP++
|
||||
40,IL
|
||||
41,IPv6
|
||||
42,SDRP
|
||||
43,IPv6-Route
|
||||
44,IPv6-Frag
|
||||
45,IDRP
|
||||
46,RSVP
|
||||
47,GRE
|
||||
48,DSR
|
||||
49,BNA
|
||||
50,ESP
|
||||
51,AH
|
||||
52,I-NLSP
|
||||
53,SWIPE (deprecated)
|
||||
54,NARP
|
||||
55,MOBILE
|
||||
56,TLSP
|
||||
57,SKIP
|
||||
58,IPv6-ICMP
|
||||
59,IPv6-NoNxt
|
||||
60,IPv6-Opts
|
||||
61,host internal
|
||||
62,CFTP
|
||||
63,local network
|
||||
64,SAT-EXPAK
|
||||
65,KRYPTOLAN
|
||||
66,RVD
|
||||
67,IPPC
|
||||
68,distributed FS
|
||||
69,SAT-MON
|
||||
70,VISA
|
||||
71,IPCV
|
||||
72,CPNX
|
||||
73,CPHB
|
||||
74,WSN
|
||||
75,PVP
|
||||
76,BR-SAT-MON
|
||||
77,SUN-ND
|
||||
78,WB-MON
|
||||
79,WB-EXPAK
|
||||
80,ISO-IP
|
||||
81,VMTP
|
||||
82,SECURE-VMTP
|
||||
83,VINES
|
||||
84,TTP
|
||||
84,IPTM
|
||||
85,NSFNET-IGP
|
||||
86,DGP
|
||||
87,TCF
|
||||
88,EIGRP
|
||||
89,OSPFIGP
|
||||
90,Sprite-RPC
|
||||
91,LARP
|
||||
92,MTP
|
||||
93,AX.25
|
||||
94,IPIP
|
||||
95,MICP (deprecated)
|
||||
96,SCC-SP
|
||||
97,ETHERIP
|
||||
98,ENCAP
|
||||
99,private encryption scheme
|
||||
100,GMTP
|
||||
101,IFMP
|
||||
102,PNNI
|
||||
103,PIM
|
||||
104,ARIS
|
||||
105,SCPS
|
||||
106,QNX
|
||||
107,A/N
|
||||
108,IPComp
|
||||
109,SNP
|
||||
110,Compaq-Peer
|
||||
111,IPX-in-IP
|
||||
112,VRRP
|
||||
113,PGM
|
||||
114,0-hop
|
||||
115,L2TP
|
||||
116,DDX
|
||||
117,IATP
|
||||
118,STP
|
||||
119,SRP
|
||||
120,UTI
|
||||
121,SMP
|
||||
122,SM (deprecated)
|
||||
123,PTP
|
||||
124,ISIS over IPv4
|
||||
125,FIRE
|
||||
126,CRTP
|
||||
127,CRUDP
|
||||
128,SSCOPMCE
|
||||
129,IPLT
|
||||
130,SPS
|
||||
131,PIPE
|
||||
132,SCTP
|
||||
133,FC
|
||||
134,RSVP-E2E-IGNORE
|
||||
135,Mobility Header
|
||||
136,UDPLite
|
||||
137,MPLS-in-IP
|
||||
138,manet
|
||||
139,HIP
|
||||
140,Shim6
|
||||
141,WESP
|
||||
142,ROHC
|
||||
143,Ethernet
|
||||
144,AGGFRAG
|
||||
145-252,
|
||||
253,experimental
|
||||
254,experimental
|
||||
255,Reserved
|
|
44
plugins/inputs/netflow/mappings.go
Normal file
44
plugins/inputs/netflow/mappings.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package netflow
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
var funcMapping = map[string]decoderFunc{
|
||||
"uint": decodeUint,
|
||||
"hex": decodeHex,
|
||||
"string": decodeString,
|
||||
"ip": decodeIP,
|
||||
"proto": decodeL4Proto,
|
||||
}
|
||||
|
||||
func loadMapping(filename string) (map[string]fieldMapping, error) {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("opening %q failed: %w", filename, err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
reader := csv.NewReader(file)
|
||||
reader.Comma = ','
|
||||
reader.Comment = '#'
|
||||
reader.TrimLeadingSpace = true
|
||||
records, err := reader.ReadAll()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading csv failed: %w", err)
|
||||
}
|
||||
|
||||
mappings := make(map[string]fieldMapping, len(records))
|
||||
for _, r := range records {
|
||||
id, name, dtype := r[0], r[1], r[2]
|
||||
fun, found := funcMapping[dtype]
|
||||
if !found {
|
||||
return nil, fmt.Errorf("unknown data-type %q for id %q", dtype, id)
|
||||
}
|
||||
mappings[id] = fieldMapping{name, fun}
|
||||
}
|
||||
|
||||
return mappings, nil
|
||||
}
|
101
plugins/inputs/netflow/mappings_ipfix_pen/ntop-35632.csv
Normal file
101
plugins/inputs/netflow/mappings_ipfix_pen/ntop-35632.csv
Normal file
|
@ -0,0 +1,101 @@
|
|||
# The following data is extracted from
|
||||
# https://www.ntop.org/guides/nprobe/flow_information_elements.html
|
||||
# and contains IPFIX element definitions for Private Enterprise Number (PEN)
|
||||
# 35632 (ntop)
|
||||
#
|
||||
# PEN.ID, name, data type
|
||||
35632.1028,protocol_ntop,string
|
||||
35632.1031,l4_src_port_name,string
|
||||
35632.1035,l4_dst_port_name,string
|
||||
35632.1036,l4_srv_port,uint
|
||||
35632.1037,l4_srv_port_name,string
|
||||
35632.80,src_fragments,uint
|
||||
35632.81,dst_fragments,uint
|
||||
35632.123,client_nw_latency_ms,uint
|
||||
35632.124,server_nw_latency_ms,uint
|
||||
35632.78,client_tcp_flags,uint
|
||||
35632.79,server_tcp_flags,uint
|
||||
35632.125,app_latency_ms,uint
|
||||
35632.471,nprobe_ipv4_address,ip
|
||||
35632.82,src_to_dst_max_throughput,uint
|
||||
35632.83,src_to_dst_min_throughput,uint
|
||||
35632.84,src_to_dst_avg_throughput,uint
|
||||
35632.85,dst_to_src_max_throughput,uint
|
||||
35632.86,dst_to_src_min_throughput,uint
|
||||
35632.87,dst_to_src_avg_throughput,uint
|
||||
35632.88,pkts_up_to_128_bytes,uint
|
||||
35632.89,pkts_128_to_256_bytes,uint
|
||||
35632.90,pkts_256_to_512_bytes,uint
|
||||
35632.91,pkts_512_to_1024_bytes,uint
|
||||
35632.92,pkts_1024_to_1514_bytes,uint
|
||||
35632.93,pkts_over_1514_bytes,uint
|
||||
35632.98,cumulative_icmp_type,uint
|
||||
35632.101,src_ip_country,string
|
||||
35632.102,src_ip_city,string
|
||||
35632.103,dst_ip_country,string
|
||||
35632.104,dst_ip_city,string
|
||||
35632.448,src_ip_long,hex
|
||||
35632.449,src_ip_lat,hex
|
||||
35632.450,dst_ip_long,hex
|
||||
35632.451,dst_ip_lat,hex
|
||||
35632.105,flow_proto_port,uint
|
||||
35632.106,upstream_tunnel_id,uint
|
||||
35632.446,upstream_session_id,uint
|
||||
35632.107,longest_flow_pkt,uint
|
||||
35632.108,shortest_flow_pkt,uint
|
||||
35632.127,retransmitted_in_bytes,uint
|
||||
35632.109,retransmitted_in_pkts,uint
|
||||
35632.128,retransmitted_out_bytes,uint
|
||||
35632.110,retransmitted_out_pkts,uint
|
||||
35632.111,ooorder_in_pkts,uint
|
||||
35632.112,ooorder_out_pkts,uint
|
||||
35632.113,untunneled_protocol,proto
|
||||
35632.114,untunneled_ipv4_src_addr,ip
|
||||
35632.115,untunneled_l4_src_port,uint
|
||||
35632.116,untunneled_ipv4_dst_addr,ip
|
||||
35632.117,untunneled_l4_dst_port,uint
|
||||
35632.118,l7_proto,uint
|
||||
35632.119,l7_proto_name,string
|
||||
35632.120,downstream_tunnel_id,uint
|
||||
35632.447,downstream_session_id,uint
|
||||
35632.188,ssl_server_name,string
|
||||
35632.189,bittorrent_hash,string
|
||||
35632.121,flow_user_name,string
|
||||
35632.122,flow_server_name,string
|
||||
35632.126,plugin_name,string
|
||||
35632.396,untunneled_ipv6_src_addr,ip
|
||||
35632.397,untunneled_ipv6_dst_addr,ip
|
||||
35632.347,pkts_ttl_eq_1,uint
|
||||
35632.346,pkts_ttl_2_5,uint
|
||||
35632.334,pkts_ttl_5_32,uint
|
||||
35632.335,pkts_ttl_32_64,uint
|
||||
35632.336,pkts_ttl_64_96,uint
|
||||
35632.337,pkts_ttl_96_128,uint
|
||||
35632.338,pkts_ttl_128_160,uint
|
||||
35632.339,pkts_ttl_160_192,uint
|
||||
35632.340,pkts_ttl_192_224,uint
|
||||
35632.341,pkts_ttl_224_255,uint
|
||||
35632.349,in_src_osi_sap,hex
|
||||
35632.350,out_dst_osi_sap,hex
|
||||
35632.391,duration_in,uint
|
||||
35632.392,duration_out,uint
|
||||
35632.415,tcp_win_min_in,uint
|
||||
35632.416,tcp_win_max_in,uint
|
||||
35632.417,tcp_win_mss_in,uint
|
||||
35632.418,tcp_win_scale_in,uint
|
||||
35632.419,tcp_win_min_out,uint
|
||||
35632.420,tcp_win_max_out,uint
|
||||
35632.421,tcp_win_mss_out,uint
|
||||
35632.422,tcp_win_scale_out,uint
|
||||
35632.438,payload_hash,uint
|
||||
35632.443,src_as_name,string
|
||||
35632.444,dst_as_name,string
|
||||
35632.472,src_to_dst_second_bytes,uint
|
||||
35632.473,dst_to_src_second_bytes,uint
|
||||
35632.489,ja3c_hash,string
|
||||
35632.490,ja3s_hash,string
|
||||
35632.491,src_host_name,string
|
||||
35632.492,dst_host_name,string
|
||||
35632.493,ssl_cipher,uint
|
||||
35632.494,ssl_unsafe_cipher,uint
|
||||
35632.495,ssl_version,uint
|
|
162
plugins/inputs/netflow/netflow.go
Normal file
162
plugins/inputs/netflow/netflow.go
Normal file
|
@ -0,0 +1,162 @@
|
|||
//go:generate ../../../tools/readme_config_includer/generator
|
||||
package netflow
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
//go:embed sample.conf
|
||||
var sampleConfig string
|
||||
|
||||
type NetFlow struct {
|
||||
ServiceAddress string `toml:"service_address"`
|
||||
ReadBufferSize config.Size `toml:"read_buffer_size"`
|
||||
Protocol string `toml:"protocol"`
|
||||
DumpPackets bool `toml:"dump_packets" deprecated:"1.35.0;use 'log_level' 'trace' instead"`
|
||||
PENFiles []string `toml:"private_enterprise_number_files"`
|
||||
Log telegraf.Logger `toml:"-"`
|
||||
|
||||
conn *net.UDPConn
|
||||
decoder protocolDecoder
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
type protocolDecoder interface {
|
||||
init() error
|
||||
decode(net.IP, []byte) ([]telegraf.Metric, error)
|
||||
}
|
||||
|
||||
func (*NetFlow) SampleConfig() string {
|
||||
return sampleConfig
|
||||
}
|
||||
|
||||
func (n *NetFlow) Init() error {
|
||||
if n.ServiceAddress == "" {
|
||||
return errors.New("service_address required")
|
||||
}
|
||||
u, err := url.Parse(n.ServiceAddress)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid service address %q: %w", n.ServiceAddress, err)
|
||||
}
|
||||
switch u.Scheme {
|
||||
case "udp", "udp4", "udp6":
|
||||
default:
|
||||
return fmt.Errorf("invalid scheme %q, should be 'udp', 'udp4' or 'udp6'", u.Scheme)
|
||||
}
|
||||
|
||||
switch strings.ToLower(n.Protocol) {
|
||||
case "netflow v9":
|
||||
if len(n.PENFiles) != 0 {
|
||||
n.Log.Warn("'private_enterprise_number_files' option will be ignored in 'netflow v9'")
|
||||
}
|
||||
n.decoder = &netflowDecoder{
|
||||
log: n.Log,
|
||||
}
|
||||
case "", "ipfix":
|
||||
n.decoder = &netflowDecoder{
|
||||
penFiles: n.PENFiles,
|
||||
log: n.Log,
|
||||
}
|
||||
case "netflow v5":
|
||||
if len(n.PENFiles) != 0 {
|
||||
n.Log.Warn("'private_enterprise_number_files' option will be ignored in 'netflow v5'")
|
||||
}
|
||||
n.decoder = &netflowv5Decoder{}
|
||||
case "sflow", "sflow v5":
|
||||
n.decoder = &sflowv5Decoder{log: n.Log}
|
||||
default:
|
||||
return fmt.Errorf("invalid protocol %q, only supports 'sflow', 'netflow v5', 'netflow v9' and 'ipfix'", n.Protocol)
|
||||
}
|
||||
|
||||
return n.decoder.init()
|
||||
}
|
||||
|
||||
func (n *NetFlow) Start(acc telegraf.Accumulator) error {
|
||||
u, err := url.Parse(n.ServiceAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addr, err := net.ResolveUDPAddr(u.Scheme, u.Host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
conn, err := net.ListenUDP(u.Scheme, addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n.conn = conn
|
||||
|
||||
if n.ReadBufferSize > 0 {
|
||||
if err := conn.SetReadBuffer(int(n.ReadBufferSize)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
n.Log.Infof("Listening on %s://%s", n.conn.LocalAddr().Network(), n.conn.LocalAddr().String())
|
||||
|
||||
n.wg.Add(1)
|
||||
go func() {
|
||||
defer n.wg.Done()
|
||||
n.read(acc)
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*NetFlow) Gather(telegraf.Accumulator) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NetFlow) Stop() {
|
||||
if n.conn != nil {
|
||||
_ = n.conn.Close()
|
||||
}
|
||||
n.wg.Wait()
|
||||
}
|
||||
|
||||
func (n *NetFlow) read(acc telegraf.Accumulator) {
|
||||
buf := make([]byte, 64*1024) // 64kB
|
||||
for {
|
||||
count, src, err := n.conn.ReadFromUDP(buf)
|
||||
if err != nil {
|
||||
if !strings.HasSuffix(err.Error(), ": use of closed network connection") {
|
||||
acc.AddError(err)
|
||||
}
|
||||
break
|
||||
}
|
||||
n.Log.Debugf("received %d bytes\n", count)
|
||||
if count < 1 {
|
||||
continue
|
||||
}
|
||||
if n.Log.Level().Includes(telegraf.Trace) || n.DumpPackets { // for backward compatibility
|
||||
n.Log.Tracef("raw data: %s", hex.EncodeToString(buf[:count]))
|
||||
}
|
||||
metrics, err := n.decoder.decode(src.IP, buf[:count])
|
||||
if err != nil {
|
||||
errWithData := fmt.Errorf("%w; raw data: %s", err, hex.EncodeToString(buf[:count]))
|
||||
acc.AddError(errWithData)
|
||||
continue
|
||||
}
|
||||
for _, m := range metrics {
|
||||
acc.AddMetric(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register the plugin
|
||||
func init() {
|
||||
inputs.Add("netflow", func() telegraf.Input {
|
||||
return &NetFlow{}
|
||||
})
|
||||
}
|
877
plugins/inputs/netflow/netflow_decoder.go
Normal file
877
plugins/inputs/netflow/netflow_decoder.go
Normal file
|
@ -0,0 +1,877 @@
|
|||
package netflow
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"regexp"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/netsampler/goflow2/v2/decoders/netflow"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/metric"
|
||||
)
|
||||
|
||||
var regexpIPFIXPENMapping = regexp.MustCompile(`\d+\.\d+`)
|
||||
|
||||
type decoderFunc func([]byte) (interface{}, error)
|
||||
|
||||
type fieldMapping struct {
|
||||
name string
|
||||
decoder decoderFunc
|
||||
}
|
||||
|
||||
// Default field mappings common for Netflow version 9 and IPFIX
|
||||
// From documentations at
|
||||
// - https://www.cisco.com/en/US/technologies/tk648/tk362/technologies_white_paper09186a00800a3db9.html
|
||||
// - https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-information-elements
|
||||
var fieldMappingsNetflowCommon = map[uint16][]fieldMapping{
|
||||
// 0: reserved
|
||||
1: {{"in_bytes", decodeUint}}, // IN_BYTES / octetDeltaCount
|
||||
2: {{"in_packets", decodeUint}}, // IN_PKTS / packetDeltaCount
|
||||
3: {{"flows", decodeUint}}, // FLOWS / deltaFlowCount
|
||||
4: {{"protocol", decodeL4Proto}}, // PROTOCOL / protocolIdentifier
|
||||
5: {{"src_tos", decodeHex}}, // SRC_TOS / ipClassOfService
|
||||
6: {{"tcp_flags", decodeTCPFlags}}, // TCP_FLAGS / tcpControlBits
|
||||
7: {{"src_port", decodeUint}}, // L4_SRC_PORT / sourceTransportPort
|
||||
8: {{"src", decodeIP}}, // IPV4_SRC_ADDR / sourceIPv4Address
|
||||
9: {{"src_mask", decodeUint}}, // SRC_MASK / sourceIPv4PrefixLength
|
||||
10: {{"in_snmp", decodeUint}}, // INPUT_SNMP / ingressInterface
|
||||
11: {{"dst_port", decodeUint}}, // L4_DST_PORT / destinationTransportPort
|
||||
12: {{"dst", decodeIP}}, // IPV4_DST_ADDR / destinationIPv4Address
|
||||
13: {{"dst_mask", decodeUint}}, // DST_MASK / destinationIPv4PrefixLength
|
||||
14: {{"out_snmp", decodeUint}}, // OUTPUT_SNMP / egressInterface
|
||||
15: {{"next_hop", decodeIP}}, // IPV4_NEXT_HOP / ipNextHopIPv4Address
|
||||
16: {{"bgp_src_as", decodeUint}}, // SRC_AS / bgpSourceAsNumber
|
||||
17: {{"bgp_dst_as", decodeUint}}, // DST_AS / bgpDestinationAsNumber
|
||||
18: {{"bgp_next_hop", decodeIP}}, // BGP_IPV4_NEXT_HOP / bgpNextHopIPv4Address
|
||||
19: {{"out_mcast_packets", decodeUint}}, // MUL_DST_PKTS / postMCastPacketDeltaCount
|
||||
20: {{"out_mcast_bytes", decodeUint}}, // MUL_DST_BYTES / postMCastOctetDeltaCount
|
||||
21: {{"last_switched", decodeUint}}, // LAST_SWITCHED / flowEndSysUpTime
|
||||
22: {{"first_switched", decodeUint}}, // FIRST_SWITCHED / flowStartSysUpTime
|
||||
23: {{"out_bytes", decodeUint}}, // OUT_BYTES / postOctetDeltaCount
|
||||
24: {{"out_packets", decodeUint}}, // OUT_PKTS / postPacketDeltaCount
|
||||
25: {{"min_packet_len", decodeUint}}, // MIN_PKT_LNGTH / minimumIpTotalLength
|
||||
26: {{"max_packet_len", decodeUint}}, // MAX_PKT_LNGTH / maximumIpTotalLength
|
||||
27: {{"src", decodeIP}}, // IPV6_SRC_ADDR / sourceIPv6Address
|
||||
28: {{"dst", decodeIP}}, // IPV6_DST_ADDR / destinationIPv6Address
|
||||
29: {{"src_mask", decodeUint}}, // IPV6_SRC_MASK / sourceIPv6PrefixLength
|
||||
30: {{"dst_mask", decodeUint}}, // IPV6_DST_MASK / destinationIPv6PrefixLength
|
||||
31: {{"flow_label", decodeHex}}, // IPV6_FLOW_LABEL / flowLabelIPv6
|
||||
32: {
|
||||
{"icmp_type", decodeByteFunc(0)}, // ICMP_TYPE / icmpTypeCodeIPv4
|
||||
{"icmp_code", decodeByteFunc(1)},
|
||||
},
|
||||
33: {{"igmp_type", decodeUint}}, // MUL_IGMP_TYPE / igmpType
|
||||
34: {{"sampling_interval", decodeUint}}, // SAMPLING_INTERVAL / samplingInterval (deprecated)
|
||||
35: {{"sampling_algo", decodeSampleAlgo}}, // SAMPLING_ALGORITHM / samplingAlgorithm (deprecated)
|
||||
36: {{"flow_active_timeout", decodeUint}}, // FLOW_ACTIVE_TIMEOUT / flowActiveTimeout
|
||||
37: {{"flow_inactive_timeout", decodeUint}}, // FLOW_INACTIVE_TIMEOUT / flowIdleTimeout
|
||||
38: {{"engine_type", decodeEngineType}}, // ENGINE_TYPE / engineType (deprecated)
|
||||
39: {{"engine_id", decodeHex}}, // ENGINE_ID / engineId (deprecated)
|
||||
40: {{"total_bytes_exported", decodeUint}}, // TOTAL_BYTES_EXP / exportedOctetTotalCount
|
||||
41: {{"total_messages_exported", decodeUint}}, // TOTAL_PKTS_EXP / exportedMessageTotalCount
|
||||
42: {{"total_flows_exported", decodeUint}}, // TOTAL_FLOWS_EXP / exportedFlowRecordTotalCount
|
||||
// 43: vendor proprietary / deprecated
|
||||
44: {{"ipv4_src_prefix", decodeIP}}, // IPV4_SRC_PREFIX / sourceIPv4Prefix
|
||||
45: {{"ipv4_dst_prefix", decodeIP}}, // IPV4_DST_PREFIX / destinationIPv4Prefix
|
||||
46: {{"mpls_top_label_type", decodeMPLSType}}, // MPLS_TOP_LABEL_TYPE / mplsTopLabelType
|
||||
47: {{"mpls_top_label_ip", decodeIP}}, // MPLS_TOP_LABEL_IP_ADDR / mplsTopLabelIPv4Address
|
||||
48: {{"flow_sampler_id", decodeUint}}, // FLOW_SAMPLER_ID / samplerId (deprecated)
|
||||
49: {{"flow_sampler_mode", decodeSampleAlgo}}, // FLOW_SAMPLER_MODE / samplerMode (deprecated)
|
||||
50: {{"flow_sampler_interval", decodeUint}}, // FLOW_SAMPLER_RANDOM_INTERVAL / samplerRandomInterval (deprecated)
|
||||
// 51: vendor proprietary / deprecated
|
||||
52: {{"min_ttl", decodeUint}}, // MIN_TTL / minimumTTL
|
||||
53: {{"max_ttl", decodeUint}}, // MAX_TTL / maximumTTL
|
||||
54: {{"fragment_id", decodeHex}}, // IPV4_IDENT / fragmentIdentification
|
||||
55: {{"dst_tos", decodeHex}}, // DST_TOS / postIpClassOfService
|
||||
56: {{"in_src_mac", decodeMAC}}, // IN_SRC_MAC / sourceMacAddress
|
||||
57: {{"out_dst_mac", decodeMAC}}, // OUT_DST_MAC / postDestinationMacAddress
|
||||
58: {{"vlan_src", decodeUint}}, // SRC_VLAN / vlanId
|
||||
59: {{"vlan_dst", decodeUint}}, // DST_VLAN / postVlanId
|
||||
60: {{"ip_version", decodeIPVersion}}, // IP_PROTOCOL_VERSION / ipVersion
|
||||
61: {{"direction", decodeDirection}}, // DIRECTION / flowDirection
|
||||
62: {{"next_hop", decodeIP}}, // IPV6_NEXT_HOP / ipNextHopIPv6Address
|
||||
63: {{"bgp_next_hop", decodeIP}}, // BPG_IPV6_NEXT_HOP / bgpNextHopIPv6Address
|
||||
64: {{"ipv6_extensions", decodeHex}}, // IPV6_OPTION_HEADERS / ipv6ExtensionHeaders
|
||||
// 65 - 69: vendor proprietary
|
||||
70: {{"mpls_label_1", decodeHex}}, // MPLS_LABEL_1 / mplsTopLabelStackSection
|
||||
71: {{"mpls_label_2", decodeHex}}, // MPLS_LABEL_2 / mplsLabelStackSection2
|
||||
72: {{"mpls_label_3", decodeHex}}, // MPLS_LABEL_3 / mplsLabelStackSection3
|
||||
73: {{"mpls_label_4", decodeHex}}, // MPLS_LABEL_4 / mplsLabelStackSection4
|
||||
74: {{"mpls_label_5", decodeHex}}, // MPLS_LABEL_5 / mplsLabelStackSection5
|
||||
75: {{"mpls_label_6", decodeHex}}, // MPLS_LABEL_6 / mplsLabelStackSection6
|
||||
76: {{"mpls_label_7", decodeHex}}, // MPLS_LABEL_7 / mplsLabelStackSection7
|
||||
77: {{"mpls_label_8", decodeHex}}, // MPLS_LABEL_8 / mplsLabelStackSection8
|
||||
78: {{"mpls_label_9", decodeHex}}, // MPLS_LABEL_9 / mplsLabelStackSection9
|
||||
79: {{"mpls_label_10", decodeHex}}, // MPLS_LABEL_10 / mplsLabelStackSection10
|
||||
80: {{"in_dst_mac", decodeMAC}}, // IN_DST_MAC / destinationMacAddress
|
||||
81: {{"out_src_mac", decodeMAC}}, // OUT_SRC_MAC / postSourceMacAddress
|
||||
82: {{"interface", decodeString}}, // IF_NAME / interfaceName
|
||||
83: {{"interface_desc", decodeString}}, // IF_DESC / interfaceDescription
|
||||
84: {{"sampler_name", decodeString}}, // SAMPLER_NAME / samplerName
|
||||
85: {{"in_total_bytes", decodeUint}}, // IN_PERMANENT_BYTES / octetTotalCount
|
||||
86: {{"in_total_packets", decodeUint}}, // IN_PERMANENT_PKTS / packetTotalCount
|
||||
// 87: vendor proprietary
|
||||
88: {{"fragment_offset", decodeUint}}, // FRAGMENT_OFFSET / fragmentOffset
|
||||
89: {
|
||||
{"fwd_status", decodeFwdStatus}, // FORWARDING STATUS / forwardingStatus
|
||||
{"fwd_reason", decodeFwdReason},
|
||||
},
|
||||
90: {{"mpls_vpn_rd", decodeHex}}, // MPLS PAL RD / mplsVpnRouteDistinguisher
|
||||
91: {{"mpls_prefix_len", decodeUint}}, // MPLS PREFIX LEN / mplsTopLabelPrefixLength
|
||||
92: {{"src_traffic_index", decodeUint}}, // SRC TRAFFIC INDEX / srcTrafficIndex
|
||||
93: {{"dst_traffic_index", decodeUint}}, // DST TRAFFIC INDEX / dstTrafficIndex
|
||||
94: {{"app_desc", decodeString}}, // APPLICATION DESCRIPTION / applicationDescription
|
||||
95: {{"app_id", decodeHex}}, // APPLICATION TAG / applicationId
|
||||
96: {{"app_name", decodeString}}, // APPLICATION NAME / applicationName
|
||||
// 97: undefined
|
||||
98: {{"out_dscp", decodeUint}}, // postipDiffServCodePoint / postIpDiffServCodePoint
|
||||
99: {{"replication_factor", decodeUint}}, // replication factor / multicastReplicationFactor
|
||||
// 100: deprecated / className
|
||||
101: {{"classification_engine_id", decodeUint}}, // undefined / classificationEngineId
|
||||
102: {{"l2_packet_section_offset", decodeUint}}, // layer2packetSectionOffset
|
||||
103: {{"l2_packet_section_size", decodeUint}}, // layer2packetSectionSize
|
||||
104: {{"l2_packet_section_data", decodeHex}}, // layer2packetSectionData
|
||||
// 105 - 127: reserved
|
||||
|
||||
// Common between Netflow v9 ASA extension
|
||||
// https://www.cisco.com/c/en/us/td/docs/security/asa/special/netflow/asa_netflow.html
|
||||
// and IPFIX.
|
||||
148: {{"flow_id", decodeUint}}, // flowId
|
||||
152: {{"flow_start_ms", decodeUint}}, // NF_F_FLOW_CREATE_TIME_MSEC / flowStartMilliseconds
|
||||
153: {{"flow_end_ms", decodeUint}}, // NF_F_FLOW_END_TIME_MSEC / flowEndMilliseconds
|
||||
176: {{"icmp_type", decodeUint}}, // NF_F_ICMP_TYPE / icmpTypeIPv4
|
||||
177: {{"icmp_code", decodeUint}}, // NF_F_ICMP_CODE / icmpCodeIPv4
|
||||
178: {{"icmp_type", decodeUint}}, // NF_F_ICMP_TYPE_IPV6 / icmpTypeIPv6
|
||||
179: {{"icmp_code", decodeUint}}, // NF_F_ICMP_CODE_IPV6 / icmpCodeIPv6
|
||||
225: {{"xlat_src", decodeIP}}, // NF_F_XLATE_SRC_ADDR_IPV4 / postNATSourceIPv4Address
|
||||
226: {{"xlat_dst", decodeIP}}, // NF_F_XLATE_DST_ADDR_IPV4 / postNATDestinationIPv4Address
|
||||
227: {{"xlat_src_port", decodeUint}}, // NF_F_XLATE_SRC_PORT / postNAPTSourceTransportPort
|
||||
228: {{"xlat_dst_port", decodeUint}}, // NF_F_XLATE_DST_PORT / postNAPTDestinationTransportPort
|
||||
231: {{"initiator_bytes", decodeUint}}, // NF_F_FWD_FLOW_DELTA_BYTES / initiatorOctets
|
||||
232: {{"responder_bytes", decodeUint}}, // NF_F_REV_FLOW_DELTA_BYTES / responderOctets
|
||||
233: {{"fw_event", decodeFWEvent}}, // NF_F_FW_EVENT / firewallEvent
|
||||
281: {{"xlat_src", decodeIP}}, // NF_F_XLATE_SRC_ADDR_IPV6 / postNATSourceIPv6Address
|
||||
282: {{"xlat_dst", decodeIP}}, // NF_F_XLATE_DST_ADDR_IPV6 / postNATDestinationIPv6Address
|
||||
323: {{"event_time_ms", decodeUint}}, // NF_F_EVENT_TIME_MSEC / observationTimeMilliseconds
|
||||
324: {{"event_time_us", decodeUint}}, // NF_F_EVENT_TIME_USEC / observationTimeMicroseconds
|
||||
325: {{"event_time_ns", decodeUint}}, // NF_F_EVENT_TIME_NSEC / observationTimeNanoseconds
|
||||
}
|
||||
|
||||
// Default field mappings specific to Netflow version 9
|
||||
// From documentation at https://www.cisco.com/c/en/us/td/docs/security/asa/special/netflow/asa_netflow.html
|
||||
var fieldMappingsNetflowV9 = map[uint16][]fieldMapping{
|
||||
33000: {{"in_acl_id", decodeHex}}, // NF_F_INGRESS_ACL_ID
|
||||
33001: {{"out_acl_id", decodeHex}}, // NF_F_EGRESS_ACL_ID
|
||||
33002: {{"fw_event_ext", decodeHex}}, // NF_F_FW_EXT_EVENT
|
||||
40000: {{"username", decodeString}}, // NF_F_USERNAME
|
||||
}
|
||||
|
||||
// Default field mappings specific to Netflow version 9
|
||||
// From documentation at
|
||||
// https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-information-elements
|
||||
var fieldMappingsIPFIX = map[uint16][]fieldMapping{
|
||||
128: {{"bgp_next_as", decodeUint}}, // bgpNextAdjacentAsNumber
|
||||
129: {{"bgp_prev_as", decodeUint}}, // bgpPrevAdjacentAsNumber
|
||||
130: {{"exporter", decodeIP}}, // exporterIPv4Address
|
||||
131: {{"exporter", decodeIP}}, // exporterIPv6Address
|
||||
132: {{"dropped_bytes", decodeUint}}, // droppedOctetDeltaCount
|
||||
133: {{"dropped_packets", decodeUint}}, // droppedPacketDeltaCount
|
||||
134: {{"dropped_bytes_total", decodeUint}}, // droppedOctetTotalCount
|
||||
135: {{"dropped_packets_total", decodeUint}}, // droppedPacketTotalCount
|
||||
136: {{"flow_end_reason", decodeFlowEndReason}}, // flowEndReason
|
||||
137: {{"common_properties_id", decodeUint}}, // commonPropertiesId
|
||||
138: {{"observation_point_id", decodeUint}}, // observationPointId
|
||||
139: {
|
||||
{"icmp_type", decodeByteFunc(0)}, // icmpTypeCodeIPv6
|
||||
{"icmp_code", decodeByteFunc(1)},
|
||||
},
|
||||
140: {{"mpls_top_label_ip", decodeIP}}, // mplsTopLabelIPv6Address
|
||||
141: {{"linecard_id", decodeUint}}, // lineCardId
|
||||
142: {{"port_id", decodeUint}}, // portId
|
||||
143: {{"metering_pid", decodeUint}}, // meteringProcessId
|
||||
144: {{"exporting_pid", decodeUint}}, // exportingProcessId
|
||||
145: {{"template_id", decodeUint}}, // templateId
|
||||
146: {{"wlan_channel", decodeUint}}, // wlanChannelId
|
||||
147: {{"wlan_ssid", decodeString}}, // wlanSSID
|
||||
// 148: common
|
||||
149: {{"observation_domain_id", decodeUint}}, // observationDomainId
|
||||
150: {{"flow_start", decodeUint}}, // flowStartSeconds
|
||||
151: {{"flow_end", decodeUint}}, // flowEndSeconds
|
||||
// 152 - 153: common
|
||||
154: {{"flow_start_us", decodeUint}}, // flowStartMicroseconds
|
||||
155: {{"flow_end_us", decodeUint}}, // flowEndMicroseconds
|
||||
156: {{"flow_start_ns", decodeUint}}, // flowStartNanoseconds
|
||||
157: {{"flow_end_ns", decodeUint}}, // flowEndNanoseconds
|
||||
158: {{"flow_start_delta_us", decodeUint}}, // flowStartDeltaMicroseconds
|
||||
159: {{"flow_end_delta_us", decodeUint}}, // flowEndDeltaMicroseconds
|
||||
160: {{"system_init_ms", decodeUint}}, // systemInitTimeMilliseconds
|
||||
161: {{"flow_duration_ms", decodeUint}}, // flowDurationMilliseconds
|
||||
162: {{"flow_duration_us", decodeUint}}, // flowDurationMicroseconds
|
||||
163: {{"flow_count_total", decodeUint}}, // observedFlowTotalCount
|
||||
164: {{"ignored_packet_total", decodeUint}}, // ignoredPacketTotalCount
|
||||
165: {{"ignored_bytes_total", decodeUint}}, // ignoredOctetTotalCount
|
||||
166: {{"notsent_flow_count_total", decodeUint}}, // notSentFlowTotalCount
|
||||
167: {{"notsent_packet_total", decodeUint}}, // notSentPacketTotalCount
|
||||
168: {{"notsent_bytes_total", decodeUint}}, // notSentOctetTotalCount
|
||||
169: {{"ipv6_dst_prefix", decodeIP}}, // destinationIPv6Prefix
|
||||
170: {{"ipv6_src_prefix", decodeIP}}, // sourceIPv6Prefix
|
||||
171: {{"out_bytes_total", decodeUint}}, // postOctetTotalCount
|
||||
172: {{"out_packets_total", decodeUint}}, // postPacketTotalCount
|
||||
173: {{"flow_key_indicator", decodeHex}}, // flowKeyIndicator
|
||||
174: {{"out_mcast_packets_total", decodeUint}}, // postMCastPacketTotalCount
|
||||
175: {{"out_mcast_bytes_total", decodeUint}}, // postMCastOctetTotalCount
|
||||
// 176 - 179: common
|
||||
180: {{"udp_src_port", decodeUint}}, // udpSourcePort
|
||||
181: {{"udp_dst_port", decodeUint}}, // udpDestinationPort
|
||||
182: {{"tcp_src_port", decodeUint}}, // tcpSourcePort
|
||||
183: {{"tcp_dst_port", decodeUint}}, // tcpDestinationPort
|
||||
184: {{"tcp_seq_number", decodeUint}}, // tcpSequenceNumber
|
||||
185: {{"tcp_ack_number", decodeUint}}, // tcpAcknowledgementNumber
|
||||
186: {{"tcp_window_size", decodeUint}}, // tcpWindowSize
|
||||
187: {{"tcp_urgent_ptr", decodeUint}}, // tcpUrgentPointer
|
||||
188: {{"tcp_header_len", decodeUint}}, // tcpHeaderLength
|
||||
189: {{"ip_header_len", decodeUint}}, // ipHeaderLength
|
||||
190: {{"ipv4_total_len", decodeUint}}, // totalLengthIPv4
|
||||
191: {{"ipv6_payload_len", decodeUint}}, // payloadLengthIPv6
|
||||
192: {{"ttl", decodeUint}}, // ipTTL
|
||||
193: {{"ipv6_next_header", decodeUint}}, // nextHeaderIPv6
|
||||
194: {{"mpls_payload_len", decodeUint}}, // mplsPayloadLength
|
||||
195: {{"dscp", decodeUint}}, // ipDiffServCodePoint
|
||||
196: {{"precedence", decodeUint}}, // ipPrecedence
|
||||
197: {{"fragment_flags", decodeFragmentFlags}}, // fragmentFlags
|
||||
198: {{"bytes_sqr_sum", decodeUint}}, // octetDeltaSumOfSquares
|
||||
199: {{"bytes_sqr_sum_total", decodeUint}}, // octetTotalSumOfSquares
|
||||
200: {{"mpls_top_label_ttl", decodeUint}}, // mplsTopLabelTTL
|
||||
201: {{"mpls_stack_len", decodeUint}}, // mplsLabelStackLength
|
||||
202: {{"mpls_stack_depth", decodeUint}}, // mplsLabelStackDepth
|
||||
203: {{"mpls_top_label_exp", decodeUint}}, // mplsTopLabelExp
|
||||
204: {{"ip_payload_len", decodeUint}}, // ipPayloadLength
|
||||
205: {{"udp_msg_len", decodeUint}}, // udpMessageLength
|
||||
206: {{"mcast", decodeUint}}, // isMulticast
|
||||
207: {{"ipv4_inet_header_len", decodeUint}}, // ipv4IHL
|
||||
208: {{"ipv4_options", decodeIPv4Options}}, // ipv4Options
|
||||
209: {{"tcp_options", decodeHex}}, // tcpOptions
|
||||
210: {{"padding", decodeHex}}, // paddingOctets
|
||||
211: {{"collector", decodeIP}}, // collectorIPv4Address
|
||||
212: {{"collector", decodeIP}}, // collectorIPv6Address
|
||||
213: {{"export_interface", decodeUint}}, // exportInterface
|
||||
214: {{"export_proto_version", decodeUint}}, // exportProtocolVersion
|
||||
215: {{"export_transport_proto", decodeUint}}, // exportTransportProtocol
|
||||
216: {{"collector_transport_port", decodeUint}}, // collectorTransportPort
|
||||
217: {{"exporter_transport_port", decodeUint}}, // exporterTransportPort
|
||||
218: {{"tcp_syn_total", decodeUint}}, // tcpSynTotalCount
|
||||
219: {{"tcp_fin_total", decodeUint}}, // tcpFinTotalCount
|
||||
220: {{"tcp_rst_total", decodeUint}}, // tcpRstTotalCount
|
||||
221: {{"tcp_psh_total", decodeUint}}, // tcpPshTotalCount
|
||||
222: {{"tcp_ack_total", decodeUint}}, // tcpAckTotalCount
|
||||
223: {{"tcp_urg_total", decodeUint}}, // tcpUrgTotalCount
|
||||
224: {{"ip_total_len", decodeUint}}, // ipTotalLength
|
||||
// 225 - 228: common
|
||||
229: {{"nat_origin_addr_realm", decodeUint}}, // natOriginatingAddressRealm
|
||||
230: {{"nat_event", decodeUint}}, // natEvent
|
||||
// 231 - 233: common
|
||||
234: {{"in_vrf_id", decodeUint}}, // ingressVRFID
|
||||
235: {{"out_vrf_id", decodeUint}}, // egressVRFID
|
||||
236: {{"vrf_name", decodeString}}, // VRFname
|
||||
237: {{"out_mpls_top_label_exp", decodeUint}}, // postMplsTopLabelExp
|
||||
238: {{"tcp_window_scale", decodeUint}}, // tcpWindowScale
|
||||
239: {{"biflow_direction", decodeBiflowDirection}}, // biflowDirection
|
||||
240: {{"eth_header_len", decodeUint}}, // ethernetHeaderLength
|
||||
241: {{"eth_payload_len", decodeUint}}, // ethernetPayloadLength
|
||||
242: {{"eth_total_len", decodeUint}}, // ethernetTotalLength
|
||||
243: {{"vlan_id", decodeUint}}, // dot1qVlanId
|
||||
244: {{"vlan_priority", decodeUint}}, // dot1qPriority
|
||||
245: {{"vlan_customer_id", decodeUint}}, // dot1qCustomerVlanId
|
||||
246: {{"vlan_customer_priority", decodeUint}}, // dot1qCustomerPriority
|
||||
247: {{"metro_evc_id", decodeString}}, // metroEvcId
|
||||
248: {{"metro_evc_type", decodeUint}}, // metroEvcType
|
||||
249: {{"pseudo_wire_id", decodeUint}}, // pseudoWireId
|
||||
250: {{"pseudo_wire_type", decodeHex}}, // pseudoWireType
|
||||
251: {{"pseudo_wire_ctrl_word", decodeHex}}, // pseudoWireControlWord
|
||||
252: {{"in_phy_interface", decodeUint}}, // ingressPhysicalInterface
|
||||
253: {{"out_phy_interface", decodeUint}}, // egressPhysicalInterface
|
||||
254: {{"out_vlan_id", decodeUint}}, // postDot1qVlanId
|
||||
255: {{"out_vlan_customer_id", decodeUint}}, // postDot1qCustomerVlanId
|
||||
256: {{"eth_type", decodeHex}}, // ethernetType
|
||||
257: {{"out_precedence", decodeUint}}, // postIpPrecedence
|
||||
258: {{"collection_time_ms", decodeUint}}, // collectionTimeMilliseconds
|
||||
259: {{"export_sctp_stream_id", decodeUint}}, // exportSctpStreamId
|
||||
260: {{"max_export_time", decodeUint}}, // maxExportSeconds
|
||||
261: {{"max_flow_end_time", decodeUint}}, // maxFlowEndSeconds
|
||||
262: {{"msg_md5", decodeHex}}, // messageMD5Checksum
|
||||
263: {{"msg_scope", decodeUint}}, // messageScope
|
||||
264: {{"min_export_time", decodeUint}}, // minExportSeconds
|
||||
265: {{"min_flow_start_time", decodeUint}}, // minFlowStartSeconds
|
||||
266: {{"opaque_bytes", decodeUint}}, // opaqueOctets
|
||||
267: { /* MUST BE IGNORED according to standard */ }, // sessionScope
|
||||
268: {{"max_flow_end_time_us", decodeUint}}, // maxFlowEndMicroseconds
|
||||
269: {{"max_flow_end_time_ms", decodeUint}}, // maxFlowEndMilliseconds
|
||||
270: {{"max_flow_end_time_ns", decodeUint}}, // maxFlowEndNanoseconds
|
||||
271: {{"min_flow_start_time_us", decodeUint}}, // minFlowStartMicroseconds
|
||||
272: {{"min_flow_start_time_ms", decodeUint}}, // minFlowStartMilliseconds
|
||||
273: {{"min_flow_start_time_ns", decodeUint}}, // minFlowStartNanoseconds
|
||||
274: {{"collector_cert", decodeString}}, // collectorCertificate
|
||||
275: {{"exporter_cert", decodeString}}, // exporterCertificate
|
||||
276: {{"data_records_reliability", decodeBool}}, // dataRecordsReliability
|
||||
277: {{"observation_point_type", decodeOpsPointType}}, // observationPointType
|
||||
278: {{"connection_new_count", decodeUint}}, // newConnectionDeltaCount
|
||||
279: {{"connection_duration_sum", decodeUint}}, // connectionSumDurationSeconds
|
||||
280: {{"connection_transaction_id", decodeUint}}, // connectionTransactionId
|
||||
// 281 - 282: common
|
||||
283: {{"nat_pool_id", decodeUint}}, // natPoolId
|
||||
284: {{"nat_pool_name", decodeString}}, // natPoolName
|
||||
285: {
|
||||
{"anon_stability_class", decodeAnonStabilityClass}, // anonymizationFlags
|
||||
{"anon_flags", decodeAnonFlags},
|
||||
},
|
||||
286: {{"anon_technique", decodeAnonTechnique}}, // anonymizationTechnique
|
||||
287: {{"information_element", decodeUint}}, // informationElementIndex
|
||||
288: {{"p2p", decodeTechnology}}, // p2pTechnology
|
||||
289: {{"tunnel", decodeTechnology}}, // tunnelTechnology
|
||||
290: {{"encryption", decodeTechnology}}, // encryptedTechnology
|
||||
291: { /* IGNORED for parse-ability */ }, // basicList
|
||||
292: { /* IGNORED for parse-ability */ }, // subTemplateList
|
||||
293: { /* IGNORED for parse-ability */ }, // subTemplateMultiList
|
||||
294: {{"bgp_validity_state", decodeUint}}, // bgpValidityState
|
||||
295: {{"ipsec_spi", decodeUint}}, // IPSecSPI
|
||||
296: {{"gre_key", decodeUint}}, // greKey
|
||||
297: {{"nat_type", decodeIPNatType}}, // natType
|
||||
298: {{"initiator_packets", decodeUint}}, // initiatorPackets
|
||||
299: {{"responder_packets", decodeUint}}, // responderPackets
|
||||
300: {{"observation_domain_name", decodeString}}, // observationDomainName
|
||||
301: {{"observation_seq_id", decodeUint}}, // selectionSequenceId
|
||||
302: {{"selector_id", decodeUint}}, // selectorId
|
||||
303: {{"information_elem_id", decodeUint}}, // informationElementId
|
||||
304: {{"selector_algo", decodeSelectorAlgorithm}}, // selectorAlgorithm
|
||||
305: {{"sampling_packet_interval", decodeUint}}, // samplingPacketInterval
|
||||
306: {{"sampling_packet_space", decodeUint}}, // samplingPacketSpace
|
||||
307: {{"sampling_time_interval_us", decodeUint}}, // samplingTimeInterval
|
||||
308: {{"sampling_time_space_us", decodeUint}}, // samplingTimeSpace
|
||||
309: {{"sampling_size", decodeUint}}, // samplingSize
|
||||
310: {{"sampling_population", decodeUint}}, // samplingPopulation
|
||||
311: {{"sampling_probability", decodeFloat64}}, // samplingProbability
|
||||
312: {{"datalink_frame_size", decodeUint}}, // dataLinkFrameSize
|
||||
313: {{"ip_header_packet_section", decodeHex}}, // ipHeaderPacketSection
|
||||
314: {{"ip_payload_packet_section", decodeHex}}, // ipPayloadPacketSection
|
||||
315: {{"datalink_frame_section", decodeHex}}, // dataLinkFrameSection
|
||||
316: {{"mpls_label_stack_section", decodeHex}}, // mplsLabelStackSection
|
||||
317: {{"mpls_payload_packet_section", decodeHex}}, // mplsPayloadPacketSection
|
||||
318: {{"selector_total_packets_observed", decodeUint}}, // selectorIdTotalPktsObserved
|
||||
319: {{"selector_total_packets_selected", decodeUint}}, // selectorIdTotalPktsSelected
|
||||
320: {{"absolute_error", decodeFloat64}}, // absoluteError
|
||||
321: {{"relative_error", decodeFloat64}}, // relativeError
|
||||
322: {{"event_time", decodeUint}}, // observationTimeSeconds
|
||||
// 323 - 325: common
|
||||
326: {{"hash_digest", decodeHex}}, // digestHashValue
|
||||
327: {{"hash_ip_payload_offset", decodeUint}}, // hashIPPayloadOffset
|
||||
328: {{"hash_ip_payload_size", decodeUint}}, // hashIPPayloadSize
|
||||
329: {{"hash_out_range_min", decodeUint}}, // hashOutputRangeMin
|
||||
330: {{"hash_out_range_max", decodeUint}}, // hashOutputRangeMax
|
||||
331: {{"hash_selected_range_min", decodeUint}}, // hashSelectedRangeMin
|
||||
332: {{"hash_selected_range_max", decodeUint}}, // hashSelectedRangeMax
|
||||
333: {{"hash_digest_out", decodeBool}}, // hashDigestOutput
|
||||
334: {{"hash_init_val", decodeUint}}, // hashInitialiserValue
|
||||
335: {{"selector_name", decodeString}}, // selectorName
|
||||
336: {{"upper_confidence_interval_limit", decodeFloat64}}, // upperCILimit
|
||||
337: {{"lower_confidence_interval_limit", decodeFloat64}}, // upperCILimit
|
||||
338: {{"confidence_level", decodeFloat64}}, // confidenceLevel
|
||||
// 339 - 346: information element fields, do not map for now
|
||||
347: {{"virtual_station_interface_id", decodeHex}}, // virtualStationInterfaceId
|
||||
348: {{"virtual_station_interface_name", decodeString}}, // virtualStationInterfaceName
|
||||
349: {{"virtual_station_uuid", decodeHex}}, // virtualStationUUID
|
||||
350: {{"virtual_station_name", decodeString}}, // virtualStationName
|
||||
351: {{"l2_segment_id", decodeUint}}, // layer2SegmentId
|
||||
352: {{"l2_bytes", decodeUint}}, // layer2OctetDeltaCount
|
||||
353: {{"l2_bytes_total", decodeUint}}, // layer2OctetTotalCount
|
||||
354: {{"in_unicast_packets_total", decodeUint}}, // ingressUnicastPacketTotalCount
|
||||
355: {{"in_mcast_packets_total", decodeUint}}, // ingressMulticastPacketTotalCount
|
||||
356: {{"in_broadcast_packets_total", decodeUint}}, // ingressBroadcastPacketTotalCount
|
||||
357: {{"out_unicast_packets_total", decodeUint}}, // egressUnicastPacketTotalCount
|
||||
358: {{"out_broadcast_packets_total", decodeUint}}, // egressBroadcastPacketTotalCount
|
||||
359: {{"monitoring_interval_start_ms", decodeUint}}, // monitoringIntervalStartMilliSeconds
|
||||
360: {{"monitoring_interval_end_ms", decodeUint}}, // monitoringIntervalEndMilliSeconds
|
||||
361: {{"port_range_start", decodeUint}}, // portRangeStart
|
||||
362: {{"port_range_end", decodeUint}}, // portRangeEnd
|
||||
363: {{"port_range_step_size", decodeUint}}, // portRangeStepSize
|
||||
364: {{"port_range_ports", decodeUint}}, // portRangeNumPorts
|
||||
365: {{"station_mac", decodeMAC}}, // staMacAddress
|
||||
366: {{"station", decodeIP}}, // staIPv4Address
|
||||
367: {{"wtp_mac", decodeMAC}}, // wtpMacAddress
|
||||
368: {{"in_interface_type", decodeUint}}, // ingressInterfaceType
|
||||
369: {{"out_interface_type", decodeUint}}, // egressInterfaceType
|
||||
370: {{"rtp_seq_number", decodeUint}}, // rtpSequenceNumber
|
||||
371: {{"username", decodeString}}, // userName
|
||||
372: {{"app_category", decodeString}}, // applicationCategoryName
|
||||
373: {{"app_subcategory", decodeHex}}, // applicationSubCategoryName
|
||||
374: {{"app_group", decodeString}}, // applicationGroupName
|
||||
375: {{"flows_original_present", decodeUint}}, // originalFlowsPresent
|
||||
376: {{"flows_original_initiated", decodeUint}}, // originalFlowsInitiated
|
||||
377: {{"flows_original_completed", decodeUint}}, // originalFlowsCompleted
|
||||
378: {{"flow_src_ip_count", decodeUint}}, // distinctCountOfSourceIPAddress
|
||||
379: {{"flow_dst_ip_count", decodeUint}}, // distinctCountOfDestinationIPAddress
|
||||
380: {{"flow_src_ipv4_count", decodeUint}}, // distinctCountOfSourceIPv4Address
|
||||
381: {{"flow_dst_ipv4_count", decodeUint}}, // distinctCountOfDestinationIPv4Address
|
||||
382: {{"flow_src_ipv6_count", decodeUint}}, // distinctCountOfSourceIPv6Address
|
||||
383: {{"flow_dst_ipv6_count", decodeUint}}, // distinctCountOfDestinationIPv6Address
|
||||
384: {{"value_dist_method", decodeValueDistMethod}}, // valueDistributionMethod
|
||||
385: {{"rfc3550_jitter_ms", decodeUint}}, // rfc3550JitterMilliseconds
|
||||
386: {{"rfc3550_jitter_us", decodeUint}}, // rfc3550JitterMicroseconds
|
||||
387: {{"rfc3550_jitter_ns", decodeUint}}, // rfc3550JitterNanoseconds
|
||||
388: {{"vlan_dei", decodeBool}}, // dot1qDEI
|
||||
389: {{"vlan_customer_dei", decodeUint}}, // dot1qCustomerDEI
|
||||
390: {{"flow_selector_algo", decodeSelectorAlgorithm}}, // flowSelectorAlgorithm
|
||||
391: {{"flow_selected_byte_count", decodeUint}}, // flowSelectedOctetDeltaCount
|
||||
392: {{"flow_selected_packet_count", decodeUint}}, // flowSelectedOctetDeltaCount
|
||||
393: {{"flow_selected_count", decodeUint}}, // flowSelectedFlowDeltaCount
|
||||
394: {{"selector_id_flows_observed_total", decodeUint}}, // selectorIDTotalFlowsObserved
|
||||
395: {{"selector_id_flows_selected_total", decodeUint}}, // selectorIDTotalFlowsSelected
|
||||
396: {{"sampling_flow_interval_count", decodeUint}}, // samplingFlowInterval
|
||||
397: {{"sampling_flow_spacing_count", decodeUint}}, // samplingFlowSpacing
|
||||
398: {{"sampling_flow_interval_ms", decodeUint}}, // flowSamplingTimeInterval
|
||||
399: {{"sampling_flow_spacing_ms", decodeUint}}, // flowSamplingTimeSpacing
|
||||
400: {{"flow_domain_hash_element_id", decodeUint}}, // hashFlowDomain
|
||||
401: {{"transport_byte_count", decodeUint}}, // transportOctetDeltaCount
|
||||
402: {{"transport_packet_count", decodeUint}}, // transportPacketDeltaCount
|
||||
403: {{"exporter_original_ip", decodeUint}}, // originalExporterIPv4Address
|
||||
404: {{"exporter_original_ip", decodeUint}}, // originalExporterIPv6Address
|
||||
405: {{"exporter_original_domain", decodeHex}}, // originalObservationDomainId
|
||||
406: {{"intermediate_process_id", decodeHex}}, // intermediateProcessId
|
||||
407: {{"ignored_data_records_total", decodeUint}}, // ignoredDataRecordTotalCount
|
||||
408: {{"datalink_frame_type", decodeDataLinkFrameType}}, // dataLinkFrameType
|
||||
409: {{"section_offset", decodeUint}}, // sectionOffset
|
||||
410: {{"section_exported_bytes", decodeUint}}, // sectionExportedOctets
|
||||
411: {{"vlan_service_instance_tag", decodeHex}}, // dot1qServiceInstanceTag
|
||||
412: {{"vlan_service_instance_id", decodeUint}}, // dot1qServiceInstanceId
|
||||
413: {{"vlan_service_instance_priority", decodeUint}}, // dot1qServiceInstancePriority
|
||||
414: {{"vlan_customer_src_mac", decodeMAC}}, // dot1qCustomerSourceMacAddress
|
||||
415: {{"vlan_customer_dst_mac", decodeMAC}}, // dot1qCustomerDestinationMacAddress
|
||||
// 416: deprecated
|
||||
417: {{"post_layer2_bytes", decodeUint}}, // postLayer2OctetDeltaCount
|
||||
418: {{"post_mcast_layer2_bytes", decodeUint}}, // postMCastLayer2OctetDeltaCount
|
||||
// 419: deprecated
|
||||
420: {{"post_layer2_bytes_total", decodeUint}}, // postLayer2OctetTotalCount
|
||||
421: {{"post_mcast_layer2_bytes_total", decodeUint}}, // postMCastLayer2OctetTotalCount
|
||||
422: {{"min_layer2_total_length", decodeUint}}, // minimumLayer2TotalLength
|
||||
423: {{"max_layer2_total_length", decodeUint}}, // maximumLayer2TotalLength
|
||||
424: {{"dropped_layer2_bytes", decodeUint}}, // droppedLayer2OctetDeltaCount
|
||||
425: {{"dropped_layer2_bytes_total", decodeUint}}, // droppedLayer2OctetTotalCount
|
||||
426: {{"ignored_layer2_bytes_total", decodeUint}}, // ignoredLayer2OctetTotalCount
|
||||
427: {{"not_sent_layer2_bytes_total", decodeUint}}, // notSentLayer2OctetTotalCount
|
||||
428: {{"layer2_bytes_sumsqr", decodeUint}}, // layer2OctetDeltaSumOfSquares
|
||||
429: {{"layer2_bytes_total_sumsqr", decodeUint}}, // layer2OctetTotalSumOfSquares
|
||||
430: {{"layer2_frames", decodeUint}}, // layer2FrameDeltaCount
|
||||
431: {{"layer2_frames_total", decodeUint}}, // layer2FrameTotalCount
|
||||
432: {{"pseudo_wire_dst", decodeIP}}, // pseudoWireDestinationIPv4Address
|
||||
433: {{"ignored_layer2_frames_total", decodeUint}}, // ignoredLayer2FrameTotalCount
|
||||
434: {{"mib_obj_value_int", decodeInt}}, // mibObjectValueInteger
|
||||
435: {{"mib_obj_value_str", decodeString}}, // mibObjectValueOctetString
|
||||
436: {{"mib_obj_value_oid", decodeHex}}, // mibObjectValueOID
|
||||
437: {{"mib_obj_value_bits", decodeHex}}, // mibObjectValueBits
|
||||
438: {{"mib_obj_value_ip", decodeIP}}, // mibObjectValueIPAddress
|
||||
439: {{"mib_obj_value_counter", decodeUint}}, // mibObjectValueCounter
|
||||
440: {{"mib_obj_value_gauge", decodeUint}}, // mibObjectValueGauge
|
||||
441: {{"mib_obj_value_time", decodeUint}}, // mibObjectValueTimeTicks
|
||||
442: {{"mib_obj_value_uint", decodeUint}}, // mibObjectValueUnsigned
|
||||
443: {{"mib_obj_value_table", decodeHex}}, // mibObjectValueTable
|
||||
444: {{"mib_obj_value_row", decodeHex}}, // mibObjectValueRow
|
||||
445: {{"mib_oid", decodeHex}}, // mibObjectIdentifier
|
||||
446: {{"mib_sub_id", decodeUint}}, // mibSubIdentifier
|
||||
447: {{"mib_index_indicator", decodeHex}}, // mibIndexIndicator
|
||||
448: {{"mib_capture_time_semantics", decodeCaptureTimeSemantics}}, // mibCaptureTimeSemantics
|
||||
449: {{"mib_context_engine_id", decodeHex}}, // mibContextEngineID
|
||||
450: {{"mib_context_name", decodeString}}, // mibContextName
|
||||
451: {{"mib_obj_name", decodeString}}, // mibObjectName
|
||||
452: {{"mib_obj_desc", decodeString}}, // mibObjectDescription
|
||||
453: {{"mib_obj_syntax", decodeString}}, // mibObjectSyntax
|
||||
454: {{"mib_module_name", decodeString}}, // mibModuleName
|
||||
455: {{"imsi", decodeString}}, // mobileIMSI
|
||||
456: {{"msisdn", decodeString}}, // mobileMSISDN
|
||||
457: {{"http_status_code", decodeUint}}, // httpStatusCode
|
||||
458: {{"src_transport_port_limit", decodeUint}}, // sourceTransportPortsLimit
|
||||
459: {{"http_request_method", decodeString}}, // httpRequestMethod
|
||||
460: {{"http_request_host", decodeString}}, // httpRequestHost
|
||||
461: {{"http_request_target", decodeString}}, // httpRequestTarget
|
||||
462: {{"http_msg_version", decodeString}}, // httpMessageVersion
|
||||
463: {{"nat_instance_id", decodeUint}}, // natInstanceID
|
||||
464: {{"internal_addr_realm", decodeHex}}, // internalAddressRealm
|
||||
465: {{"external_addr_realm", decodeHex}}, // externalAddressRealm
|
||||
466: {{"nat_quota_exceeded_event", decodeUint}}, // natQuotaExceededEvent
|
||||
467: {{"nat_threshold_event", decodeUint}}, // natThresholdEvent
|
||||
468: {{"http_user_agent", decodeString}}, // httpUserAgent
|
||||
469: {{"http_content_type", decodeString}}, // httpContentType
|
||||
470: {{"http_reason_phrase", decodeString}}, // httpReasonPhrase
|
||||
471: {{"max_session_entries", decodeUint}}, // maxSessionEntries
|
||||
472: {{"max_bib_entries", decodeUint}}, // maxBIBEntries
|
||||
473: {{"max_entries_per_user", decodeUint}}, // maxEntriesPerUser
|
||||
474: {{"max_subscribers", decodeUint}}, // maxSubscribers
|
||||
475: {{"max_fragments_pending_reassembly", decodeUint}}, // maxFragmentsPendingReassembly
|
||||
476: {{"addr_pool_threshold_high", decodeUint}}, // addressPoolHighThreshold
|
||||
477: {{"addr_pool_threshold_low", decodeUint}}, // addressPoolLowThreshold
|
||||
478: {{"addr_port_mapping_threshold_high", decodeUint}}, // addressPortMappingHighThreshold
|
||||
479: {{"addr_port_mapping_threshold_low", decodeUint}}, // addressPortMappingLowThreshold
|
||||
480: {{"addr_port_mapping_per_user_threshold_high", decodeUint}}, // addressPortMappingPerUserHighThreshold
|
||||
481: {{"global_addr_mapping_threshold_high", decodeUint}}, // globalAddressMappingHighThreshold
|
||||
482: {{"vpn_identifier", decodeIP}}, // vpnIdentifier
|
||||
483: {{"bgp_community", decodeUint}}, // bgpCommunity
|
||||
484: {{"bgp_src_community_list", decodeHex}}, // bgpSourceCommunityList
|
||||
485: {{"bgp_dst_community_list", decodeHex}}, // bgpDestinationCommunityList
|
||||
486: {{"bgp_extended_community", decodeHex}}, // bgpExtendedCommunity
|
||||
487: {{"bgp_src_extended_community_list", decodeHex}}, // bgpSourceExtendedCommunityList
|
||||
488: {{"bgp_dst_extended_community_list", decodeHex}}, // bgpDestinationExtendedCommunityList
|
||||
489: {{"bgp_large_community", decodeHex}}, // bgpLargeCommunity
|
||||
490: {{"bgp_src_large_community_list", decodeHex}}, // bgpSourceLargeCommunityList
|
||||
491: {{"bgp_dst_large_community_list", decodeHex}}, // bgpDestinationLargeCommunityList
|
||||
}
|
||||
|
||||
// Decoder structure
|
||||
type netflowDecoder struct {
|
||||
penFiles []string
|
||||
log telegraf.Logger
|
||||
|
||||
templates map[string]netflow.NetFlowTemplateSystem
|
||||
mappingsV9 map[uint16]fieldMapping
|
||||
mappingsIPFIX map[uint16]fieldMapping
|
||||
mappingsPEN map[string]fieldMapping
|
||||
|
||||
logged map[string]bool
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func (d *netflowDecoder) decode(srcIP net.IP, payload []byte) ([]telegraf.Metric, error) {
|
||||
var metrics []telegraf.Metric
|
||||
|
||||
t := time.Now()
|
||||
src := srcIP.String()
|
||||
|
||||
// Prepare the templates used to decode the messages
|
||||
d.Lock()
|
||||
if _, ok := d.templates[src]; !ok {
|
||||
d.templates[src] = netflow.CreateTemplateSystem()
|
||||
}
|
||||
templates := d.templates[src]
|
||||
d.Unlock()
|
||||
|
||||
// Decode the overall message
|
||||
var msg9 netflow.NFv9Packet
|
||||
var msg10 netflow.IPFIXPacket
|
||||
buf := bytes.NewBuffer(payload)
|
||||
if err := netflow.DecodeMessageVersion(buf, templates, &msg9, &msg10); err != nil {
|
||||
if errors.Is(err, netflow.ErrorTemplateNotFound) {
|
||||
msg := "Skipping packet until the device resends the required template..."
|
||||
d.log.Warnf("%v. %s", err, msg)
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("decoding message failed: %w", err)
|
||||
}
|
||||
|
||||
// Extract metrics
|
||||
switch {
|
||||
case msg9.Version == 9:
|
||||
msg := msg9
|
||||
for _, flowsets := range msg.FlowSets {
|
||||
switch fs := flowsets.(type) {
|
||||
case netflow.TemplateFlowSet:
|
||||
case netflow.NFv9OptionsTemplateFlowSet:
|
||||
case netflow.OptionsDataFlowSet:
|
||||
for _, record := range fs.Records {
|
||||
tags := map[string]string{
|
||||
"source": src,
|
||||
"version": "NetFlowV9",
|
||||
}
|
||||
fields := make(map[string]interface{})
|
||||
for _, value := range record.ScopesValues {
|
||||
decodedFields, err := d.decodeValueV9(value)
|
||||
if err != nil {
|
||||
d.log.Errorf("decoding option record %+v failed: %v", record, err)
|
||||
continue
|
||||
}
|
||||
for _, field := range decodedFields {
|
||||
fields[field.Key] = field.Value
|
||||
}
|
||||
}
|
||||
for _, value := range record.OptionsValues {
|
||||
decodedFields, err := d.decodeValueV9(value)
|
||||
if err != nil {
|
||||
d.log.Errorf("decoding option record %+v failed: %v", record, err)
|
||||
continue
|
||||
}
|
||||
for _, field := range decodedFields {
|
||||
fields[field.Key] = field.Value
|
||||
}
|
||||
}
|
||||
metrics = append(metrics, metric.New("netflow_options", tags, fields, t))
|
||||
}
|
||||
case netflow.DataFlowSet:
|
||||
for _, record := range fs.Records {
|
||||
tags := map[string]string{
|
||||
"source": src,
|
||||
"version": "NetFlowV9",
|
||||
}
|
||||
fields := make(map[string]interface{})
|
||||
for _, value := range record.Values {
|
||||
decodedFields, err := d.decodeValueV9(value)
|
||||
if err != nil {
|
||||
d.log.Errorf("decoding record %+v failed: %v", record, err)
|
||||
continue
|
||||
}
|
||||
for _, field := range decodedFields {
|
||||
fields[field.Key] = field.Value
|
||||
}
|
||||
}
|
||||
metrics = append(metrics, metric.New("netflow", tags, fields, t))
|
||||
}
|
||||
}
|
||||
}
|
||||
case msg10.Version == 10:
|
||||
msg := msg10
|
||||
for _, flowsets := range msg.FlowSets {
|
||||
switch fs := flowsets.(type) {
|
||||
case netflow.TemplateFlowSet:
|
||||
case netflow.IPFIXOptionsTemplateFlowSet:
|
||||
case netflow.OptionsDataFlowSet:
|
||||
for _, record := range fs.Records {
|
||||
tags := map[string]string{
|
||||
"source": src,
|
||||
"version": "IPFIX",
|
||||
}
|
||||
fields := make(map[string]interface{})
|
||||
for _, value := range record.ScopesValues {
|
||||
decodedFields, err := d.decodeValueIPFIX(value)
|
||||
if err != nil {
|
||||
d.log.Errorf("decoding option record %+v failed: %v", record, err)
|
||||
continue
|
||||
}
|
||||
for _, field := range decodedFields {
|
||||
fields[field.Key] = field.Value
|
||||
}
|
||||
}
|
||||
for _, value := range record.OptionsValues {
|
||||
decodedFields, err := d.decodeValueIPFIX(value)
|
||||
if err != nil {
|
||||
d.log.Errorf("decoding option record %+v failed: %v", record, err)
|
||||
continue
|
||||
}
|
||||
for _, field := range decodedFields {
|
||||
fields[field.Key] = field.Value
|
||||
}
|
||||
}
|
||||
metrics = append(metrics, metric.New("netflow_options", tags, fields, t))
|
||||
}
|
||||
case netflow.DataFlowSet:
|
||||
for _, record := range fs.Records {
|
||||
tags := map[string]string{
|
||||
"source": srcIP.String(),
|
||||
"version": "IPFIX",
|
||||
}
|
||||
fields := make(map[string]interface{})
|
||||
t := time.Now()
|
||||
for _, value := range record.Values {
|
||||
decodedFields, err := d.decodeValueIPFIX(value)
|
||||
if err != nil {
|
||||
d.log.Errorf("decoding value %+v failed: %v", value, err)
|
||||
continue
|
||||
}
|
||||
for _, field := range decodedFields {
|
||||
fields[field.Key] = field.Value
|
||||
}
|
||||
}
|
||||
metrics = append(metrics, metric.New("netflow", tags, fields, t))
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("invalid message of type")
|
||||
}
|
||||
|
||||
return metrics, nil
|
||||
}
|
||||
|
||||
func (d *netflowDecoder) init() error {
|
||||
if err := initL4ProtoMapping(); err != nil {
|
||||
return fmt.Errorf("initializing layer 4 protocol mapping failed: %w", err)
|
||||
}
|
||||
if err := initIPv4OptionMapping(); err != nil {
|
||||
return fmt.Errorf("initializing IPv4 options mapping failed: %w", err)
|
||||
}
|
||||
|
||||
d.templates = make(map[string]netflow.NetFlowTemplateSystem)
|
||||
d.mappingsV9 = make(map[uint16]fieldMapping)
|
||||
d.mappingsIPFIX = make(map[uint16]fieldMapping)
|
||||
d.mappingsPEN = make(map[string]fieldMapping)
|
||||
for _, fn := range d.penFiles {
|
||||
d.log.Debugf("Loading PEN mapping file %q...", fn)
|
||||
mappings, err := loadMapping(fn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for k, v := range mappings {
|
||||
if !regexpIPFIXPENMapping.MatchString(k) {
|
||||
return fmt.Errorf("key %q in file %q does not match pattern <PEN>.<element-id>; maybe wrong file", k, fn)
|
||||
}
|
||||
if _, found := d.mappingsPEN[k]; found {
|
||||
return fmt.Errorf("duplicate entries for ID %q", k)
|
||||
}
|
||||
d.mappingsPEN[k] = v
|
||||
}
|
||||
}
|
||||
d.log.Infof("Loaded %d PEN mappings...", len(d.mappingsPEN))
|
||||
|
||||
d.logged = make(map[string]bool)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *netflowDecoder) decodeValueV9(field netflow.DataField) ([]telegraf.Field, error) {
|
||||
raw := field.Value.([]byte)
|
||||
elementID := field.Type
|
||||
|
||||
// Check the user-specified mapping
|
||||
if m, found := d.mappingsV9[elementID]; found {
|
||||
v, err := m.decoder(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []telegraf.Field{{Key: m.name, Value: v}}, nil
|
||||
}
|
||||
|
||||
// Check the version specific default field mappings
|
||||
if mappings, found := fieldMappingsNetflowV9[elementID]; found {
|
||||
var fields []telegraf.Field
|
||||
for _, m := range mappings {
|
||||
v, err := m.decoder(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fields = append(fields, telegraf.Field{Key: m.name, Value: v})
|
||||
}
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
// Check the common default field mappings
|
||||
if mappings, found := fieldMappingsNetflowCommon[elementID]; found {
|
||||
var fields []telegraf.Field
|
||||
for _, m := range mappings {
|
||||
v, err := m.decoder(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fields = append(fields, telegraf.Field{Key: m.name, Value: v})
|
||||
}
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
// Fallback to IPFIX mappings as some devices seem to send IPFIX elements in
|
||||
// Netflow v9 packets. See https://github.com/influxdata/telegraf/issues/14902
|
||||
// and https://github.com/influxdata/telegraf/issues/14903.
|
||||
if mappings, found := fieldMappingsIPFIX[elementID]; found {
|
||||
var fields []telegraf.Field
|
||||
for _, m := range mappings {
|
||||
v, err := m.decoder(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fields = append(fields, telegraf.Field{Key: m.name, Value: v})
|
||||
}
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
// Return the raw data if no mapping was found
|
||||
key := fmt.Sprintf("type_%d", elementID)
|
||||
if !d.logged[key] {
|
||||
d.log.Debugf("unknown Netflow v9 data field %v", field)
|
||||
d.logged[key] = true
|
||||
}
|
||||
v, err := decodeHex(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return []telegraf.Field{{Key: key, Value: v}}, nil
|
||||
}
|
||||
|
||||
func (d *netflowDecoder) decodeValueIPFIX(field netflow.DataField) ([]telegraf.Field, error) {
|
||||
raw := field.Value.([]byte)
|
||||
|
||||
// Checking for reverse elements according to RFC5103
|
||||
var prefix string
|
||||
elementID := field.Type
|
||||
if field.Type&0x4000 != 0 {
|
||||
prefix = "rev_"
|
||||
elementID = field.Type & (0x4000 ^ 0xffff)
|
||||
}
|
||||
|
||||
// Handle messages with Private Enterprise Numbers (PENs)
|
||||
if field.PenProvided {
|
||||
key := fmt.Sprintf("%d.%d", field.Pen, elementID)
|
||||
if m, found := d.mappingsPEN[key]; found {
|
||||
name := prefix + m.name
|
||||
v, err := m.decoder(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []telegraf.Field{{Key: name, Value: v}}, nil
|
||||
}
|
||||
if !d.logged[key] {
|
||||
d.log.Debugf("unknown IPFIX PEN data field %v", field)
|
||||
d.logged[key] = true
|
||||
}
|
||||
name := fmt.Sprintf("type_%d_%s%d", field.Pen, prefix, elementID)
|
||||
v, err := decodeHex(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []telegraf.Field{{Key: name, Value: v}}, nil
|
||||
}
|
||||
|
||||
// Check the user-specified mapping
|
||||
if m, found := d.mappingsIPFIX[elementID]; found {
|
||||
v, err := m.decoder(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []telegraf.Field{{Key: prefix + m.name, Value: v}}, nil
|
||||
}
|
||||
|
||||
// Check the version specific default field mappings
|
||||
if mappings, found := fieldMappingsIPFIX[elementID]; found {
|
||||
var fields []telegraf.Field
|
||||
for _, m := range mappings {
|
||||
v, err := m.decoder(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fields = append(fields, telegraf.Field{Key: prefix + m.name, Value: v})
|
||||
}
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
// Check the common default field mappings
|
||||
if mappings, found := fieldMappingsNetflowCommon[elementID]; found {
|
||||
var fields []telegraf.Field
|
||||
for _, m := range mappings {
|
||||
v, err := m.decoder(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fields = append(fields, telegraf.Field{Key: prefix + m.name, Value: v})
|
||||
}
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
// Return the raw data if no mapping was found
|
||||
key := fmt.Sprintf("type_%d", elementID)
|
||||
if !d.logged[key] {
|
||||
d.log.Debugf("unknown IPFIX data field %v", field)
|
||||
d.logged[key] = true
|
||||
}
|
||||
v, err := decodeHex(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []telegraf.Field{{Key: key, Value: v}}, nil
|
||||
}
|
296
plugins/inputs/netflow/netflow_test.go
Normal file
296
plugins/inputs/netflow/netflow_test.go
Normal file
|
@ -0,0 +1,296 @@
|
|||
package netflow
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/netsampler/goflow2/v2/decoders/netflow"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
"github.com/influxdata/telegraf/plugins/parsers/influx"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
address string
|
||||
protocol string
|
||||
errmsg string
|
||||
}{
|
||||
{
|
||||
name: "Netflow v5",
|
||||
address: "udp://:2055",
|
||||
protocol: "netflow v5",
|
||||
},
|
||||
{
|
||||
name: "Netflow v5 (uppercase)",
|
||||
address: "udp://:2055",
|
||||
protocol: "Netflow v5",
|
||||
},
|
||||
{
|
||||
name: "Netflow v9",
|
||||
address: "udp://:2055",
|
||||
protocol: "netflow v9",
|
||||
},
|
||||
{
|
||||
name: "Netflow v9 (uppercase)",
|
||||
address: "udp://:2055",
|
||||
protocol: "Netflow v9",
|
||||
},
|
||||
{
|
||||
name: "IPFIX",
|
||||
address: "udp://:2055",
|
||||
protocol: "ipfix",
|
||||
},
|
||||
{
|
||||
name: "IPFIX (uppercase)",
|
||||
address: "udp://:2055",
|
||||
protocol: "IPFIX",
|
||||
},
|
||||
{
|
||||
name: "invalid protocol",
|
||||
address: "udp://:2055",
|
||||
protocol: "foo",
|
||||
errmsg: "invalid protocol",
|
||||
},
|
||||
{
|
||||
name: "UDP",
|
||||
address: "udp://:2055",
|
||||
protocol: "netflow v5",
|
||||
},
|
||||
{
|
||||
name: "UDP4",
|
||||
address: "udp4://:2055",
|
||||
protocol: "netflow v5",
|
||||
},
|
||||
{
|
||||
name: "UDP6",
|
||||
address: "udp6://:2055",
|
||||
protocol: "netflow v5",
|
||||
},
|
||||
{
|
||||
name: "empty service address",
|
||||
address: "",
|
||||
protocol: "netflow v5",
|
||||
errmsg: "service_address required",
|
||||
},
|
||||
{
|
||||
name: "invalid address scheme",
|
||||
address: "tcp://:2055",
|
||||
protocol: "netflow v5",
|
||||
errmsg: "invalid scheme",
|
||||
},
|
||||
{
|
||||
name: "invalid service address",
|
||||
address: "udp://198.168.1.290:la",
|
||||
protocol: "netflow v5",
|
||||
errmsg: "invalid service address",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
plugin := &NetFlow{
|
||||
ServiceAddress: tt.address,
|
||||
Protocol: tt.protocol,
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
err := plugin.Init()
|
||||
if tt.errmsg != "" {
|
||||
require.ErrorContains(t, err, tt.errmsg)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMissingTemplate(t *testing.T) {
|
||||
raw := "000a00bc646b84c000000000000000e7010500ac000000000001dbe100000000"
|
||||
raw += "0000038a060018bdeac0a802c8000000000001bb6810f9f90000000000000000"
|
||||
raw += "000157b8c40155f28a00005056b3e365005056b3a7f804646b8471646b84e600"
|
||||
raw += "00018843fd5cf60000018843ff232e000000000000000e00000000000007bc00"
|
||||
raw += "000005000009560000000300dc00000000000000000000000000000e3130342e"
|
||||
raw += "31362e3234392e3234390e3130342e31362e3234392e323439000000"
|
||||
msg, err := hex.DecodeString(raw)
|
||||
require.NoError(t, err)
|
||||
|
||||
var acc testutil.Accumulator
|
||||
var logger testutil.CaptureLogger
|
||||
plugin := &NetFlow{
|
||||
ServiceAddress: "udp://127.0.0.1:0",
|
||||
Log: &logger,
|
||||
}
|
||||
require.NoError(t, plugin.Init())
|
||||
require.NoError(t, plugin.Start(&acc))
|
||||
defer plugin.Stop()
|
||||
|
||||
// Create a client without TLS
|
||||
addr := plugin.conn.LocalAddr()
|
||||
client, err := createClient(plugin.ServiceAddress, addr)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Write the message
|
||||
_, err = client.Write(msg)
|
||||
require.NoErrorf(t, err, "writing message failed: %v", err)
|
||||
require.NoError(t, client.Close())
|
||||
|
||||
// We expect a warning here
|
||||
require.Eventually(t, func() bool {
|
||||
return len(logger.Warnings()) > 0
|
||||
}, 3*time.Second, 100*time.Millisecond, "did not receive expected warnings")
|
||||
|
||||
var found bool
|
||||
for _, w := range logger.Warnings() {
|
||||
found = found || strings.Contains(w, netflow.ErrorTemplateNotFound.Error())
|
||||
}
|
||||
require.True(t, found, "warning not found")
|
||||
}
|
||||
|
||||
func TestWrongMapping(t *testing.T) {
|
||||
var logger testutil.CaptureLogger
|
||||
plugin := &NetFlow{
|
||||
ServiceAddress: "udp://127.0.0.1:0",
|
||||
Protocol: "ipfix",
|
||||
PENFiles: []string{"testcases/netflow_mapping.csv"},
|
||||
Log: &logger,
|
||||
}
|
||||
require.ErrorContains(t, plugin.Init(), "does not match pattern")
|
||||
}
|
||||
|
||||
func TestCases(t *testing.T) {
|
||||
// Get all directories in testdata
|
||||
folders, err := os.ReadDir("testcases")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Register the plugin
|
||||
inputs.Add("netflow", func() telegraf.Input {
|
||||
return &NetFlow{}
|
||||
})
|
||||
|
||||
// Prepare the influx parser for expectations
|
||||
parser := &influx.Parser{}
|
||||
require.NoError(t, parser.Init())
|
||||
|
||||
for _, f := range folders {
|
||||
// Only handle folders
|
||||
if !f.IsDir() {
|
||||
continue
|
||||
}
|
||||
testcasePath := filepath.Join("testcases", f.Name())
|
||||
configFilename := filepath.Join(testcasePath, "telegraf.conf")
|
||||
inputFiles := filepath.Join(testcasePath, "*.bin")
|
||||
expectedFilename := filepath.Join(testcasePath, "expected.out")
|
||||
expectedErrorFilename := filepath.Join(testcasePath, "expected.err")
|
||||
|
||||
// Compare options
|
||||
options := []cmp.Option{
|
||||
testutil.IgnoreTime(),
|
||||
testutil.SortMetrics(),
|
||||
}
|
||||
|
||||
t.Run(f.Name(), func(t *testing.T) {
|
||||
// Read the input data
|
||||
var messages [][]byte
|
||||
matches, err := filepath.Glob(inputFiles)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, matches)
|
||||
sort.Strings(matches)
|
||||
for _, fn := range matches {
|
||||
m, err := os.ReadFile(fn)
|
||||
require.NoError(t, err)
|
||||
messages = append(messages, m)
|
||||
}
|
||||
|
||||
// Read the expected output if any
|
||||
var expected []telegraf.Metric
|
||||
if _, err := os.Stat(expectedFilename); err == nil {
|
||||
var err error
|
||||
expected, err = testutil.ParseMetricsFromFile(expectedFilename, parser)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// Read the expected output if any
|
||||
var expectedErrors []string
|
||||
if _, err := os.Stat(expectedErrorFilename); err == nil {
|
||||
var err error
|
||||
expectedErrors, err = testutil.ParseLinesFromFile(expectedErrorFilename)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, expectedErrors)
|
||||
}
|
||||
|
||||
// Configure the plugin
|
||||
cfg := config.NewConfig()
|
||||
require.NoError(t, cfg.LoadConfig(configFilename))
|
||||
require.Len(t, cfg.Inputs, 1)
|
||||
|
||||
// Setup and start the plugin
|
||||
var acc testutil.Accumulator
|
||||
plugin := cfg.Inputs[0].Input.(*NetFlow)
|
||||
require.NoError(t, plugin.Init())
|
||||
require.NoError(t, plugin.Start(&acc))
|
||||
defer plugin.Stop()
|
||||
|
||||
// Create a client without TLS
|
||||
addr := plugin.conn.LocalAddr()
|
||||
client, err := createClient(plugin.ServiceAddress, addr)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Write the given sequence
|
||||
for i, msg := range messages {
|
||||
_, err := client.Write(msg)
|
||||
require.NoErrorf(t, err, "writing message from %q failed: %v", matches[i], err)
|
||||
}
|
||||
require.NoError(t, client.Close())
|
||||
|
||||
getNErrors := func() int {
|
||||
acc.Lock()
|
||||
defer acc.Unlock()
|
||||
return len(acc.Errors)
|
||||
}
|
||||
require.Eventuallyf(t, func() bool {
|
||||
return getNErrors() >= len(expectedErrors)
|
||||
}, 3*time.Second, 100*time.Millisecond, "did not receive errors (%d/%d)", getNErrors(), len(expectedErrors))
|
||||
|
||||
require.Lenf(t, acc.Errors, len(expectedErrors), "got errors: %v", acc.Errors)
|
||||
sort.SliceStable(acc.Errors, func(i, j int) bool {
|
||||
return acc.Errors[i].Error() < acc.Errors[j].Error()
|
||||
})
|
||||
for i, err := range acc.Errors {
|
||||
require.ErrorContains(t, err, expectedErrors[i])
|
||||
}
|
||||
|
||||
require.Eventuallyf(t, func() bool {
|
||||
acc.Lock()
|
||||
defer acc.Unlock()
|
||||
return acc.NMetrics() >= uint64(len(expected))
|
||||
}, 3*time.Second, 100*time.Millisecond, "did not receive metrics (%d/%d)", acc.NMetrics(), len(expected))
|
||||
|
||||
// Check the metric nevertheless as we might get some metrics despite errors.
|
||||
actual := acc.GetTelegrafMetrics()
|
||||
testutil.RequireMetricsEqual(t, expected, actual, options...)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func createClient(endpoint string, addr net.Addr) (net.Conn, error) {
|
||||
// Determine the protocol in a crude fashion
|
||||
parts := strings.SplitN(endpoint, "://", 2)
|
||||
if len(parts) != 2 {
|
||||
return nil, fmt.Errorf("invalid endpoint %q", endpoint)
|
||||
}
|
||||
protocol := parts[0]
|
||||
return net.Dial(protocol, addr.String())
|
||||
}
|
91
plugins/inputs/netflow/netflow_v5.go
Normal file
91
plugins/inputs/netflow/netflow_v5.go
Normal file
|
@ -0,0 +1,91 @@
|
|||
package netflow
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/netsampler/goflow2/v2/decoders/netflowlegacy"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/metric"
|
||||
)
|
||||
|
||||
// Decoder structure
|
||||
type netflowv5Decoder struct{}
|
||||
|
||||
func (*netflowv5Decoder) init() error {
|
||||
if err := initL4ProtoMapping(); err != nil {
|
||||
return fmt.Errorf("initializing layer 4 protocol mapping failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*netflowv5Decoder) decode(srcIP net.IP, payload []byte) ([]telegraf.Metric, error) {
|
||||
src := srcIP.String()
|
||||
|
||||
// Decode the message
|
||||
var msg netflowlegacy.PacketNetFlowV5
|
||||
buf := bytes.NewBuffer(payload)
|
||||
if err := netflowlegacy.DecodeMessageVersion(buf, &msg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Extract metrics
|
||||
t := time.Unix(int64(msg.UnixSecs), int64(msg.UnixNSecs))
|
||||
metrics := make([]telegraf.Metric, 0, len(msg.Records))
|
||||
for _, record := range msg.Records {
|
||||
tags := map[string]string{
|
||||
"source": src,
|
||||
"version": "NetFlowV5",
|
||||
}
|
||||
fields := map[string]interface{}{
|
||||
"flows": msg.Count,
|
||||
"sys_uptime": msg.SysUptime,
|
||||
"seq_number": msg.FlowSequence,
|
||||
"engine_type": mapEngineType(msg.EngineType),
|
||||
"sampling_interval": msg.SamplingInterval,
|
||||
"in_snmp": record.Input,
|
||||
"out_snmp": record.Output,
|
||||
"in_packets": record.DPkts,
|
||||
"in_bytes": record.DOctets,
|
||||
"first_switched": record.First,
|
||||
"last_switched": record.Last,
|
||||
"src_port": record.SrcPort,
|
||||
"dst_port": record.DstPort,
|
||||
"tcp_flags": mapTCPFlags(record.TCPFlags),
|
||||
"protocol": mapL4Proto(record.Proto),
|
||||
"bgp_src_as": record.SrcAS,
|
||||
"bgp_dst_as": record.DstAS,
|
||||
"src_mask": record.SrcMask,
|
||||
"dst_mask": record.DstMask,
|
||||
}
|
||||
|
||||
var err error
|
||||
fields["engine_id"], err = decodeHex([]byte{msg.EngineId})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'engine_id' failed: %w", err)
|
||||
}
|
||||
fields["src"], err = decodeIPFromUint32(uint32(record.SrcAddr))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'src' failed: %w", err)
|
||||
}
|
||||
fields["dst"], err = decodeIPFromUint32(uint32(record.DstAddr))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'dst' failed: %w", err)
|
||||
}
|
||||
fields["next_hop"], err = decodeIPFromUint32(uint32(record.NextHop))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'next_hop' failed: %w", err)
|
||||
}
|
||||
fields["src_tos"], err = decodeHex([]byte{record.Tos})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'src_tos' failed: %w", err)
|
||||
}
|
||||
|
||||
metrics = append(metrics, metric.New("netflow", tags, fields, t))
|
||||
}
|
||||
|
||||
return metrics, nil
|
||||
}
|
28
plugins/inputs/netflow/sample.conf
Normal file
28
plugins/inputs/netflow/sample.conf
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Netflow v5, Netflow v9 and IPFIX collector
|
||||
[[inputs.netflow]]
|
||||
## Address to listen for netflow,ipfix or sflow packets.
|
||||
## example: service_address = "udp://:2055"
|
||||
## service_address = "udp4://:2055"
|
||||
## service_address = "udp6://:2055"
|
||||
service_address = "udp://:2055"
|
||||
|
||||
## Set the size of the operating system's receive buffer.
|
||||
## example: read_buffer_size = "64KiB"
|
||||
## Uses the system's default if not set.
|
||||
# read_buffer_size = ""
|
||||
|
||||
## Protocol version to use for decoding.
|
||||
## Available options are
|
||||
## "ipfix" -- IPFIX / Netflow v10 protocol (also works for Netflow v9)
|
||||
## "netflow v5" -- Netflow v5 protocol
|
||||
## "netflow v9" -- Netflow v9 protocol (also works for IPFIX)
|
||||
## "sflow v5" -- sFlow v5 protocol
|
||||
# protocol = "ipfix"
|
||||
|
||||
## Private Enterprise Numbers (PEN) mappings for decoding
|
||||
## This option allows to specify vendor-specific mapping files to use during
|
||||
## decoding.
|
||||
# private_enterprise_number_files = []
|
||||
|
||||
## Log incoming packets for tracing issues
|
||||
# log_level = "trace"
|
544
plugins/inputs/netflow/sflow_v5.go
Normal file
544
plugins/inputs/netflow/sflow_v5.go
Normal file
|
@ -0,0 +1,544 @@
|
|||
package netflow
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gopacket/gopacket"
|
||||
"github.com/gopacket/gopacket/layers"
|
||||
"github.com/netsampler/goflow2/v2/decoders/sflow"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/metric"
|
||||
)
|
||||
|
||||
// Decoder structure
|
||||
type sflowv5Decoder struct {
|
||||
log telegraf.Logger
|
||||
|
||||
warnedCounterRaw map[uint32]bool
|
||||
warnedFlowRaw map[int64]bool
|
||||
}
|
||||
|
||||
func (d *sflowv5Decoder) init() error {
|
||||
if err := initL4ProtoMapping(); err != nil {
|
||||
return fmt.Errorf("initializing layer 4 protocol mapping failed: %w", err)
|
||||
}
|
||||
d.warnedCounterRaw = make(map[uint32]bool)
|
||||
d.warnedFlowRaw = make(map[int64]bool)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *sflowv5Decoder) decode(srcIP net.IP, payload []byte) ([]telegraf.Metric, error) {
|
||||
t := time.Now()
|
||||
src := srcIP.String()
|
||||
|
||||
// Decode the message
|
||||
var msg sflow.Packet
|
||||
buf := bytes.NewBuffer(payload)
|
||||
if err := sflow.DecodeMessageVersion(buf, &msg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Extract metrics
|
||||
metrics := make([]telegraf.Metric, 0, len(msg.Samples))
|
||||
for _, s := range msg.Samples {
|
||||
tags := map[string]string{
|
||||
"source": src,
|
||||
"version": "sFlowV5",
|
||||
}
|
||||
|
||||
switch sample := s.(type) {
|
||||
case sflow.FlowSample:
|
||||
fields := map[string]interface{}{
|
||||
"ip_version": decodeSflowIPVersion(msg.IPVersion),
|
||||
"sys_uptime": msg.Uptime,
|
||||
"agent_subid": msg.SubAgentId,
|
||||
"seq_number": sample.Header.SampleSequenceNumber,
|
||||
"sampling_interval": sample.SamplingRate,
|
||||
"in_total_packets": sample.SamplePool,
|
||||
"sampling_drops": sample.Drops,
|
||||
"in_snmp": sample.Input,
|
||||
}
|
||||
|
||||
var err error
|
||||
fields["agent_ip"], err = decodeIP(msg.AgentIP)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'agent_ip' failed: %w", err)
|
||||
}
|
||||
|
||||
if sample.Output>>31 == 0 {
|
||||
fields["out_snmp"] = sample.Output & 0x7fffffff
|
||||
}
|
||||
// Decode the source information
|
||||
if name := decodeSflowSourceInterface(sample.Header.SourceIdType); name != "" {
|
||||
fields[name] = sample.Header.SourceIdValue
|
||||
}
|
||||
// Decode the sampling direction
|
||||
if sample.Header.SourceIdValue == sample.Input {
|
||||
fields["direction"] = "ingress"
|
||||
} else {
|
||||
fields["direction"] = "egress"
|
||||
}
|
||||
recordFields, err := d.decodeFlowRecords(sample.Records)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range recordFields {
|
||||
fields[k] = v
|
||||
}
|
||||
metrics = append(metrics, metric.New("netflow", tags, fields, t))
|
||||
case sflow.ExpandedFlowSample:
|
||||
fields := map[string]interface{}{
|
||||
"ip_version": decodeSflowIPVersion(msg.IPVersion),
|
||||
"sys_uptime": msg.Uptime,
|
||||
"agent_subid": msg.SubAgentId,
|
||||
"seq_number": sample.Header.SampleSequenceNumber,
|
||||
"sampling_interval": sample.SamplingRate,
|
||||
"in_total_packets": sample.SamplePool,
|
||||
"sampling_drops": sample.Drops,
|
||||
"in_snmp": sample.InputIfValue,
|
||||
}
|
||||
|
||||
var err error
|
||||
fields["agent_ip"], err = decodeIP(msg.AgentIP)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'agent_ip' failed: %w", err)
|
||||
}
|
||||
|
||||
if sample.OutputIfFormat == 0 {
|
||||
fields["out_snmp"] = sample.OutputIfValue
|
||||
}
|
||||
// Decode the source information
|
||||
if name := decodeSflowSourceInterface(sample.Header.SourceIdType); name != "" {
|
||||
fields[name] = sample.Header.SourceIdValue
|
||||
}
|
||||
// Decode the sampling direction
|
||||
if sample.Header.SourceIdValue == sample.InputIfValue {
|
||||
fields["direction"] = "ingress"
|
||||
} else {
|
||||
fields["direction"] = "egress"
|
||||
}
|
||||
recordFields, err := d.decodeFlowRecords(sample.Records)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range recordFields {
|
||||
fields[k] = v
|
||||
}
|
||||
metrics = append(metrics, metric.New("netflow", tags, fields, t))
|
||||
case sflow.CounterSample:
|
||||
fields := map[string]interface{}{
|
||||
"ip_version": decodeSflowIPVersion(msg.IPVersion),
|
||||
"sys_uptime": msg.Uptime,
|
||||
"agent_subid": msg.SubAgentId,
|
||||
"seq_number": sample.Header.SampleSequenceNumber,
|
||||
}
|
||||
|
||||
var err error
|
||||
fields["agent_ip"], err = decodeIP(msg.AgentIP)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'agent_ip' failed: %w", err)
|
||||
}
|
||||
|
||||
// Decode the source information
|
||||
if name := decodeSflowSourceInterface(sample.Header.SourceIdType); name != "" {
|
||||
fields[name] = sample.Header.SourceIdValue
|
||||
}
|
||||
recordFields, err := d.decodeCounterRecords(sample.Records)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range recordFields {
|
||||
fields[k] = v
|
||||
}
|
||||
metrics = append(metrics, metric.New("netflow", tags, fields, t))
|
||||
case sflow.DropSample:
|
||||
fields := map[string]interface{}{
|
||||
"ip_version": decodeSflowIPVersion(msg.IPVersion),
|
||||
"sys_uptime": msg.Uptime,
|
||||
"agent_subid": msg.SubAgentId,
|
||||
"seq_number": sample.Header.SampleSequenceNumber,
|
||||
"sampling_drops": sample.Drops,
|
||||
"in_snmp": sample.Input,
|
||||
"out_snmp": sample.Output,
|
||||
"reason": sample.Reason,
|
||||
}
|
||||
|
||||
var err error
|
||||
fields["agent_ip"], err = decodeIP(msg.AgentIP)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'agent_ip' failed: %w", err)
|
||||
}
|
||||
|
||||
// Decode the source information
|
||||
if name := decodeSflowSourceInterface(sample.Header.SourceIdType); name != "" {
|
||||
fields[name] = sample.Header.SourceIdValue
|
||||
}
|
||||
// Decode the sampling direction
|
||||
if sample.Header.SourceIdValue == sample.Input {
|
||||
fields["direction"] = "ingress"
|
||||
} else {
|
||||
fields["direction"] = "egress"
|
||||
}
|
||||
recordFields, err := d.decodeFlowRecords(sample.Records)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range recordFields {
|
||||
fields[k] = v
|
||||
}
|
||||
metrics = append(metrics, metric.New("netflow", tags, fields, t))
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown record type %T", s)
|
||||
}
|
||||
}
|
||||
|
||||
return metrics, nil
|
||||
}
|
||||
|
||||
func (d *sflowv5Decoder) decodeFlowRecords(records []sflow.FlowRecord) (map[string]interface{}, error) {
|
||||
fields := make(map[string]interface{})
|
||||
for _, r := range records {
|
||||
if r.Data == nil {
|
||||
continue
|
||||
}
|
||||
switch record := r.Data.(type) {
|
||||
case sflow.SampledHeader:
|
||||
fields["l2_protocol"] = decodeSflowHeaderProtocol(record.Protocol)
|
||||
fields["l2_bytes"] = record.FrameLength
|
||||
pktfields, err := d.decodeRawHeaderSample(&record)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range pktfields {
|
||||
fields[k] = v
|
||||
}
|
||||
case sflow.SampledEthernet:
|
||||
var err error
|
||||
fields["eth_total_len"] = record.Length
|
||||
fields["in_src_mac"], err = decodeMAC(record.SrcMac)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'in_src_mac' failed: %w", err)
|
||||
}
|
||||
fields["out_dst_mac"], err = decodeMAC(record.DstMac)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'out_dst_mac' failed: %w", err)
|
||||
}
|
||||
fields["datalink_frame_type"] = layers.EthernetType(record.EthType & 0x0000ffff).String()
|
||||
case sflow.SampledIPv4:
|
||||
var err error
|
||||
fields["ipv4_total_len"] = record.Length
|
||||
fields["protocol"] = mapL4Proto(uint8(record.Protocol & 0x000000ff))
|
||||
fields["src"], err = decodeIP(record.SrcIP)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'src' failed: %w", err)
|
||||
}
|
||||
fields["dst"], err = decodeIP(record.DstIP)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'dst' failed: %w", err)
|
||||
}
|
||||
fields["src_port"] = record.SrcPort
|
||||
fields["dst_port"] = record.DstPort
|
||||
fields["src_tos"] = record.Tos
|
||||
fields["tcp_flags"], err = decodeTCPFlags([]byte{byte(record.TcpFlags & 0x000000ff)})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'tcp_flags' failed: %w", err)
|
||||
}
|
||||
case sflow.SampledIPv6:
|
||||
var err error
|
||||
fields["ipv6_total_len"] = record.Length
|
||||
fields["protocol"] = mapL4Proto(uint8(record.Protocol & 0x000000ff))
|
||||
fields["src"], err = decodeIP(record.SrcIP)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'src' failed: %w", err)
|
||||
}
|
||||
fields["dst"], err = decodeIP(record.DstIP)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'dst' failed: %w", err)
|
||||
}
|
||||
fields["src_port"] = record.SrcPort
|
||||
fields["dst_port"] = record.DstPort
|
||||
fields["tcp_flags"], err = decodeTCPFlags([]byte{byte(record.TcpFlags & 0x000000ff)})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'tcp_flags' failed: %w", err)
|
||||
}
|
||||
case sflow.ExtendedSwitch:
|
||||
fields["vlan_src"] = record.SrcVlan
|
||||
fields["vlan_src_priority"] = record.SrcPriority
|
||||
fields["vlan_dst"] = record.DstVlan
|
||||
fields["vlan_dst_priority"] = record.DstPriority
|
||||
case sflow.ExtendedRouter:
|
||||
var err error
|
||||
fields["next_hop"], err = decodeIP(record.NextHop)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'next_hop' failed: %w", err)
|
||||
}
|
||||
fields["src_mask"] = record.SrcMaskLen
|
||||
fields["dst_mask"] = record.DstMaskLen
|
||||
case sflow.ExtendedGateway:
|
||||
var err error
|
||||
fields["next_hop_ip_version"] = record.NextHopIPVersion
|
||||
fields["next_hop"], err = decodeIP(record.NextHop)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'next_hop' failed: %w", err)
|
||||
}
|
||||
fields["bgp_as"] = record.AS
|
||||
fields["bgp_src_as"] = record.SrcAS
|
||||
fields["bgp_dst_as"] = record.ASDestinations
|
||||
fields["bgp_as_path_type"] = record.ASPathType
|
||||
fields["bgp_as_path_length"] = record.ASPathLength
|
||||
fields["bgp_next_hop"], err = decodeIP(record.NextHop)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding 'bgp_next_hop' failed: %w", err)
|
||||
}
|
||||
fields["bgp_prev_as"] = record.SrcPeerAS
|
||||
if len(record.ASPath) > 0 {
|
||||
fields["bgp_next_as"] = record.ASPath[0]
|
||||
}
|
||||
fields["community_length"] = record.CommunitiesLength
|
||||
parts := make([]string, 0, len(record.Communities))
|
||||
for _, c := range record.Communities {
|
||||
parts = append(parts, "0x"+strconv.FormatUint(uint64(c), 16))
|
||||
}
|
||||
fields["communities"] = strings.Join(parts, ",")
|
||||
fields["local_pref"] = record.LocalPref
|
||||
case sflow.EgressQueue:
|
||||
fields["out_queue"] = record.Queue
|
||||
case sflow.ExtendedACL:
|
||||
fields["acl_id"] = record.Number
|
||||
fields["acl_name"] = record.Name
|
||||
switch record.Direction {
|
||||
case 1:
|
||||
fields["direction"] = "ingress"
|
||||
case 2:
|
||||
fields["direction"] = "egress"
|
||||
default:
|
||||
fields["direction"] = "unknown"
|
||||
}
|
||||
case sflow.ExtendedFunction:
|
||||
fields["function"] = record.Symbol
|
||||
default:
|
||||
return nil, fmt.Errorf("unhandled flow record type %T", r.Data)
|
||||
}
|
||||
}
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
func (d *sflowv5Decoder) decodeRawHeaderSample(record *sflow.SampledHeader) (map[string]interface{}, error) {
|
||||
var packet gopacket.Packet
|
||||
switch record.Protocol {
|
||||
case 1: // ETHERNET-ISO8023
|
||||
packet = gopacket.NewPacket(record.HeaderData, layers.LayerTypeEthernet, gopacket.Default)
|
||||
case 2: // ISO88024-TOKENBUS
|
||||
fallthrough
|
||||
case 3: // ISO88025-TOKENRING
|
||||
fallthrough
|
||||
case 4: // FDDI
|
||||
fallthrough
|
||||
case 5: // FRAME-RELAY
|
||||
fallthrough
|
||||
case 6: // X25
|
||||
fallthrough
|
||||
case 7: // PPP
|
||||
fallthrough
|
||||
case 8: // SMDS
|
||||
fallthrough
|
||||
case 9: // AAL5
|
||||
fallthrough
|
||||
case 10: // AAL5-IP
|
||||
fallthrough
|
||||
case 11: // IPv4
|
||||
fallthrough
|
||||
case 12: // IPv6
|
||||
fallthrough
|
||||
case 13: // MPLS
|
||||
fallthrough
|
||||
default:
|
||||
return nil, fmt.Errorf("unhandled protocol %d", record.Protocol)
|
||||
}
|
||||
|
||||
fields := make(map[string]interface{})
|
||||
for _, pkt := range packet.Layers() {
|
||||
switch l := pkt.(type) {
|
||||
case *layers.Ethernet:
|
||||
fields["in_src_mac"] = l.SrcMAC.String()
|
||||
fields["out_dst_mac"] = l.DstMAC.String()
|
||||
fields["datalink_frame_type"] = l.EthernetType.String()
|
||||
if l.Length > 0 {
|
||||
fields["eth_header_len"] = l.Length
|
||||
}
|
||||
case *layers.Dot1Q:
|
||||
fields["vlan_id"] = l.VLANIdentifier
|
||||
fields["vlan_priority"] = l.Priority
|
||||
fields["vlan_drop_eligible"] = l.DropEligible
|
||||
case *layers.IPv4:
|
||||
fields["ip_version"] = decodePacketIPVersion(l.Version)
|
||||
fields["ipv4_inet_header_len"] = l.IHL
|
||||
fields["src_tos"] = l.TOS
|
||||
fields["ipv4_total_len"] = l.Length
|
||||
fields["ipv4_id"] = l.Id // ?
|
||||
fields["ttl"] = l.TTL
|
||||
fields["protocol"] = mapL4Proto(uint8(l.Protocol))
|
||||
fields["src"] = l.SrcIP.String()
|
||||
fields["dst"] = l.DstIP.String()
|
||||
|
||||
flags := []byte("........")
|
||||
if l.Flags&layers.IPv4EvilBit > 0 {
|
||||
flags[7] = byte('E')
|
||||
}
|
||||
if l.Flags&layers.IPv4DontFragment > 0 {
|
||||
flags[6] = byte('D')
|
||||
}
|
||||
if l.Flags&layers.IPv4MoreFragments > 0 {
|
||||
flags[5] = byte('M')
|
||||
}
|
||||
fields["fragment_flags"] = string(flags)
|
||||
fields["fragment_offset"] = l.FragOffset
|
||||
fields["ip_total_len"] = l.Length
|
||||
case *layers.IPv6:
|
||||
fields["ip_version"] = decodePacketIPVersion(l.Version)
|
||||
fields["ipv6_total_len"] = l.Length
|
||||
fields["ttl"] = l.HopLimit
|
||||
fields["protocol"] = mapL4Proto(uint8(l.NextHeader))
|
||||
fields["src"] = l.SrcIP.String()
|
||||
fields["dst"] = l.DstIP.String()
|
||||
fields["ip_total_len"] = l.Length
|
||||
case *layers.TCP:
|
||||
fields["src_port"] = uint16(l.SrcPort)
|
||||
fields["dst_port"] = uint16(l.DstPort)
|
||||
fields["tcp_seq_number"] = l.Seq
|
||||
fields["tcp_ack_number"] = l.Ack
|
||||
fields["tcp_window_size"] = l.Window
|
||||
fields["tcp_urgent_ptr"] = l.Urgent
|
||||
flags := []byte("........")
|
||||
if l.FIN {
|
||||
flags[7] = byte('F')
|
||||
}
|
||||
if l.SYN {
|
||||
flags[6] = byte('S')
|
||||
}
|
||||
if l.RST {
|
||||
flags[5] = byte('R')
|
||||
}
|
||||
if l.PSH {
|
||||
flags[4] = byte('P')
|
||||
}
|
||||
if l.ACK {
|
||||
flags[3] = byte('A')
|
||||
}
|
||||
if l.URG {
|
||||
flags[2] = byte('U')
|
||||
}
|
||||
if l.ECE {
|
||||
flags[1] = byte('E')
|
||||
}
|
||||
if l.CWR {
|
||||
flags[0] = byte('C')
|
||||
}
|
||||
fields["tcp_flags"] = string(flags)
|
||||
case *layers.UDP:
|
||||
fields["src_port"] = uint16(l.SrcPort)
|
||||
fields["dst_port"] = uint16(l.DstPort)
|
||||
fields["ip_total_len"] = l.Length
|
||||
case *gopacket.Payload:
|
||||
// Ignore the payload
|
||||
default:
|
||||
ltype := int64(pkt.LayerType())
|
||||
if !d.warnedFlowRaw[ltype] {
|
||||
contents := hex.EncodeToString(pkt.LayerContents())
|
||||
payload := hex.EncodeToString(pkt.LayerPayload())
|
||||
d.log.Warnf("Unknown flow raw flow message %s (%d):", pkt.LayerType().String(), pkt.LayerType())
|
||||
d.log.Warnf(" contents: %s", contents)
|
||||
d.log.Warnf(" payload: %s", payload)
|
||||
|
||||
d.log.Warn("This message is only printed once.")
|
||||
}
|
||||
d.warnedFlowRaw[ltype] = true
|
||||
}
|
||||
}
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
func (d *sflowv5Decoder) decodeCounterRecords(records []sflow.CounterRecord) (map[string]interface{}, error) {
|
||||
for _, r := range records {
|
||||
if r.Data == nil {
|
||||
continue
|
||||
}
|
||||
switch record := r.Data.(type) {
|
||||
case sflow.IfCounters:
|
||||
fields := map[string]interface{}{
|
||||
"interface": record.IfIndex,
|
||||
"interface_type": record.IfType,
|
||||
"speed": record.IfSpeed,
|
||||
"in_bytes": record.IfInOctets,
|
||||
"in_unicast_packets_total": record.IfInUcastPkts,
|
||||
"in_mcast_packets_total": record.IfInMulticastPkts,
|
||||
"in_broadcast_packets_total": record.IfInBroadcastPkts,
|
||||
"in_dropped_packets": record.IfInDiscards,
|
||||
"in_errors": record.IfInErrors,
|
||||
"in_unknown_protocol": record.IfInUnknownProtos,
|
||||
"out_bytes": record.IfOutOctets,
|
||||
"out_unicast_packets_total": record.IfOutUcastPkts,
|
||||
"out_mcast_packets_total": record.IfOutMulticastPkts,
|
||||
"out_broadcast_packets_total": record.IfOutBroadcastPkts,
|
||||
"out_dropped_packets": record.IfOutDiscards,
|
||||
"out_errors": record.IfOutErrors,
|
||||
"promiscuous": record.IfPromiscuousMode,
|
||||
}
|
||||
if record.IfStatus == 0 {
|
||||
fields["status"] = "down"
|
||||
} else {
|
||||
fields["status"] = "up"
|
||||
}
|
||||
return fields, nil
|
||||
case sflow.EthernetCounters:
|
||||
fields := map[string]interface{}{
|
||||
"type": "IEEE 802.3",
|
||||
"collision_frames_single": record.Dot3StatsSingleCollisionFrames,
|
||||
"collision_frames_multi": record.Dot3StatsMultipleCollisionFrames,
|
||||
"collisions_late": record.Dot3StatsLateCollisions,
|
||||
"collisions_excessive": record.Dot3StatsExcessiveCollisions,
|
||||
"deferred": record.Dot3StatsDeferredTransmissions,
|
||||
"errors_alignment": record.Dot3StatsAlignmentErrors,
|
||||
"errors_fcs": record.Dot3StatsFCSErrors,
|
||||
"errors_sqetest": record.Dot3StatsSQETestErrors,
|
||||
"errors_internal_mac_tx": record.Dot3StatsInternalMacTransmitErrors,
|
||||
"errors_internal_mac_rx": record.Dot3StatsInternalMacReceiveErrors,
|
||||
"errors_carrier_sense": record.Dot3StatsCarrierSenseErrors,
|
||||
"errors_frame_too_long": record.Dot3StatsFrameTooLongs,
|
||||
"errors_symbols": record.Dot3StatsSymbolErrors,
|
||||
}
|
||||
return fields, nil
|
||||
case sflow.RawRecord:
|
||||
switch r.Header.DataFormat {
|
||||
case 1005:
|
||||
// Openflow port-name
|
||||
if len(record.Data) < 4 {
|
||||
return nil, fmt.Errorf("invalid data for raw counter %+v", r)
|
||||
}
|
||||
fields := map[string]interface{}{
|
||||
"port_name": string(record.Data[4:]),
|
||||
}
|
||||
return fields, nil
|
||||
default:
|
||||
if !d.warnedCounterRaw[r.Header.DataFormat] {
|
||||
data := hex.EncodeToString(record.Data)
|
||||
d.log.Warnf("Unknown counter raw flow message %d: %s", r.Header.DataFormat, data)
|
||||
d.log.Warn("This message is only printed once.")
|
||||
}
|
||||
d.warnedCounterRaw[r.Header.DataFormat] = true
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unhandled counter record type %T", r.Data)
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
31
plugins/inputs/netflow/testcases/ipfix_example/expected.out
Normal file
31
plugins/inputs/netflow/testcases/ipfix_example/expected.out
Normal file
|
@ -0,0 +1,31 @@
|
|||
netflow,source=127.0.0.1,version=IPFIX protocol="tcp",dst_port=443u,in_total_bytes=52u,src_tos="0x00",dst="44.233.90.52",src_port=51008u,flow_end_reason="end of flow",in_total_packets=1u,src="192.168.119.100",type_6871_40="0x0000",flow_start_ms=1666345513807u,vlan_src=0u,flow_end_ms=1666345513807u 1684917213504248417
|
||||
netflow,source=127.0.0.1,version=IPFIX type_29305_5="0x00",in_total_bytes=80u,type_29305_86="0x00000001",in_total_packets=2u,type_29305_85="0x00000028",flow_end_reason="end of flow",vlan_src=0u,src="192.168.119.100",flow_end_ms=1666345513816u,dst_port=443u,protocol="tcp",type_6871_21="0x00000009",dst="104.17.240.92",type_29305_58="0x0000",type_6871_40="0x0000",type_6871_rev_40="0x0000",flow_start_ms=1666345513807u,src_port=54330u,src_tos="0x00" 1684917213504502791
|
||||
netflow,source=127.0.0.1,version=IPFIX src="192.168.119.100",dst="44.233.90.52",type_6871_rev_40="0x0000",dst_port=443u,type_6871_21="0x000000aa",type_6871_40="0x0000",flow_end_reason="end of flow",flow_end_ms=1666345513977u,type_29305_85="0x00000028",type_29305_5="0x00",vlan_src=0u,flow_start_ms=1666345513807u,src_tos="0x00",protocol="tcp",src_port=51024u,type_29305_86="0x00000001",in_total_bytes=52u,in_total_packets=1u,type_29305_58="0x0000" 1684917213504688593
|
||||
netflow,source=127.0.0.1,version=IPFIX flow_end_reason="forced end",src_port=58246u,src="192.168.119.100",flow_end_ms=1666345513806u,dst_port=53u,flow_start_ms=1666345513806u,in_total_packets=2u,src_tos="0x00",type_29305_58="0x0000",in_total_bytes=140u,type_6871_21="0x00000000",protocol="udp",type_6871_rev_40="0x0000",vlan_src=0u,type_6871_40="0x0001",type_29305_5="0x00",type_29305_85="0x0000009c",type_29305_86="0x00000002",dst="192.168.119.17" 1684917213504857795
|
||||
netflow,source=127.0.0.1,version=IPFIX type_29305_86="0x00000002",type_29305_58="0x0000",protocol="udp",type_29305_85="0x000000dd",dst="192.168.119.17",in_total_packets=2u,type_6871_rev_40="0x0000",flow_end_ms=1666345513832u,src="192.168.119.100",src_port=58879u,type_6871_21="0x00000021",vlan_src=0u,flow_end_reason="forced end",type_6871_40="0x0001",flow_start_ms=1666345513799u,type_29305_5="0x00",dst_port=53u,src_tos="0x00",in_total_bytes=112u 1684917213505013747
|
||||
netflow,source=127.0.0.1,version=IPFIX protocol="udp",type_6871_rev_40="0x0000",vlan_src=0u,type_6871_40="0x0001",type_29305_58="0x0000",type_29305_5="0x00",dst="192.168.119.17",type_29305_86="0x00000002",src="192.168.119.100",flow_end_ms=1666345514167u,type_29305_85="0x0000020a",dst_port=53u,flow_end_reason="forced end",type_6871_21="0x00000000",src_tos="0x00",src_port=56439u,flow_start_ms=1666345514150u,in_total_packets=2u,in_total_bytes=154u 1684917213505160049
|
||||
netflow,source=127.0.0.1,version=IPFIX type_6871_rev_40="0x0000",type_29305_85="0x00011254",dst_port=443u,type_29305_86="0x00000044",flow_start_ms=1666345513832u,src="192.168.119.100",in_total_bytes=5853u,protocol="udp",flow_end_reason="forced end",vlan_src=0u,in_total_packets=43u,type_29305_58="0x0000",type_6871_40="0x0000",flow_end_ms=1666345514328u,src_tos="0x00",src_port=57795u,dst="34.149.140.181",type_29305_5="0x00",type_6871_21="0x00000012" 1684917213505306401
|
||||
netflow,source=127.0.0.1,version=IPFIX src_tos="0x00",flow_start_ms=1666345512753u,dst="239.255.255.250",src="192.168.119.100",type_6871_40="0x0001",dst_port=1900u,protocol="udp",vlan_src=0u,src_port=57622u,flow_end_ms=1666345515756u,flow_end_reason="forced end",in_total_bytes=784u,in_total_packets=4u 1684917213505453773
|
||||
netflow,source=127.0.0.1,version=IPFIX protocol="udp",type_29305_5="0x00",flow_start_ms=1666345512531u,type_6871_21="0x00000011",type_29305_86="0x00000066",type_29305_58="0x0000",flow_end_ms=1666345519408u,dst="216.58.212.132",flow_end_reason="forced end",in_total_bytes=6105u,type_6871_rev_40="0x0000",in_total_packets=60u,vlan_src=0u,src_tos="0x00",dst_port=443u,src_port=54458u,type_6871_40="0x0000",type_29305_85="0x00016837",src="192.168.119.100" 1684917213505487043
|
||||
netflow,source=127.0.0.1,version=IPFIX type_6871_rev_40="0x0000",type_29305_86="0x00000001",flow_start_ms=1666345519932u,src_tos="0x00",in_total_bytes=52u,flow_end_ms=1666345519942u,type_29305_58="0x0000",type_6871_21="0x0000000a",in_total_packets=1u,dst="13.32.99.76",src="192.168.119.100",vlan_src=0u,protocol="tcp",src_port=60758u,type_6871_40="0x0000",type_29305_5="0x00",dst_port=443u,flow_end_reason="forced end",type_29305_85="0x00000034" 1684917213505641375
|
||||
netflow,source=127.0.0.1,version=IPFIX type_29305_58="0x0000",protocol="tcp",type_6871_21="0x0000000a",src="192.168.119.100",src_tos="0x00",in_total_packets=1u,type_6871_40="0x0000",flow_end_ms=1666345519942u,type_6871_rev_40="0x0000",flow_start_ms=1666345519932u,type_29305_86="0x00000001",in_total_bytes=40u,dst_port=443u,vlan_src=0u,type_29305_5="0x00",type_29305_85="0x00000028",flow_end_reason="forced end",dst="104.17.146.91",src_port=58432u 1684917213505792347
|
||||
netflow,source=127.0.0.1,version=IPFIX type_6871_rev_40="0x0000",src_port=36397u,flow_start_ms=1666345521006u,type_29305_5="0x00",src_tos="0x00",in_total_bytes=138u,type_29305_85="0x0000011c",type_6871_21="0x00000000",type_6871_40="0x0001",vlan_src=0u,protocol="udp",dst_port=53u,src="192.168.119.100",type_29305_58="0x0000",in_total_packets=2u,type_29305_86="0x00000002",flow_end_ms=1666345521006u,dst="192.168.119.17",flow_end_reason="forced end" 1684917213505948399
|
||||
netflow,source=127.0.0.1,version=IPFIX type_29305_58="0x0000",src="192.168.119.100",type_29305_86="0x00000002",flow_end_reason="forced end",in_total_packets=2u,type_6871_21="0x00000000",flow_start_ms=1666345520998u,type_6871_40="0x0001",vlan_src=0u,protocol="udp",type_6871_rev_40="0x0000",src_port=39786u,type_29305_85="0x000000c1",in_total_bytes=112u,dst_port=53u,dst="192.168.119.17",src_tos="0x00",type_29305_5="0x00",flow_end_ms=1666345521019u 1684917213506093831
|
||||
netflow,source=127.0.0.1,version=IPFIX dst_port=443u,type_6871_21="0x00000009",flow_start_ms=1666345521006u,vlan_src=0u,type_29305_58="0x0000",src_tos="0x00",src="192.168.119.100",type_6871_40="0x0000",flow_end_ms=1666345521032u,src_port=52370u,type_29305_85="0x0000028d",in_total_bytes=860u,type_6871_rev_40="0x0000",type_29305_5="0x00",flow_end_reason="forced end",type_29305_86="0x00000004",in_total_packets=5u,protocol="tcp",dst="185.199.109.154" 1684917213506254733
|
||||
netflow,source=127.0.0.1,version=IPFIX flow_end_ms=1666345521742u,vlan_src=0u,type_6871_40="0x0001",in_total_packets=2u,type_29305_58="0x0000",src_tos="0x00",src_port=44461u,dst="192.168.119.17",type_29305_5="0x00",type_29305_86="0x00000002",type_6871_21="0x00000000",type_29305_85="0x00000146",flow_start_ms=1666345521742u,in_total_bytes=150u,type_6871_rev_40="0x0000",src="192.168.119.100",protocol="udp",dst_port=53u,flow_end_reason="forced end" 1684917213506407245
|
||||
netflow,source=127.0.0.1,version=IPFIX src="192.168.119.100",in_total_packets=5u,protocol="tcp",flow_end_reason="forced end",flow_start_ms=1666345521742u,type_6871_21="0x00000009",vlan_src=0u,dst="185.199.109.154",type_6871_40="0x0000",type_29305_58="0x0000",type_29305_85="0x0000028d",dst_port=443u,type_29305_5="0x00",flow_end_ms=1666345521771u,in_total_bytes=860u,src_port=52376u,type_29305_86="0x00000004",src_tos="0x00",type_6871_rev_40="0x0000" 1684917213506554437
|
||||
netflow,source=127.0.0.1,version=IPFIX type_6871_21="0x00000000",vlan_src=0u,src_tos="0x00",flow_end_reason="forced end",flow_start_ms=1666345521780u,flow_end_ms=1666345521780u,type_6871_40="0x0001",src="192.168.119.100",type_29305_86="0x00000002",protocol="udp",dst_port=53u,type_29305_5="0x00",dst="192.168.119.17",type_29305_58="0x0000",in_total_packets=2u,in_total_bytes=158u,src_port=51858u,type_6871_rev_40="0x0000",type_29305_85="0x0000014e" 1684917213506702419
|
||||
netflow,source=127.0.0.1,version=IPFIX type_29305_5="0x00",vlan_src=0u,in_total_bytes=150u,flow_start_ms=1666345521780u,protocol="udp",in_total_packets=2u,dst_port=53u,dst="192.168.119.17",src="192.168.119.100",type_29305_86="0x00000002",src_port=34970u,flow_end_reason="forced end",type_6871_40="0x0001",type_29305_58="0x0000",type_29305_85="0x00000158",type_6871_rev_40="0x0000",src_tos="0x00",flow_end_ms=1666345521794u,type_6871_21="0x0000000d" 1684917213506851241
|
||||
netflow,source=127.0.0.1,version=IPFIX type_29305_58="0x0000",vlan_src=0u,type_29305_5="0x00",dst_port=53u,flow_end_ms=1666345521836u,src_port=52794u,type_6871_40="0x0001",flow_start_ms=1666345521813u,type_6871_rev_40="0x0000",in_total_bytes=144u,in_total_packets=2u,type_6871_21="0x00000017",protocol="udp",flow_end_reason="forced end",src_tos="0x00",type_29305_86="0x00000002",type_29305_85="0x00000122",dst="192.168.119.17",src="192.168.119.100" 1684917213507002733
|
||||
netflow,source=127.0.0.1,version=IPFIX in_total_bytes=142u,in_total_packets=2u,src_port=43629u,src_tos="0x00",dst="192.168.119.17",type_6871_rev_40="0x0000",vlan_src=0u,protocol="udp",type_6871_40="0x0001",type_29305_58="0x0000",dst_port=53u,flow_end_ms=1666345522050u,type_6871_21="0x0000000b",type_29305_5="0x00",src="192.168.119.100",type_29305_86="0x00000002",flow_end_reason="forced end",flow_start_ms=1666345522036u,type_29305_85="0x0000013e" 1684917213507151155
|
||||
netflow,source=127.0.0.1,version=IPFIX src_port=48781u,dst_port=53u,protocol="udp",dst="192.168.119.17",type_29305_85="0x00000117",type_29305_5="0x00",src="192.168.119.100",type_6871_40="0x0001",flow_start_ms=1666345522229u,type_6871_21="0x00000000",type_29305_86="0x00000002",type_6871_rev_40="0x0000",flow_end_reason="forced end",vlan_src=0u,src_tos="0x00",in_total_bytes=132u,flow_end_ms=1666345522240u,in_total_packets=2u,type_29305_58="0x0000" 1684917213507318937
|
||||
netflow,source=127.0.0.1,version=IPFIX src_tos="0x00",type_29305_58="0x0000",in_total_bytes=120u,src_port=43078u,flow_start_ms=1666345522279u,vlan_src=0u,flow_end_ms=1666345522291u,type_29305_5="0x00",type_6871_rev_40="0x0000",dst_port=53u,type_29305_85="0x000000c9",type_6871_21="0x00000000",in_total_packets=2u,type_29305_86="0x00000002",type_6871_40="0x0001",src="192.168.119.100",protocol="udp",flow_end_reason="forced end",dst="192.168.119.17" 1684917213507703742
|
||||
netflow,source=127.0.0.1,version=IPFIX type_29305_58="0x0000",type_29305_86="0x00000062",dst="185.199.111.133",type_6871_rev_40="0x0000",dst_port=443u,flow_start_ms=1666345521806u,vlan_src=0u,type_6871_40="0x0000",type_29305_5="0x00",type_29305_85="0x00004b0d",in_total_bytes=11855u,src_tos="0x00",type_6871_21="0x00000008",in_total_packets=80u,flow_end_ms=1666345525312u,src="192.168.119.100",src_port=49880u,flow_end_reason="forced end",protocol="tcp" 1684917213507860084
|
||||
netflow,source=127.0.0.1,version=IPFIX type_6871_21="0x00000066",type_29305_58="0x0000",type_29305_5="0x00",type_6871_rev_40="0x0000",type_29305_85="0x0000161c",src_tos="0x00",in_total_packets=16u,flow_end_reason="forced end",dst_port=443u,type_29305_86="0x0000000f",flow_end_ms=1666345525417u,src_port=43438u,protocol="tcp",type_6871_40="0x0000",src="192.168.119.100",flow_start_ms=1666345522240u,in_total_bytes=4552u,dst="140.82.113.21",vlan_src=0u 1684917213508012376
|
||||
netflow,source=127.0.0.1,version=IPFIX vlan_src=0u,protocol="tcp",src_tos="0x00",flow_start_ms=1666345522291u,flow_end_ms=1666345525576u,src="192.168.119.100",type_29305_86="0x00000032",in_total_packets=63u,src_port=59884u,dst_port=443u,type_29305_85="0x000025ce",type_29305_58="0x0000",type_29305_5="0x00",dst="140.82.121.6",type_6871_40="0x0000",type_6871_21="0x00000009",in_total_bytes=58028u,flow_end_reason="forced end",type_6871_rev_40="0x0000" 1684917213508167138
|
||||
netflow,source=127.0.0.1,version=IPFIX type_29305_86="0x00000009",flow_end_ms=1666345525645u,protocol="tcp",src_port=443u,type_29305_85="0x00000f38",type_29305_5="0x00",flow_end_reason="forced end",dst_port=49448u,dst="192.168.119.100",in_total_packets=7u,type_6871_rev_40="0x0000",src="140.82.113.25",src_tos="0x00",flow_start_ms=1666345518733u,vlan_src=0u,in_total_bytes=659u,type_6871_21="0x00000000",type_29305_58="0x0000",type_6871_40="0x0000" 1684917213508315850
|
||||
netflow,source=127.0.0.1,version=IPFIX vlan_src=0u,type_29305_85="0x00001590",src="192.168.119.100",protocol="udp",dst_port=443u,type_29305_58="0x0000",type_29305_86="0x00000015",flow_start_ms=1666345514168u,src_tos="0x00",type_6871_rev_40="0x0000",dst="142.250.186.170",in_total_packets=17u,src_port=58246u,type_6871_21="0x00000012",flow_end_ms=1666345525871u,flow_end_reason="forced end",type_29305_5="0x00",type_6871_40="0x0000",in_total_bytes=3248u 1684917213508463452
|
||||
netflow,source=127.0.0.1,version=IPFIX dst="140.82.121.3",flow_start_ms=1666345521019u,type_29305_86="0x000000d4",type_6871_40="0x0000",type_29305_85="0x0003e1d9",in_total_packets=125u,protocol="tcp",flow_end_reason="forced end",in_total_bytes=16640u,type_29305_58="0x0000",flow_end_ms=1666345525880u,type_6871_21="0x00000009",type_29305_5="0x00",dst_port=443u,src_tos="0x00",type_6871_rev_40="0x0000",vlan_src=0u,src="192.168.119.100",src_port=37792u 1684917213508608204
|
||||
netflow,source=127.0.0.1,version=IPFIX type_6871_40="0x0001",src="192.168.119.100",vlan_src=0u,type_6871_rev_40="0x0000",type_29305_58="0x0000",src_port=50077u,flow_end_ms=1666345527739u,type_29305_5="0x00",flow_start_ms=1666345527739u,in_total_packets=2u,src_tos="0x00",flow_end_reason="forced end",type_6871_21="0x00000000",type_29305_86="0x00000002",dst_port=53u,in_total_bytes=120u,type_29305_85="0x000000a4",protocol="udp",dst="192.168.119.17" 1684917213508754156
|
||||
netflow_options,source=127.0.0.1,version=IPFIX dropped_packets_total=0u,event_time=1666725027u,exporter="192.168.119.100",exporting_pid=66602u,ignored_packet_total=22u,in_total_packets=1070u,notsent_packet_total=0u,observation_domain_id=0u,system_init_ms=1666725027000u,total_flows_exported=29u,type_6871_32868="0x00000000",type_6871_32869="0x00000000",type_6871_32870="0x00001d1f",type_6871_32871="0x00043278",type_6871_32872="0x00000004",type_6871_32873="0x0000001a" 1715165599875551764
|
||||
netflow_options,source=127.0.0.1,version=IPFIX event_time=1666725027u,exporting_pid=66602u,observation_domain_id=0u,padding="0x000000000000",type_6871_33318="0x00000000",type_6871_33319="0x0000",type_6871_33322="0x00d00500000001635834a3" 1715165599878686750
|
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_0.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_0.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_1.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_1.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_2.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_2.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_3.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_3.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_4.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_4.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_5.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_5.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_6.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_example/ipfix_6.bin
Normal file
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
[[inputs.netflow]]
|
||||
service_address = "udp://127.0.0.1:0"
|
126
plugins/inputs/netflow/testcases/ipfix_options/expected.out
Normal file
126
plugins/inputs/netflow/testcases/ipfix_options/expected.out
Normal file
|
@ -0,0 +1,126 @@
|
|||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Third Party Connect Protocol",app_id="0x01000022",app_name="3pc" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Active Networks",app_id="0x0100006b",app_name="an" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="any host internal protocol",app_id="0x0100003d",app_name="any-host-internal" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="ARGUS",app_id="0x0100000d",app_name="argus" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="ARIS",app_id="0x01000068",app_name="aris" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="AX.25 Frames",app_id="0x0100005d",app_name="ax25" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="BBN RCC Monitoring",app_id="0x0100000a",app_name="bbnrccmon" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="BNA",app_id="0x01000031",app_name="bna" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Backroom SATNET Monitoring",app_id="0x0100004c",app_name="br-sat-mon" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="CBT",app_id="0x01000007",app_name="cbt" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="CFTP",app_id="0x0100003e",app_name="cftp" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Chaos",app_id="0x01000010",app_name="chaos" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Compaq Peer Protocol",app_id="0x0100006e",app_name="compaq-peer" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Computer Protocol Heart Beat",app_id="0x01000049",app_name="cphb" 1715165504617351694
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Computer Protocol Network Executive",app_id="0x01000048",app_name="cpnx" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Combat Radio Transport Protocol",app_id="0x0100007e",app_name="crtp" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Combat Radio User Datagram",app_id="0x0100007f",app_name="crudp" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Datagram Congestion Control Protocol",app_id="0x01000021",app_name="dccp" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="DCN Measurement Subsystems",app_id="0x01000013",app_name="dcn-meas" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Datagram Delivery Protocol",app_id="0x01000025",app_name="ddp" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="D-II Data Exchange",app_id="0x01000074",app_name="ddx" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Dissimilar Gateway Protocol",app_id="0x01000056",app_name="dgp" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Dynamic Source Routing Protocol",app_id="0x01000030",app_name="dsr" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Exterior Gateway Protocol",app_id="0x01000008",app_name="egp" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Enhanced Interior Gateway Routing Protocol",app_id="0x01000058",app_name="eigrp" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="EMCON",app_id="0x0100000e",app_name="emcon" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Encapsulation Header",app_id="0x01000062",app_name="encap" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Ethernet-within-IP Encapsulation",app_id="0x01000061",app_name="etherip" 1715165504617776018
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Fibre Channel",app_id="0x01000085",app_name="fc" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="FIRE",app_id="0x0100007d",app_name="fire" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Gateway-to-Gateway",app_id="0x01000003",app_name="ggp" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="graphical Media Transfer Protocol ",app_id="0x01000064",app_name="gmtp" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="General Routing Encapsulation",app_id="0x0100002f",app_name="gre" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Host Identity Protocol",app_id="0x0100008b",app_name="hip" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Host Monitoring",app_id="0x01000014",app_name="hmp" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="DEPRECATED, traffic will not match",app_id="0x01000000",app_name="hopopt" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Integrated Net Layer Security TUBA",app_id="0x01000034",app_name="i-nlsp" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Interactive Agent Transfer Protocol",app_id="0x01000075",app_name="iatp" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Internet Control Message Protocol",app_id="0x01000001",app_name="icmp" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Inter-Domain Policy Routing Protocol",app_id="0x01000023",app_name="idpr" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="IDPR Control Message Transport Proto",app_id="0x01000026",app_name="idpr-cmtp" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Inter-Domain Routing Protocol",app_id="0x0100002d",app_name="idrp" 1715165504618074830
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Ipsilon Flow Management Protocol",app_id="0x01000065",app_name="ifmp" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Cisco interior gateway ",app_id="0x01000009",app_name="igrp" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="IL Transport Protocol",app_id="0x01000028",app_name="il" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="IP Payload Compression Protocol",app_id="0x0100006c",app_name="ipcomp" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Internet Packet Core Utility",app_id="0x01000047",app_name="ipcv" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="IP in IP",app_id="0x01000004",app_name="ipinip" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="IP-within-IP Encapsulation Protocol",app_id="0x0100005e",app_name="ipip" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="IPLT",app_id="0x01000081",app_name="iplt" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Internet Pluribus Packet Core",app_id="0x01000043",app_name="ippc" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="DEPRECATED, traffic will not match",app_id="0x0100002c",app_name="ipv6-frag" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="ICMP for IPv6",app_id="0x0100003a",app_name="ipv6-icmp" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="DEPRECATED, traffic will not match",app_id="0x0100003b",app_name="ipv6-nonxt" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="DEPRECATED, traffic will not match",app_id="0x0100003c",app_name="ipv6-opts" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="DEPRECATED, traffic will not match",app_id="0x0100002b",app_name="ipv6-route" 1715165504618379393
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Ipv6 encapsulated",app_id="0x01000029",app_name="ipv6inip" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="IPX in IP",app_id="0x0100006f",app_name="ipx-in-ip" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Internet Reliable Transaction",app_id="0x0100001c",app_name="irtp" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Intermediate System-to-Intermediate System (ISIS) over ",app_id="0x0100007c",app_name="isis" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="ISO Transport Protocol Class 4",app_id="0x0100001d",app_name="iso-tp4" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Layer 2 Tunneling Protocol",app_id="0x01000073",app_name="l2tp" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Locus Address Resolution Protocol",app_id="0x0100005b",app_name="larp" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Leaf-1",app_id="0x01000019",app_name="leaf-1" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Leaf-2",app_id="0x0100001a",app_name="leaf-2" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="MANET Protocols",app_id="0x0100008a",app_name="manet" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="MERIT Internodal Protocol",app_id="0x01000020",app_name="merit-inp" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="MFE Network Services Protocol",app_id="0x0100001f",app_name="mfe-nsp" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Mobile Internetworking Control Pro.",app_id="0x0100005f",app_name="micp" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="IP Mobility",app_id="0x01000037",app_name="mobile" 1715165504618664785
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="MPLS-in-IP",app_id="0x01000089",app_name="mpls-in-ip" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Multicast Transport Protocol",app_id="0x0100005c",app_name="mtp" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Multiplexing",app_id="0x01000012",app_name="mux" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="NBMA Address Resolution Protocol",app_id="0x01000036",app_name="narp" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Bulk Data Transfer Protocol",app_id="0x0100001e",app_name="netblt" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="NSFNET-IGP",app_id="0x01000055",app_name="nsfnet-igp" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Network Voice Protocol",app_id="0x0100000b",app_name="nvp-ii" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Open Shortest Path First",app_id="0x01000059",app_name="ospf" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="PGM Reliable Transport Protocol",app_id="0x01000071",app_name="pgm" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Protocol Independent Multicast",app_id="0x01000067",app_name="pim" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Private IP Encapsulation within IP",app_id="0x01000083",app_name="pipe" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="PNNI over IP",app_id="0x01000066",app_name="pnni" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Packet Radio Measurement",app_id="0x01000015",app_name="prm" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Performance Transparency Protocol",app_id="0x0100007b",app_name="ptp" 1715165504618966128
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="PUP",app_id="0x0100000c",app_name="pup" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Packet Video Protocol",app_id="0x0100004b",app_name="pvp" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="QNX",app_id="0x0100006a",app_name="qnx" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Reliable Data Protocol",app_id="0x0100001b",app_name="rdp" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Resource Reservation Protocol",app_id="0x0100002e",app_name="rsvp" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="RSVP-E2E-IGNORE",app_id="0x01000086",app_name="rsvp-e2e-ignore" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="MIT Remote Virtual Disk Protocol",app_id="0x01000042",app_name="rvd" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="SATNET and Backroom EXPAK",app_id="0x01000040",app_name="sat-expak" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="SATNET Monitoring",app_id="0x01000045",app_name="sat-mon" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Semaphore Communications Sec. Pro.",app_id="0x01000060",app_name="scc-sp" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Schedule Transfer Protocol",app_id="0x01000076",app_name="schedule-transfer" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="SCPS",app_id="0x01000069",app_name="scps" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Stream Control Transmission Protocol",app_id="0x01000084",app_name="sctp" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Source Demand Routing Protocol",app_id="0x0100002a",app_name="sdrp" 1715165504619268091
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="SECURE-VMTP",app_id="0x01000052",app_name="secure-vmtp" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="SKIP",app_id="0x01000039",app_name="skip" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="SM",app_id="0x0100007a",app_name="sm" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Simple Message Protocol",app_id="0x01000079",app_name="smp" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Sitara Networks Protocol",app_id="0x0100006d",app_name="snp" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Sprite RPC Protocol",app_id="0x0100005a",app_name="sprite-rpc" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Secure Packet Shield",app_id="0x01000082",app_name="sps" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="SpectraLink Radio Protocol",app_id="0x01000077",app_name="srp" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="SSCOPMCE",app_id="0x01000080",app_name="sscopmce" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Stream",app_id="0x01000005",app_name="st" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="SUN ND PROTOCOL-Temporary",app_id="0x0100004d",app_name="sun-nd" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="IP with Encryption",app_id="0x01000035",app_name="swipe" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="TCF",app_id="0x01000057",app_name="tcf" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Transport Layer Security Protocol",app_id="0x01000038",app_name="tlsp" 1715165504619574503
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="TP++ Transport Protocol",app_id="0x01000027",app_name="tp++" 1715165504619894286
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Trunk-1",app_id="0x01000017",app_name="trunk-1" 1715165504619894286
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Trunk-2",app_id="0x01000018",app_name="trunk-2" 1715165504619894286
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="TTP",app_id="0x01000054",app_name="ttp" 1715165504619894286
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="UDPLite, Lightweight connectionless User Datagram Proto",app_id="0x01000088",app_name="udplite" 1715165504619894286
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="UTI",app_id="0x01000078",app_name="uti" 1715165504619894286
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="VISA Protocol",app_id="0x01000046",app_name="visa" 1715165504619894286
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="VMTP",app_id="0x01000051",app_name="vmtp" 1715165504619894286
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Virtual Router Redundancy Protocol",app_id="0x01000070",app_name="vrrp" 1715165504619894286
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="WIDEBAND EXPAK",app_id="0x0100004f",app_name="wb-expak" 1715165504619894286
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="WIDEBAND Monitoring",app_id="0x0100004e",app_name="wb-mon" 1715165504619894286
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Wang Span Network",app_id="0x0100004a",app_name="wsn" 1715165504619894286
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="Cross Net Debugger",app_id="0x0100000f",app_name="xnet" 1715165504619894286
|
||||
netflow_options,source=127.0.0.1,version=IPFIX app_desc="XEROX NS IDP",app_id="0x01000016",app_name="xns-idp" 1715165504619894286
|
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-001.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-001.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-002.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-002.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-003.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-003.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-004.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-004.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-005.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-005.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-006.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-006.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-007.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-007.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-008.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-008.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-009.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_options/message-009.bin
Normal file
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
[[inputs.netflow]]
|
||||
service_address = "udp://127.0.0.1:0"
|
|
@ -0,0 +1,2 @@
|
|||
netflow,source=127.0.0.1,version=IPFIX app_latency_ms=0u,flow_end_ms=1684767922502u,ssl_unsafe_cipher=0u,src_mask=0u,dst_port=44400u,in_src_mac="00:50:56:b3:86:e7",src_tos="0x00",ja3c_hash="",server_nw_latency_ms=0u,l7_proto=37u,last_switched=22474460u,tcp_flags="........",ja3s_hash="",in_snmp=0u,flow_start_ms=1684767922502u,ssl_version=0u,client_nw_latency_ms=0u,out_dst_mac="00:50:56:b3:a7:f8",src="192.168.2.203",dst_mask=0u,next_hop="0.0.0.0",flow_end=1684767922u,ssl_cipher=0u,src_port=51413u,dst_tos="0x00",ip_version="IPv4",retransmitted_out_bytes=0u,in_bytes=122u,out_snmp=0u,protocol="udp",first_switched=22474460u,retransmitted_in_pkts=0u,dst="189.127.188.175",retransmitted_in_bytes=0u,flow_start=1684767922u,ssl_server_name="",retransmitted_out_pkts=0u,in_packets=1u 1684928292858572674
|
||||
netflow,source=127.0.0.1,version=IPFIX app_latency_ms=0u,out_dst_mac="00:50:56:b3:a7:f8",protocol="udp",ja3c_hash="",ssl_unsafe_cipher=0u,dst_mask=0u,retransmitted_in_pkts=0u,out_snmp=0u,flow_start_ms=1684767922502u,ssl_cipher=0u,l7_proto=37u,in_snmp=0u,retransmitted_in_bytes=0u,src_tos="0x00",last_switched=22474460u,ssl_version=0u,in_packets=1u,first_switched=22474460u,flow_end=1684767922u,src="192.168.2.203",retransmitted_out_pkts=0u,src_port=51413u,client_nw_latency_ms=0u,next_hop="0.0.0.0",dst="177.234.165.79",server_nw_latency_ms=0u,tcp_flags="........",flow_start=1684767922u,src_mask=0u,dst_port=47707u,ssl_server_name="",ip_version="IPv4",retransmitted_out_bytes=0u,dst_tos="0x00",in_bytes=86u,flow_end_ms=1684767922502u,ja3s_hash="",in_src_mac="00:50:56:b3:86:e7" 1684928292858831665
|
BIN
plugins/inputs/netflow/testcases/ipfix_pen_35632/message-1.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_pen_35632/message-1.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_pen_35632/message-2.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_pen_35632/message-2.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_pen_35632/message-3.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_pen_35632/message-3.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/ipfix_pen_35632/message-4.bin
Normal file
BIN
plugins/inputs/netflow/testcases/ipfix_pen_35632/message-4.bin
Normal file
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
[[inputs.netflow]]
|
||||
service_address = "udp://127.0.0.1:0"
|
||||
private_enterprise_number_files = ["mappings_ipfix_pen/ntop-35632.csv"]
|
|
@ -0,0 +1,2 @@
|
|||
netflow,source=127.0.0.1,version=IPFIX ip_version="IPv4",dst_port=44400u,dst_tos="0x00",flow_end_ms=1684767922502u,type_35632_127="0x00000000",flow_start=1684767922u,src="192.168.2.203",flow_end=1684767922u,type_35632_493="0x0000",first_switched=22474460u,type_35632_188="",protocol="udp",in_src_mac="00:50:56:b3:86:e7",type_35632_128="0x00000000",in_snmp=0u,src_mask=0u,out_snmp=0u,type_35632_124="0x00000000",type_35632_494="0x00",in_bytes=122u,type_35632_110="0x00000000",out_dst_mac="00:50:56:b3:a7:f8",type_35632_490="",dst_mask=0u,type_35632_495="0x0000",last_switched=22474460u,in_packets=1u,type_35632_123="0x00000000",dst="189.127.188.175",src_tos="0x00",type_35632_118="0x0025",type_35632_125="0x00000000",next_hop="0.0.0.0",src_port=51413u,tcp_flags="........",flow_start_ms=1684767922502u,type_35632_489="",type_35632_109="0x00000000" 1684848566299341667
|
||||
netflow,source=127.0.0.1,version=IPFIX src_mask=0u,out_snmp=0u,type_35632_188="",type_35632_118="0x0025",type_35632_109="0x00000000",type_35632_124="0x00000000",in_packets=1u,dst="177.234.165.79",dst_port=47707u,type_35632_125="0x00000000",tcp_flags="........",flow_end=1684767922u,type_35632_128="0x00000000",protocol="udp",type_35632_490="",dst_mask=0u,last_switched=22474460u,flow_end_ms=1684767922502u,type_35632_489="",in_bytes=86u,type_35632_123="0x00000000",next_hop="0.0.0.0",ip_version="IPv4",src_port=51413u,dst_tos="0x00",type_35632_494="0x00",src="192.168.2.203",type_35632_127="0x00000000",flow_start_ms=1684767922502u,type_35632_493="0x0000",in_src_mac="00:50:56:b3:86:e7",flow_start=1684767922u,first_switched=22474460u,out_dst_mac="00:50:56:b3:a7:f8",src_tos="0x00",type_35632_110="0x00000000",type_35632_495="0x0000",in_snmp=0u 1684848566299737019
|
BIN
plugins/inputs/netflow/testcases/issue_13305/message-1.bin
Normal file
BIN
plugins/inputs/netflow/testcases/issue_13305/message-1.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/issue_13305/message-2.bin
Normal file
BIN
plugins/inputs/netflow/testcases/issue_13305/message-2.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/issue_13305/message-3.bin
Normal file
BIN
plugins/inputs/netflow/testcases/issue_13305/message-3.bin
Normal file
Binary file not shown.
BIN
plugins/inputs/netflow/testcases/issue_13305/message-4.bin
Normal file
BIN
plugins/inputs/netflow/testcases/issue_13305/message-4.bin
Normal file
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
[[inputs.netflow]]
|
||||
service_address = "udp://127.0.0.1:0"
|
|
@ -0,0 +1,2 @@
|
|||
netflow,source=127.0.0.1,version=IPFIX bgp_dst_as=2152u,bgp_src_as=65535u,direction="ingress",dst="101.104.199.17",dst_port=50202u,flow_end=0u,flow_start=0u,flows=1u,in_bytes=256u,in_packets=1u,in_snmp=101u,out_snmp=201u,protocol="tcp",src="0.0.0.0",src_port=443u 1701440347872006922
|
||||
netflow,source=127.0.0.1,version=IPFIX bgp_dst_as=2152u,bgp_src_as=65535u,direction="ingress",dst="2001:db8:0:1::1",dst_port=50202u,flow_end=0u,flow_start=0u,flows=1u,in_bytes=256u,in_packets=1u,in_snmp=101u,out_snmp=201u,protocol="tcp",src="::6568:c711:0:0:6568:c711",src_port=443u 1701440347872025552
|
BIN
plugins/inputs/netflow/testcases/issue_14370/message.bin
Normal file
BIN
plugins/inputs/netflow/testcases/issue_14370/message.bin
Normal file
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
[[inputs.netflow]]
|
||||
service_address = "udp://127.0.0.1:0"
|
7
plugins/inputs/netflow/testcases/netflow_mapping.csv
Normal file
7
plugins/inputs/netflow/testcases/netflow_mapping.csv
Normal file
|
@ -0,0 +1,7 @@
|
|||
58500,protocol_ntop,string
|
||||
58503,l4_src_port_name,string
|
||||
58507,l4_dst_port_name,string
|
||||
58508,l4_srv_port,uint
|
||||
58509,l4_srv_port_name,string
|
||||
57552,src_fragments,uint
|
||||
57553,dst_fragments,uint
|
|
|
@ -0,0 +1,8 @@
|
|||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="140.82.121.3",src_port=443u,dst="192.168.119.100",dst_port=55516u,flows=8u,in_bytes=87477u,in_packets=78u,first_switched=86400660u,last_switched=86403316u,tcp_flags="...AP...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="140.82.121.6",src_port=443u,dst="192.168.119.100",dst_port=36408u,flows=8u,in_bytes=5009u,in_packets=21u,first_switched=86400447u,last_switched=86403267u,tcp_flags="...AP...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="140.82.112.22",src_port=443u,dst="192.168.119.100",dst_port=39638u,flows=8u,in_bytes=925u,in_packets=6u,first_switched=86400324u,last_switched=86403214u,tcp_flags="...AP...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="140.82.114.26",src_port=443u,dst="192.168.119.100",dst_port=49398u,flows=8u,in_bytes=250u,in_packets=2u,first_switched=86403131u,last_switched=86403362u,tcp_flags="...AP...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="192.168.119.100",src_port=55516u,dst="140.82.121.3",dst_port=443u,flows=8u,in_bytes=4969u,in_packets=37u,first_switched=86400652u,last_switched=86403269u,tcp_flags="...AP...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="192.168.119.100",src_port=36408u,dst="140.82.121.6",dst_port=443u,flows=8u,in_bytes=2736u,in_packets=21u,first_switched=86400438u,last_switched=86403258u,tcp_flags="...AP...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="192.168.119.100",src_port=39638u,dst="140.82.112.22",dst_port=443u,flows=8u,in_bytes=1560u,in_packets=6u,first_switched=86400225u,last_switched=86403255u,tcp_flags="...AP...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
||||
netflow,source=127.0.0.1,version=NetFlowV5 protocol="tcp",src="192.168.119.100",src_port=49398u,dst="140.82.114.26",dst_port=443u,flows=8u,in_bytes=697u,in_packets=4u,first_switched=86403030u,last_switched=86403362u,tcp_flags="...AP...",engine_type="19",engine_id="0x56",sys_uptime=90003000u,src_tos="0x00",bgp_src_as=0u,bgp_dst_as=0u,src_mask=0u,dst_mask=0u,in_snmp=0u,out_snmp=0u,next_hop="0.0.0.0",seq_number=0u,sampling_interval=0u
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
[[inputs.netflow]]
|
||||
service_address = "udp://127.0.0.1:0"
|
||||
protocol = "netflow v5"
|
|
@ -0,0 +1,8 @@
|
|||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="140.82.121.3",src_port=443u,dst="192.168.119.100",dst_port=55516u,in_bytes=87477u,in_packets=78u,flow_start_ms=1666350478660u,flow_end_ms=1666350481316u,tcp_flags="...AP...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="140.82.121.6",src_port=443u,dst="192.168.119.100",dst_port=36408u,in_bytes=5009u,in_packets=21u,flow_start_ms=1666350478447u,flow_end_ms=1666350481267u,tcp_flags="...AP...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="140.82.112.22",src_port=443u,dst="192.168.119.100",dst_port=39638u,in_bytes=925u,in_packets=6u,flow_start_ms=1666350478324u,flow_end_ms=1666350481214u,tcp_flags="...AP...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="140.82.114.26",src_port=443u,dst="192.168.119.100",dst_port=49398u,in_bytes=250u,in_packets=2u,flow_start_ms=1666350481131u,flow_end_ms=1666350481362u,tcp_flags="...AP...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="192.168.119.100",src_port=55516u,dst="140.82.121.3",dst_port=443u,in_bytes=4969u,in_packets=37u,flow_start_ms=1666350478652u,flow_end_ms=1666350481269u,tcp_flags="...AP...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="192.168.119.100",src_port=36408u,dst="140.82.121.6",dst_port=443u,in_bytes=2736u,in_packets=21u,flow_start_ms=1666350478438u,flow_end_ms=1666350481258u,tcp_flags="...AP...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="192.168.119.100",src_port=39638u,dst="140.82.112.22",dst_port=443u,in_bytes=1560u,in_packets=6u,flow_start_ms=1666350478225u,flow_end_ms=1666350481255u,tcp_flags="...AP...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
||||
netflow,source=127.0.0.1,version=NetFlowV9 protocol="tcp",src="192.168.119.100",src_port=49398u,dst="140.82.114.26",dst_port=443u,in_bytes=697u,in_packets=4u,flow_start_ms=1666350481030u,flow_end_ms=1666350481362u,tcp_flags="...AP...",engine_type="17",engine_id="0x01",icmp_type=0u,icmp_code=0u,fwd_status="unknown",fwd_reason="unknown",src_tos="0x00"
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
[[inputs.netflow]]
|
||||
service_address = "udp://127.0.0.1:0"
|
|
@ -0,0 +1,8 @@
|
|||
netflow_options,source=127.0.0.1,version=NetFlowV9 in_bytes=169952189u,in_snmp=1u,interface="Te0/0/0",interface_desc="TenGigabitEthernet0/0/0",out_snmp=1u 1713379378304536264
|
||||
netflow_options,source=127.0.0.1,version=NetFlowV9 in_bytes=169952189u,in_snmp=2u,interface="Te0/0/1",interface_desc="TenGigabitEthernet0/0/1",out_snmp=2u 1713379378304536264
|
||||
netflow_options,source=127.0.0.1,version=NetFlowV9 in_bytes=169952189u,in_snmp=3u,interface="Te0/0/2",interface_desc="TenGigabitEthernet0/0/2",out_snmp=3u 1713379378304536264
|
||||
netflow_options,source=127.0.0.1,version=NetFlowV9 in_bytes=169952189u,in_snmp=4u,interface="Te0/0/3",interface_desc="TenGigabitEthernet0/0/3",out_snmp=4u 1713379378304536264
|
||||
netflow_options,source=127.0.0.1,version=NetFlowV9 in_bytes=169952189u,in_snmp=5u,interface="Te0/0/4",interface_desc="TenGigabitEthernet0/0/4",out_snmp=5u 1713379378304536264
|
||||
netflow_options,source=127.0.0.1,version=NetFlowV9 in_bytes=169952189u,in_snmp=6u,interface="Te0/0/5",interface_desc="TenGigabitEthernet0/0/5",out_snmp=6u 1713379378304536264
|
||||
netflow_options,source=127.0.0.1,version=NetFlowV9 in_bytes=169952189u,in_snmp=7u,interface="Gi0",interface_desc="GigabitEthernet0",out_snmp=7u 1713379378304536264
|
||||
netflow_options,source=127.0.0.1,version=NetFlowV9 in_bytes=169952189u,in_snmp=10u,interface="Lo0",interface_desc="Loopback0",out_snmp=10u 1713379378304536264
|
BIN
plugins/inputs/netflow/testcases/netflow_v9_options/message.bin
Normal file
BIN
plugins/inputs/netflow/testcases/netflow_v9_options/message.bin
Normal file
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
[[inputs.netflow]]
|
||||
service_address = "udp://127.0.0.1:0"
|
|
@ -0,0 +1 @@
|
|||
netflow,source=127.0.0.1,version=sFlowV5 sys_uptime=12414u,agent_ip="192.168.119.184",agent_subid=100000u,seq_number=2u,direction="ingress",in_snmp=1u,out_snmp=2u,out_queue=42u,reason=1u,sampling_drops=256u,ip_version="IPv4" 12414000000
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
[[inputs.netflow]]
|
||||
service_address = "udp://127.0.0.1:0"
|
||||
protocol = "sflow v5"
|
|
@ -0,0 +1,7 @@
|
|||
netflow,source=127.0.0.1,version=sFlowV5 agent_ip="192.168.227.2",agent_subid=0u,in_broadcast_packets_total=2502106u,in_bytes=21286022420858u,in_dropped_packets=0u,in_errors=0u,in_mcast_packets_total=81495048u,in_snmp=101u,in_unicast_packets_total=1153749508u,in_unknown_protocol=0u,interface=101u,interface_type=6u,ip_version="IPv4",out_broadcast_packets_total=1251275u,out_bytes=8929238553590u,out_dropped_packets=0u,out_errors=0u,out_mcast_packets_total=3753944u,out_unicast_packets_total=3892490465u,promiscuous=0u,seq_number=300415u,speed=1000000000u,status="up",sys_uptime=2042523538u 1728660319352704090
|
||||
netflow,source=127.0.0.1,version=sFlowV5 agent_ip="192.168.227.2",agent_subid=0u,datalink_frame_type="IPv4",direction="ingress",dst="192.168.101.2",dst_port=2055u,fragment_flags="........",fragment_offset=0u,in_snmp=96u,in_src_mac="00:09:0f:09:00:01",in_total_packets=687103949u,ip_total_len=1248u,ip_version="IPv4",ipv4_id=49746u,ipv4_inet_header_len=5u,ipv4_total_len=1268u,l2_bytes=1286u,l2_protocol="ETHERNET-ISO8023",out_dst_mac="48:21:0b:3b:76:59",out_snmp=95u,protocol="udp",sampling_drops=8731u,sampling_interval=200u,seq_number=2404916u,src="192.168.227.2",src_port=49469u,src_tos=0u,sys_uptime=2042523538u,ttl=63u,vlan_dst=154u,vlan_dst_priority=0u,vlan_src=154u,vlan_src_priority=0u 1728660319352704090
|
||||
netflow,source=127.0.0.1,version=sFlowV5 agent_ip="192.168.227.2",agent_subid=0u,datalink_frame_type="IPv4",direction="egress",dst="192.168.100.104",dst_port=52851u,fragment_flags="......D.",fragment_offset=0u,in_snmp=60u,in_src_mac="dc:2c:6e:b9:1a:c6",in_total_packets=804503573u,ip_total_len=525u,ip_version="IPv4",ipv4_id=0u,ipv4_inet_header_len=5u,ipv4_total_len=545u,l2_bytes=563u,l2_protocol="ETHERNET-ISO8023",out_dst_mac="00:09:0f:09:00:00",out_snmp=60u,protocol="udp",sampling_drops=14255907u,sampling_interval=200u,seq_number=20451226u,src="142.250.200.99",src_port=443u,src_tos=0u,sys_uptime=2042523538u,ttl=51u,vlan_dst=250u,vlan_dst_priority=0u,vlan_src=250u,vlan_src_priority=4294967295u 1728660319352704090
|
||||
netflow,source=127.0.0.1,version=sFlowV5 agent_ip="192.168.227.2",agent_subid=0u,datalink_frame_type="IPv6",direction="egress",dst="ff02::16",in_snmp=76u,in_src_mac="00:e0:4c:68:00:5c",in_total_packets=1062946518u,ip_total_len=56u,ip_version="IPv6",ipv6_total_len=56u,l2_bytes=114u,l2_protocol="ETHERNET-ISO8023",out_dst_mac="33:33:00:00:00:16",protocol="hopopt",sampling_drops=30750u,sampling_interval=200u,seq_number=899357u,src="fe80::f3a8:9738:cab4:2286",sys_uptime=2042523538u,ttl=1u,vlan_dst=153u,vlan_dst_priority=0u,vlan_src=153u,vlan_src_priority=4294967295u 1728660319352704090
|
||||
netflow,source=127.0.0.1,version=sFlowV5 agent_ip="192.168.227.2",agent_subid=0u,datalink_frame_type="IPv4",direction="egress",dst="142.250.185.14",dst_port=443u,fragment_flags="......D.",fragment_offset=0u,in_snmp=101u,in_src_mac="00:09:0f:09:00:00",in_total_packets=840275157u,ip_total_len=39u,ip_version="IPv4",ipv4_id=40468u,ipv4_inet_header_len=5u,ipv4_total_len=59u,l2_bytes=77u,l2_protocol="ETHERNET-ISO8023",out_dst_mac="00:00:5e:00:01:7b",out_snmp=101u,protocol="udp",sampling_drops=14100530u,sampling_interval=200u,seq_number=20640786u,src="192.168.153.106",src_port=64969u,src_tos=0u,sys_uptime=2042523538u,ttl=127u,vlan_dst=250u,vlan_dst_priority=0u,vlan_src=250u,vlan_src_priority=4294967295u 1728660319352704090
|
||||
netflow,source=127.0.0.1,version=sFlowV5 agent_ip="192.168.227.2",agent_subid=0u,datalink_frame_type="IPv4",direction="ingress",dst="192.168.153.106",dst_port=64969u,fragment_flags="......D.",fragment_offset=0u,in_snmp=6u,in_src_mac="00:09:0f:09:00:08",in_total_packets=774315870u,ip_total_len=681u,ip_version="IPv4",ipv4_id=0u,ipv4_inet_header_len=5u,ipv4_total_len=701u,l2_bytes=719u,l2_protocol="ETHERNET-ISO8023",out_dst_mac="7c:8a:e1:be:20:52",out_snmp=97u,protocol="udp",sampling_drops=2262938u,sampling_interval=200u,seq_number=17418932u,src="142.250.185.14",src_port=443u,src_tos=0u,sys_uptime=2042523538u,ttl=50u,vlan_dst=153u,vlan_dst_priority=0u,vlan_src=153u,vlan_src_priority=0u 1728660319352704090
|
||||
netflow,source=127.0.0.1,version=sFlowV5 agent_ip="192.168.227.2",agent_subid=0u,datalink_frame_type="IPv6",direction="egress",dst="ff02::1:3",dst_port=5355u,in_snmp=72u,in_src_mac="00:e0:4c:68:00:5c",in_total_packets=1172072178u,ip_total_len=35u,ip_version="IPv6",ipv6_total_len=35u,l2_bytes=93u,l2_protocol="ETHERNET-ISO8023",out_dst_mac="33:33:00:01:00:03",protocol="udp",sampling_drops=27512u,sampling_interval=200u,seq_number=704213u,src="fe80::f3a8:9738:cab4:2286",src_port=49770u,sys_uptime=2042523538u,ttl=1u,vlan_dst=153u,vlan_dst_priority=0u,vlan_src=153u,vlan_src_priority=4294967295u 1728660319352704090
|
BIN
plugins/inputs/netflow/testcases/sflow_issue_15918/message.bin
Normal file
BIN
plugins/inputs/netflow/testcases/sflow_issue_15918/message.bin
Normal file
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
[[inputs.netflow]]
|
||||
service_address = "udp://127.0.0.1:0"
|
||||
protocol = "sflow v5"
|
|
@ -0,0 +1 @@
|
|||
netflow,source=127.0.0.1,version=sFlowV5 sys_uptime=12414u,agent_ip="192.168.119.184",agent_subid=100000u,seq_number=2u,in_snmp=3u,port_name="eno1",ip_version="IPv4" 12414000000
|
BIN
plugins/inputs/netflow/testcases/sflow_v5_example/sflow_v5.bin
Normal file
BIN
plugins/inputs/netflow/testcases/sflow_v5_example/sflow_v5.bin
Normal file
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
[[inputs.netflow]]
|
||||
service_address = "udp://127.0.0.1:0"
|
||||
protocol = "sflow v5"
|
728
plugins/inputs/netflow/type_conversion.go
Normal file
728
plugins/inputs/netflow/type_conversion.go
Normal file
|
@ -0,0 +1,728 @@
|
|||
package netflow
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"encoding/binary"
|
||||
"encoding/csv"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// From https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
|
||||
//
|
||||
//go:embed layer4_protocol_numbers.csv
|
||||
var l4ProtoFile []byte
|
||||
|
||||
// From https://www.iana.org/assignments/ip-parameters/ip-parameters.xhtml
|
||||
//
|
||||
//go:embed ipv4_options.csv
|
||||
var ip4OptionFile []byte
|
||||
|
||||
var l4ProtoMapping map[uint8]string
|
||||
var ipv4OptionMapping []string
|
||||
|
||||
func initL4ProtoMapping() error {
|
||||
buf := bytes.NewBuffer(l4ProtoFile)
|
||||
reader := csv.NewReader(buf)
|
||||
records, err := reader.ReadAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(records) < 2 {
|
||||
return errors.New("empty file")
|
||||
}
|
||||
|
||||
l4ProtoMapping = make(map[uint8]string)
|
||||
for _, r := range records[1:] {
|
||||
if len(r) != 2 {
|
||||
return fmt.Errorf("invalid record: %v", r)
|
||||
}
|
||||
name := strings.ToLower(r[1])
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
id, err := strconv.ParseUint(r[0], 10, 8)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", err, r)
|
||||
}
|
||||
l4ProtoMapping[uint8(id)] = name
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func initIPv4OptionMapping() error {
|
||||
buf := bytes.NewBuffer(ip4OptionFile)
|
||||
reader := csv.NewReader(buf)
|
||||
records, err := reader.ReadAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(records) < 2 {
|
||||
return errors.New("empty file")
|
||||
}
|
||||
|
||||
ipv4OptionMapping = make([]string, 32)
|
||||
for _, r := range records[1:] {
|
||||
if len(r) != 2 {
|
||||
return fmt.Errorf("invalid record: %v", r)
|
||||
}
|
||||
idx, err := strconv.ParseUint(r[0], 10, 8)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", err, r)
|
||||
}
|
||||
ipv4OptionMapping[idx] = r[1]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodeInt(b []byte) (interface{}, error) {
|
||||
switch len(b) {
|
||||
case 0:
|
||||
return int64(0), nil
|
||||
case 1:
|
||||
return int64(int8(b[0])), nil
|
||||
case 2:
|
||||
return int64(int16(binary.BigEndian.Uint16(b))), nil
|
||||
case 4:
|
||||
return int64(int32(binary.BigEndian.Uint32(b))), nil
|
||||
case 8:
|
||||
return int64(binary.BigEndian.Uint64(b)), nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid length for int buffer %v", b)
|
||||
}
|
||||
|
||||
func decodeUint(b []byte) (interface{}, error) {
|
||||
switch len(b) {
|
||||
case 0:
|
||||
return uint64(0), nil
|
||||
case 1:
|
||||
return uint64(b[0]), nil
|
||||
case 2:
|
||||
return uint64(binary.BigEndian.Uint16(b)), nil
|
||||
case 4:
|
||||
return uint64(binary.BigEndian.Uint32(b)), nil
|
||||
case 8:
|
||||
return binary.BigEndian.Uint64(b), nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid length for uint buffer %v", b)
|
||||
}
|
||||
|
||||
func decodeFloat64(b []byte) (interface{}, error) {
|
||||
raw := binary.BigEndian.Uint64(b)
|
||||
return math.Float64frombits(raw), nil
|
||||
}
|
||||
|
||||
// According to https://www.rfc-editor.org/rfc/rfc5101#section-6.1.5
|
||||
func decodeBool(b []byte) (interface{}, error) {
|
||||
if len(b) == 0 {
|
||||
return nil, errors.New("empty data")
|
||||
}
|
||||
if b[0] == 1 {
|
||||
return true, nil
|
||||
}
|
||||
if b[0] == 2 {
|
||||
return false, nil
|
||||
}
|
||||
return b[0], nil
|
||||
}
|
||||
|
||||
func decodeHex(b []byte) (interface{}, error) {
|
||||
if len(b) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
return "0x" + hex.EncodeToString(b), nil
|
||||
}
|
||||
|
||||
func decodeString(b []byte) (interface{}, error) {
|
||||
return strings.TrimRight(string(b), "\x00"), nil
|
||||
}
|
||||
|
||||
func decodeMAC(b []byte) (interface{}, error) {
|
||||
mac := net.HardwareAddr(b)
|
||||
return mac.String(), nil
|
||||
}
|
||||
|
||||
func decodeIP(b []byte) (interface{}, error) {
|
||||
ip := net.IP(b)
|
||||
return ip.String(), nil
|
||||
}
|
||||
|
||||
func decodeIPFromUint32(a uint32) (interface{}, error) {
|
||||
b := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(b, a)
|
||||
return decodeIP(b)
|
||||
}
|
||||
|
||||
func decodeL4Proto(b []byte) (interface{}, error) {
|
||||
return mapL4Proto(b[0]), nil
|
||||
}
|
||||
|
||||
func mapL4Proto(id uint8) string {
|
||||
name, found := l4ProtoMapping[id]
|
||||
if found {
|
||||
return name
|
||||
}
|
||||
return strconv.FormatUint(uint64(id), 10)
|
||||
}
|
||||
|
||||
func decodeIPv4Options(b []byte) (interface{}, error) {
|
||||
flags := binary.BigEndian.Uint32(b)
|
||||
|
||||
var result []string
|
||||
for i := 0; i < 32; i++ {
|
||||
name := ipv4OptionMapping[i]
|
||||
if name == "" {
|
||||
name = fmt.Sprintf("UA%d", i)
|
||||
}
|
||||
if (flags>>i)&0x01 != 0 {
|
||||
result = append(result, name)
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(result, ","), nil
|
||||
}
|
||||
|
||||
func decodeTCPFlags(b []byte) (interface{}, error) {
|
||||
if len(b) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
if len(b) == 1 {
|
||||
return mapTCPFlags(b[0]), nil
|
||||
}
|
||||
|
||||
// IPFIX has more flags
|
||||
results := make([]string, 0, 8)
|
||||
for i := 7; i >= 0; i-- {
|
||||
if (b[0]>>i)&0x01 != 0 {
|
||||
// Currently all flags are reserved so denote the bit set
|
||||
results = append(results, "*")
|
||||
} else {
|
||||
results = append(results, ".")
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:gosec // False positive (b[1] is not out of range - it is ensured by above checks)
|
||||
return strings.Join(results, "") + mapTCPFlags(b[1]), nil
|
||||
}
|
||||
|
||||
func mapTCPFlags(flags uint8) string {
|
||||
flagMapping := []string{
|
||||
"F", // FIN
|
||||
"S", // SYN
|
||||
"R", // RST
|
||||
"P", // PSH
|
||||
"A", // ACK
|
||||
"U", // URG
|
||||
"E", // ECE
|
||||
"C", // CWR
|
||||
}
|
||||
|
||||
result := make([]string, 0, 8)
|
||||
|
||||
for i := 7; i >= 0; i-- {
|
||||
if (flags>>i)&0x01 != 0 {
|
||||
result = append(result, flagMapping[i])
|
||||
} else {
|
||||
result = append(result, ".")
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(result, "")
|
||||
}
|
||||
|
||||
func decodeFragmentFlags(b []byte) (interface{}, error) {
|
||||
flagMapping := []string{
|
||||
"*", // do not care
|
||||
"*", // do not care
|
||||
"*", // do not care
|
||||
"*", // do not care
|
||||
"*", // do not care
|
||||
"M", // MF -- more fragments
|
||||
"D", // DF -- don't fragment
|
||||
"R", // RS -- reserved
|
||||
}
|
||||
|
||||
flags := b[0]
|
||||
result := make([]string, 0, 8)
|
||||
for i := 7; i >= 0; i-- {
|
||||
if (flags>>i)&0x01 != 0 {
|
||||
result = append(result, flagMapping[i])
|
||||
} else {
|
||||
result = append(result, ".")
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(result, ""), nil
|
||||
}
|
||||
|
||||
func decodeSampleAlgo(b []byte) (interface{}, error) {
|
||||
switch b[0] {
|
||||
case 1:
|
||||
return "deterministic", nil
|
||||
case 2:
|
||||
return "random", nil
|
||||
}
|
||||
return strconv.FormatUint(uint64(b[0]), 10), nil
|
||||
}
|
||||
|
||||
func decodeEngineType(b []byte) (interface{}, error) {
|
||||
return mapEngineType(b[0]), nil
|
||||
}
|
||||
|
||||
func mapEngineType(b uint8) string {
|
||||
switch b {
|
||||
case 0:
|
||||
return "RP"
|
||||
case 1:
|
||||
return "VIP/linecard"
|
||||
case 2:
|
||||
return "PFC/DFC"
|
||||
}
|
||||
return strconv.FormatUint(uint64(b), 10)
|
||||
}
|
||||
|
||||
func decodeMPLSType(b []byte) (interface{}, error) {
|
||||
switch b[0] {
|
||||
case 0:
|
||||
return "unknown", nil
|
||||
case 1:
|
||||
return "TE-MIDPT", nil
|
||||
case 2:
|
||||
return "Pseudowire", nil
|
||||
case 3:
|
||||
return "VPN", nil
|
||||
case 4:
|
||||
return "BGP", nil
|
||||
case 5:
|
||||
return "LDP", nil
|
||||
case 6:
|
||||
return "Path computation element", nil
|
||||
case 7:
|
||||
return "OSPFv2", nil
|
||||
case 8:
|
||||
return "OSPFv3", nil
|
||||
case 9:
|
||||
return "IS-IS", nil
|
||||
case 10:
|
||||
return "BGP segment routing Prefix-SID", nil
|
||||
}
|
||||
return strconv.FormatUint(uint64(b[0]), 10), nil
|
||||
}
|
||||
|
||||
func decodeIPVersion(b []byte) (interface{}, error) {
|
||||
switch b[0] {
|
||||
case 4:
|
||||
return "IPv4", nil
|
||||
case 6:
|
||||
return "IPv6", nil
|
||||
}
|
||||
return strconv.FormatUint(uint64(b[0]), 10), nil
|
||||
}
|
||||
|
||||
func decodePacketIPVersion(v uint8) string {
|
||||
switch v {
|
||||
case 4:
|
||||
return "IPv4"
|
||||
case 6:
|
||||
return "IPv6"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
func decodeDirection(b []byte) (interface{}, error) {
|
||||
switch b[0] {
|
||||
case 0:
|
||||
return "ingress", nil
|
||||
case 1:
|
||||
return "egress", nil
|
||||
}
|
||||
return strconv.FormatUint(uint64(b[0]), 10), nil
|
||||
}
|
||||
|
||||
// https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-forwarding-status
|
||||
func decodeFwdStatus(b []byte) (interface{}, error) {
|
||||
switch b[0] >> 6 {
|
||||
case 0:
|
||||
return "unknown", nil
|
||||
case 1:
|
||||
return "forwarded", nil
|
||||
case 2:
|
||||
return "dropped", nil
|
||||
case 3:
|
||||
return "consumed", nil
|
||||
}
|
||||
return "invalid", nil
|
||||
}
|
||||
|
||||
// https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-forwarding-status
|
||||
func decodeFwdReason(b []byte) (interface{}, error) {
|
||||
switch b[0] {
|
||||
// unknown
|
||||
case 0:
|
||||
return "unknown", nil
|
||||
// forwarded
|
||||
case 64:
|
||||
return "unknown", nil
|
||||
case 65:
|
||||
return "fragmented", nil
|
||||
case 66:
|
||||
return "not fragmented", nil
|
||||
// dropped
|
||||
case 128:
|
||||
return "unknown", nil
|
||||
case 129:
|
||||
return "ACL deny", nil
|
||||
case 130:
|
||||
return "ACL drop", nil
|
||||
case 131:
|
||||
return "unroutable", nil
|
||||
case 132:
|
||||
return "adjacency", nil
|
||||
case 133:
|
||||
return "fragmentation and DF set", nil
|
||||
case 134:
|
||||
return "bad header checksum", nil
|
||||
case 135:
|
||||
return "bad total length", nil
|
||||
case 136:
|
||||
return "bad header length", nil
|
||||
case 137:
|
||||
return "bad TTL", nil
|
||||
case 138:
|
||||
return "policer", nil
|
||||
case 139:
|
||||
return "WRED", nil
|
||||
case 140:
|
||||
return "RPF", nil
|
||||
case 141:
|
||||
return "for us", nil
|
||||
case 142:
|
||||
return "bad output interface", nil
|
||||
case 143:
|
||||
return "hardware", nil
|
||||
// consumed
|
||||
case 192:
|
||||
return "unknown", nil
|
||||
case 193:
|
||||
return "terminate punt adjacency", nil
|
||||
case 194:
|
||||
return "terminate incomplete adjacency", nil
|
||||
case 195:
|
||||
return "terminate for us", nil
|
||||
case 14:
|
||||
return "", nil
|
||||
}
|
||||
return "invalid", nil
|
||||
}
|
||||
|
||||
// https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-firewall-event
|
||||
func decodeFWEvent(b []byte) (interface{}, error) {
|
||||
switch b[0] {
|
||||
case 0:
|
||||
return "ignore", nil
|
||||
case 1:
|
||||
return "flow created", nil
|
||||
case 2:
|
||||
return "flow deleted", nil
|
||||
case 3:
|
||||
return "flow denied", nil
|
||||
case 4:
|
||||
return "flow alert", nil
|
||||
case 5:
|
||||
return "flow update", nil
|
||||
}
|
||||
return strconv.FormatUint(uint64(b[0]), 10), nil
|
||||
}
|
||||
|
||||
// https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-flow-end-reason
|
||||
func decodeFlowEndReason(b []byte) (interface{}, error) {
|
||||
switch b[0] {
|
||||
case 0:
|
||||
return "reserved", nil
|
||||
case 1:
|
||||
return "idle timeout", nil
|
||||
case 2:
|
||||
return "active timeout", nil
|
||||
case 3:
|
||||
return "end of flow", nil
|
||||
case 4:
|
||||
return "forced end", nil
|
||||
case 5:
|
||||
return "lack of resources", nil
|
||||
}
|
||||
return "unassigned", nil
|
||||
}
|
||||
|
||||
// https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-biflow-direction
|
||||
func decodeBiflowDirection(b []byte) (interface{}, error) {
|
||||
switch b[0] {
|
||||
case 0:
|
||||
return "arbitrary", nil
|
||||
case 1:
|
||||
return "initiator", nil
|
||||
case 2:
|
||||
return "reverse initiator", nil
|
||||
case 3:
|
||||
return "perimeter", nil
|
||||
}
|
||||
return "unassigned", nil
|
||||
}
|
||||
|
||||
// https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-observation-point-type
|
||||
func decodeOpsPointType(b []byte) (interface{}, error) {
|
||||
switch b[0] {
|
||||
case 0:
|
||||
return "invalid", nil
|
||||
case 1:
|
||||
return "physical port", nil
|
||||
case 2:
|
||||
return "port channel", nil
|
||||
case 3:
|
||||
return "vlan", nil
|
||||
}
|
||||
return "unassigned", nil
|
||||
}
|
||||
|
||||
func decodeAnonStabilityClass(b []byte) (interface{}, error) {
|
||||
switch b[1] & 0x03 {
|
||||
case 1:
|
||||
return "session", nil
|
||||
case 2:
|
||||
return "exporter-collector", nil
|
||||
case 3:
|
||||
return "stable", nil
|
||||
}
|
||||
return "undefined", nil
|
||||
}
|
||||
|
||||
func decodeAnonFlags(b []byte) (interface{}, error) {
|
||||
var result []string
|
||||
if b[0]&(1<<2) != 0 {
|
||||
result = append(result, "PmA")
|
||||
}
|
||||
|
||||
if b[0]&(1<<3) != 0 {
|
||||
result = append(result, "LOR")
|
||||
}
|
||||
|
||||
return strings.Join(result, ","), nil
|
||||
}
|
||||
|
||||
// https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-anonymization-technique
|
||||
func decodeAnonTechnique(b []byte) (interface{}, error) {
|
||||
tech := binary.BigEndian.Uint16(b)
|
||||
switch tech {
|
||||
case 0:
|
||||
return "undefined", nil
|
||||
case 1:
|
||||
return "none", nil
|
||||
case 2:
|
||||
return "precision degradation", nil
|
||||
case 3:
|
||||
return "binning", nil
|
||||
case 4:
|
||||
return "enumeration", nil
|
||||
case 5:
|
||||
return "permutation", nil
|
||||
case 6:
|
||||
return "structure permutation", nil
|
||||
case 7:
|
||||
return "reverse truncation", nil
|
||||
case 8:
|
||||
return "noise", nil
|
||||
case 9:
|
||||
return "offset", nil
|
||||
}
|
||||
return "unassigned", nil
|
||||
}
|
||||
|
||||
func decodeTechnology(b []byte) (interface{}, error) {
|
||||
switch string(b) {
|
||||
case "yes", "y", "1":
|
||||
return "yes", nil
|
||||
case "no", "n", "2":
|
||||
return "no", nil
|
||||
case "unassigned", "u", "0":
|
||||
return "unassigned", nil
|
||||
}
|
||||
switch b[0] {
|
||||
case 0:
|
||||
return "unassigned", nil
|
||||
case 1:
|
||||
return "yes", nil
|
||||
case 2:
|
||||
return "no", nil
|
||||
}
|
||||
return "undefined", nil
|
||||
}
|
||||
|
||||
// https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-nat-type
|
||||
func decodeIPNatType(b []byte) (interface{}, error) {
|
||||
tech := binary.BigEndian.Uint16(b)
|
||||
switch tech {
|
||||
case 0:
|
||||
return "unknown", nil
|
||||
case 1:
|
||||
return "NAT44", nil
|
||||
case 2:
|
||||
return "NAT64", nil
|
||||
case 3:
|
||||
return "NAT46", nil
|
||||
case 4:
|
||||
return "IPv4 no NAT", nil
|
||||
case 5:
|
||||
return "NAT66", nil
|
||||
case 6:
|
||||
return "IPv6 no NAT", nil
|
||||
}
|
||||
return "unassigned", nil
|
||||
}
|
||||
|
||||
// https://www.iana.org/assignments/psamp-parameters/psamp-parameters.xhtml
|
||||
func decodeSelectorAlgorithm(b []byte) (interface{}, error) {
|
||||
tech := binary.BigEndian.Uint16(b)
|
||||
switch tech {
|
||||
case 0:
|
||||
return "reserved", nil
|
||||
case 1:
|
||||
return "systematic count-based sampling", nil
|
||||
case 2:
|
||||
return "systematic time-based sampling", nil
|
||||
case 3:
|
||||
return "random n-out-of-N sampling", nil
|
||||
case 4:
|
||||
return "uniform probabilistic sampling", nil
|
||||
case 5:
|
||||
return "property match filtering", nil
|
||||
case 6:
|
||||
return "hash based filtering using BOB", nil
|
||||
case 7:
|
||||
return "hash based filtering using IPSX", nil
|
||||
case 8:
|
||||
return "hash based filtering using CRC", nil
|
||||
case 9:
|
||||
return "flow-state dependent", nil
|
||||
}
|
||||
return "unassigned", nil
|
||||
}
|
||||
|
||||
// https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-value-distribution-method
|
||||
func decodeValueDistMethod(b []byte) (interface{}, error) {
|
||||
switch b[0] {
|
||||
case 0:
|
||||
return "unspecified", nil
|
||||
case 1:
|
||||
return "start interval", nil
|
||||
case 2:
|
||||
return "end interval", nil
|
||||
case 3:
|
||||
return "mid interval", nil
|
||||
case 4:
|
||||
return "simple uniform distribution", nil
|
||||
case 5:
|
||||
return "proportional uniform distribution", nil
|
||||
case 6:
|
||||
return "simulated process", nil
|
||||
case 7:
|
||||
return "direct", nil
|
||||
}
|
||||
return "unassigned", nil
|
||||
}
|
||||
|
||||
// https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-data-link-frame-type
|
||||
func decodeDataLinkFrameType(b []byte) (interface{}, error) {
|
||||
switch binary.BigEndian.Uint16(b) {
|
||||
case 0x0001:
|
||||
return "IEEE802.3 ethernet", nil
|
||||
case 0x0002:
|
||||
return "IEEE802.11 MAC", nil
|
||||
}
|
||||
return "unassigned", nil
|
||||
}
|
||||
|
||||
// https://www.iana.org/assignments/ipfix/ipfix.xhtml#ipfix-mib-capture-time-semantics
|
||||
func decodeCaptureTimeSemantics(b []byte) (interface{}, error) {
|
||||
switch b[0] {
|
||||
case 0:
|
||||
return "undefined", nil
|
||||
case 1:
|
||||
return "begin", nil
|
||||
case 2:
|
||||
return "end", nil
|
||||
case 3:
|
||||
return "export", nil
|
||||
case 4:
|
||||
return "average", nil
|
||||
}
|
||||
return "unassigned", nil
|
||||
}
|
||||
|
||||
func decodeSflowIPVersion(v uint32) string {
|
||||
switch v {
|
||||
case 0:
|
||||
return "unknown"
|
||||
case 1:
|
||||
return "IPv4"
|
||||
case 2:
|
||||
return "IPv6"
|
||||
}
|
||||
return strconv.FormatUint(uint64(v), 10)
|
||||
}
|
||||
|
||||
func decodeSflowSourceInterface(t uint32) string {
|
||||
switch t {
|
||||
case 0:
|
||||
return "in_snmp"
|
||||
case 1:
|
||||
return "in_vlan_id"
|
||||
case 2:
|
||||
return "in_phy_interface"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func decodeSflowHeaderProtocol(t uint32) string {
|
||||
switch t {
|
||||
case 1:
|
||||
return "ETHERNET-ISO8023"
|
||||
case 2:
|
||||
return "ISO88024-TOKENBUS"
|
||||
case 3:
|
||||
return "ISO88025-TOKENRING"
|
||||
case 4:
|
||||
return "FDDI"
|
||||
case 5:
|
||||
return "FRAME-RELAY"
|
||||
case 6:
|
||||
return "X25"
|
||||
case 7:
|
||||
return "PPP"
|
||||
case 8:
|
||||
return "SMDS"
|
||||
case 9:
|
||||
return "AAL5"
|
||||
case 10:
|
||||
return "AAL5-IP"
|
||||
case 11:
|
||||
return "IPv4"
|
||||
case 12:
|
||||
return "IPv6"
|
||||
case 13:
|
||||
return "MPLS"
|
||||
}
|
||||
return "unassigned"
|
||||
}
|
||||
|
||||
func decodeByteFunc(idx int) decoderFunc {
|
||||
return func(b []byte) (interface{}, error) { return b[idx], nil }
|
||||
}
|
466
plugins/inputs/netflow/type_conversion_test.go
Normal file
466
plugins/inputs/netflow/type_conversion_test.go
Normal file
|
@ -0,0 +1,466 @@
|
|||
package netflow
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
func TestDecodeInt32(t *testing.T) {
|
||||
buf := []byte{0x82, 0xad, 0x80, 0x86}
|
||||
v, err := decodeInt(buf)
|
||||
require.NoError(t, err)
|
||||
out, ok := v.(int64)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, int64(-2102558586), out)
|
||||
}
|
||||
|
||||
func TestDecodeUint(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in []byte
|
||||
expected uint64
|
||||
}{
|
||||
{
|
||||
name: "uint8",
|
||||
in: []byte{0x42},
|
||||
expected: 66,
|
||||
},
|
||||
{
|
||||
name: "uint16",
|
||||
in: []byte{0x0A, 0x42},
|
||||
expected: 2626,
|
||||
},
|
||||
{
|
||||
name: "uint32",
|
||||
in: []byte{0x82, 0xad, 0x80, 0x86},
|
||||
expected: 2192408710,
|
||||
},
|
||||
{
|
||||
name: "uint64",
|
||||
in: []byte{0x00, 0x00, 0x23, 0x42, 0x8f, 0xad, 0x80, 0x86},
|
||||
expected: 38768785326214,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
v, err := decodeUint(tt.in)
|
||||
require.NoError(t, err)
|
||||
out, ok := v.(uint64)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, tt.expected, out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeUintInvalid(t *testing.T) {
|
||||
_, err := decodeUint([]byte{0x00, 0x00, 0x00})
|
||||
require.ErrorContains(t, err, "invalid length")
|
||||
}
|
||||
|
||||
func TestDecodeFloat64(t *testing.T) {
|
||||
buf := []byte{0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2e, 0xea}
|
||||
v, err := decodeFloat64(buf)
|
||||
require.NoError(t, err)
|
||||
out, ok := v.(float64)
|
||||
require.True(t, ok)
|
||||
require.InDelta(t, float64(3.14159265359), out, testutil.DefaultDelta)
|
||||
}
|
||||
|
||||
func TestDecodeBool(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in []byte
|
||||
expected interface{}
|
||||
}{
|
||||
{
|
||||
name: "zero",
|
||||
in: []byte{0x00},
|
||||
expected: uint8(0),
|
||||
},
|
||||
{
|
||||
name: "true",
|
||||
in: []byte{0x01},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "false",
|
||||
in: []byte{0x02},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "other",
|
||||
in: []byte{0x23},
|
||||
expected: uint8(35),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
out, err := decodeBool(tt.in)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.expected, out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeHex(t *testing.T) {
|
||||
buf := []byte{0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2e, 0xea}
|
||||
v, err := decodeHex(buf)
|
||||
require.NoError(t, err)
|
||||
out, ok := v.(string)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, "0x400921fb54442eea", out)
|
||||
}
|
||||
|
||||
func TestDecodeString(t *testing.T) {
|
||||
buf := []byte{0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x74, 0x65, 0x6c, 0x65, 0x67, 0x72, 0x61, 0x66}
|
||||
v, err := decodeString(buf)
|
||||
require.NoError(t, err)
|
||||
out, ok := v.(string)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, "hello telegraf", out)
|
||||
}
|
||||
|
||||
func TestDecodeMAC(t *testing.T) {
|
||||
buf := []byte{0x2c, 0xf0, 0x5d, 0xe9, 0x04, 0x42}
|
||||
v, err := decodeMAC(buf)
|
||||
require.NoError(t, err)
|
||||
out, ok := v.(string)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, "2c:f0:5d:e9:04:42", out)
|
||||
}
|
||||
|
||||
func TestDecodeIP(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in []byte
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "localhost IPv4",
|
||||
in: []byte{0x7f, 0x00, 0x00, 0x01},
|
||||
expected: "127.0.0.1",
|
||||
},
|
||||
{
|
||||
name: "unrouted IPv4",
|
||||
in: []byte{0xc0, 0xa8, 0x04, 0x42},
|
||||
expected: "192.168.4.66",
|
||||
},
|
||||
{
|
||||
name: "localhost IPv6",
|
||||
in: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
expected: "::1",
|
||||
},
|
||||
{
|
||||
name: "local network IPv6",
|
||||
in: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, 0xd6, 0x8e, 0x07, 0x7f, 0x59, 0x5a, 0x23, 0xf1},
|
||||
expected: "::fe80:d68e:77f:595a:23f1",
|
||||
},
|
||||
{
|
||||
name: "google.com IPv6",
|
||||
in: []byte{0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x14, 0x50, 0x40, 0x01, 0x08, 0x11, 0x00, 0x00, 0x20, 0x0e},
|
||||
expected: "::2a00:1450:4001:811:0:200e",
|
||||
},
|
||||
{
|
||||
name: "stripped in between IPv6",
|
||||
in: []byte{0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x50, 0x40, 0x01, 0x08, 0x11, 0x00, 0x01, 0x20, 0x0e},
|
||||
expected: "2a00::1450:4001:811:1:200e",
|
||||
},
|
||||
{
|
||||
name: "IPv6 not enough bytes",
|
||||
in: []byte{0x00, 0x00, 0x00, 0xff, 0x00, 0x01},
|
||||
expected: "?000000ff0001",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
v, err := decodeIP(tt.in)
|
||||
require.NoError(t, err)
|
||||
out, ok := v.(string)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, tt.expected, out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeIPFromUint32(t *testing.T) {
|
||||
in := uint32(0x7f000001)
|
||||
v, err := decodeIPFromUint32(in)
|
||||
require.NoError(t, err)
|
||||
out, ok := v.(string)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, "127.0.0.1", out)
|
||||
}
|
||||
|
||||
func TestDecodeLayer4ProtocolNumber(t *testing.T) {
|
||||
require.NoError(t, initL4ProtoMapping())
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
in []byte
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "ICMP 1",
|
||||
in: []byte{0x01},
|
||||
expected: "icmp",
|
||||
},
|
||||
{
|
||||
name: "IPv4 4",
|
||||
in: []byte{0x04},
|
||||
expected: "ipv4",
|
||||
},
|
||||
{
|
||||
name: "IPv6 41",
|
||||
in: []byte{0x29},
|
||||
expected: "ipv6",
|
||||
},
|
||||
{
|
||||
name: "L2TP 115",
|
||||
in: []byte{0x73},
|
||||
expected: "l2tp",
|
||||
},
|
||||
{
|
||||
name: "PTP 123",
|
||||
in: []byte{0x7b},
|
||||
expected: "ptp",
|
||||
},
|
||||
{
|
||||
name: "unassigned 201",
|
||||
in: []byte{0xc9},
|
||||
expected: "201",
|
||||
},
|
||||
{
|
||||
name: "experimental 254",
|
||||
in: []byte{0xfe},
|
||||
expected: "experimental",
|
||||
},
|
||||
{
|
||||
name: "Reserved 255",
|
||||
in: []byte{0xff},
|
||||
expected: "reserved",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
v, err := decodeL4Proto(tt.in)
|
||||
require.NoError(t, err)
|
||||
out, ok := v.(string)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, tt.expected, out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeIPv4Options(t *testing.T) {
|
||||
require.NoError(t, initIPv4OptionMapping())
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
bits []int
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "none",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "all",
|
||||
bits: []int{
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31,
|
||||
},
|
||||
expected: "EOOL,NOP,SEC,LSR,TS,E-SEC,CIPSO,RR,SID,SSR,ZSU,MTUP," +
|
||||
"MTUR,FINN,VISA,ENCODE,IMITD,EIP,TR,ADDEXT,RTRALT,SDB," +
|
||||
"UA22,DPS,UMP,QS,UA26,UA27,UA28,UA29,EXP,UA31",
|
||||
},
|
||||
{
|
||||
name: "EOOL",
|
||||
bits: []int{0},
|
||||
expected: "EOOL",
|
||||
},
|
||||
{
|
||||
name: "SSR",
|
||||
bits: []int{9},
|
||||
expected: "SSR",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var options uint32
|
||||
for _, bit := range tt.bits {
|
||||
options |= 1 << bit
|
||||
}
|
||||
in := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(in, options)
|
||||
|
||||
v, err := decodeIPv4Options(in)
|
||||
require.NoError(t, err)
|
||||
out, ok := v.(string)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, tt.expected, out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeTCPFlags(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
bits []int
|
||||
expected string
|
||||
ipfix bool
|
||||
}{
|
||||
{
|
||||
name: "none",
|
||||
expected: "........",
|
||||
},
|
||||
{
|
||||
name: "none IPFIX",
|
||||
expected: "................",
|
||||
ipfix: true,
|
||||
},
|
||||
{
|
||||
name: "all",
|
||||
bits: []int{0, 1, 2, 3, 4, 5, 6, 7},
|
||||
expected: "CEUAPRSF",
|
||||
},
|
||||
{
|
||||
name: "all IPFIX",
|
||||
bits: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
expected: "********CEUAPRSF",
|
||||
ipfix: true,
|
||||
},
|
||||
{
|
||||
name: "SYN",
|
||||
bits: []int{1},
|
||||
expected: "......S.",
|
||||
},
|
||||
{
|
||||
name: "SYN/ACK",
|
||||
bits: []int{1, 4},
|
||||
expected: "...A..S.",
|
||||
},
|
||||
{
|
||||
name: "ACK",
|
||||
bits: []int{4},
|
||||
expected: "...A....",
|
||||
},
|
||||
{
|
||||
name: "FIN",
|
||||
bits: []int{0},
|
||||
expected: ".......F",
|
||||
},
|
||||
{
|
||||
name: "FIN/ACK",
|
||||
bits: []int{0, 4},
|
||||
expected: "...A...F",
|
||||
},
|
||||
{
|
||||
name: "ACK IPFIX",
|
||||
bits: []int{4},
|
||||
expected: "...........A....",
|
||||
ipfix: true,
|
||||
},
|
||||
{
|
||||
name: "FIN IPFIX",
|
||||
bits: []int{0},
|
||||
expected: "...............F",
|
||||
ipfix: true,
|
||||
},
|
||||
{
|
||||
name: "ECN Nounce Sum IPFIX",
|
||||
bits: []int{8},
|
||||
expected: ".......*........",
|
||||
ipfix: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var in []byte
|
||||
|
||||
if tt.ipfix {
|
||||
var options uint16
|
||||
for _, bit := range tt.bits {
|
||||
options |= 1 << bit
|
||||
}
|
||||
in = make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(in, options)
|
||||
} else {
|
||||
var options uint8
|
||||
for _, bit := range tt.bits {
|
||||
options |= 1 << bit
|
||||
}
|
||||
in = []byte{options}
|
||||
}
|
||||
v, err := decodeTCPFlags(in)
|
||||
require.NoError(t, err)
|
||||
out, ok := v.(string)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, tt.expected, out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeFragmentFlags(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
bits []int
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "none",
|
||||
expected: "........",
|
||||
},
|
||||
{
|
||||
name: "all",
|
||||
bits: []int{0, 1, 2, 3, 4, 5, 6, 7},
|
||||
expected: "RDM*****",
|
||||
},
|
||||
{
|
||||
name: "RS",
|
||||
bits: []int{7},
|
||||
expected: "R.......",
|
||||
},
|
||||
{
|
||||
name: "DF",
|
||||
bits: []int{6},
|
||||
expected: ".D......",
|
||||
},
|
||||
{
|
||||
name: "MF",
|
||||
bits: []int{5},
|
||||
expected: "..M.....",
|
||||
},
|
||||
{
|
||||
name: "Bit 7 (LSB)",
|
||||
bits: []int{0},
|
||||
expected: ".......*",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var flags uint8
|
||||
for _, bit := range tt.bits {
|
||||
flags |= 1 << bit
|
||||
}
|
||||
in := []byte{flags}
|
||||
v, err := decodeFragmentFlags(in)
|
||||
require.NoError(t, err)
|
||||
out, ok := v.(string)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, tt.expected, out)
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue