123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187 |
- // 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
- }
|