From ca6003af1a7e1adb7d45879c2d5038bc05c2bb1a Mon Sep 17 00:00:00 2001 From: Ondrej Fabry Date: Fri, 2 Aug 2019 15:07:53 +0200 Subject: Migrate to modules, refactor Makefile and use Travis for CI - migrate to Go modules and remove vendor - refactor Makefile - add version package and store version - split extras from the rest - use travis for CI Change-Id: I81b35220653b0f7c9a0fcdd4c527d691ec1e96c1 Signed-off-by: Ondrej Fabry --- vendor/github.com/google/gopacket/layers/sflow.go | 2187 --------------------- 1 file changed, 2187 deletions(-) delete mode 100644 vendor/github.com/google/gopacket/layers/sflow.go (limited to 'vendor/github.com/google/gopacket/layers/sflow.go') diff --git a/vendor/github.com/google/gopacket/layers/sflow.go b/vendor/github.com/google/gopacket/layers/sflow.go deleted file mode 100644 index 55ce31e..0000000 --- a/vendor/github.com/google/gopacket/layers/sflow.go +++ /dev/null @@ -1,2187 +0,0 @@ -// Copyright 2014 Google, Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. - -/* -This layer decodes SFlow version 5 datagrams. - -The specification can be found here: http://sflow.org/sflow_version_5.txt - -Additional developer information about sflow can be found at: -http://sflow.org/developers/specifications.php - -And SFlow in general: -http://sflow.org/index.php - -Two forms of sample data are defined: compact and expanded. The -Specification has this to say: - - Compact and expand forms of counter and flow samples are defined. - An agent must not mix compact/expanded encodings. If an agent - will never use ifIndex numbers >= 2^24 then it must use compact - encodings for all interfaces. Otherwise the expanded formats must - be used for all interfaces. - -This decoder only supports the compact form, because that is the only -one for which data was avaialble. - -The datagram is composed of one or more samples of type flow or counter, -and each sample is composed of one or more records describing the sample. -A sample is a single instance of sampled inforamtion, and each record in -the sample gives additional / supplimentary information about the sample. - -The following sample record types are supported: - - Raw Packet Header - opaque = flow_data; enterprise = 0; format = 1 - - Extended Switch Data - opaque = flow_data; enterprise = 0; format = 1001 - - Extended Router Data - opaque = flow_data; enterprise = 0; format = 1002 - - Extended Gateway Data - opaque = flow_data; enterprise = 0; format = 1003 - - Extended User Data - opaque = flow_data; enterprise = 0; format = 1004 - - Extended URL Data - opaque = flow_data; enterprise = 0; format = 1005 - -The following types of counter records are supported: - - Generic Interface Counters - see RFC 2233 - opaque = counter_data; enterprise = 0; format = 1 - - Ethernet Interface Counters - see RFC 2358 - opaque = counter_data; enterprise = 0; format = 2 - -SFlow is encoded using XDR (RFC4506). There are a few places -where the standard 4-byte fields are partitioned into two -bitfields of different lengths. I'm not sure why the designers -chose to pack together two values like this in some places, and -in others they use the entire 4-byte value to store a number that -will never be more than a few bits. In any case, there are a couple -of types defined to handle the decoding of these bitfields, and -that's why they're there. */ - -package layers - -import ( - "encoding/binary" - "errors" - "fmt" - "net" - - "github.com/google/gopacket" -) - -// SFlowRecord holds both flow sample records and counter sample records. -// A Record is the structure that actually holds the sampled data -// and / or counters. -type SFlowRecord interface { -} - -// SFlowDataSource encodes a 2-bit SFlowSourceFormat in its most significant -// 2 bits, and an SFlowSourceValue in its least significant 30 bits. -// These types and values define the meaning of the inteface information -// presented in the sample metadata. -type SFlowDataSource int32 - -func (sdc SFlowDataSource) decode() (SFlowSourceFormat, SFlowSourceValue) { - leftField := sdc >> 30 - rightField := uint32(0x3FFFFFFF) & uint32(sdc) - return SFlowSourceFormat(leftField), SFlowSourceValue(rightField) -} - -type SFlowDataSourceExpanded struct { - SourceIDClass SFlowSourceFormat - SourceIDIndex SFlowSourceValue -} - -func (sdce SFlowDataSourceExpanded) decode() (SFlowSourceFormat, SFlowSourceValue) { - leftField := sdce.SourceIDClass >> 30 - rightField := uint32(0x3FFFFFFF) & uint32(sdce.SourceIDIndex) - return SFlowSourceFormat(leftField), SFlowSourceValue(rightField) -} - -type SFlowSourceFormat uint32 - -type SFlowSourceValue uint32 - -const ( - SFlowTypeSingleInterface SFlowSourceFormat = 0 - SFlowTypePacketDiscarded SFlowSourceFormat = 1 - SFlowTypeMultipleDestinations SFlowSourceFormat = 2 -) - -func (sdf SFlowSourceFormat) String() string { - switch sdf { - case SFlowTypeSingleInterface: - return "Single Interface" - case SFlowTypePacketDiscarded: - return "Packet Discarded" - case SFlowTypeMultipleDestinations: - return "Multiple Destinations" - default: - return "UNKNOWN" - } -} - -func decodeSFlow(data []byte, p gopacket.PacketBuilder) error { - s := &SFlowDatagram{} - err := s.DecodeFromBytes(data, p) - if err != nil { - return err - } - p.AddLayer(s) - p.SetApplicationLayer(s) - return nil -} - -// SFlowDatagram is the outermost container which holds some basic information -// about the reporting agent, and holds at least one sample record -type SFlowDatagram struct { - BaseLayer - - DatagramVersion uint32 - AgentAddress net.IP - SubAgentID uint32 - SequenceNumber uint32 - AgentUptime uint32 - SampleCount uint32 - FlowSamples []SFlowFlowSample - CounterSamples []SFlowCounterSample -} - -// An SFlow datagram's outer container has the following -// structure: - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int sFlow version (2|4|5) | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int IP version of the Agent (1=v4|2=v6) | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / Agent IP address (v4=4byte|v6=16byte) / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int sub agent id | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int datagram sequence number | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int switch uptime in ms | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int n samples in datagram | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / n samples / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -// SFlowDataFormat encodes the EnterpriseID in the most -// significant 12 bits, and the SampleType in the least significant -// 20 bits. -type SFlowDataFormat uint32 - -func (sdf SFlowDataFormat) decode() (SFlowEnterpriseID, SFlowSampleType) { - leftField := sdf >> 12 - rightField := uint32(0xFFF) & uint32(sdf) - return SFlowEnterpriseID(leftField), SFlowSampleType(rightField) -} - -// SFlowEnterpriseID is used to differentiate between the -// official SFlow standard, and other, vendor-specific -// types of flow data. (Similiar to SNMP's enterprise MIB -// OIDs) Only the office SFlow Enterprise ID is decoded -// here. -type SFlowEnterpriseID uint32 - -const ( - SFlowStandard SFlowEnterpriseID = 0 -) - -func (eid SFlowEnterpriseID) String() string { - switch eid { - case SFlowStandard: - return "Standard SFlow" - default: - return "" - } -} - -func (eid SFlowEnterpriseID) GetType() SFlowEnterpriseID { - return SFlowStandard -} - -// SFlowSampleType specifies the type of sample. Only flow samples -// and counter samples are supported -type SFlowSampleType uint32 - -const ( - SFlowTypeFlowSample SFlowSampleType = 1 - SFlowTypeCounterSample SFlowSampleType = 2 - SFlowTypeExpandedFlowSample SFlowSampleType = 3 - SFlowTypeExpandedCounterSample SFlowSampleType = 4 -) - -func (st SFlowSampleType) GetType() SFlowSampleType { - switch st { - case SFlowTypeFlowSample: - return SFlowTypeFlowSample - case SFlowTypeCounterSample: - return SFlowTypeCounterSample - case SFlowTypeExpandedFlowSample: - return SFlowTypeExpandedFlowSample - case SFlowTypeExpandedCounterSample: - return SFlowTypeExpandedCounterSample - default: - panic("Invalid Sample Type") - } -} - -func (st SFlowSampleType) String() string { - switch st { - case SFlowTypeFlowSample: - return "Flow Sample" - case SFlowTypeCounterSample: - return "Counter Sample" - case SFlowTypeExpandedFlowSample: - return "Expanded Flow Sample" - case SFlowTypeExpandedCounterSample: - return "Expanded Counter Sample" - default: - return "" - } -} - -func (s *SFlowDatagram) LayerType() gopacket.LayerType { return LayerTypeSFlow } - -func (d *SFlowDatagram) Payload() []byte { return nil } - -func (d *SFlowDatagram) CanDecode() gopacket.LayerClass { return LayerTypeSFlow } - -func (d *SFlowDatagram) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload } - -// SFlowIPType determines what form the IP address being decoded will -// take. This is an XDR union type allowing for both IPv4 and IPv6 -type SFlowIPType uint32 - -const ( - SFlowIPv4 SFlowIPType = 1 - SFlowIPv6 SFlowIPType = 2 -) - -func (s SFlowIPType) String() string { - switch s { - case SFlowIPv4: - return "IPv4" - case SFlowIPv6: - return "IPv6" - default: - return "" - } -} - -func (s SFlowIPType) Length() int { - switch s { - case SFlowIPv4: - return 4 - case SFlowIPv6: - return 16 - default: - return 0 - } -} - -func (s *SFlowDatagram) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { - var agentAddressType SFlowIPType - - data, s.DatagramVersion = data[4:], binary.BigEndian.Uint32(data[:4]) - data, agentAddressType = data[4:], SFlowIPType(binary.BigEndian.Uint32(data[:4])) - data, s.AgentAddress = data[agentAddressType.Length():], data[:agentAddressType.Length()] - data, s.SubAgentID = data[4:], binary.BigEndian.Uint32(data[:4]) - data, s.SequenceNumber = data[4:], binary.BigEndian.Uint32(data[:4]) - data, s.AgentUptime = data[4:], binary.BigEndian.Uint32(data[:4]) - data, s.SampleCount = data[4:], binary.BigEndian.Uint32(data[:4]) - - if s.SampleCount < 1 { - return fmt.Errorf("SFlow Datagram has invalid sample length: %d", s.SampleCount) - } - for i := uint32(0); i < s.SampleCount; i++ { - sdf := SFlowDataFormat(binary.BigEndian.Uint32(data[:4])) - _, sampleType := sdf.decode() - switch sampleType { - case SFlowTypeFlowSample: - if flowSample, err := decodeFlowSample(&data, false); err == nil { - s.FlowSamples = append(s.FlowSamples, flowSample) - } else { - return err - } - case SFlowTypeCounterSample: - if counterSample, err := decodeCounterSample(&data, false); err == nil { - s.CounterSamples = append(s.CounterSamples, counterSample) - } else { - return err - } - case SFlowTypeExpandedFlowSample: - if flowSample, err := decodeFlowSample(&data, true); err == nil { - s.FlowSamples = append(s.FlowSamples, flowSample) - } else { - return err - } - case SFlowTypeExpandedCounterSample: - if counterSample, err := decodeCounterSample(&data, true); err == nil { - s.CounterSamples = append(s.CounterSamples, counterSample) - } else { - return err - } - - default: - return fmt.Errorf("Unsupported SFlow sample type %d", sampleType) - } - } - return nil -} - -// SFlowFlowSample represents a sampled packet and contains -// one or more records describing the packet -type SFlowFlowSample struct { - EnterpriseID SFlowEnterpriseID - Format SFlowSampleType - SampleLength uint32 - SequenceNumber uint32 - SourceIDClass SFlowSourceFormat - SourceIDIndex SFlowSourceValue - SamplingRate uint32 - SamplePool uint32 - Dropped uint32 - InputInterfaceFormat uint32 - InputInterface uint32 - OutputInterfaceFormat uint32 - OutputInterface uint32 - RecordCount uint32 - Records []SFlowRecord -} - -// Flow samples have the following structure. Note -// the bit fields to encode the Enterprise ID and the -// Flow record format: type 1 - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | sample length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int sample sequence number | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// |id type | src id index value | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int sampling rate | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int sample pool | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int drops | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int input ifIndex | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int output ifIndex | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int number of records | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / flow records / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -// Flow samples have the following structure. -// Flow record format: type 3 - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | sample length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int sample sequence number | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int src id type | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int src id index value | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int sampling rate | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int sample pool | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int drops | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int input interface format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int input interface value | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int output interface format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int output interface value | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int number of records | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / flow records / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -type SFlowFlowDataFormat uint32 - -func (fdf SFlowFlowDataFormat) decode() (SFlowEnterpriseID, SFlowFlowRecordType) { - leftField := fdf >> 12 - rightField := uint32(0xFFF) & uint32(fdf) - return SFlowEnterpriseID(leftField), SFlowFlowRecordType(rightField) -} - -func (fs SFlowFlowSample) GetRecords() []SFlowRecord { - return fs.Records -} - -func (fs SFlowFlowSample) GetType() SFlowSampleType { - return SFlowTypeFlowSample -} - -func skipRecord(data *[]byte) { - recordLength := int(binary.BigEndian.Uint32((*data)[4:])) - *data = (*data)[(recordLength+((4-recordLength)%4))+8:] -} - -func decodeFlowSample(data *[]byte, expanded bool) (SFlowFlowSample, error) { - s := SFlowFlowSample{} - var sdf SFlowDataFormat - *data, sdf = (*data)[4:], SFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - var sdc SFlowDataSource - - s.EnterpriseID, s.Format = sdf.decode() - *data, s.SampleLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, s.SequenceNumber = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - if expanded { - *data, s.SourceIDClass = (*data)[4:], SFlowSourceFormat(binary.BigEndian.Uint32((*data)[:4])) - *data, s.SourceIDIndex = (*data)[4:], SFlowSourceValue(binary.BigEndian.Uint32((*data)[:4])) - } else { - *data, sdc = (*data)[4:], SFlowDataSource(binary.BigEndian.Uint32((*data)[:4])) - s.SourceIDClass, s.SourceIDIndex = sdc.decode() - } - *data, s.SamplingRate = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, s.SamplePool = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, s.Dropped = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - - if expanded { - *data, s.InputInterfaceFormat = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, s.InputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, s.OutputInterfaceFormat = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, s.OutputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - } else { - *data, s.InputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, s.OutputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - } - *data, s.RecordCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - - for i := uint32(0); i < s.RecordCount; i++ { - rdf := SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - _, flowRecordType := rdf.decode() - - switch flowRecordType { - case SFlowTypeRawPacketFlow: - if record, err := decodeRawPacketFlowRecord(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedUserFlow: - if record, err := decodeExtendedUserFlow(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedUrlFlow: - if record, err := decodeExtendedURLRecord(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedSwitchFlow: - if record, err := decodeExtendedSwitchFlowRecord(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedRouterFlow: - if record, err := decodeExtendedRouterFlowRecord(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedGatewayFlow: - if record, err := decodeExtendedGatewayFlowRecord(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeEthernetFrameFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeEthernetFrameFlow") - case SFlowTypeIpv4Flow: - if record, err := decodeSFlowIpv4Record(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeIpv6Flow: - if record, err := decodeSFlowIpv6Record(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedMlpsFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeExtendedMlpsFlow") - case SFlowTypeExtendedNatFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeExtendedNatFlow") - case SFlowTypeExtendedMlpsTunnelFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeExtendedMlpsTunnelFlow") - case SFlowTypeExtendedMlpsVcFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeExtendedMlpsVcFlow") - case SFlowTypeExtendedMlpsFecFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeExtendedMlpsFecFlow") - case SFlowTypeExtendedMlpsLvpFecFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeExtendedMlpsLvpFecFlow") - case SFlowTypeExtendedVlanFlow: - // TODO - skipRecord(data) - return s, errors.New("skipping TypeExtendedVlanFlow") - case SFlowTypeExtendedIpv4TunnelEgressFlow: - if record, err := decodeExtendedIpv4TunnelEgress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedIpv4TunnelIngressFlow: - if record, err := decodeExtendedIpv4TunnelIngress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedIpv6TunnelEgressFlow: - if record, err := decodeExtendedIpv6TunnelEgress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedIpv6TunnelIngressFlow: - if record, err := decodeExtendedIpv6TunnelIngress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedDecapsulateEgressFlow: - if record, err := decodeExtendedDecapsulateEgress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedDecapsulateIngressFlow: - if record, err := decodeExtendedDecapsulateIngress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedVniEgressFlow: - if record, err := decodeExtendedVniEgress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeExtendedVniIngressFlow: - if record, err := decodeExtendedVniIngress(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - default: - return s, fmt.Errorf("Unsupported flow record type: %d", flowRecordType) - } - } - return s, nil -} - -// Counter samples report information about various counter -// objects. Typically these are items like IfInOctets, or -// CPU / Memory stats, etc. SFlow will report these at regular -// intervals as configured on the agent. If one were sufficiently -// industrious, this could be used to replace the typical -// SNMP polling used for such things. -type SFlowCounterSample struct { - EnterpriseID SFlowEnterpriseID - Format SFlowSampleType - SampleLength uint32 - SequenceNumber uint32 - SourceIDClass SFlowSourceFormat - SourceIDIndex SFlowSourceValue - RecordCount uint32 - Records []SFlowRecord -} - -// Counter samples have the following structure: - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int sample sequence number | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// |id type | src id index value | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | int number of records | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / counter records / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -type SFlowCounterDataFormat uint32 - -func (cdf SFlowCounterDataFormat) decode() (SFlowEnterpriseID, SFlowCounterRecordType) { - leftField := cdf >> 12 - rightField := uint32(0xFFF) & uint32(cdf) - return SFlowEnterpriseID(leftField), SFlowCounterRecordType(rightField) -} - -// GetRecords will return a slice of interface types -// representing records. A type switch can be used to -// get at the underlying SFlowCounterRecordType. -func (cs SFlowCounterSample) GetRecords() []SFlowRecord { - return cs.Records -} - -// GetType will report the type of sample. Only the -// compact form of counter samples is supported -func (cs SFlowCounterSample) GetType() SFlowSampleType { - return SFlowTypeCounterSample -} - -type SFlowCounterRecordType uint32 - -const ( - SFlowTypeGenericInterfaceCounters SFlowCounterRecordType = 1 - SFlowTypeEthernetInterfaceCounters SFlowCounterRecordType = 2 - SFlowTypeTokenRingInterfaceCounters SFlowCounterRecordType = 3 - SFlowType100BaseVGInterfaceCounters SFlowCounterRecordType = 4 - SFlowTypeVLANCounters SFlowCounterRecordType = 5 - SFlowTypeProcessorCounters SFlowCounterRecordType = 1001 -) - -func (cr SFlowCounterRecordType) String() string { - switch cr { - case SFlowTypeGenericInterfaceCounters: - return "Generic Interface Counters" - case SFlowTypeEthernetInterfaceCounters: - return "Ethernet Interface Counters" - case SFlowTypeTokenRingInterfaceCounters: - return "Token Ring Interface Counters" - case SFlowType100BaseVGInterfaceCounters: - return "100BaseVG Interface Counters" - case SFlowTypeVLANCounters: - return "VLAN Counters" - case SFlowTypeProcessorCounters: - return "Processor Counters" - default: - return "" - - } -} - -func decodeCounterSample(data *[]byte, expanded bool) (SFlowCounterSample, error) { - s := SFlowCounterSample{} - var sdc SFlowDataSource - var sdce SFlowDataSourceExpanded - var sdf SFlowDataFormat - - *data, sdf = (*data)[4:], SFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - s.EnterpriseID, s.Format = sdf.decode() - *data, s.SampleLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, s.SequenceNumber = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - if expanded { - *data, sdce = (*data)[8:], SFlowDataSourceExpanded{SFlowSourceFormat(binary.BigEndian.Uint32((*data)[:4])), SFlowSourceValue(binary.BigEndian.Uint32((*data)[4:8]))} - s.SourceIDClass, s.SourceIDIndex = sdce.decode() - } else { - *data, sdc = (*data)[4:], SFlowDataSource(binary.BigEndian.Uint32((*data)[:4])) - s.SourceIDClass, s.SourceIDIndex = sdc.decode() - } - *data, s.RecordCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - - for i := uint32(0); i < s.RecordCount; i++ { - cdf := SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) - _, counterRecordType := cdf.decode() - switch counterRecordType { - case SFlowTypeGenericInterfaceCounters: - if record, err := decodeGenericInterfaceCounters(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeEthernetInterfaceCounters: - if record, err := decodeEthernetCounters(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - case SFlowTypeTokenRingInterfaceCounters: - skipRecord(data) - return s, errors.New("skipping TypeTokenRingInterfaceCounters") - case SFlowType100BaseVGInterfaceCounters: - skipRecord(data) - return s, errors.New("skipping Type100BaseVGInterfaceCounters") - case SFlowTypeVLANCounters: - skipRecord(data) - return s, errors.New("skipping TypeVLANCounters") - case SFlowTypeProcessorCounters: - if record, err := decodeProcessorCounters(data); err == nil { - s.Records = append(s.Records, record) - } else { - return s, err - } - default: - return s, fmt.Errorf("Invalid counter record type: %d", counterRecordType) - } - } - return s, nil -} - -// SFlowBaseFlowRecord holds the fields common to all records -// of type SFlowFlowRecordType -type SFlowBaseFlowRecord struct { - EnterpriseID SFlowEnterpriseID - Format SFlowFlowRecordType - FlowDataLength uint32 -} - -func (bfr SFlowBaseFlowRecord) GetType() SFlowFlowRecordType { - return bfr.Format -} - -// SFlowFlowRecordType denotes what kind of Flow Record is -// represented. See RFC 3176 -type SFlowFlowRecordType uint32 - -const ( - SFlowTypeRawPacketFlow SFlowFlowRecordType = 1 - SFlowTypeEthernetFrameFlow SFlowFlowRecordType = 2 - SFlowTypeIpv4Flow SFlowFlowRecordType = 3 - SFlowTypeIpv6Flow SFlowFlowRecordType = 4 - SFlowTypeExtendedSwitchFlow SFlowFlowRecordType = 1001 - SFlowTypeExtendedRouterFlow SFlowFlowRecordType = 1002 - SFlowTypeExtendedGatewayFlow SFlowFlowRecordType = 1003 - SFlowTypeExtendedUserFlow SFlowFlowRecordType = 1004 - SFlowTypeExtendedUrlFlow SFlowFlowRecordType = 1005 - SFlowTypeExtendedMlpsFlow SFlowFlowRecordType = 1006 - SFlowTypeExtendedNatFlow SFlowFlowRecordType = 1007 - SFlowTypeExtendedMlpsTunnelFlow SFlowFlowRecordType = 1008 - SFlowTypeExtendedMlpsVcFlow SFlowFlowRecordType = 1009 - SFlowTypeExtendedMlpsFecFlow SFlowFlowRecordType = 1010 - SFlowTypeExtendedMlpsLvpFecFlow SFlowFlowRecordType = 1011 - SFlowTypeExtendedVlanFlow SFlowFlowRecordType = 1012 - SFlowTypeExtendedIpv4TunnelEgressFlow SFlowFlowRecordType = 1023 - SFlowTypeExtendedIpv4TunnelIngressFlow SFlowFlowRecordType = 1024 - SFlowTypeExtendedIpv6TunnelEgressFlow SFlowFlowRecordType = 1025 - SFlowTypeExtendedIpv6TunnelIngressFlow SFlowFlowRecordType = 1026 - SFlowTypeExtendedDecapsulateEgressFlow SFlowFlowRecordType = 1027 - SFlowTypeExtendedDecapsulateIngressFlow SFlowFlowRecordType = 1028 - SFlowTypeExtendedVniEgressFlow SFlowFlowRecordType = 1029 - SFlowTypeExtendedVniIngressFlow SFlowFlowRecordType = 1030 -) - -func (rt SFlowFlowRecordType) String() string { - switch rt { - case SFlowTypeRawPacketFlow: - return "Raw Packet Flow Record" - case SFlowTypeEthernetFrameFlow: - return "Ethernet Frame Flow Record" - case SFlowTypeIpv4Flow: - return "IPv4 Flow Record" - case SFlowTypeIpv6Flow: - return "IPv6 Flow Record" - case SFlowTypeExtendedSwitchFlow: - return "Extended Switch Flow Record" - case SFlowTypeExtendedRouterFlow: - return "Extended Router Flow Record" - case SFlowTypeExtendedGatewayFlow: - return "Extended Gateway Flow Record" - case SFlowTypeExtendedUserFlow: - return "Extended User Flow Record" - case SFlowTypeExtendedUrlFlow: - return "Extended URL Flow Record" - case SFlowTypeExtendedMlpsFlow: - return "Extended MPLS Flow Record" - case SFlowTypeExtendedNatFlow: - return "Extended NAT Flow Record" - case SFlowTypeExtendedMlpsTunnelFlow: - return "Extended MPLS Tunnel Flow Record" - case SFlowTypeExtendedMlpsVcFlow: - return "Extended MPLS VC Flow Record" - case SFlowTypeExtendedMlpsFecFlow: - return "Extended MPLS FEC Flow Record" - case SFlowTypeExtendedMlpsLvpFecFlow: - return "Extended MPLS LVP FEC Flow Record" - case SFlowTypeExtendedVlanFlow: - return "Extended VLAN Flow Record" - case SFlowTypeExtendedIpv4TunnelEgressFlow: - return "Extended IPv4 Tunnel Egress Record" - case SFlowTypeExtendedIpv4TunnelIngressFlow: - return "Extended IPv4 Tunnel Ingress Record" - case SFlowTypeExtendedIpv6TunnelEgressFlow: - return "Extended IPv6 Tunnel Egress Record" - case SFlowTypeExtendedIpv6TunnelIngressFlow: - return "Extended IPv6 Tunnel Ingress Record" - case SFlowTypeExtendedDecapsulateEgressFlow: - return "Extended Decapsulate Egress Record" - case SFlowTypeExtendedDecapsulateIngressFlow: - return "Extended Decapsulate Ingress Record" - case SFlowTypeExtendedVniEgressFlow: - return "Extended VNI Ingress Record" - case SFlowTypeExtendedVniIngressFlow: - return "Extended VNI Ingress Record" - default: - return "" - } -} - -// SFlowRawPacketFlowRecords hold information about a sampled -// packet grabbed as it transited the agent. This is -// perhaps the most useful and interesting record type, -// as it holds the headers of the sampled packet and -// can be used to build up a complete picture of the -// traffic patterns on a network. -// -// The raw packet header is sent back into gopacket for -// decoding, and the resulting gopackt.Packet is stored -// in the Header member -type SFlowRawPacketFlowRecord struct { - SFlowBaseFlowRecord - HeaderProtocol SFlowRawHeaderProtocol - FrameLength uint32 - PayloadRemoved uint32 - HeaderLength uint32 - Header gopacket.Packet -} - -// Raw packet record types have the following structure: - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Header Protocol | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Frame Length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Payload Removed | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Header Length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// \ Header \ -// \ \ -// \ \ -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -type SFlowRawHeaderProtocol uint32 - -const ( - SFlowProtoEthernet SFlowRawHeaderProtocol = 1 - SFlowProtoISO88024 SFlowRawHeaderProtocol = 2 - SFlowProtoISO88025 SFlowRawHeaderProtocol = 3 - SFlowProtoFDDI SFlowRawHeaderProtocol = 4 - SFlowProtoFrameRelay SFlowRawHeaderProtocol = 5 - SFlowProtoX25 SFlowRawHeaderProtocol = 6 - SFlowProtoPPP SFlowRawHeaderProtocol = 7 - SFlowProtoSMDS SFlowRawHeaderProtocol = 8 - SFlowProtoAAL5 SFlowRawHeaderProtocol = 9 - SFlowProtoAAL5_IP SFlowRawHeaderProtocol = 10 /* e.g. Cisco AAL5 mux */ - SFlowProtoIPv4 SFlowRawHeaderProtocol = 11 - SFlowProtoIPv6 SFlowRawHeaderProtocol = 12 - SFlowProtoMPLS SFlowRawHeaderProtocol = 13 - SFlowProtoPOS SFlowRawHeaderProtocol = 14 /* RFC 1662, 2615 */ -) - -func (sfhp SFlowRawHeaderProtocol) String() string { - switch sfhp { - case SFlowProtoEthernet: - return "ETHERNET-ISO88023" - case SFlowProtoISO88024: - return "ISO88024-TOKENBUS" - case SFlowProtoISO88025: - return "ISO88025-TOKENRING" - case SFlowProtoFDDI: - return "FDDI" - case SFlowProtoFrameRelay: - return "FRAME-RELAY" - case SFlowProtoX25: - return "X25" - case SFlowProtoPPP: - return "PPP" - case SFlowProtoSMDS: - return "SMDS" - case SFlowProtoAAL5: - return "AAL5" - case SFlowProtoAAL5_IP: - return "AAL5-IP" - case SFlowProtoIPv4: - return "IPv4" - case SFlowProtoIPv6: - return "IPv6" - case SFlowProtoMPLS: - return "MPLS" - case SFlowProtoPOS: - return "POS" - } - return "UNKNOWN" -} - -func decodeRawPacketFlowRecord(data *[]byte) (SFlowRawPacketFlowRecord, error) { - rec := SFlowRawPacketFlowRecord{} - header := []byte{} - var fdf SFlowFlowDataFormat - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - rec.EnterpriseID, rec.Format = fdf.decode() - *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, rec.HeaderProtocol = (*data)[4:], SFlowRawHeaderProtocol(binary.BigEndian.Uint32((*data)[:4])) - *data, rec.FrameLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, rec.PayloadRemoved = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, rec.HeaderLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - headerLenWithPadding := int(rec.HeaderLength + ((4 - rec.HeaderLength) % 4)) - *data, header = (*data)[headerLenWithPadding:], (*data)[:headerLenWithPadding] - rec.Header = gopacket.NewPacket(header, LayerTypeEthernet, gopacket.Default) - return rec, nil -} - -// SFlowExtendedSwitchFlowRecord give additional information -// about the sampled packet if it's available. It's mainly -// useful for getting at the incoming and outgoing VLANs -// An agent may or may not provide this information. -type SFlowExtendedSwitchFlowRecord struct { - SFlowBaseFlowRecord - IncomingVLAN uint32 - IncomingVLANPriority uint32 - OutgoingVLAN uint32 - OutgoingVLANPriority uint32 -} - -// Extended switch records have the following structure: - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Incoming VLAN | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Incoming VLAN Priority | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Outgoing VLAN | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Outgoing VLAN Priority | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -func decodeExtendedSwitchFlowRecord(data *[]byte) (SFlowExtendedSwitchFlowRecord, error) { - es := SFlowExtendedSwitchFlowRecord{} - var fdf SFlowFlowDataFormat - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - es.EnterpriseID, es.Format = fdf.decode() - *data, es.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, es.IncomingVLAN = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, es.IncomingVLANPriority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, es.OutgoingVLAN = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, es.OutgoingVLANPriority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - return es, nil -} - -// SFlowExtendedRouterFlowRecord gives additional information -// about the layer 3 routing information used to forward -// the packet -type SFlowExtendedRouterFlowRecord struct { - SFlowBaseFlowRecord - NextHop net.IP - NextHopSourceMask uint32 - NextHopDestinationMask uint32 -} - -// Extended router records have the following structure: - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IP version of next hop router (1=v4|2=v6) | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / Next Hop address (v4=4byte|v6=16byte) / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Next Hop Source Mask | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Next Hop Destination Mask | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -func decodeExtendedRouterFlowRecord(data *[]byte) (SFlowExtendedRouterFlowRecord, error) { - er := SFlowExtendedRouterFlowRecord{} - var fdf SFlowFlowDataFormat - var extendedRouterAddressType SFlowIPType - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - er.EnterpriseID, er.Format = fdf.decode() - *data, er.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, extendedRouterAddressType = (*data)[4:], SFlowIPType(binary.BigEndian.Uint32((*data)[:4])) - *data, er.NextHop = (*data)[extendedRouterAddressType.Length():], (*data)[:extendedRouterAddressType.Length()] - *data, er.NextHopSourceMask = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, er.NextHopDestinationMask = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - return er, nil -} - -// SFlowExtendedGatewayFlowRecord describes information treasured by -// nework engineers everywhere: AS path information listing which -// BGP peer sent the packet, and various other BGP related info. -// This information is vital because it gives a picture of how much -// traffic is being sent from / received by various BGP peers. - -// Extended gateway records have the following structure: - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IP version of next hop router (1=v4|2=v6) | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / Next Hop address (v4=4byte|v6=16byte) / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | AS | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Source AS | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Peer AS | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | AS Path Count | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / AS Path / Sequence / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / Communities / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Local Pref | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -// AS Path / Sequence: - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | AS Source Type (Path=1 / Sequence=2) | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Path / Sequence length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / Path / Sequence Members / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -// Communities: - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | communitiy length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / communitiy Members / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -type SFlowExtendedGatewayFlowRecord struct { - SFlowBaseFlowRecord - NextHop net.IP - AS uint32 - SourceAS uint32 - PeerAS uint32 - ASPathCount uint32 - ASPath []SFlowASDestination - Communities []uint32 - LocalPref uint32 -} - -type SFlowASPathType uint32 - -const ( - SFlowASSet SFlowASPathType = 1 - SFlowASSequence SFlowASPathType = 2 -) - -func (apt SFlowASPathType) String() string { - switch apt { - case SFlowASSet: - return "AS Set" - case SFlowASSequence: - return "AS Sequence" - default: - return "" - } -} - -type SFlowASDestination struct { - Type SFlowASPathType - Count uint32 - Members []uint32 -} - -func (asd SFlowASDestination) String() string { - switch asd.Type { - case SFlowASSet: - return fmt.Sprint("AS Set:", asd.Members) - case SFlowASSequence: - return fmt.Sprint("AS Sequence:", asd.Members) - default: - return "" - } -} - -func (ad *SFlowASDestination) decodePath(data *[]byte) { - *data, ad.Type = (*data)[4:], SFlowASPathType(binary.BigEndian.Uint32((*data)[:4])) - *data, ad.Count = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - ad.Members = make([]uint32, ad.Count) - for i := uint32(0); i < ad.Count; i++ { - var member uint32 - *data, member = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - ad.Members[i] = member - } -} - -func decodeExtendedGatewayFlowRecord(data *[]byte) (SFlowExtendedGatewayFlowRecord, error) { - eg := SFlowExtendedGatewayFlowRecord{} - var fdf SFlowFlowDataFormat - var extendedGatewayAddressType SFlowIPType - var communitiesLength uint32 - var community uint32 - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - eg.EnterpriseID, eg.Format = fdf.decode() - *data, eg.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, extendedGatewayAddressType = (*data)[4:], SFlowIPType(binary.BigEndian.Uint32((*data)[:4])) - *data, eg.NextHop = (*data)[extendedGatewayAddressType.Length():], (*data)[:extendedGatewayAddressType.Length()] - *data, eg.AS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, eg.SourceAS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, eg.PeerAS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, eg.ASPathCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - for i := uint32(0); i < eg.ASPathCount; i++ { - asPath := SFlowASDestination{} - asPath.decodePath(data) - eg.ASPath = append(eg.ASPath, asPath) - } - *data, communitiesLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - eg.Communities = make([]uint32, communitiesLength) - for j := uint32(0); j < communitiesLength; j++ { - *data, community = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - eg.Communities[j] = community - } - *data, eg.LocalPref = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - return eg, nil -} - -// ************************************************** -// Extended URL Flow Record -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | direction | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | URL | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Host | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -type SFlowURLDirection uint32 - -const ( - SFlowURLsrc SFlowURLDirection = 1 - SFlowURLdst SFlowURLDirection = 2 -) - -func (urld SFlowURLDirection) String() string { - switch urld { - case SFlowURLsrc: - return "Source address is the server" - case SFlowURLdst: - return "Destination address is the server" - default: - return "" - } -} - -type SFlowExtendedURLRecord struct { - SFlowBaseFlowRecord - Direction SFlowURLDirection - URL string - Host string -} - -func decodeExtendedURLRecord(data *[]byte) (SFlowExtendedURLRecord, error) { - eur := SFlowExtendedURLRecord{} - var fdf SFlowFlowDataFormat - var urlLen uint32 - var urlLenWithPad int - var hostLen uint32 - var hostLenWithPad int - var urlBytes []byte - var hostBytes []byte - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - eur.EnterpriseID, eur.Format = fdf.decode() - *data, eur.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, eur.Direction = (*data)[4:], SFlowURLDirection(binary.BigEndian.Uint32((*data)[:4])) - *data, urlLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - urlLenWithPad = int(urlLen + ((4 - urlLen) % 4)) - *data, urlBytes = (*data)[urlLenWithPad:], (*data)[:urlLenWithPad] - eur.URL = string(urlBytes[:urlLen]) - *data, hostLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - hostLenWithPad = int(hostLen + ((4 - hostLen) % 4)) - *data, hostBytes = (*data)[hostLenWithPad:], (*data)[:hostLenWithPad] - eur.Host = string(hostBytes[:hostLen]) - return eur, nil -} - -// ************************************************** -// Extended User Flow Record -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Source Character Set | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Source User Id | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Destination Character Set | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Destination User ID | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -type SFlowExtendedUserFlow struct { - SFlowBaseFlowRecord - SourceCharSet SFlowCharSet - SourceUserID string - DestinationCharSet SFlowCharSet - DestinationUserID string -} - -type SFlowCharSet uint32 - -const ( - SFlowCSunknown SFlowCharSet = 2 - SFlowCSASCII SFlowCharSet = 3 - SFlowCSISOLatin1 SFlowCharSet = 4 - SFlowCSISOLatin2 SFlowCharSet = 5 - SFlowCSISOLatin3 SFlowCharSet = 6 - SFlowCSISOLatin4 SFlowCharSet = 7 - SFlowCSISOLatinCyrillic SFlowCharSet = 8 - SFlowCSISOLatinArabic SFlowCharSet = 9 - SFlowCSISOLatinGreek SFlowCharSet = 10 - SFlowCSISOLatinHebrew SFlowCharSet = 11 - SFlowCSISOLatin5 SFlowCharSet = 12 - SFlowCSISOLatin6 SFlowCharSet = 13 - SFlowCSISOTextComm SFlowCharSet = 14 - SFlowCSHalfWidthKatakana SFlowCharSet = 15 - SFlowCSJISEncoding SFlowCharSet = 16 - SFlowCSShiftJIS SFlowCharSet = 17 - SFlowCSEUCPkdFmtJapanese SFlowCharSet = 18 - SFlowCSEUCFixWidJapanese SFlowCharSet = 19 - SFlowCSISO4UnitedKingdom SFlowCharSet = 20 - SFlowCSISO11SwedishForNames SFlowCharSet = 21 - SFlowCSISO15Italian SFlowCharSet = 22 - SFlowCSISO17Spanish SFlowCharSet = 23 - SFlowCSISO21German SFlowCharSet = 24 - SFlowCSISO60DanishNorwegian SFlowCharSet = 25 - SFlowCSISO69French SFlowCharSet = 26 - SFlowCSISO10646UTF1 SFlowCharSet = 27 - SFlowCSISO646basic1983 SFlowCharSet = 28 - SFlowCSINVARIANT SFlowCharSet = 29 - SFlowCSISO2IntlRefVersion SFlowCharSet = 30 - SFlowCSNATSSEFI SFlowCharSet = 31 - SFlowCSNATSSEFIADD SFlowCharSet = 32 - SFlowCSNATSDANO SFlowCharSet = 33 - SFlowCSNATSDANOADD SFlowCharSet = 34 - SFlowCSISO10Swedish SFlowCharSet = 35 - SFlowCSKSC56011987 SFlowCharSet = 36 - SFlowCSISO2022KR SFlowCharSet = 37 - SFlowCSEUCKR SFlowCharSet = 38 - SFlowCSISO2022JP SFlowCharSet = 39 - SFlowCSISO2022JP2 SFlowCharSet = 40 - SFlowCSISO13JISC6220jp SFlowCharSet = 41 - SFlowCSISO14JISC6220ro SFlowCharSet = 42 - SFlowCSISO16Portuguese SFlowCharSet = 43 - SFlowCSISO18Greek7Old SFlowCharSet = 44 - SFlowCSISO19LatinGreek SFlowCharSet = 45 - SFlowCSISO25French SFlowCharSet = 46 - SFlowCSISO27LatinGreek1 SFlowCharSet = 47 - SFlowCSISO5427Cyrillic SFlowCharSet = 48 - SFlowCSISO42JISC62261978 SFlowCharSet = 49 - SFlowCSISO47BSViewdata SFlowCharSet = 50 - SFlowCSISO49INIS SFlowCharSet = 51 - SFlowCSISO50INIS8 SFlowCharSet = 52 - SFlowCSISO51INISCyrillic SFlowCharSet = 53 - SFlowCSISO54271981 SFlowCharSet = 54 - SFlowCSISO5428Greek SFlowCharSet = 55 - SFlowCSISO57GB1988 SFlowCharSet = 56 - SFlowCSISO58GB231280 SFlowCharSet = 57 - SFlowCSISO61Norwegian2 SFlowCharSet = 58 - SFlowCSISO70VideotexSupp1 SFlowCharSet = 59 - SFlowCSISO84Portuguese2 SFlowCharSet = 60 - SFlowCSISO85Spanish2 SFlowCharSet = 61 - SFlowCSISO86Hungarian SFlowCharSet = 62 - SFlowCSISO87JISX0208 SFlowCharSet = 63 - SFlowCSISO88Greek7 SFlowCharSet = 64 - SFlowCSISO89ASMO449 SFlowCharSet = 65 - SFlowCSISO90 SFlowCharSet = 66 - SFlowCSISO91JISC62291984a SFlowCharSet = 67 - SFlowCSISO92JISC62991984b SFlowCharSet = 68 - SFlowCSISO93JIS62291984badd SFlowCharSet = 69 - SFlowCSISO94JIS62291984hand SFlowCharSet = 70 - SFlowCSISO95JIS62291984handadd SFlowCharSet = 71 - SFlowCSISO96JISC62291984kana SFlowCharSet = 72 - SFlowCSISO2033 SFlowCharSet = 73 - SFlowCSISO99NAPLPS SFlowCharSet = 74 - SFlowCSISO102T617bit SFlowCharSet = 75 - SFlowCSISO103T618bit SFlowCharSet = 76 - SFlowCSISO111ECMACyrillic SFlowCharSet = 77 - SFlowCSa71 SFlowCharSet = 78 - SFlowCSa72 SFlowCharSet = 79 - SFlowCSISO123CSAZ24341985gr SFlowCharSet = 80 - SFlowCSISO88596E SFlowCharSet = 81 - SFlowCSISO88596I SFlowCharSet = 82 - SFlowCSISO128T101G2 SFlowCharSet = 83 - SFlowCSISO88598E SFlowCharSet = 84 - SFlowCSISO88598I SFlowCharSet = 85 - SFlowCSISO139CSN369103 SFlowCharSet = 86 - SFlowCSISO141JUSIB1002 SFlowCharSet = 87 - SFlowCSISO143IECP271 SFlowCharSet = 88 - SFlowCSISO146Serbian SFlowCharSet = 89 - SFlowCSISO147Macedonian SFlowCharSet = 90 - SFlowCSISO150 SFlowCharSet = 91 - SFlowCSISO151Cuba SFlowCharSet = 92 - SFlowCSISO6937Add SFlowCharSet = 93 - SFlowCSISO153GOST1976874 SFlowCharSet = 94 - SFlowCSISO8859Supp SFlowCharSet = 95 - SFlowCSISO10367Box SFlowCharSet = 96 - SFlowCSISO158Lap SFlowCharSet = 97 - SFlowCSISO159JISX02121990 SFlowCharSet = 98 - SFlowCSISO646Danish SFlowCharSet = 99 - SFlowCSUSDK SFlowCharSet = 100 - SFlowCSDKUS SFlowCharSet = 101 - SFlowCSKSC5636 SFlowCharSet = 102 - SFlowCSUnicode11UTF7 SFlowCharSet = 103 - SFlowCSISO2022CN SFlowCharSet = 104 - SFlowCSISO2022CNEXT SFlowCharSet = 105 - SFlowCSUTF8 SFlowCharSet = 106 - SFlowCSISO885913 SFlowCharSet = 109 - SFlowCSISO885914 SFlowCharSet = 110 - SFlowCSISO885915 SFlowCharSet = 111 - SFlowCSISO885916 SFlowCharSet = 112 - SFlowCSGBK SFlowCharSet = 113 - SFlowCSGB18030 SFlowCharSet = 114 - SFlowCSOSDEBCDICDF0415 SFlowCharSet = 115 - SFlowCSOSDEBCDICDF03IRV SFlowCharSet = 116 - SFlowCSOSDEBCDICDF041 SFlowCharSet = 117 - SFlowCSISO115481 SFlowCharSet = 118 - SFlowCSKZ1048 SFlowCharSet = 119 - SFlowCSUnicode SFlowCharSet = 1000 - SFlowCSUCS4 SFlowCharSet = 1001 - SFlowCSUnicodeASCII SFlowCharSet = 1002 - SFlowCSUnicodeLatin1 SFlowCharSet = 1003 - SFlowCSUnicodeJapanese SFlowCharSet = 1004 - SFlowCSUnicodeIBM1261 SFlowCharSet = 1005 - SFlowCSUnicodeIBM1268 SFlowCharSet = 1006 - SFlowCSUnicodeIBM1276 SFlowCharSet = 1007 - SFlowCSUnicodeIBM1264 SFlowCharSet = 1008 - SFlowCSUnicodeIBM1265 SFlowCharSet = 1009 - SFlowCSUnicode11 SFlowCharSet = 1010 - SFlowCSSCSU SFlowCharSet = 1011 - SFlowCSUTF7 SFlowCharSet = 1012 - SFlowCSUTF16BE SFlowCharSet = 1013 - SFlowCSUTF16LE SFlowCharSet = 1014 - SFlowCSUTF16 SFlowCharSet = 1015 - SFlowCSCESU8 SFlowCharSet = 1016 - SFlowCSUTF32 SFlowCharSet = 1017 - SFlowCSUTF32BE SFlowCharSet = 1018 - SFlowCSUTF32LE SFlowCharSet = 1019 - SFlowCSBOCU1 SFlowCharSet = 1020 - SFlowCSWindows30Latin1 SFlowCharSet = 2000 - SFlowCSWindows31Latin1 SFlowCharSet = 2001 - SFlowCSWindows31Latin2 SFlowCharSet = 2002 - SFlowCSWindows31Latin5 SFlowCharSet = 2003 - SFlowCSHPRoman8 SFlowCharSet = 2004 - SFlowCSAdobeStandardEncoding SFlowCharSet = 2005 - SFlowCSVenturaUS SFlowCharSet = 2006 - SFlowCSVenturaInternational SFlowCharSet = 2007 - SFlowCSDECMCS SFlowCharSet = 2008 - SFlowCSPC850Multilingual SFlowCharSet = 2009 - SFlowCSPCp852 SFlowCharSet = 2010 - SFlowCSPC8CodePage437 SFlowCharSet = 2011 - SFlowCSPC8DanishNorwegian SFlowCharSet = 2012 - SFlowCSPC862LatinHebrew SFlowCharSet = 2013 - SFlowCSPC8Turkish SFlowCharSet = 2014 - SFlowCSIBMSymbols SFlowCharSet = 2015 - SFlowCSIBMThai SFlowCharSet = 2016 - SFlowCSHPLegal SFlowCharSet = 2017 - SFlowCSHPPiFont SFlowCharSet = 2018 - SFlowCSHPMath8 SFlowCharSet = 2019 - SFlowCSHPPSMath SFlowCharSet = 2020 - SFlowCSHPDesktop SFlowCharSet = 2021 - SFlowCSVenturaMath SFlowCharSet = 2022 - SFlowCSMicrosoftPublishing SFlowCharSet = 2023 - SFlowCSWindows31J SFlowCharSet = 2024 - SFlowCSGB2312 SFlowCharSet = 2025 - SFlowCSBig5 SFlowCharSet = 2026 - SFlowCSMacintosh SFlowCharSet = 2027 - SFlowCSIBM037 SFlowCharSet = 2028 - SFlowCSIBM038 SFlowCharSet = 2029 - SFlowCSIBM273 SFlowCharSet = 2030 - SFlowCSIBM274 SFlowCharSet = 2031 - SFlowCSIBM275 SFlowCharSet = 2032 - SFlowCSIBM277 SFlowCharSet = 2033 - SFlowCSIBM278 SFlowCharSet = 2034 - SFlowCSIBM280 SFlowCharSet = 2035 - SFlowCSIBM281 SFlowCharSet = 2036 - SFlowCSIBM284 SFlowCharSet = 2037 - SFlowCSIBM285 SFlowCharSet = 2038 - SFlowCSIBM290 SFlowCharSet = 2039 - SFlowCSIBM297 SFlowCharSet = 2040 - SFlowCSIBM420 SFlowCharSet = 2041 - SFlowCSIBM423 SFlowCharSet = 2042 - SFlowCSIBM424 SFlowCharSet = 2043 - SFlowCSIBM500 SFlowCharSet = 2044 - SFlowCSIBM851 SFlowCharSet = 2045 - SFlowCSIBM855 SFlowCharSet = 2046 - SFlowCSIBM857 SFlowCharSet = 2047 - SFlowCSIBM860 SFlowCharSet = 2048 - SFlowCSIBM861 SFlowCharSet = 2049 - SFlowCSIBM863 SFlowCharSet = 2050 - SFlowCSIBM864 SFlowCharSet = 2051 - SFlowCSIBM865 SFlowCharSet = 2052 - SFlowCSIBM868 SFlowCharSet = 2053 - SFlowCSIBM869 SFlowCharSet = 2054 - SFlowCSIBM870 SFlowCharSet = 2055 - SFlowCSIBM871 SFlowCharSet = 2056 - SFlowCSIBM880 SFlowCharSet = 2057 - SFlowCSIBM891 SFlowCharSet = 2058 - SFlowCSIBM903 SFlowCharSet = 2059 - SFlowCSIBBM904 SFlowCharSet = 2060 - SFlowCSIBM905 SFlowCharSet = 2061 - SFlowCSIBM918 SFlowCharSet = 2062 - SFlowCSIBM1026 SFlowCharSet = 2063 - SFlowCSIBMEBCDICATDE SFlowCharSet = 2064 - SFlowCSEBCDICATDEA SFlowCharSet = 2065 - SFlowCSEBCDICCAFR SFlowCharSet = 2066 - SFlowCSEBCDICDKNO SFlowCharSet = 2067 - SFlowCSEBCDICDKNOA SFlowCharSet = 2068 - SFlowCSEBCDICFISE SFlowCharSet = 2069 - SFlowCSEBCDICFISEA SFlowCharSet = 2070 - SFlowCSEBCDICFR SFlowCharSet = 2071 - SFlowCSEBCDICIT SFlowCharSet = 2072 - SFlowCSEBCDICPT SFlowCharSet = 2073 - SFlowCSEBCDICES SFlowCharSet = 2074 - SFlowCSEBCDICESA SFlowCharSet = 2075 - SFlowCSEBCDICESS SFlowCharSet = 2076 - SFlowCSEBCDICUK SFlowCharSet = 2077 - SFlowCSEBCDICUS SFlowCharSet = 2078 - SFlowCSUnknown8BiT SFlowCharSet = 2079 - SFlowCSMnemonic SFlowCharSet = 2080 - SFlowCSMnem SFlowCharSet = 2081 - SFlowCSVISCII SFlowCharSet = 2082 - SFlowCSVIQR SFlowCharSet = 2083 - SFlowCSKOI8R SFlowCharSet = 2084 - SFlowCSHZGB2312 SFlowCharSet = 2085 - SFlowCSIBM866 SFlowCharSet = 2086 - SFlowCSPC775Baltic SFlowCharSet = 2087 - SFlowCSKOI8U SFlowCharSet = 2088 - SFlowCSIBM00858 SFlowCharSet = 2089 - SFlowCSIBM00924 SFlowCharSet = 2090 - SFlowCSIBM01140 SFlowCharSet = 2091 - SFlowCSIBM01141 SFlowCharSet = 2092 - SFlowCSIBM01142 SFlowCharSet = 2093 - SFlowCSIBM01143 SFlowCharSet = 2094 - SFlowCSIBM01144 SFlowCharSet = 2095 - SFlowCSIBM01145 SFlowCharSet = 2096 - SFlowCSIBM01146 SFlowCharSet = 2097 - SFlowCSIBM01147 SFlowCharSet = 2098 - SFlowCSIBM01148 SFlowCharSet = 2099 - SFlowCSIBM01149 SFlowCharSet = 2100 - SFlowCSBig5HKSCS SFlowCharSet = 2101 - SFlowCSIBM1047 SFlowCharSet = 2102 - SFlowCSPTCP154 SFlowCharSet = 2103 - SFlowCSAmiga1251 SFlowCharSet = 2104 - SFlowCSKOI7switched SFlowCharSet = 2105 - SFlowCSBRF SFlowCharSet = 2106 - SFlowCSTSCII SFlowCharSet = 2107 - SFlowCSCP51932 SFlowCharSet = 2108 - SFlowCSWindows874 SFlowCharSet = 2109 - SFlowCSWindows1250 SFlowCharSet = 2250 - SFlowCSWindows1251 SFlowCharSet = 2251 - SFlowCSWindows1252 SFlowCharSet = 2252 - SFlowCSWindows1253 SFlowCharSet = 2253 - SFlowCSWindows1254 SFlowCharSet = 2254 - SFlowCSWindows1255 SFlowCharSet = 2255 - SFlowCSWindows1256 SFlowCharSet = 2256 - SFlowCSWindows1257 SFlowCharSet = 2257 - SFlowCSWindows1258 SFlowCharSet = 2258 - SFlowCSTIS620 SFlowCharSet = 2259 - SFlowCS50220 SFlowCharSet = 2260 - SFlowCSreserved SFlowCharSet = 3000 -) - -func decodeExtendedUserFlow(data *[]byte) (SFlowExtendedUserFlow, error) { - eu := SFlowExtendedUserFlow{} - var fdf SFlowFlowDataFormat - var srcUserLen uint32 - var srcUserLenWithPad int - var srcUserBytes []byte - var dstUserLen uint32 - var dstUserLenWithPad int - var dstUserBytes []byte - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - eu.EnterpriseID, eu.Format = fdf.decode() - *data, eu.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, eu.SourceCharSet = (*data)[4:], SFlowCharSet(binary.BigEndian.Uint32((*data)[:4])) - *data, srcUserLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - srcUserLenWithPad = int(srcUserLen + ((4 - srcUserLen) % 4)) - *data, srcUserBytes = (*data)[srcUserLenWithPad:], (*data)[:srcUserLenWithPad] - eu.SourceUserID = string(srcUserBytes[:srcUserLen]) - *data, eu.DestinationCharSet = (*data)[4:], SFlowCharSet(binary.BigEndian.Uint32((*data)[:4])) - *data, dstUserLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - dstUserLenWithPad = int(dstUserLen + ((4 - dstUserLen) % 4)) - *data, dstUserBytes = (*data)[dstUserLenWithPad:], (*data)[:dstUserLenWithPad] - eu.DestinationUserID = string(dstUserBytes[:dstUserLen]) - return eu, nil -} - -// ************************************************** -// Packet IP version 4 Record -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Protocol | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Source IPv4 | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Destination IPv4 | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Source Port | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Destionation Port | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | TCP Flags | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | TOS | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -type SFlowIpv4Record struct { - // The length of the IP packet excluding ower layer encapsulations - Length uint32 - // IP Protocol type (for example, TCP = 6, UDP = 17) - Protocol uint32 - // Source IP Address - IPSrc net.IP - // Destination IP Address - IPDst net.IP - // TCP/UDP source port number or equivalent - PortSrc uint32 - // TCP/UDP destination port number or equivalent - PortDst uint32 - // TCP flags - TCPFlags uint32 - // IP type of service - TOS uint32 -} - -func decodeSFlowIpv4Record(data *[]byte) (SFlowIpv4Record, error) { - si := SFlowIpv4Record{} - - *data, si.Length = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, si.Protocol = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, si.IPSrc = (*data)[4:], net.IP((*data)[:4]) - *data, si.IPDst = (*data)[4:], net.IP((*data)[:4]) - *data, si.PortSrc = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, si.PortDst = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, si.TCPFlags = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, si.TOS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - - return si, nil -} - -// ************************************************** -// Packet IP version 6 Record -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Protocol | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Source IPv4 | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Destination IPv4 | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Source Port | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Destionation Port | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | TCP Flags | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Priority | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -type SFlowIpv6Record struct { - // The length of the IP packet excluding ower layer encapsulations - Length uint32 - // IP Protocol type (for example, TCP = 6, UDP = 17) - Protocol uint32 - // Source IP Address - IPSrc net.IP - // Destination IP Address - IPDst net.IP - // TCP/UDP source port number or equivalent - PortSrc uint32 - // TCP/UDP destination port number or equivalent - PortDst uint32 - // TCP flags - TCPFlags uint32 - // IP priority - Priority uint32 -} - -func decodeSFlowIpv6Record(data *[]byte) (SFlowIpv6Record, error) { - si := SFlowIpv6Record{} - - *data, si.Length = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, si.Protocol = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, si.IPSrc = (*data)[16:], net.IP((*data)[:16]) - *data, si.IPDst = (*data)[16:], net.IP((*data)[:16]) - *data, si.PortSrc = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, si.PortDst = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, si.TCPFlags = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, si.Priority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - - return si, nil -} - -// ************************************************** -// Extended IPv4 Tunnel Egress -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / Packet IP version 4 Record / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -type SFlowExtendedIpv4TunnelEgressRecord struct { - SFlowBaseFlowRecord - SFlowIpv4Record SFlowIpv4Record -} - -func decodeExtendedIpv4TunnelEgress(data *[]byte) (SFlowExtendedIpv4TunnelEgressRecord, error) { - rec := SFlowExtendedIpv4TunnelEgressRecord{} - var fdf SFlowFlowDataFormat - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - rec.EnterpriseID, rec.Format = fdf.decode() - *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - rec.SFlowIpv4Record, _ = decodeSFlowIpv4Record(data) - - return rec, nil -} - -// ************************************************** -// Extended IPv4 Tunnel Ingress -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / Packet IP version 4 Record / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -type SFlowExtendedIpv4TunnelIngressRecord struct { - SFlowBaseFlowRecord - SFlowIpv4Record SFlowIpv4Record -} - -func decodeExtendedIpv4TunnelIngress(data *[]byte) (SFlowExtendedIpv4TunnelIngressRecord, error) { - rec := SFlowExtendedIpv4TunnelIngressRecord{} - var fdf SFlowFlowDataFormat - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - rec.EnterpriseID, rec.Format = fdf.decode() - *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - rec.SFlowIpv4Record, _ = decodeSFlowIpv4Record(data) - - return rec, nil -} - -// ************************************************** -// Extended IPv6 Tunnel Egress -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / Packet IP version 6 Record / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -type SFlowExtendedIpv6TunnelEgressRecord struct { - SFlowBaseFlowRecord - SFlowIpv6Record -} - -func decodeExtendedIpv6TunnelEgress(data *[]byte) (SFlowExtendedIpv6TunnelEgressRecord, error) { - rec := SFlowExtendedIpv6TunnelEgressRecord{} - var fdf SFlowFlowDataFormat - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - rec.EnterpriseID, rec.Format = fdf.decode() - *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - rec.SFlowIpv6Record, _ = decodeSFlowIpv6Record(data) - - return rec, nil -} - -// ************************************************** -// Extended IPv6 Tunnel Ingress -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / Packet IP version 6 Record / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -type SFlowExtendedIpv6TunnelIngressRecord struct { - SFlowBaseFlowRecord - SFlowIpv6Record -} - -func decodeExtendedIpv6TunnelIngress(data *[]byte) (SFlowExtendedIpv6TunnelIngressRecord, error) { - rec := SFlowExtendedIpv6TunnelIngressRecord{} - var fdf SFlowFlowDataFormat - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - rec.EnterpriseID, rec.Format = fdf.decode() - *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - rec.SFlowIpv6Record, _ = decodeSFlowIpv6Record(data) - - return rec, nil -} - -// ************************************************** -// Extended Decapsulate Egress -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Inner Header Offset | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -type SFlowExtendedDecapsulateEgressRecord struct { - SFlowBaseFlowRecord - InnerHeaderOffset uint32 -} - -func decodeExtendedDecapsulateEgress(data *[]byte) (SFlowExtendedDecapsulateEgressRecord, error) { - rec := SFlowExtendedDecapsulateEgressRecord{} - var fdf SFlowFlowDataFormat - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - rec.EnterpriseID, rec.Format = fdf.decode() - *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, rec.InnerHeaderOffset = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - - return rec, nil -} - -// ************************************************** -// Extended Decapsulate Ingress -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | Inner Header Offset | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -type SFlowExtendedDecapsulateIngressRecord struct { - SFlowBaseFlowRecord - InnerHeaderOffset uint32 -} - -func decodeExtendedDecapsulateIngress(data *[]byte) (SFlowExtendedDecapsulateIngressRecord, error) { - rec := SFlowExtendedDecapsulateIngressRecord{} - var fdf SFlowFlowDataFormat - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - rec.EnterpriseID, rec.Format = fdf.decode() - *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, rec.InnerHeaderOffset = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - - return rec, nil -} - -// ************************************************** -// Extended VNI Egress -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | VNI | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -type SFlowExtendedVniEgressRecord struct { - SFlowBaseFlowRecord - VNI uint32 -} - -func decodeExtendedVniEgress(data *[]byte) (SFlowExtendedVniEgressRecord, error) { - rec := SFlowExtendedVniEgressRecord{} - var fdf SFlowFlowDataFormat - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - rec.EnterpriseID, rec.Format = fdf.decode() - *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, rec.VNI = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - - return rec, nil -} - -// ************************************************** -// Extended VNI Ingress -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | record length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | VNI | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -type SFlowExtendedVniIngressRecord struct { - SFlowBaseFlowRecord - VNI uint32 -} - -func decodeExtendedVniIngress(data *[]byte) (SFlowExtendedVniIngressRecord, error) { - rec := SFlowExtendedVniIngressRecord{} - var fdf SFlowFlowDataFormat - - *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4])) - rec.EnterpriseID, rec.Format = fdf.decode() - *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, rec.VNI = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - - return rec, nil -} - -// ************************************************** -// Counter Record -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | counter length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / counter data / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -type SFlowBaseCounterRecord struct { - EnterpriseID SFlowEnterpriseID - Format SFlowCounterRecordType - FlowDataLength uint32 -} - -func (bcr SFlowBaseCounterRecord) GetType() SFlowCounterRecordType { - switch bcr.Format { - case SFlowTypeGenericInterfaceCounters: - return SFlowTypeGenericInterfaceCounters - case SFlowTypeEthernetInterfaceCounters: - return SFlowTypeEthernetInterfaceCounters - case SFlowTypeTokenRingInterfaceCounters: - return SFlowTypeTokenRingInterfaceCounters - case SFlowType100BaseVGInterfaceCounters: - return SFlowType100BaseVGInterfaceCounters - case SFlowTypeVLANCounters: - return SFlowTypeVLANCounters - case SFlowTypeProcessorCounters: - return SFlowTypeProcessorCounters - - } - unrecognized := fmt.Sprint("Unrecognized counter record type:", bcr.Format) - panic(unrecognized) -} - -// ************************************************** -// Counter Record -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | counter length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfIndex | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfType | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfSpeed | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfDirection | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfStatus | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IFInOctets | -// | | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfInUcastPkts | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfInMulticastPkts | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfInBroadcastPkts | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfInDiscards | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | InInErrors | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfInUnknownProtos | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfOutOctets | -// | | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfOutUcastPkts | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfOutMulticastPkts | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfOutBroadcastPkts | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfOutDiscards | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfOUtErrors | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | IfPromiscouousMode | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -type SFlowGenericInterfaceCounters struct { - SFlowBaseCounterRecord - IfIndex uint32 - IfType uint32 - IfSpeed uint64 - IfDirection uint32 - IfStatus uint32 - IfInOctets uint64 - IfInUcastPkts uint32 - IfInMulticastPkts uint32 - IfInBroadcastPkts uint32 - IfInDiscards uint32 - IfInErrors uint32 - IfInUnknownProtos uint32 - IfOutOctets uint64 - IfOutUcastPkts uint32 - IfOutMulticastPkts uint32 - IfOutBroadcastPkts uint32 - IfOutDiscards uint32 - IfOutErrors uint32 - IfPromiscuousMode uint32 -} - -func decodeGenericInterfaceCounters(data *[]byte) (SFlowGenericInterfaceCounters, error) { - gic := SFlowGenericInterfaceCounters{} - var cdf SFlowCounterDataFormat - - *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) - gic.EnterpriseID, gic.Format = cdf.decode() - *data, gic.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfIndex = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfType = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfSpeed = (*data)[8:], binary.BigEndian.Uint64((*data)[:8]) - *data, gic.IfDirection = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfStatus = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfInOctets = (*data)[8:], binary.BigEndian.Uint64((*data)[:8]) - *data, gic.IfInUcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfInMulticastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfInBroadcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfInDiscards = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfInErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfInUnknownProtos = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfOutOctets = (*data)[8:], binary.BigEndian.Uint64((*data)[:8]) - *data, gic.IfOutUcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfOutMulticastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfOutBroadcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfOutDiscards = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfOutErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, gic.IfPromiscuousMode = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - return gic, nil -} - -// ************************************************** -// Counter Record -// ************************************************** - -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | counter length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// / counter data / -// / / -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -type SFlowEthernetCounters struct { - SFlowBaseCounterRecord - AlignmentErrors uint32 - FCSErrors uint32 - SingleCollisionFrames uint32 - MultipleCollisionFrames uint32 - SQETestErrors uint32 - DeferredTransmissions uint32 - LateCollisions uint32 - ExcessiveCollisions uint32 - InternalMacTransmitErrors uint32 - CarrierSenseErrors uint32 - FrameTooLongs uint32 - InternalMacReceiveErrors uint32 - SymbolErrors uint32 -} - -func decodeEthernetCounters(data *[]byte) (SFlowEthernetCounters, error) { - ec := SFlowEthernetCounters{} - var cdf SFlowCounterDataFormat - - *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) - ec.EnterpriseID, ec.Format = cdf.decode() - *data, ec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, ec.AlignmentErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, ec.FCSErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, ec.SingleCollisionFrames = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, ec.MultipleCollisionFrames = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, ec.SQETestErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, ec.DeferredTransmissions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, ec.LateCollisions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, ec.ExcessiveCollisions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, ec.InternalMacTransmitErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, ec.CarrierSenseErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, ec.FrameTooLongs = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, ec.InternalMacReceiveErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, ec.SymbolErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - return ec, nil -} - -// ************************************************** -// Processor Counter Record -// ************************************************** -// 0 15 31 -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | 20 bit Interprise (0) |12 bit format | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | counter length | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | FiveSecCpu | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | OneMinCpu | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | GiveMinCpu | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | TotalMemory | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -// | FreeMemory | -// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - -type SFlowProcessorCounters struct { - SFlowBaseCounterRecord - FiveSecCpu uint32 // 5 second average CPU utilization - OneMinCpu uint32 // 1 minute average CPU utilization - FiveMinCpu uint32 // 5 minute average CPU utilization - TotalMemory uint64 // total memory (in bytes) - FreeMemory uint64 // free memory (in bytes) -} - -func decodeProcessorCounters(data *[]byte) (SFlowProcessorCounters, error) { - pc := SFlowProcessorCounters{} - var cdf SFlowCounterDataFormat - var high32, low32 uint32 - - *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4])) - pc.EnterpriseID, pc.Format = cdf.decode() - *data, pc.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - - *data, pc.FiveSecCpu = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, pc.OneMinCpu = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, pc.FiveMinCpu = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, high32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, low32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - pc.TotalMemory = (uint64(high32) << 32) + uint64(low32) - *data, high32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - *data, low32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4]) - pc.FreeMemory = (uint64(high32)) + uint64(low32) - - return pc, nil -} -- cgit 1.2.3-korg