Skip to content

gravwell/sflow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sFlow

Go library for decoding sFlow v5 datagrams.

Getting started

The decoder takes any io.Reader containing a raw sFlow v5 packet and returns the parsed structure, or an error:

decoder := sflow.NewDecoder(reader)
dgram, err := decoder.Decode()
// dgram contains Version, AgentIP, Samples, etc.
// Each sample (FlowSample, CounterSample, ...) contains typed Records.

Trying it out

A simple way to test out the decoder is by running host-sflow through Docker:

docker run --rm \
  -e "COLLECTOR=127.0.0.1" \
  -e "NET=host" \
  --net=host \
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
  sflow/host-sflow

host-sflow will now send UDP packets from your host traffic to port 6343. We provide a simple example in this repo that will listen on the same port, decode them and print them to stdout. To test it out, in another terminal, run:

go run github.com/gravwell/sflow/example

Which will produce output similar to this:

2026/02/19 14:27:32 [OK] Packet #1 from 127.0.0.1:43439: Version:5 IPVersion:1 AgentIP:10.0.0.134 SubAgentID:100000 SequenceNumber:55 Uptime:1642041 SamplesCount:1
2026/02/19 14:27:32   Sample[0] CounterSampleExpanded: Format:4 Length:760 SequenceNum:55 SourceIDType:2 SourceIDIndex:1 RecordCount:11
2026/02/19 14:27:32     Record[0] *datagram.VirtNode: &{RecordHeader:{Format:2100 Length:28} Mhz:2500 CPUs:24 Memory:58588684288 MemoryFree:16246149120 NumDomains:0}
2026/02/19 14:27:32     Record[1] *datagram.HostAdapters: &{RecordHeader:{Format:2001 Length:68} Adapters:[{IFIndex:6 MACAddresses:[[200 163 98 18 192 115 0 0]]} ...]}
2026/02/19 14:27:32     Record[2] *datagram.MIB2UDPGroup: &{RecordHeader:{Format:2010 Length:28} UDPInDatagrams:6369235 UDPNoPorts:3190 UDPInErrors:2511 UDPOutDatagrams:8229427 UDPRcvbufErrors:2}
...

Implementation Status

All sample containers (FlowSample, CounterSample, FlowSampleExpanded, CounterSampleExpanded, DiscardedPacket) are implemented.

Legend: ✅ = implemented, ✅✅ = implemented with test coverage, ❌ = not implemented

Counter Records (Enterprise = 0)

Format Structure Status
1 if_counters
2 ethernet_counters
3 tokenring_counters
4 vg_counters
5 vlan_counters
6 ieee80211_counters
7 lag_port_stats
8 slow_path_counts
9 ib_counters
10 sfp
1001 processor
1002 radio_utilization
1003 queue_length
1004 of_port
1005 port_name ✅✅
2000 host_descr ✅✅
2001 host_adapters ✅✅
2002 host_parent ✅✅
2003 host_cpu ✅✅
2004 host_memory ✅✅
2005 host_disk_io ✅✅
2006 host_net_io ✅✅
2007 mib2_ip_group ✅✅
2008 mib2_icmp_group ✅✅
2009 mib2_tcp_group ✅✅
2010 mib2_udp_group ✅✅
2100 virt_node ✅✅
2101 virt_cpu ✅✅
2102 virt_memory ✅✅
2103 virt_disk_io ✅✅
2104 virt_net_io ✅✅
2105 jmx_runtime
2106 jmx_statistics
2200 memcached_counters
2201 http_counters
2202 app_operations
2203 app_resources
2204 memcache_counters
2206 app_workers
2207 ovs_dp_stats
3000 energy
3001 temperature
3002 humidity
3003 fans

Flow Records (Enterprise = 0)

Format Structure Status
1 sampled_header ✅✅
2 sampled_ethernet
3 sampled_ipv4
4 sampled_ipv6
1001 extended_switch ✅✅
1002 extended_router
1003 extended_gateway
1004 extended_user
1005 extended_url
1006 extended_mpls
1007 extended_nat
1008 extended_mpls_tunnel
1009 extended_mpls_vc
1010 extended_mpls_FTN
1011 extended_mpls_LDP_FEC
1012 extended_vlantunnel
1013 extended_80211_payload
1014 extended_80211_rx
1015 extended_80211_tx
1016 extended_80211_aggregation
1017 extended_openflow_v1
1018 extended_fcs
1019 extended_queue_length
1020 extended_nat_ports
1021 extended_L2_tunnel_egress
1022 extended_L2_tunnel_ingress
1023 extended_ipv4_tunnel_egress
1024 extended_ipv4_tunnel_ingress
1025 extended_ipv6_tunnel_egress
1026 extended_ipv6_tunnel_ingress
1027 extended_decapsulate_egress
1028 extended_decapsulate_ingress
1029 extended_vni_egress
1030 extended_vni_ingress
1031 extended_ib_lrh
1032 extended_ib_grh
1033 extended_ib_brh
1034 extended_vlanin
1035 extended_vlanout
1036 extended_egress_queue ✅✅
1037 extended_acl ✅✅
1038 extended_function ✅✅
1039 extended_transit
1040 extended_queue
1041 extended_hw_trap
1042 extended_linux_drop_reason ✅✅
1043 extended_timestamp
2000 transaction
2001 extended_nfs_storage_txn
2002 extended_scsi_storage_txn
2003 extended_http_transaction
2100 extended_socket_ipv4
2101 extended_socket_ipv6
2102 extended_proxy_socket_ipv4
2103 extended_proxy_socket_ipv6
2200 memcached_operations
2201 http_request
2202 app_operations
2203 app_parent_context
2204 app_initiators
2205 app_targets
2206 http_requests
2207 extended_proxy_request
2208 extended_nav_timing
2209 extended_tcp_info ✅✅
2210 extended_entities

Unknown sample formats decode as UnknownSample with raw data preserved. Unknown flow and counter record formats decode as UnknownRecord with raw data preserved. This allows the decoder to process datagrams containing unimplemented or vendor-specific structures without error.

Want a structure implemented or tested? Send us a raw sFlow packet capture containing it. PRs are welcome!

Architecture

  • sflow.go: Top-level API
  • datagram/: Low-level XDR types matching sFlow wire format
  • decoder/: Higher-level decoded types with proper Go field names
  • xdr/: RFC 4506 XDR encoding/decoding primitives
  • internal/cmd/testgen/: Utility for capturing live sFlow packets and generating test cases

Security

The decoder protects against OOM attacks by limiting datagrams to 65,536 bytes via io.LimitedReader and validating all count fields against remaining bytes before allocation.

Testing

The internal/cmd/testgen binary captures live sFlow packets as .bin files. Run sflowtool-ref.bash on the captured files to generate .json reference output from the official sflowtool (via Docker) for validation.

References

About

sFlow decoding in Go

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors