sflow.go 98 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567
  1. // Copyright 2014 Google, Inc. All rights reserved.
  2. //
  3. // Use of this source code is governed by a BSD-style license
  4. // that can be found in the LICENSE file in the root of the source
  5. // tree.
  6. /*
  7. This layer decodes SFlow version 5 datagrams.
  8. The specification can be found here: http://sflow.org/sflow_version_5.txt
  9. Additional developer information about sflow can be found at:
  10. http://sflow.org/developers/specifications.php
  11. And SFlow in general:
  12. http://sflow.org/index.php
  13. Two forms of sample data are defined: compact and expanded. The
  14. Specification has this to say:
  15. Compact and expand forms of counter and flow samples are defined.
  16. An agent must not mix compact/expanded encodings. If an agent
  17. will never use ifIndex numbers >= 2^24 then it must use compact
  18. encodings for all interfaces. Otherwise the expanded formats must
  19. be used for all interfaces.
  20. This decoder only supports the compact form, because that is the only
  21. one for which data was available.
  22. The datagram is composed of one or more samples of type flow or counter,
  23. and each sample is composed of one or more records describing the sample.
  24. A sample is a single instance of sampled inforamtion, and each record in
  25. the sample gives additional / supplimentary information about the sample.
  26. The following sample record types are supported:
  27. Raw Packet Header
  28. opaque = flow_data; enterprise = 0; format = 1
  29. Extended Switch Data
  30. opaque = flow_data; enterprise = 0; format = 1001
  31. Extended Router Data
  32. opaque = flow_data; enterprise = 0; format = 1002
  33. Extended Gateway Data
  34. opaque = flow_data; enterprise = 0; format = 1003
  35. Extended User Data
  36. opaque = flow_data; enterprise = 0; format = 1004
  37. Extended URL Data
  38. opaque = flow_data; enterprise = 0; format = 1005
  39. The following types of counter records are supported:
  40. Generic Interface Counters - see RFC 2233
  41. opaque = counter_data; enterprise = 0; format = 1
  42. Ethernet Interface Counters - see RFC 2358
  43. opaque = counter_data; enterprise = 0; format = 2
  44. SFlow is encoded using XDR (RFC4506). There are a few places
  45. where the standard 4-byte fields are partitioned into two
  46. bitfields of different lengths. I'm not sure why the designers
  47. chose to pack together two values like this in some places, and
  48. in others they use the entire 4-byte value to store a number that
  49. will never be more than a few bits. In any case, there are a couple
  50. of types defined to handle the decoding of these bitfields, and
  51. that's why they're there. */
  52. package layers
  53. import (
  54. "encoding/binary"
  55. "errors"
  56. "fmt"
  57. "net"
  58. "github.com/google/gopacket"
  59. )
  60. // SFlowRecord holds both flow sample records and counter sample records.
  61. // A Record is the structure that actually holds the sampled data
  62. // and / or counters.
  63. type SFlowRecord interface {
  64. }
  65. // SFlowDataSource encodes a 2-bit SFlowSourceFormat in its most significant
  66. // 2 bits, and an SFlowSourceValue in its least significant 30 bits.
  67. // These types and values define the meaning of the inteface information
  68. // presented in the sample metadata.
  69. type SFlowDataSource int32
  70. func (sdc SFlowDataSource) decode() (SFlowSourceFormat, SFlowSourceValue) {
  71. leftField := sdc >> 30
  72. rightField := uint32(0x3FFFFFFF) & uint32(sdc)
  73. return SFlowSourceFormat(leftField), SFlowSourceValue(rightField)
  74. }
  75. type SFlowDataSourceExpanded struct {
  76. SourceIDClass SFlowSourceFormat
  77. SourceIDIndex SFlowSourceValue
  78. }
  79. func (sdce SFlowDataSourceExpanded) decode() (SFlowSourceFormat, SFlowSourceValue) {
  80. leftField := sdce.SourceIDClass >> 30
  81. rightField := uint32(0x3FFFFFFF) & uint32(sdce.SourceIDIndex)
  82. return SFlowSourceFormat(leftField), SFlowSourceValue(rightField)
  83. }
  84. type SFlowSourceFormat uint32
  85. type SFlowSourceValue uint32
  86. const (
  87. SFlowTypeSingleInterface SFlowSourceFormat = 0
  88. SFlowTypePacketDiscarded SFlowSourceFormat = 1
  89. SFlowTypeMultipleDestinations SFlowSourceFormat = 2
  90. )
  91. func (sdf SFlowSourceFormat) String() string {
  92. switch sdf {
  93. case SFlowTypeSingleInterface:
  94. return "Single Interface"
  95. case SFlowTypePacketDiscarded:
  96. return "Packet Discarded"
  97. case SFlowTypeMultipleDestinations:
  98. return "Multiple Destinations"
  99. default:
  100. return "UNKNOWN"
  101. }
  102. }
  103. func decodeSFlow(data []byte, p gopacket.PacketBuilder) error {
  104. s := &SFlowDatagram{}
  105. err := s.DecodeFromBytes(data, p)
  106. if err != nil {
  107. return err
  108. }
  109. p.AddLayer(s)
  110. p.SetApplicationLayer(s)
  111. return nil
  112. }
  113. // SFlowDatagram is the outermost container which holds some basic information
  114. // about the reporting agent, and holds at least one sample record
  115. type SFlowDatagram struct {
  116. BaseLayer
  117. DatagramVersion uint32
  118. AgentAddress net.IP
  119. SubAgentID uint32
  120. SequenceNumber uint32
  121. AgentUptime uint32
  122. SampleCount uint32
  123. FlowSamples []SFlowFlowSample
  124. CounterSamples []SFlowCounterSample
  125. }
  126. // An SFlow datagram's outer container has the following
  127. // structure:
  128. // 0 15 31
  129. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  130. // | int sFlow version (2|4|5) |
  131. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  132. // | int IP version of the Agent (1=v4|2=v6) |
  133. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  134. // / Agent IP address (v4=4byte|v6=16byte) /
  135. // / /
  136. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  137. // | int sub agent id |
  138. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  139. // | int datagram sequence number |
  140. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  141. // | int switch uptime in ms |
  142. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  143. // | int n samples in datagram |
  144. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  145. // / n samples /
  146. // / /
  147. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  148. // SFlowDataFormat encodes the EnterpriseID in the most
  149. // significant 12 bits, and the SampleType in the least significant
  150. // 20 bits.
  151. type SFlowDataFormat uint32
  152. func (sdf SFlowDataFormat) decode() (SFlowEnterpriseID, SFlowSampleType) {
  153. leftField := sdf >> 12
  154. rightField := uint32(0xFFF) & uint32(sdf)
  155. return SFlowEnterpriseID(leftField), SFlowSampleType(rightField)
  156. }
  157. // SFlowEnterpriseID is used to differentiate between the
  158. // official SFlow standard, and other, vendor-specific
  159. // types of flow data. (Similiar to SNMP's enterprise MIB
  160. // OIDs) Only the office SFlow Enterprise ID is decoded
  161. // here.
  162. type SFlowEnterpriseID uint32
  163. const (
  164. SFlowStandard SFlowEnterpriseID = 0
  165. )
  166. func (eid SFlowEnterpriseID) String() string {
  167. switch eid {
  168. case SFlowStandard:
  169. return "Standard SFlow"
  170. default:
  171. return ""
  172. }
  173. }
  174. func (eid SFlowEnterpriseID) GetType() SFlowEnterpriseID {
  175. return SFlowStandard
  176. }
  177. // SFlowSampleType specifies the type of sample. Only flow samples
  178. // and counter samples are supported
  179. type SFlowSampleType uint32
  180. const (
  181. SFlowTypeFlowSample SFlowSampleType = 1
  182. SFlowTypeCounterSample SFlowSampleType = 2
  183. SFlowTypeExpandedFlowSample SFlowSampleType = 3
  184. SFlowTypeExpandedCounterSample SFlowSampleType = 4
  185. )
  186. func (st SFlowSampleType) GetType() SFlowSampleType {
  187. switch st {
  188. case SFlowTypeFlowSample:
  189. return SFlowTypeFlowSample
  190. case SFlowTypeCounterSample:
  191. return SFlowTypeCounterSample
  192. case SFlowTypeExpandedFlowSample:
  193. return SFlowTypeExpandedFlowSample
  194. case SFlowTypeExpandedCounterSample:
  195. return SFlowTypeExpandedCounterSample
  196. default:
  197. panic("Invalid Sample Type")
  198. }
  199. }
  200. func (st SFlowSampleType) String() string {
  201. switch st {
  202. case SFlowTypeFlowSample:
  203. return "Flow Sample"
  204. case SFlowTypeCounterSample:
  205. return "Counter Sample"
  206. case SFlowTypeExpandedFlowSample:
  207. return "Expanded Flow Sample"
  208. case SFlowTypeExpandedCounterSample:
  209. return "Expanded Counter Sample"
  210. default:
  211. return ""
  212. }
  213. }
  214. func (s *SFlowDatagram) LayerType() gopacket.LayerType { return LayerTypeSFlow }
  215. func (d *SFlowDatagram) Payload() []byte { return nil }
  216. func (d *SFlowDatagram) CanDecode() gopacket.LayerClass { return LayerTypeSFlow }
  217. func (d *SFlowDatagram) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload }
  218. // SFlowIPType determines what form the IP address being decoded will
  219. // take. This is an XDR union type allowing for both IPv4 and IPv6
  220. type SFlowIPType uint32
  221. const (
  222. SFlowIPv4 SFlowIPType = 1
  223. SFlowIPv6 SFlowIPType = 2
  224. )
  225. func (s SFlowIPType) String() string {
  226. switch s {
  227. case SFlowIPv4:
  228. return "IPv4"
  229. case SFlowIPv6:
  230. return "IPv6"
  231. default:
  232. return ""
  233. }
  234. }
  235. func (s SFlowIPType) Length() int {
  236. switch s {
  237. case SFlowIPv4:
  238. return 4
  239. case SFlowIPv6:
  240. return 16
  241. default:
  242. return 0
  243. }
  244. }
  245. func (s *SFlowDatagram) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  246. var agentAddressType SFlowIPType
  247. data, s.DatagramVersion = data[4:], binary.BigEndian.Uint32(data[:4])
  248. data, agentAddressType = data[4:], SFlowIPType(binary.BigEndian.Uint32(data[:4]))
  249. data, s.AgentAddress = data[agentAddressType.Length():], data[:agentAddressType.Length()]
  250. data, s.SubAgentID = data[4:], binary.BigEndian.Uint32(data[:4])
  251. data, s.SequenceNumber = data[4:], binary.BigEndian.Uint32(data[:4])
  252. data, s.AgentUptime = data[4:], binary.BigEndian.Uint32(data[:4])
  253. data, s.SampleCount = data[4:], binary.BigEndian.Uint32(data[:4])
  254. if s.SampleCount < 1 {
  255. return fmt.Errorf("SFlow Datagram has invalid sample length: %d", s.SampleCount)
  256. }
  257. for i := uint32(0); i < s.SampleCount; i++ {
  258. sdf := SFlowDataFormat(binary.BigEndian.Uint32(data[:4]))
  259. _, sampleType := sdf.decode()
  260. switch sampleType {
  261. case SFlowTypeFlowSample:
  262. if flowSample, err := decodeFlowSample(&data, false); err == nil {
  263. s.FlowSamples = append(s.FlowSamples, flowSample)
  264. } else {
  265. return err
  266. }
  267. case SFlowTypeCounterSample:
  268. if counterSample, err := decodeCounterSample(&data, false); err == nil {
  269. s.CounterSamples = append(s.CounterSamples, counterSample)
  270. } else {
  271. return err
  272. }
  273. case SFlowTypeExpandedFlowSample:
  274. if flowSample, err := decodeFlowSample(&data, true); err == nil {
  275. s.FlowSamples = append(s.FlowSamples, flowSample)
  276. } else {
  277. return err
  278. }
  279. case SFlowTypeExpandedCounterSample:
  280. if counterSample, err := decodeCounterSample(&data, true); err == nil {
  281. s.CounterSamples = append(s.CounterSamples, counterSample)
  282. } else {
  283. return err
  284. }
  285. default:
  286. return fmt.Errorf("Unsupported SFlow sample type %d", sampleType)
  287. }
  288. }
  289. return nil
  290. }
  291. // SFlowFlowSample represents a sampled packet and contains
  292. // one or more records describing the packet
  293. type SFlowFlowSample struct {
  294. EnterpriseID SFlowEnterpriseID
  295. Format SFlowSampleType
  296. SampleLength uint32
  297. SequenceNumber uint32
  298. SourceIDClass SFlowSourceFormat
  299. SourceIDIndex SFlowSourceValue
  300. SamplingRate uint32
  301. SamplePool uint32
  302. Dropped uint32
  303. InputInterfaceFormat uint32
  304. InputInterface uint32
  305. OutputInterfaceFormat uint32
  306. OutputInterface uint32
  307. RecordCount uint32
  308. Records []SFlowRecord
  309. }
  310. // Flow samples have the following structure. Note
  311. // the bit fields to encode the Enterprise ID and the
  312. // Flow record format: type 1
  313. // 0 15 31
  314. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  315. // | 20 bit Interprise (0) |12 bit format |
  316. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  317. // | sample length |
  318. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  319. // | int sample sequence number |
  320. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  321. // |id type | src id index value |
  322. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  323. // | int sampling rate |
  324. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  325. // | int sample pool |
  326. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  327. // | int drops |
  328. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  329. // | int input ifIndex |
  330. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  331. // | int output ifIndex |
  332. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  333. // | int number of records |
  334. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  335. // / flow records /
  336. // / /
  337. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  338. // Flow samples have the following structure.
  339. // Flow record format: type 3
  340. // 0 15 31
  341. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  342. // | 20 bit Interprise (0) |12 bit format |
  343. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  344. // | sample length |
  345. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  346. // | int sample sequence number |
  347. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  348. // | int src id type |
  349. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  350. // | int src id index value |
  351. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  352. // | int sampling rate |
  353. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  354. // | int sample pool |
  355. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  356. // | int drops |
  357. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  358. // | int input interface format |
  359. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  360. // | int input interface value |
  361. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  362. // | int output interface format |
  363. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  364. // | int output interface value |
  365. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  366. // | int number of records |
  367. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  368. // / flow records /
  369. // / /
  370. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  371. type SFlowFlowDataFormat uint32
  372. func (fdf SFlowFlowDataFormat) decode() (SFlowEnterpriseID, SFlowFlowRecordType) {
  373. leftField := fdf >> 12
  374. rightField := uint32(0xFFF) & uint32(fdf)
  375. return SFlowEnterpriseID(leftField), SFlowFlowRecordType(rightField)
  376. }
  377. func (fs SFlowFlowSample) GetRecords() []SFlowRecord {
  378. return fs.Records
  379. }
  380. func (fs SFlowFlowSample) GetType() SFlowSampleType {
  381. return SFlowTypeFlowSample
  382. }
  383. func skipRecord(data *[]byte) {
  384. recordLength := int(binary.BigEndian.Uint32((*data)[4:]))
  385. *data = (*data)[(recordLength+((4-recordLength)%4))+8:]
  386. }
  387. func decodeFlowSample(data *[]byte, expanded bool) (SFlowFlowSample, error) {
  388. s := SFlowFlowSample{}
  389. var sdf SFlowDataFormat
  390. *data, sdf = (*data)[4:], SFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  391. var sdc SFlowDataSource
  392. s.EnterpriseID, s.Format = sdf.decode()
  393. if len(*data) < 4 {
  394. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  395. }
  396. *data, s.SampleLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  397. if len(*data) < 4 {
  398. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  399. }
  400. *data, s.SequenceNumber = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  401. if expanded {
  402. if len(*data) < 4 {
  403. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  404. }
  405. *data, s.SourceIDClass = (*data)[4:], SFlowSourceFormat(binary.BigEndian.Uint32((*data)[:4]))
  406. if len(*data) < 4 {
  407. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  408. }
  409. *data, s.SourceIDIndex = (*data)[4:], SFlowSourceValue(binary.BigEndian.Uint32((*data)[:4]))
  410. } else {
  411. if len(*data) < 4 {
  412. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  413. }
  414. *data, sdc = (*data)[4:], SFlowDataSource(binary.BigEndian.Uint32((*data)[:4]))
  415. s.SourceIDClass, s.SourceIDIndex = sdc.decode()
  416. }
  417. if len(*data) < 4 {
  418. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  419. }
  420. *data, s.SamplingRate = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  421. if len(*data) < 4 {
  422. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  423. }
  424. *data, s.SamplePool = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  425. if len(*data) < 4 {
  426. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  427. }
  428. *data, s.Dropped = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  429. if expanded {
  430. if len(*data) < 4 {
  431. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  432. }
  433. *data, s.InputInterfaceFormat = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  434. if len(*data) < 4 {
  435. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  436. }
  437. *data, s.InputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  438. if len(*data) < 4 {
  439. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  440. }
  441. *data, s.OutputInterfaceFormat = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  442. if len(*data) < 4 {
  443. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  444. }
  445. *data, s.OutputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  446. } else {
  447. if len(*data) < 4 {
  448. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  449. }
  450. *data, s.InputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  451. if len(*data) < 4 {
  452. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  453. }
  454. *data, s.OutputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  455. }
  456. if len(*data) < 4 {
  457. return SFlowFlowSample{}, errors.New("ethernet counters too small")
  458. }
  459. *data, s.RecordCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  460. for i := uint32(0); i < s.RecordCount; i++ {
  461. rdf := SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  462. enterpriseID, flowRecordType := rdf.decode()
  463. // Try to decode when EnterpriseID is 0 signaling
  464. // default sflow structs are used according specification
  465. // Unexpected behavior detected for e.g. with pmacct
  466. if enterpriseID == 0 {
  467. switch flowRecordType {
  468. case SFlowTypeRawPacketFlow:
  469. if record, err := decodeRawPacketFlowRecord(data); err == nil {
  470. s.Records = append(s.Records, record)
  471. } else {
  472. return s, err
  473. }
  474. case SFlowTypeExtendedUserFlow:
  475. if record, err := decodeExtendedUserFlow(data); err == nil {
  476. s.Records = append(s.Records, record)
  477. } else {
  478. return s, err
  479. }
  480. case SFlowTypeExtendedUrlFlow:
  481. if record, err := decodeExtendedURLRecord(data); err == nil {
  482. s.Records = append(s.Records, record)
  483. } else {
  484. return s, err
  485. }
  486. case SFlowTypeExtendedSwitchFlow:
  487. if record, err := decodeExtendedSwitchFlowRecord(data); err == nil {
  488. s.Records = append(s.Records, record)
  489. } else {
  490. return s, err
  491. }
  492. case SFlowTypeExtendedRouterFlow:
  493. if record, err := decodeExtendedRouterFlowRecord(data); err == nil {
  494. s.Records = append(s.Records, record)
  495. } else {
  496. return s, err
  497. }
  498. case SFlowTypeExtendedGatewayFlow:
  499. if record, err := decodeExtendedGatewayFlowRecord(data); err == nil {
  500. s.Records = append(s.Records, record)
  501. } else {
  502. return s, err
  503. }
  504. case SFlowTypeEthernetFrameFlow:
  505. if record, err := decodeEthernetFrameFlowRecord(data); err == nil {
  506. s.Records = append(s.Records, record)
  507. } else {
  508. return s, err
  509. }
  510. case SFlowTypeIpv4Flow:
  511. if record, err := decodeSFlowIpv4Record(data); err == nil {
  512. s.Records = append(s.Records, record)
  513. } else {
  514. return s, err
  515. }
  516. case SFlowTypeIpv6Flow:
  517. if record, err := decodeSFlowIpv6Record(data); err == nil {
  518. s.Records = append(s.Records, record)
  519. } else {
  520. return s, err
  521. }
  522. case SFlowTypeExtendedMlpsFlow:
  523. // TODO
  524. skipRecord(data)
  525. return s, errors.New("skipping TypeExtendedMlpsFlow")
  526. case SFlowTypeExtendedNatFlow:
  527. // TODO
  528. skipRecord(data)
  529. return s, errors.New("skipping TypeExtendedNatFlow")
  530. case SFlowTypeExtendedMlpsTunnelFlow:
  531. // TODO
  532. skipRecord(data)
  533. return s, errors.New("skipping TypeExtendedMlpsTunnelFlow")
  534. case SFlowTypeExtendedMlpsVcFlow:
  535. // TODO
  536. skipRecord(data)
  537. return s, errors.New("skipping TypeExtendedMlpsVcFlow")
  538. case SFlowTypeExtendedMlpsFecFlow:
  539. // TODO
  540. skipRecord(data)
  541. return s, errors.New("skipping TypeExtendedMlpsFecFlow")
  542. case SFlowTypeExtendedMlpsLvpFecFlow:
  543. // TODO
  544. skipRecord(data)
  545. return s, errors.New("skipping TypeExtendedMlpsLvpFecFlow")
  546. case SFlowTypeExtendedVlanFlow:
  547. // TODO
  548. skipRecord(data)
  549. return s, errors.New("skipping TypeExtendedVlanFlow")
  550. case SFlowTypeExtendedIpv4TunnelEgressFlow:
  551. if record, err := decodeExtendedIpv4TunnelEgress(data); err == nil {
  552. s.Records = append(s.Records, record)
  553. } else {
  554. return s, err
  555. }
  556. case SFlowTypeExtendedIpv4TunnelIngressFlow:
  557. if record, err := decodeExtendedIpv4TunnelIngress(data); err == nil {
  558. s.Records = append(s.Records, record)
  559. } else {
  560. return s, err
  561. }
  562. case SFlowTypeExtendedIpv6TunnelEgressFlow:
  563. if record, err := decodeExtendedIpv6TunnelEgress(data); err == nil {
  564. s.Records = append(s.Records, record)
  565. } else {
  566. return s, err
  567. }
  568. case SFlowTypeExtendedIpv6TunnelIngressFlow:
  569. if record, err := decodeExtendedIpv6TunnelIngress(data); err == nil {
  570. s.Records = append(s.Records, record)
  571. } else {
  572. return s, err
  573. }
  574. case SFlowTypeExtendedDecapsulateEgressFlow:
  575. if record, err := decodeExtendedDecapsulateEgress(data); err == nil {
  576. s.Records = append(s.Records, record)
  577. } else {
  578. return s, err
  579. }
  580. case SFlowTypeExtendedDecapsulateIngressFlow:
  581. if record, err := decodeExtendedDecapsulateIngress(data); err == nil {
  582. s.Records = append(s.Records, record)
  583. } else {
  584. return s, err
  585. }
  586. case SFlowTypeExtendedVniEgressFlow:
  587. if record, err := decodeExtendedVniEgress(data); err == nil {
  588. s.Records = append(s.Records, record)
  589. } else {
  590. return s, err
  591. }
  592. case SFlowTypeExtendedVniIngressFlow:
  593. if record, err := decodeExtendedVniIngress(data); err == nil {
  594. s.Records = append(s.Records, record)
  595. } else {
  596. return s, err
  597. }
  598. default:
  599. return s, fmt.Errorf("Unsupported flow record type: %d", flowRecordType)
  600. }
  601. } else {
  602. skipRecord(data)
  603. }
  604. }
  605. return s, nil
  606. }
  607. // Counter samples report information about various counter
  608. // objects. Typically these are items like IfInOctets, or
  609. // CPU / Memory stats, etc. SFlow will report these at regular
  610. // intervals as configured on the agent. If one were sufficiently
  611. // industrious, this could be used to replace the typical
  612. // SNMP polling used for such things.
  613. type SFlowCounterSample struct {
  614. EnterpriseID SFlowEnterpriseID
  615. Format SFlowSampleType
  616. SampleLength uint32
  617. SequenceNumber uint32
  618. SourceIDClass SFlowSourceFormat
  619. SourceIDIndex SFlowSourceValue
  620. RecordCount uint32
  621. Records []SFlowRecord
  622. }
  623. // Counter samples have the following structure:
  624. // 0 15 31
  625. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  626. // | int sample sequence number |
  627. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  628. // |id type | src id index value |
  629. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  630. // | int number of records |
  631. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  632. // / counter records /
  633. // / /
  634. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  635. type SFlowCounterDataFormat uint32
  636. func (cdf SFlowCounterDataFormat) decode() (SFlowEnterpriseID, SFlowCounterRecordType) {
  637. leftField := cdf >> 12
  638. rightField := uint32(0xFFF) & uint32(cdf)
  639. return SFlowEnterpriseID(leftField), SFlowCounterRecordType(rightField)
  640. }
  641. // GetRecords will return a slice of interface types
  642. // representing records. A type switch can be used to
  643. // get at the underlying SFlowCounterRecordType.
  644. func (cs SFlowCounterSample) GetRecords() []SFlowRecord {
  645. return cs.Records
  646. }
  647. // GetType will report the type of sample. Only the
  648. // compact form of counter samples is supported
  649. func (cs SFlowCounterSample) GetType() SFlowSampleType {
  650. return SFlowTypeCounterSample
  651. }
  652. type SFlowCounterRecordType uint32
  653. const (
  654. SFlowTypeGenericInterfaceCounters SFlowCounterRecordType = 1
  655. SFlowTypeEthernetInterfaceCounters SFlowCounterRecordType = 2
  656. SFlowTypeTokenRingInterfaceCounters SFlowCounterRecordType = 3
  657. SFlowType100BaseVGInterfaceCounters SFlowCounterRecordType = 4
  658. SFlowTypeVLANCounters SFlowCounterRecordType = 5
  659. SFlowTypeLACPCounters SFlowCounterRecordType = 7
  660. SFlowTypeProcessorCounters SFlowCounterRecordType = 1001
  661. SFlowTypeOpenflowPortCounters SFlowCounterRecordType = 1004
  662. SFlowTypePORTNAMECounters SFlowCounterRecordType = 1005
  663. SFLowTypeAPPRESOURCESCounters SFlowCounterRecordType = 2203
  664. SFlowTypeOVSDPCounters SFlowCounterRecordType = 2207
  665. )
  666. func (cr SFlowCounterRecordType) String() string {
  667. switch cr {
  668. case SFlowTypeGenericInterfaceCounters:
  669. return "Generic Interface Counters"
  670. case SFlowTypeEthernetInterfaceCounters:
  671. return "Ethernet Interface Counters"
  672. case SFlowTypeTokenRingInterfaceCounters:
  673. return "Token Ring Interface Counters"
  674. case SFlowType100BaseVGInterfaceCounters:
  675. return "100BaseVG Interface Counters"
  676. case SFlowTypeVLANCounters:
  677. return "VLAN Counters"
  678. case SFlowTypeLACPCounters:
  679. return "LACP Counters"
  680. case SFlowTypeProcessorCounters:
  681. return "Processor Counters"
  682. case SFlowTypeOpenflowPortCounters:
  683. return "Openflow Port Counters"
  684. case SFlowTypePORTNAMECounters:
  685. return "PORT NAME Counters"
  686. case SFLowTypeAPPRESOURCESCounters:
  687. return "App Resources Counters"
  688. case SFlowTypeOVSDPCounters:
  689. return "OVSDP Counters"
  690. default:
  691. return ""
  692. }
  693. }
  694. func decodeCounterSample(data *[]byte, expanded bool) (SFlowCounterSample, error) {
  695. s := SFlowCounterSample{}
  696. var sdc SFlowDataSource
  697. var sdce SFlowDataSourceExpanded
  698. var sdf SFlowDataFormat
  699. *data, sdf = (*data)[4:], SFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  700. s.EnterpriseID, s.Format = sdf.decode()
  701. *data, s.SampleLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  702. *data, s.SequenceNumber = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  703. if expanded {
  704. *data, sdce = (*data)[8:], SFlowDataSourceExpanded{SFlowSourceFormat(binary.BigEndian.Uint32((*data)[:4])), SFlowSourceValue(binary.BigEndian.Uint32((*data)[4:8]))}
  705. s.SourceIDClass, s.SourceIDIndex = sdce.decode()
  706. } else {
  707. *data, sdc = (*data)[4:], SFlowDataSource(binary.BigEndian.Uint32((*data)[:4]))
  708. s.SourceIDClass, s.SourceIDIndex = sdc.decode()
  709. }
  710. *data, s.RecordCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  711. for i := uint32(0); i < s.RecordCount; i++ {
  712. cdf := SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  713. _, counterRecordType := cdf.decode()
  714. switch counterRecordType {
  715. case SFlowTypeGenericInterfaceCounters:
  716. if record, err := decodeGenericInterfaceCounters(data); err == nil {
  717. s.Records = append(s.Records, record)
  718. } else {
  719. return s, err
  720. }
  721. case SFlowTypeEthernetInterfaceCounters:
  722. if record, err := decodeEthernetCounters(data); err == nil {
  723. s.Records = append(s.Records, record)
  724. } else {
  725. return s, err
  726. }
  727. case SFlowTypeTokenRingInterfaceCounters:
  728. skipRecord(data)
  729. return s, errors.New("skipping TypeTokenRingInterfaceCounters")
  730. case SFlowType100BaseVGInterfaceCounters:
  731. skipRecord(data)
  732. return s, errors.New("skipping Type100BaseVGInterfaceCounters")
  733. case SFlowTypeVLANCounters:
  734. if record, err := decodeVLANCounters(data); err == nil {
  735. s.Records = append(s.Records, record)
  736. } else {
  737. return s, err
  738. }
  739. case SFlowTypeLACPCounters:
  740. if record, err := decodeLACPCounters(data); err == nil {
  741. s.Records = append(s.Records, record)
  742. } else {
  743. return s, err
  744. }
  745. case SFlowTypeProcessorCounters:
  746. if record, err := decodeProcessorCounters(data); err == nil {
  747. s.Records = append(s.Records, record)
  748. } else {
  749. return s, err
  750. }
  751. case SFlowTypeOpenflowPortCounters:
  752. if record, err := decodeOpenflowportCounters(data); err == nil {
  753. s.Records = append(s.Records, record)
  754. } else {
  755. return s, err
  756. }
  757. case SFlowTypePORTNAMECounters:
  758. if record, err := decodePortnameCounters(data); err == nil {
  759. s.Records = append(s.Records, record)
  760. } else {
  761. return s, err
  762. }
  763. case SFLowTypeAPPRESOURCESCounters:
  764. if record, err := decodeAppresourcesCounters(data); err == nil {
  765. s.Records = append(s.Records, record)
  766. } else {
  767. return s, err
  768. }
  769. case SFlowTypeOVSDPCounters:
  770. if record, err := decodeOVSDPCounters(data); err == nil {
  771. s.Records = append(s.Records, record)
  772. } else {
  773. return s, err
  774. }
  775. default:
  776. return s, fmt.Errorf("Invalid counter record type: %d", counterRecordType)
  777. }
  778. }
  779. return s, nil
  780. }
  781. // SFlowBaseFlowRecord holds the fields common to all records
  782. // of type SFlowFlowRecordType
  783. type SFlowBaseFlowRecord struct {
  784. EnterpriseID SFlowEnterpriseID
  785. Format SFlowFlowRecordType
  786. FlowDataLength uint32
  787. }
  788. func (bfr SFlowBaseFlowRecord) GetType() SFlowFlowRecordType {
  789. return bfr.Format
  790. }
  791. // SFlowFlowRecordType denotes what kind of Flow Record is
  792. // represented. See RFC 3176
  793. type SFlowFlowRecordType uint32
  794. const (
  795. SFlowTypeRawPacketFlow SFlowFlowRecordType = 1
  796. SFlowTypeEthernetFrameFlow SFlowFlowRecordType = 2
  797. SFlowTypeIpv4Flow SFlowFlowRecordType = 3
  798. SFlowTypeIpv6Flow SFlowFlowRecordType = 4
  799. SFlowTypeExtendedSwitchFlow SFlowFlowRecordType = 1001
  800. SFlowTypeExtendedRouterFlow SFlowFlowRecordType = 1002
  801. SFlowTypeExtendedGatewayFlow SFlowFlowRecordType = 1003
  802. SFlowTypeExtendedUserFlow SFlowFlowRecordType = 1004
  803. SFlowTypeExtendedUrlFlow SFlowFlowRecordType = 1005
  804. SFlowTypeExtendedMlpsFlow SFlowFlowRecordType = 1006
  805. SFlowTypeExtendedNatFlow SFlowFlowRecordType = 1007
  806. SFlowTypeExtendedMlpsTunnelFlow SFlowFlowRecordType = 1008
  807. SFlowTypeExtendedMlpsVcFlow SFlowFlowRecordType = 1009
  808. SFlowTypeExtendedMlpsFecFlow SFlowFlowRecordType = 1010
  809. SFlowTypeExtendedMlpsLvpFecFlow SFlowFlowRecordType = 1011
  810. SFlowTypeExtendedVlanFlow SFlowFlowRecordType = 1012
  811. SFlowTypeExtendedIpv4TunnelEgressFlow SFlowFlowRecordType = 1023
  812. SFlowTypeExtendedIpv4TunnelIngressFlow SFlowFlowRecordType = 1024
  813. SFlowTypeExtendedIpv6TunnelEgressFlow SFlowFlowRecordType = 1025
  814. SFlowTypeExtendedIpv6TunnelIngressFlow SFlowFlowRecordType = 1026
  815. SFlowTypeExtendedDecapsulateEgressFlow SFlowFlowRecordType = 1027
  816. SFlowTypeExtendedDecapsulateIngressFlow SFlowFlowRecordType = 1028
  817. SFlowTypeExtendedVniEgressFlow SFlowFlowRecordType = 1029
  818. SFlowTypeExtendedVniIngressFlow SFlowFlowRecordType = 1030
  819. )
  820. func (rt SFlowFlowRecordType) String() string {
  821. switch rt {
  822. case SFlowTypeRawPacketFlow:
  823. return "Raw Packet Flow Record"
  824. case SFlowTypeEthernetFrameFlow:
  825. return "Ethernet Frame Flow Record"
  826. case SFlowTypeIpv4Flow:
  827. return "IPv4 Flow Record"
  828. case SFlowTypeIpv6Flow:
  829. return "IPv6 Flow Record"
  830. case SFlowTypeExtendedSwitchFlow:
  831. return "Extended Switch Flow Record"
  832. case SFlowTypeExtendedRouterFlow:
  833. return "Extended Router Flow Record"
  834. case SFlowTypeExtendedGatewayFlow:
  835. return "Extended Gateway Flow Record"
  836. case SFlowTypeExtendedUserFlow:
  837. return "Extended User Flow Record"
  838. case SFlowTypeExtendedUrlFlow:
  839. return "Extended URL Flow Record"
  840. case SFlowTypeExtendedMlpsFlow:
  841. return "Extended MPLS Flow Record"
  842. case SFlowTypeExtendedNatFlow:
  843. return "Extended NAT Flow Record"
  844. case SFlowTypeExtendedMlpsTunnelFlow:
  845. return "Extended MPLS Tunnel Flow Record"
  846. case SFlowTypeExtendedMlpsVcFlow:
  847. return "Extended MPLS VC Flow Record"
  848. case SFlowTypeExtendedMlpsFecFlow:
  849. return "Extended MPLS FEC Flow Record"
  850. case SFlowTypeExtendedMlpsLvpFecFlow:
  851. return "Extended MPLS LVP FEC Flow Record"
  852. case SFlowTypeExtendedVlanFlow:
  853. return "Extended VLAN Flow Record"
  854. case SFlowTypeExtendedIpv4TunnelEgressFlow:
  855. return "Extended IPv4 Tunnel Egress Record"
  856. case SFlowTypeExtendedIpv4TunnelIngressFlow:
  857. return "Extended IPv4 Tunnel Ingress Record"
  858. case SFlowTypeExtendedIpv6TunnelEgressFlow:
  859. return "Extended IPv6 Tunnel Egress Record"
  860. case SFlowTypeExtendedIpv6TunnelIngressFlow:
  861. return "Extended IPv6 Tunnel Ingress Record"
  862. case SFlowTypeExtendedDecapsulateEgressFlow:
  863. return "Extended Decapsulate Egress Record"
  864. case SFlowTypeExtendedDecapsulateIngressFlow:
  865. return "Extended Decapsulate Ingress Record"
  866. case SFlowTypeExtendedVniEgressFlow:
  867. return "Extended VNI Ingress Record"
  868. case SFlowTypeExtendedVniIngressFlow:
  869. return "Extended VNI Ingress Record"
  870. default:
  871. return ""
  872. }
  873. }
  874. // SFlowRawPacketFlowRecords hold information about a sampled
  875. // packet grabbed as it transited the agent. This is
  876. // perhaps the most useful and interesting record type,
  877. // as it holds the headers of the sampled packet and
  878. // can be used to build up a complete picture of the
  879. // traffic patterns on a network.
  880. //
  881. // The raw packet header is sent back into gopacket for
  882. // decoding, and the resulting gopackt.Packet is stored
  883. // in the Header member
  884. type SFlowRawPacketFlowRecord struct {
  885. SFlowBaseFlowRecord
  886. HeaderProtocol SFlowRawHeaderProtocol
  887. FrameLength uint32
  888. PayloadRemoved uint32
  889. HeaderLength uint32
  890. Header gopacket.Packet
  891. }
  892. // Raw packet record types have the following structure:
  893. // 0 15 31
  894. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  895. // | 20 bit Interprise (0) |12 bit format |
  896. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  897. // | record length |
  898. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  899. // | Header Protocol |
  900. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  901. // | Frame Length |
  902. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  903. // | Payload Removed |
  904. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  905. // | Header Length |
  906. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  907. // \ Header \
  908. // \ \
  909. // \ \
  910. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  911. type SFlowRawHeaderProtocol uint32
  912. const (
  913. SFlowProtoEthernet SFlowRawHeaderProtocol = 1
  914. SFlowProtoISO88024 SFlowRawHeaderProtocol = 2
  915. SFlowProtoISO88025 SFlowRawHeaderProtocol = 3
  916. SFlowProtoFDDI SFlowRawHeaderProtocol = 4
  917. SFlowProtoFrameRelay SFlowRawHeaderProtocol = 5
  918. SFlowProtoX25 SFlowRawHeaderProtocol = 6
  919. SFlowProtoPPP SFlowRawHeaderProtocol = 7
  920. SFlowProtoSMDS SFlowRawHeaderProtocol = 8
  921. SFlowProtoAAL5 SFlowRawHeaderProtocol = 9
  922. SFlowProtoAAL5_IP SFlowRawHeaderProtocol = 10 /* e.g. Cisco AAL5 mux */
  923. SFlowProtoIPv4 SFlowRawHeaderProtocol = 11
  924. SFlowProtoIPv6 SFlowRawHeaderProtocol = 12
  925. SFlowProtoMPLS SFlowRawHeaderProtocol = 13
  926. SFlowProtoPOS SFlowRawHeaderProtocol = 14 /* RFC 1662, 2615 */
  927. )
  928. func (sfhp SFlowRawHeaderProtocol) String() string {
  929. switch sfhp {
  930. case SFlowProtoEthernet:
  931. return "ETHERNET-ISO88023"
  932. case SFlowProtoISO88024:
  933. return "ISO88024-TOKENBUS"
  934. case SFlowProtoISO88025:
  935. return "ISO88025-TOKENRING"
  936. case SFlowProtoFDDI:
  937. return "FDDI"
  938. case SFlowProtoFrameRelay:
  939. return "FRAME-RELAY"
  940. case SFlowProtoX25:
  941. return "X25"
  942. case SFlowProtoPPP:
  943. return "PPP"
  944. case SFlowProtoSMDS:
  945. return "SMDS"
  946. case SFlowProtoAAL5:
  947. return "AAL5"
  948. case SFlowProtoAAL5_IP:
  949. return "AAL5-IP"
  950. case SFlowProtoIPv4:
  951. return "IPv4"
  952. case SFlowProtoIPv6:
  953. return "IPv6"
  954. case SFlowProtoMPLS:
  955. return "MPLS"
  956. case SFlowProtoPOS:
  957. return "POS"
  958. }
  959. return "UNKNOWN"
  960. }
  961. func decodeRawPacketFlowRecord(data *[]byte) (SFlowRawPacketFlowRecord, error) {
  962. rec := SFlowRawPacketFlowRecord{}
  963. header := []byte{}
  964. var fdf SFlowFlowDataFormat
  965. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  966. rec.EnterpriseID, rec.Format = fdf.decode()
  967. *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  968. *data, rec.HeaderProtocol = (*data)[4:], SFlowRawHeaderProtocol(binary.BigEndian.Uint32((*data)[:4]))
  969. *data, rec.FrameLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  970. *data, rec.PayloadRemoved = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  971. *data, rec.HeaderLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  972. headerLenWithPadding := int(rec.HeaderLength + ((4 - rec.HeaderLength) % 4))
  973. *data, header = (*data)[headerLenWithPadding:], (*data)[:headerLenWithPadding]
  974. rec.Header = gopacket.NewPacket(header, LayerTypeEthernet, gopacket.Default)
  975. return rec, nil
  976. }
  977. // SFlowExtendedSwitchFlowRecord give additional information
  978. // about the sampled packet if it's available. It's mainly
  979. // useful for getting at the incoming and outgoing VLANs
  980. // An agent may or may not provide this information.
  981. type SFlowExtendedSwitchFlowRecord struct {
  982. SFlowBaseFlowRecord
  983. IncomingVLAN uint32
  984. IncomingVLANPriority uint32
  985. OutgoingVLAN uint32
  986. OutgoingVLANPriority uint32
  987. }
  988. // Extended switch records have the following structure:
  989. // 0 15 31
  990. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  991. // | 20 bit Interprise (0) |12 bit format |
  992. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  993. // | record length |
  994. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  995. // | Incoming VLAN |
  996. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  997. // | Incoming VLAN Priority |
  998. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  999. // | Outgoing VLAN |
  1000. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1001. // | Outgoing VLAN Priority |
  1002. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1003. func decodeExtendedSwitchFlowRecord(data *[]byte) (SFlowExtendedSwitchFlowRecord, error) {
  1004. es := SFlowExtendedSwitchFlowRecord{}
  1005. var fdf SFlowFlowDataFormat
  1006. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1007. es.EnterpriseID, es.Format = fdf.decode()
  1008. *data, es.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1009. *data, es.IncomingVLAN = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1010. *data, es.IncomingVLANPriority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1011. *data, es.OutgoingVLAN = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1012. *data, es.OutgoingVLANPriority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1013. return es, nil
  1014. }
  1015. // SFlowExtendedRouterFlowRecord gives additional information
  1016. // about the layer 3 routing information used to forward
  1017. // the packet
  1018. type SFlowExtendedRouterFlowRecord struct {
  1019. SFlowBaseFlowRecord
  1020. NextHop net.IP
  1021. NextHopSourceMask uint32
  1022. NextHopDestinationMask uint32
  1023. }
  1024. // Extended router records have the following structure:
  1025. // 0 15 31
  1026. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1027. // | 20 bit Interprise (0) |12 bit format |
  1028. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1029. // | record length |
  1030. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1031. // | IP version of next hop router (1=v4|2=v6) |
  1032. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1033. // / Next Hop address (v4=4byte|v6=16byte) /
  1034. // / /
  1035. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1036. // | Next Hop Source Mask |
  1037. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1038. // | Next Hop Destination Mask |
  1039. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1040. func decodeExtendedRouterFlowRecord(data *[]byte) (SFlowExtendedRouterFlowRecord, error) {
  1041. er := SFlowExtendedRouterFlowRecord{}
  1042. var fdf SFlowFlowDataFormat
  1043. var extendedRouterAddressType SFlowIPType
  1044. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1045. er.EnterpriseID, er.Format = fdf.decode()
  1046. *data, er.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1047. *data, extendedRouterAddressType = (*data)[4:], SFlowIPType(binary.BigEndian.Uint32((*data)[:4]))
  1048. *data, er.NextHop = (*data)[extendedRouterAddressType.Length():], (*data)[:extendedRouterAddressType.Length()]
  1049. *data, er.NextHopSourceMask = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1050. *data, er.NextHopDestinationMask = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1051. return er, nil
  1052. }
  1053. // SFlowExtendedGatewayFlowRecord describes information treasured by
  1054. // nework engineers everywhere: AS path information listing which
  1055. // BGP peer sent the packet, and various other BGP related info.
  1056. // This information is vital because it gives a picture of how much
  1057. // traffic is being sent from / received by various BGP peers.
  1058. // Extended gateway records have the following structure:
  1059. // 0 15 31
  1060. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1061. // | 20 bit Interprise (0) |12 bit format |
  1062. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1063. // | record length |
  1064. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1065. // | IP version of next hop router (1=v4|2=v6) |
  1066. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1067. // / Next Hop address (v4=4byte|v6=16byte) /
  1068. // / /
  1069. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1070. // | AS |
  1071. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1072. // | Source AS |
  1073. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1074. // | Peer AS |
  1075. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1076. // | AS Path Count |
  1077. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1078. // / AS Path / Sequence /
  1079. // / /
  1080. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1081. // / Communities /
  1082. // / /
  1083. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1084. // | Local Pref |
  1085. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1086. // AS Path / Sequence:
  1087. // 0 15 31
  1088. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1089. // | AS Source Type (Path=1 / Sequence=2) |
  1090. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1091. // | Path / Sequence length |
  1092. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1093. // / Path / Sequence Members /
  1094. // / /
  1095. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1096. // Communities:
  1097. // 0 15 31
  1098. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1099. // | communitiy length |
  1100. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1101. // / communitiy Members /
  1102. // / /
  1103. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1104. type SFlowExtendedGatewayFlowRecord struct {
  1105. SFlowBaseFlowRecord
  1106. NextHop net.IP
  1107. AS uint32
  1108. SourceAS uint32
  1109. PeerAS uint32
  1110. ASPathCount uint32
  1111. ASPath []SFlowASDestination
  1112. Communities []uint32
  1113. LocalPref uint32
  1114. }
  1115. type SFlowASPathType uint32
  1116. const (
  1117. SFlowASSet SFlowASPathType = 1
  1118. SFlowASSequence SFlowASPathType = 2
  1119. )
  1120. func (apt SFlowASPathType) String() string {
  1121. switch apt {
  1122. case SFlowASSet:
  1123. return "AS Set"
  1124. case SFlowASSequence:
  1125. return "AS Sequence"
  1126. default:
  1127. return ""
  1128. }
  1129. }
  1130. type SFlowASDestination struct {
  1131. Type SFlowASPathType
  1132. Count uint32
  1133. Members []uint32
  1134. }
  1135. func (asd SFlowASDestination) String() string {
  1136. switch asd.Type {
  1137. case SFlowASSet:
  1138. return fmt.Sprint("AS Set:", asd.Members)
  1139. case SFlowASSequence:
  1140. return fmt.Sprint("AS Sequence:", asd.Members)
  1141. default:
  1142. return ""
  1143. }
  1144. }
  1145. func (ad *SFlowASDestination) decodePath(data *[]byte) {
  1146. *data, ad.Type = (*data)[4:], SFlowASPathType(binary.BigEndian.Uint32((*data)[:4]))
  1147. *data, ad.Count = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1148. ad.Members = make([]uint32, ad.Count)
  1149. for i := uint32(0); i < ad.Count; i++ {
  1150. var member uint32
  1151. *data, member = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1152. ad.Members[i] = member
  1153. }
  1154. }
  1155. func decodeExtendedGatewayFlowRecord(data *[]byte) (SFlowExtendedGatewayFlowRecord, error) {
  1156. eg := SFlowExtendedGatewayFlowRecord{}
  1157. var fdf SFlowFlowDataFormat
  1158. var extendedGatewayAddressType SFlowIPType
  1159. var communitiesLength uint32
  1160. var community uint32
  1161. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1162. eg.EnterpriseID, eg.Format = fdf.decode()
  1163. *data, eg.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1164. *data, extendedGatewayAddressType = (*data)[4:], SFlowIPType(binary.BigEndian.Uint32((*data)[:4]))
  1165. *data, eg.NextHop = (*data)[extendedGatewayAddressType.Length():], (*data)[:extendedGatewayAddressType.Length()]
  1166. *data, eg.AS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1167. *data, eg.SourceAS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1168. *data, eg.PeerAS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1169. *data, eg.ASPathCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1170. for i := uint32(0); i < eg.ASPathCount; i++ {
  1171. asPath := SFlowASDestination{}
  1172. asPath.decodePath(data)
  1173. eg.ASPath = append(eg.ASPath, asPath)
  1174. }
  1175. *data, communitiesLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1176. eg.Communities = make([]uint32, communitiesLength)
  1177. for j := uint32(0); j < communitiesLength; j++ {
  1178. *data, community = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1179. eg.Communities[j] = community
  1180. }
  1181. *data, eg.LocalPref = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1182. return eg, nil
  1183. }
  1184. // **************************************************
  1185. // Extended URL Flow Record
  1186. // **************************************************
  1187. // 0 15 31
  1188. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1189. // | 20 bit Interprise (0) |12 bit format |
  1190. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1191. // | record length |
  1192. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1193. // | direction |
  1194. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1195. // | URL |
  1196. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1197. // | Host |
  1198. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1199. type SFlowURLDirection uint32
  1200. const (
  1201. SFlowURLsrc SFlowURLDirection = 1
  1202. SFlowURLdst SFlowURLDirection = 2
  1203. )
  1204. func (urld SFlowURLDirection) String() string {
  1205. switch urld {
  1206. case SFlowURLsrc:
  1207. return "Source address is the server"
  1208. case SFlowURLdst:
  1209. return "Destination address is the server"
  1210. default:
  1211. return ""
  1212. }
  1213. }
  1214. type SFlowExtendedURLRecord struct {
  1215. SFlowBaseFlowRecord
  1216. Direction SFlowURLDirection
  1217. URL string
  1218. Host string
  1219. }
  1220. func decodeExtendedURLRecord(data *[]byte) (SFlowExtendedURLRecord, error) {
  1221. eur := SFlowExtendedURLRecord{}
  1222. var fdf SFlowFlowDataFormat
  1223. var urlLen uint32
  1224. var urlLenWithPad int
  1225. var hostLen uint32
  1226. var hostLenWithPad int
  1227. var urlBytes []byte
  1228. var hostBytes []byte
  1229. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1230. eur.EnterpriseID, eur.Format = fdf.decode()
  1231. *data, eur.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1232. *data, eur.Direction = (*data)[4:], SFlowURLDirection(binary.BigEndian.Uint32((*data)[:4]))
  1233. *data, urlLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1234. urlLenWithPad = int(urlLen + ((4 - urlLen) % 4))
  1235. *data, urlBytes = (*data)[urlLenWithPad:], (*data)[:urlLenWithPad]
  1236. eur.URL = string(urlBytes[:urlLen])
  1237. *data, hostLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1238. hostLenWithPad = int(hostLen + ((4 - hostLen) % 4))
  1239. *data, hostBytes = (*data)[hostLenWithPad:], (*data)[:hostLenWithPad]
  1240. eur.Host = string(hostBytes[:hostLen])
  1241. return eur, nil
  1242. }
  1243. // **************************************************
  1244. // Extended User Flow Record
  1245. // **************************************************
  1246. // 0 15 31
  1247. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1248. // | 20 bit Interprise (0) |12 bit format |
  1249. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1250. // | record length |
  1251. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1252. // | Source Character Set |
  1253. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1254. // | Source User Id |
  1255. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1256. // | Destination Character Set |
  1257. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1258. // | Destination User ID |
  1259. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1260. type SFlowExtendedUserFlow struct {
  1261. SFlowBaseFlowRecord
  1262. SourceCharSet SFlowCharSet
  1263. SourceUserID string
  1264. DestinationCharSet SFlowCharSet
  1265. DestinationUserID string
  1266. }
  1267. type SFlowCharSet uint32
  1268. const (
  1269. SFlowCSunknown SFlowCharSet = 2
  1270. SFlowCSASCII SFlowCharSet = 3
  1271. SFlowCSISOLatin1 SFlowCharSet = 4
  1272. SFlowCSISOLatin2 SFlowCharSet = 5
  1273. SFlowCSISOLatin3 SFlowCharSet = 6
  1274. SFlowCSISOLatin4 SFlowCharSet = 7
  1275. SFlowCSISOLatinCyrillic SFlowCharSet = 8
  1276. SFlowCSISOLatinArabic SFlowCharSet = 9
  1277. SFlowCSISOLatinGreek SFlowCharSet = 10
  1278. SFlowCSISOLatinHebrew SFlowCharSet = 11
  1279. SFlowCSISOLatin5 SFlowCharSet = 12
  1280. SFlowCSISOLatin6 SFlowCharSet = 13
  1281. SFlowCSISOTextComm SFlowCharSet = 14
  1282. SFlowCSHalfWidthKatakana SFlowCharSet = 15
  1283. SFlowCSJISEncoding SFlowCharSet = 16
  1284. SFlowCSShiftJIS SFlowCharSet = 17
  1285. SFlowCSEUCPkdFmtJapanese SFlowCharSet = 18
  1286. SFlowCSEUCFixWidJapanese SFlowCharSet = 19
  1287. SFlowCSISO4UnitedKingdom SFlowCharSet = 20
  1288. SFlowCSISO11SwedishForNames SFlowCharSet = 21
  1289. SFlowCSISO15Italian SFlowCharSet = 22
  1290. SFlowCSISO17Spanish SFlowCharSet = 23
  1291. SFlowCSISO21German SFlowCharSet = 24
  1292. SFlowCSISO60DanishNorwegian SFlowCharSet = 25
  1293. SFlowCSISO69French SFlowCharSet = 26
  1294. SFlowCSISO10646UTF1 SFlowCharSet = 27
  1295. SFlowCSISO646basic1983 SFlowCharSet = 28
  1296. SFlowCSINVARIANT SFlowCharSet = 29
  1297. SFlowCSISO2IntlRefVersion SFlowCharSet = 30
  1298. SFlowCSNATSSEFI SFlowCharSet = 31
  1299. SFlowCSNATSSEFIADD SFlowCharSet = 32
  1300. SFlowCSNATSDANO SFlowCharSet = 33
  1301. SFlowCSNATSDANOADD SFlowCharSet = 34
  1302. SFlowCSISO10Swedish SFlowCharSet = 35
  1303. SFlowCSKSC56011987 SFlowCharSet = 36
  1304. SFlowCSISO2022KR SFlowCharSet = 37
  1305. SFlowCSEUCKR SFlowCharSet = 38
  1306. SFlowCSISO2022JP SFlowCharSet = 39
  1307. SFlowCSISO2022JP2 SFlowCharSet = 40
  1308. SFlowCSISO13JISC6220jp SFlowCharSet = 41
  1309. SFlowCSISO14JISC6220ro SFlowCharSet = 42
  1310. SFlowCSISO16Portuguese SFlowCharSet = 43
  1311. SFlowCSISO18Greek7Old SFlowCharSet = 44
  1312. SFlowCSISO19LatinGreek SFlowCharSet = 45
  1313. SFlowCSISO25French SFlowCharSet = 46
  1314. SFlowCSISO27LatinGreek1 SFlowCharSet = 47
  1315. SFlowCSISO5427Cyrillic SFlowCharSet = 48
  1316. SFlowCSISO42JISC62261978 SFlowCharSet = 49
  1317. SFlowCSISO47BSViewdata SFlowCharSet = 50
  1318. SFlowCSISO49INIS SFlowCharSet = 51
  1319. SFlowCSISO50INIS8 SFlowCharSet = 52
  1320. SFlowCSISO51INISCyrillic SFlowCharSet = 53
  1321. SFlowCSISO54271981 SFlowCharSet = 54
  1322. SFlowCSISO5428Greek SFlowCharSet = 55
  1323. SFlowCSISO57GB1988 SFlowCharSet = 56
  1324. SFlowCSISO58GB231280 SFlowCharSet = 57
  1325. SFlowCSISO61Norwegian2 SFlowCharSet = 58
  1326. SFlowCSISO70VideotexSupp1 SFlowCharSet = 59
  1327. SFlowCSISO84Portuguese2 SFlowCharSet = 60
  1328. SFlowCSISO85Spanish2 SFlowCharSet = 61
  1329. SFlowCSISO86Hungarian SFlowCharSet = 62
  1330. SFlowCSISO87JISX0208 SFlowCharSet = 63
  1331. SFlowCSISO88Greek7 SFlowCharSet = 64
  1332. SFlowCSISO89ASMO449 SFlowCharSet = 65
  1333. SFlowCSISO90 SFlowCharSet = 66
  1334. SFlowCSISO91JISC62291984a SFlowCharSet = 67
  1335. SFlowCSISO92JISC62991984b SFlowCharSet = 68
  1336. SFlowCSISO93JIS62291984badd SFlowCharSet = 69
  1337. SFlowCSISO94JIS62291984hand SFlowCharSet = 70
  1338. SFlowCSISO95JIS62291984handadd SFlowCharSet = 71
  1339. SFlowCSISO96JISC62291984kana SFlowCharSet = 72
  1340. SFlowCSISO2033 SFlowCharSet = 73
  1341. SFlowCSISO99NAPLPS SFlowCharSet = 74
  1342. SFlowCSISO102T617bit SFlowCharSet = 75
  1343. SFlowCSISO103T618bit SFlowCharSet = 76
  1344. SFlowCSISO111ECMACyrillic SFlowCharSet = 77
  1345. SFlowCSa71 SFlowCharSet = 78
  1346. SFlowCSa72 SFlowCharSet = 79
  1347. SFlowCSISO123CSAZ24341985gr SFlowCharSet = 80
  1348. SFlowCSISO88596E SFlowCharSet = 81
  1349. SFlowCSISO88596I SFlowCharSet = 82
  1350. SFlowCSISO128T101G2 SFlowCharSet = 83
  1351. SFlowCSISO88598E SFlowCharSet = 84
  1352. SFlowCSISO88598I SFlowCharSet = 85
  1353. SFlowCSISO139CSN369103 SFlowCharSet = 86
  1354. SFlowCSISO141JUSIB1002 SFlowCharSet = 87
  1355. SFlowCSISO143IECP271 SFlowCharSet = 88
  1356. SFlowCSISO146Serbian SFlowCharSet = 89
  1357. SFlowCSISO147Macedonian SFlowCharSet = 90
  1358. SFlowCSISO150 SFlowCharSet = 91
  1359. SFlowCSISO151Cuba SFlowCharSet = 92
  1360. SFlowCSISO6937Add SFlowCharSet = 93
  1361. SFlowCSISO153GOST1976874 SFlowCharSet = 94
  1362. SFlowCSISO8859Supp SFlowCharSet = 95
  1363. SFlowCSISO10367Box SFlowCharSet = 96
  1364. SFlowCSISO158Lap SFlowCharSet = 97
  1365. SFlowCSISO159JISX02121990 SFlowCharSet = 98
  1366. SFlowCSISO646Danish SFlowCharSet = 99
  1367. SFlowCSUSDK SFlowCharSet = 100
  1368. SFlowCSDKUS SFlowCharSet = 101
  1369. SFlowCSKSC5636 SFlowCharSet = 102
  1370. SFlowCSUnicode11UTF7 SFlowCharSet = 103
  1371. SFlowCSISO2022CN SFlowCharSet = 104
  1372. SFlowCSISO2022CNEXT SFlowCharSet = 105
  1373. SFlowCSUTF8 SFlowCharSet = 106
  1374. SFlowCSISO885913 SFlowCharSet = 109
  1375. SFlowCSISO885914 SFlowCharSet = 110
  1376. SFlowCSISO885915 SFlowCharSet = 111
  1377. SFlowCSISO885916 SFlowCharSet = 112
  1378. SFlowCSGBK SFlowCharSet = 113
  1379. SFlowCSGB18030 SFlowCharSet = 114
  1380. SFlowCSOSDEBCDICDF0415 SFlowCharSet = 115
  1381. SFlowCSOSDEBCDICDF03IRV SFlowCharSet = 116
  1382. SFlowCSOSDEBCDICDF041 SFlowCharSet = 117
  1383. SFlowCSISO115481 SFlowCharSet = 118
  1384. SFlowCSKZ1048 SFlowCharSet = 119
  1385. SFlowCSUnicode SFlowCharSet = 1000
  1386. SFlowCSUCS4 SFlowCharSet = 1001
  1387. SFlowCSUnicodeASCII SFlowCharSet = 1002
  1388. SFlowCSUnicodeLatin1 SFlowCharSet = 1003
  1389. SFlowCSUnicodeJapanese SFlowCharSet = 1004
  1390. SFlowCSUnicodeIBM1261 SFlowCharSet = 1005
  1391. SFlowCSUnicodeIBM1268 SFlowCharSet = 1006
  1392. SFlowCSUnicodeIBM1276 SFlowCharSet = 1007
  1393. SFlowCSUnicodeIBM1264 SFlowCharSet = 1008
  1394. SFlowCSUnicodeIBM1265 SFlowCharSet = 1009
  1395. SFlowCSUnicode11 SFlowCharSet = 1010
  1396. SFlowCSSCSU SFlowCharSet = 1011
  1397. SFlowCSUTF7 SFlowCharSet = 1012
  1398. SFlowCSUTF16BE SFlowCharSet = 1013
  1399. SFlowCSUTF16LE SFlowCharSet = 1014
  1400. SFlowCSUTF16 SFlowCharSet = 1015
  1401. SFlowCSCESU8 SFlowCharSet = 1016
  1402. SFlowCSUTF32 SFlowCharSet = 1017
  1403. SFlowCSUTF32BE SFlowCharSet = 1018
  1404. SFlowCSUTF32LE SFlowCharSet = 1019
  1405. SFlowCSBOCU1 SFlowCharSet = 1020
  1406. SFlowCSWindows30Latin1 SFlowCharSet = 2000
  1407. SFlowCSWindows31Latin1 SFlowCharSet = 2001
  1408. SFlowCSWindows31Latin2 SFlowCharSet = 2002
  1409. SFlowCSWindows31Latin5 SFlowCharSet = 2003
  1410. SFlowCSHPRoman8 SFlowCharSet = 2004
  1411. SFlowCSAdobeStandardEncoding SFlowCharSet = 2005
  1412. SFlowCSVenturaUS SFlowCharSet = 2006
  1413. SFlowCSVenturaInternational SFlowCharSet = 2007
  1414. SFlowCSDECMCS SFlowCharSet = 2008
  1415. SFlowCSPC850Multilingual SFlowCharSet = 2009
  1416. SFlowCSPCp852 SFlowCharSet = 2010
  1417. SFlowCSPC8CodePage437 SFlowCharSet = 2011
  1418. SFlowCSPC8DanishNorwegian SFlowCharSet = 2012
  1419. SFlowCSPC862LatinHebrew SFlowCharSet = 2013
  1420. SFlowCSPC8Turkish SFlowCharSet = 2014
  1421. SFlowCSIBMSymbols SFlowCharSet = 2015
  1422. SFlowCSIBMThai SFlowCharSet = 2016
  1423. SFlowCSHPLegal SFlowCharSet = 2017
  1424. SFlowCSHPPiFont SFlowCharSet = 2018
  1425. SFlowCSHPMath8 SFlowCharSet = 2019
  1426. SFlowCSHPPSMath SFlowCharSet = 2020
  1427. SFlowCSHPDesktop SFlowCharSet = 2021
  1428. SFlowCSVenturaMath SFlowCharSet = 2022
  1429. SFlowCSMicrosoftPublishing SFlowCharSet = 2023
  1430. SFlowCSWindows31J SFlowCharSet = 2024
  1431. SFlowCSGB2312 SFlowCharSet = 2025
  1432. SFlowCSBig5 SFlowCharSet = 2026
  1433. SFlowCSMacintosh SFlowCharSet = 2027
  1434. SFlowCSIBM037 SFlowCharSet = 2028
  1435. SFlowCSIBM038 SFlowCharSet = 2029
  1436. SFlowCSIBM273 SFlowCharSet = 2030
  1437. SFlowCSIBM274 SFlowCharSet = 2031
  1438. SFlowCSIBM275 SFlowCharSet = 2032
  1439. SFlowCSIBM277 SFlowCharSet = 2033
  1440. SFlowCSIBM278 SFlowCharSet = 2034
  1441. SFlowCSIBM280 SFlowCharSet = 2035
  1442. SFlowCSIBM281 SFlowCharSet = 2036
  1443. SFlowCSIBM284 SFlowCharSet = 2037
  1444. SFlowCSIBM285 SFlowCharSet = 2038
  1445. SFlowCSIBM290 SFlowCharSet = 2039
  1446. SFlowCSIBM297 SFlowCharSet = 2040
  1447. SFlowCSIBM420 SFlowCharSet = 2041
  1448. SFlowCSIBM423 SFlowCharSet = 2042
  1449. SFlowCSIBM424 SFlowCharSet = 2043
  1450. SFlowCSIBM500 SFlowCharSet = 2044
  1451. SFlowCSIBM851 SFlowCharSet = 2045
  1452. SFlowCSIBM855 SFlowCharSet = 2046
  1453. SFlowCSIBM857 SFlowCharSet = 2047
  1454. SFlowCSIBM860 SFlowCharSet = 2048
  1455. SFlowCSIBM861 SFlowCharSet = 2049
  1456. SFlowCSIBM863 SFlowCharSet = 2050
  1457. SFlowCSIBM864 SFlowCharSet = 2051
  1458. SFlowCSIBM865 SFlowCharSet = 2052
  1459. SFlowCSIBM868 SFlowCharSet = 2053
  1460. SFlowCSIBM869 SFlowCharSet = 2054
  1461. SFlowCSIBM870 SFlowCharSet = 2055
  1462. SFlowCSIBM871 SFlowCharSet = 2056
  1463. SFlowCSIBM880 SFlowCharSet = 2057
  1464. SFlowCSIBM891 SFlowCharSet = 2058
  1465. SFlowCSIBM903 SFlowCharSet = 2059
  1466. SFlowCSIBBM904 SFlowCharSet = 2060
  1467. SFlowCSIBM905 SFlowCharSet = 2061
  1468. SFlowCSIBM918 SFlowCharSet = 2062
  1469. SFlowCSIBM1026 SFlowCharSet = 2063
  1470. SFlowCSIBMEBCDICATDE SFlowCharSet = 2064
  1471. SFlowCSEBCDICATDEA SFlowCharSet = 2065
  1472. SFlowCSEBCDICCAFR SFlowCharSet = 2066
  1473. SFlowCSEBCDICDKNO SFlowCharSet = 2067
  1474. SFlowCSEBCDICDKNOA SFlowCharSet = 2068
  1475. SFlowCSEBCDICFISE SFlowCharSet = 2069
  1476. SFlowCSEBCDICFISEA SFlowCharSet = 2070
  1477. SFlowCSEBCDICFR SFlowCharSet = 2071
  1478. SFlowCSEBCDICIT SFlowCharSet = 2072
  1479. SFlowCSEBCDICPT SFlowCharSet = 2073
  1480. SFlowCSEBCDICES SFlowCharSet = 2074
  1481. SFlowCSEBCDICESA SFlowCharSet = 2075
  1482. SFlowCSEBCDICESS SFlowCharSet = 2076
  1483. SFlowCSEBCDICUK SFlowCharSet = 2077
  1484. SFlowCSEBCDICUS SFlowCharSet = 2078
  1485. SFlowCSUnknown8BiT SFlowCharSet = 2079
  1486. SFlowCSMnemonic SFlowCharSet = 2080
  1487. SFlowCSMnem SFlowCharSet = 2081
  1488. SFlowCSVISCII SFlowCharSet = 2082
  1489. SFlowCSVIQR SFlowCharSet = 2083
  1490. SFlowCSKOI8R SFlowCharSet = 2084
  1491. SFlowCSHZGB2312 SFlowCharSet = 2085
  1492. SFlowCSIBM866 SFlowCharSet = 2086
  1493. SFlowCSPC775Baltic SFlowCharSet = 2087
  1494. SFlowCSKOI8U SFlowCharSet = 2088
  1495. SFlowCSIBM00858 SFlowCharSet = 2089
  1496. SFlowCSIBM00924 SFlowCharSet = 2090
  1497. SFlowCSIBM01140 SFlowCharSet = 2091
  1498. SFlowCSIBM01141 SFlowCharSet = 2092
  1499. SFlowCSIBM01142 SFlowCharSet = 2093
  1500. SFlowCSIBM01143 SFlowCharSet = 2094
  1501. SFlowCSIBM01144 SFlowCharSet = 2095
  1502. SFlowCSIBM01145 SFlowCharSet = 2096
  1503. SFlowCSIBM01146 SFlowCharSet = 2097
  1504. SFlowCSIBM01147 SFlowCharSet = 2098
  1505. SFlowCSIBM01148 SFlowCharSet = 2099
  1506. SFlowCSIBM01149 SFlowCharSet = 2100
  1507. SFlowCSBig5HKSCS SFlowCharSet = 2101
  1508. SFlowCSIBM1047 SFlowCharSet = 2102
  1509. SFlowCSPTCP154 SFlowCharSet = 2103
  1510. SFlowCSAmiga1251 SFlowCharSet = 2104
  1511. SFlowCSKOI7switched SFlowCharSet = 2105
  1512. SFlowCSBRF SFlowCharSet = 2106
  1513. SFlowCSTSCII SFlowCharSet = 2107
  1514. SFlowCSCP51932 SFlowCharSet = 2108
  1515. SFlowCSWindows874 SFlowCharSet = 2109
  1516. SFlowCSWindows1250 SFlowCharSet = 2250
  1517. SFlowCSWindows1251 SFlowCharSet = 2251
  1518. SFlowCSWindows1252 SFlowCharSet = 2252
  1519. SFlowCSWindows1253 SFlowCharSet = 2253
  1520. SFlowCSWindows1254 SFlowCharSet = 2254
  1521. SFlowCSWindows1255 SFlowCharSet = 2255
  1522. SFlowCSWindows1256 SFlowCharSet = 2256
  1523. SFlowCSWindows1257 SFlowCharSet = 2257
  1524. SFlowCSWindows1258 SFlowCharSet = 2258
  1525. SFlowCSTIS620 SFlowCharSet = 2259
  1526. SFlowCS50220 SFlowCharSet = 2260
  1527. SFlowCSreserved SFlowCharSet = 3000
  1528. )
  1529. func decodeExtendedUserFlow(data *[]byte) (SFlowExtendedUserFlow, error) {
  1530. eu := SFlowExtendedUserFlow{}
  1531. var fdf SFlowFlowDataFormat
  1532. var srcUserLen uint32
  1533. var srcUserLenWithPad int
  1534. var srcUserBytes []byte
  1535. var dstUserLen uint32
  1536. var dstUserLenWithPad int
  1537. var dstUserBytes []byte
  1538. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1539. eu.EnterpriseID, eu.Format = fdf.decode()
  1540. *data, eu.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1541. *data, eu.SourceCharSet = (*data)[4:], SFlowCharSet(binary.BigEndian.Uint32((*data)[:4]))
  1542. *data, srcUserLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1543. srcUserLenWithPad = int(srcUserLen + ((4 - srcUserLen) % 4))
  1544. *data, srcUserBytes = (*data)[srcUserLenWithPad:], (*data)[:srcUserLenWithPad]
  1545. eu.SourceUserID = string(srcUserBytes[:srcUserLen])
  1546. *data, eu.DestinationCharSet = (*data)[4:], SFlowCharSet(binary.BigEndian.Uint32((*data)[:4]))
  1547. *data, dstUserLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1548. dstUserLenWithPad = int(dstUserLen + ((4 - dstUserLen) % 4))
  1549. *data, dstUserBytes = (*data)[dstUserLenWithPad:], (*data)[:dstUserLenWithPad]
  1550. eu.DestinationUserID = string(dstUserBytes[:dstUserLen])
  1551. return eu, nil
  1552. }
  1553. // **************************************************
  1554. // Packet IP version 4 Record
  1555. // **************************************************
  1556. // 0 15 31
  1557. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1558. // | Length |
  1559. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1560. // | Protocol |
  1561. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1562. // | Source IPv4 |
  1563. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1564. // | Destination IPv4 |
  1565. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1566. // | Source Port |
  1567. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1568. // | Destionation Port |
  1569. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1570. // | TCP Flags |
  1571. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1572. // | TOS |
  1573. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1574. type SFlowIpv4Record struct {
  1575. // The length of the IP packet excluding ower layer encapsulations
  1576. Length uint32
  1577. // IP Protocol type (for example, TCP = 6, UDP = 17)
  1578. Protocol uint32
  1579. // Source IP Address
  1580. IPSrc net.IP
  1581. // Destination IP Address
  1582. IPDst net.IP
  1583. // TCP/UDP source port number or equivalent
  1584. PortSrc uint32
  1585. // TCP/UDP destination port number or equivalent
  1586. PortDst uint32
  1587. // TCP flags
  1588. TCPFlags uint32
  1589. // IP type of service
  1590. TOS uint32
  1591. }
  1592. func decodeSFlowIpv4Record(data *[]byte) (SFlowIpv4Record, error) {
  1593. si := SFlowIpv4Record{}
  1594. *data, si.Length = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1595. *data, si.Protocol = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1596. *data, si.IPSrc = (*data)[4:], net.IP((*data)[:4])
  1597. *data, si.IPDst = (*data)[4:], net.IP((*data)[:4])
  1598. *data, si.PortSrc = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1599. *data, si.PortDst = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1600. *data, si.TCPFlags = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1601. *data, si.TOS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1602. return si, nil
  1603. }
  1604. // **************************************************
  1605. // Packet IP version 6 Record
  1606. // **************************************************
  1607. // 0 15 31
  1608. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1609. // | Length |
  1610. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1611. // | Protocol |
  1612. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1613. // | Source IPv4 |
  1614. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1615. // | Destination IPv4 |
  1616. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1617. // | Source Port |
  1618. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1619. // | Destionation Port |
  1620. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1621. // | TCP Flags |
  1622. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1623. // | Priority |
  1624. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1625. type SFlowIpv6Record struct {
  1626. // The length of the IP packet excluding ower layer encapsulations
  1627. Length uint32
  1628. // IP Protocol type (for example, TCP = 6, UDP = 17)
  1629. Protocol uint32
  1630. // Source IP Address
  1631. IPSrc net.IP
  1632. // Destination IP Address
  1633. IPDst net.IP
  1634. // TCP/UDP source port number or equivalent
  1635. PortSrc uint32
  1636. // TCP/UDP destination port number or equivalent
  1637. PortDst uint32
  1638. // TCP flags
  1639. TCPFlags uint32
  1640. // IP priority
  1641. Priority uint32
  1642. }
  1643. func decodeSFlowIpv6Record(data *[]byte) (SFlowIpv6Record, error) {
  1644. si := SFlowIpv6Record{}
  1645. *data, si.Length = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1646. *data, si.Protocol = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1647. *data, si.IPSrc = (*data)[16:], net.IP((*data)[:16])
  1648. *data, si.IPDst = (*data)[16:], net.IP((*data)[:16])
  1649. *data, si.PortSrc = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1650. *data, si.PortDst = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1651. *data, si.TCPFlags = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1652. *data, si.Priority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1653. return si, nil
  1654. }
  1655. // **************************************************
  1656. // Extended IPv4 Tunnel Egress
  1657. // **************************************************
  1658. // 0 15 31
  1659. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1660. // | 20 bit Interprise (0) |12 bit format |
  1661. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1662. // | record length |
  1663. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1664. // / Packet IP version 4 Record /
  1665. // / /
  1666. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1667. type SFlowExtendedIpv4TunnelEgressRecord struct {
  1668. SFlowBaseFlowRecord
  1669. SFlowIpv4Record SFlowIpv4Record
  1670. }
  1671. func decodeExtendedIpv4TunnelEgress(data *[]byte) (SFlowExtendedIpv4TunnelEgressRecord, error) {
  1672. rec := SFlowExtendedIpv4TunnelEgressRecord{}
  1673. var fdf SFlowFlowDataFormat
  1674. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1675. rec.EnterpriseID, rec.Format = fdf.decode()
  1676. *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1677. rec.SFlowIpv4Record, _ = decodeSFlowIpv4Record(data)
  1678. return rec, nil
  1679. }
  1680. // **************************************************
  1681. // Extended IPv4 Tunnel Ingress
  1682. // **************************************************
  1683. // 0 15 31
  1684. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1685. // | 20 bit Interprise (0) |12 bit format |
  1686. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1687. // | record length |
  1688. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1689. // / Packet IP version 4 Record /
  1690. // / /
  1691. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1692. type SFlowExtendedIpv4TunnelIngressRecord struct {
  1693. SFlowBaseFlowRecord
  1694. SFlowIpv4Record SFlowIpv4Record
  1695. }
  1696. func decodeExtendedIpv4TunnelIngress(data *[]byte) (SFlowExtendedIpv4TunnelIngressRecord, error) {
  1697. rec := SFlowExtendedIpv4TunnelIngressRecord{}
  1698. var fdf SFlowFlowDataFormat
  1699. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1700. rec.EnterpriseID, rec.Format = fdf.decode()
  1701. *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1702. rec.SFlowIpv4Record, _ = decodeSFlowIpv4Record(data)
  1703. return rec, nil
  1704. }
  1705. // **************************************************
  1706. // Extended IPv6 Tunnel Egress
  1707. // **************************************************
  1708. // 0 15 31
  1709. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1710. // | 20 bit Interprise (0) |12 bit format |
  1711. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1712. // | record length |
  1713. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1714. // / Packet IP version 6 Record /
  1715. // / /
  1716. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1717. type SFlowExtendedIpv6TunnelEgressRecord struct {
  1718. SFlowBaseFlowRecord
  1719. SFlowIpv6Record
  1720. }
  1721. func decodeExtendedIpv6TunnelEgress(data *[]byte) (SFlowExtendedIpv6TunnelEgressRecord, error) {
  1722. rec := SFlowExtendedIpv6TunnelEgressRecord{}
  1723. var fdf SFlowFlowDataFormat
  1724. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1725. rec.EnterpriseID, rec.Format = fdf.decode()
  1726. *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1727. rec.SFlowIpv6Record, _ = decodeSFlowIpv6Record(data)
  1728. return rec, nil
  1729. }
  1730. // **************************************************
  1731. // Extended IPv6 Tunnel Ingress
  1732. // **************************************************
  1733. // 0 15 31
  1734. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1735. // | 20 bit Interprise (0) |12 bit format |
  1736. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1737. // | record length |
  1738. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1739. // / Packet IP version 6 Record /
  1740. // / /
  1741. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1742. type SFlowExtendedIpv6TunnelIngressRecord struct {
  1743. SFlowBaseFlowRecord
  1744. SFlowIpv6Record
  1745. }
  1746. func decodeExtendedIpv6TunnelIngress(data *[]byte) (SFlowExtendedIpv6TunnelIngressRecord, error) {
  1747. rec := SFlowExtendedIpv6TunnelIngressRecord{}
  1748. var fdf SFlowFlowDataFormat
  1749. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1750. rec.EnterpriseID, rec.Format = fdf.decode()
  1751. *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1752. rec.SFlowIpv6Record, _ = decodeSFlowIpv6Record(data)
  1753. return rec, nil
  1754. }
  1755. // **************************************************
  1756. // Extended Decapsulate Egress
  1757. // **************************************************
  1758. // 0 15 31
  1759. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1760. // | 20 bit Interprise (0) |12 bit format |
  1761. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1762. // | record length |
  1763. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1764. // | Inner Header Offset |
  1765. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1766. type SFlowExtendedDecapsulateEgressRecord struct {
  1767. SFlowBaseFlowRecord
  1768. InnerHeaderOffset uint32
  1769. }
  1770. func decodeExtendedDecapsulateEgress(data *[]byte) (SFlowExtendedDecapsulateEgressRecord, error) {
  1771. rec := SFlowExtendedDecapsulateEgressRecord{}
  1772. var fdf SFlowFlowDataFormat
  1773. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1774. rec.EnterpriseID, rec.Format = fdf.decode()
  1775. *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1776. *data, rec.InnerHeaderOffset = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1777. return rec, nil
  1778. }
  1779. // **************************************************
  1780. // Extended Decapsulate Ingress
  1781. // **************************************************
  1782. // 0 15 31
  1783. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1784. // | 20 bit Interprise (0) |12 bit format |
  1785. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1786. // | record length |
  1787. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1788. // | Inner Header Offset |
  1789. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1790. type SFlowExtendedDecapsulateIngressRecord struct {
  1791. SFlowBaseFlowRecord
  1792. InnerHeaderOffset uint32
  1793. }
  1794. func decodeExtendedDecapsulateIngress(data *[]byte) (SFlowExtendedDecapsulateIngressRecord, error) {
  1795. rec := SFlowExtendedDecapsulateIngressRecord{}
  1796. var fdf SFlowFlowDataFormat
  1797. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1798. rec.EnterpriseID, rec.Format = fdf.decode()
  1799. *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1800. *data, rec.InnerHeaderOffset = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1801. return rec, nil
  1802. }
  1803. // **************************************************
  1804. // Extended VNI Egress
  1805. // **************************************************
  1806. // 0 15 31
  1807. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1808. // | 20 bit Interprise (0) |12 bit format |
  1809. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1810. // | record length |
  1811. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1812. // | VNI |
  1813. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1814. type SFlowExtendedVniEgressRecord struct {
  1815. SFlowBaseFlowRecord
  1816. VNI uint32
  1817. }
  1818. func decodeExtendedVniEgress(data *[]byte) (SFlowExtendedVniEgressRecord, error) {
  1819. rec := SFlowExtendedVniEgressRecord{}
  1820. var fdf SFlowFlowDataFormat
  1821. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1822. rec.EnterpriseID, rec.Format = fdf.decode()
  1823. *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1824. *data, rec.VNI = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1825. return rec, nil
  1826. }
  1827. // **************************************************
  1828. // Extended VNI Ingress
  1829. // **************************************************
  1830. // 0 15 31
  1831. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1832. // | 20 bit Interprise (0) |12 bit format |
  1833. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1834. // | record length |
  1835. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1836. // | VNI |
  1837. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1838. type SFlowExtendedVniIngressRecord struct {
  1839. SFlowBaseFlowRecord
  1840. VNI uint32
  1841. }
  1842. func decodeExtendedVniIngress(data *[]byte) (SFlowExtendedVniIngressRecord, error) {
  1843. rec := SFlowExtendedVniIngressRecord{}
  1844. var fdf SFlowFlowDataFormat
  1845. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1846. rec.EnterpriseID, rec.Format = fdf.decode()
  1847. *data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1848. *data, rec.VNI = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1849. return rec, nil
  1850. }
  1851. // **************************************************
  1852. // Counter Record
  1853. // **************************************************
  1854. // 0 15 31
  1855. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1856. // | 20 bit Interprise (0) |12 bit format |
  1857. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1858. // | counter length |
  1859. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1860. // / counter data /
  1861. // / /
  1862. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1863. type SFlowBaseCounterRecord struct {
  1864. EnterpriseID SFlowEnterpriseID
  1865. Format SFlowCounterRecordType
  1866. FlowDataLength uint32
  1867. }
  1868. func (bcr SFlowBaseCounterRecord) GetType() SFlowCounterRecordType {
  1869. switch bcr.Format {
  1870. case SFlowTypeGenericInterfaceCounters:
  1871. return SFlowTypeGenericInterfaceCounters
  1872. case SFlowTypeEthernetInterfaceCounters:
  1873. return SFlowTypeEthernetInterfaceCounters
  1874. case SFlowTypeTokenRingInterfaceCounters:
  1875. return SFlowTypeTokenRingInterfaceCounters
  1876. case SFlowType100BaseVGInterfaceCounters:
  1877. return SFlowType100BaseVGInterfaceCounters
  1878. case SFlowTypeVLANCounters:
  1879. return SFlowTypeVLANCounters
  1880. case SFlowTypeLACPCounters:
  1881. return SFlowTypeLACPCounters
  1882. case SFlowTypeProcessorCounters:
  1883. return SFlowTypeProcessorCounters
  1884. case SFlowTypeOpenflowPortCounters:
  1885. return SFlowTypeOpenflowPortCounters
  1886. case SFlowTypePORTNAMECounters:
  1887. return SFlowTypePORTNAMECounters
  1888. case SFLowTypeAPPRESOURCESCounters:
  1889. return SFLowTypeAPPRESOURCESCounters
  1890. case SFlowTypeOVSDPCounters:
  1891. return SFlowTypeOVSDPCounters
  1892. }
  1893. unrecognized := fmt.Sprint("Unrecognized counter record type:", bcr.Format)
  1894. panic(unrecognized)
  1895. }
  1896. // **************************************************
  1897. // Counter Record
  1898. // **************************************************
  1899. // 0 15 31
  1900. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1901. // | 20 bit Interprise (0) |12 bit format |
  1902. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1903. // | counter length |
  1904. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1905. // | IfIndex |
  1906. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1907. // | IfType |
  1908. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1909. // | IfSpeed |
  1910. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1911. // | IfDirection |
  1912. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1913. // | IfStatus |
  1914. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1915. // | IFInOctets |
  1916. // | |
  1917. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1918. // | IfInUcastPkts |
  1919. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1920. // | IfInMulticastPkts |
  1921. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1922. // | IfInBroadcastPkts |
  1923. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1924. // | IfInDiscards |
  1925. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1926. // | InInErrors |
  1927. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1928. // | IfInUnknownProtos |
  1929. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1930. // | IfOutOctets |
  1931. // | |
  1932. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1933. // | IfOutUcastPkts |
  1934. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1935. // | IfOutMulticastPkts |
  1936. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1937. // | IfOutBroadcastPkts |
  1938. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1939. // | IfOutDiscards |
  1940. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1941. // | IfOUtErrors |
  1942. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1943. // | IfPromiscouousMode |
  1944. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1945. type SFlowGenericInterfaceCounters struct {
  1946. SFlowBaseCounterRecord
  1947. IfIndex uint32
  1948. IfType uint32
  1949. IfSpeed uint64
  1950. IfDirection uint32
  1951. IfStatus uint32
  1952. IfInOctets uint64
  1953. IfInUcastPkts uint32
  1954. IfInMulticastPkts uint32
  1955. IfInBroadcastPkts uint32
  1956. IfInDiscards uint32
  1957. IfInErrors uint32
  1958. IfInUnknownProtos uint32
  1959. IfOutOctets uint64
  1960. IfOutUcastPkts uint32
  1961. IfOutMulticastPkts uint32
  1962. IfOutBroadcastPkts uint32
  1963. IfOutDiscards uint32
  1964. IfOutErrors uint32
  1965. IfPromiscuousMode uint32
  1966. }
  1967. func decodeGenericInterfaceCounters(data *[]byte) (SFlowGenericInterfaceCounters, error) {
  1968. gic := SFlowGenericInterfaceCounters{}
  1969. var cdf SFlowCounterDataFormat
  1970. *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  1971. gic.EnterpriseID, gic.Format = cdf.decode()
  1972. *data, gic.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1973. *data, gic.IfIndex = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1974. *data, gic.IfType = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1975. *data, gic.IfSpeed = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])
  1976. *data, gic.IfDirection = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1977. *data, gic.IfStatus = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1978. *data, gic.IfInOctets = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])
  1979. *data, gic.IfInUcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1980. *data, gic.IfInMulticastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1981. *data, gic.IfInBroadcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1982. *data, gic.IfInDiscards = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1983. *data, gic.IfInErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1984. *data, gic.IfInUnknownProtos = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1985. *data, gic.IfOutOctets = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])
  1986. *data, gic.IfOutUcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1987. *data, gic.IfOutMulticastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1988. *data, gic.IfOutBroadcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1989. *data, gic.IfOutDiscards = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1990. *data, gic.IfOutErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1991. *data, gic.IfPromiscuousMode = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  1992. return gic, nil
  1993. }
  1994. // **************************************************
  1995. // Counter Record
  1996. // **************************************************
  1997. // 0 15 31
  1998. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  1999. // | 20 bit Interprise (0) |12 bit format |
  2000. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2001. // | counter length |
  2002. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2003. // / counter data /
  2004. // / /
  2005. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2006. type SFlowEthernetCounters struct {
  2007. SFlowBaseCounterRecord
  2008. AlignmentErrors uint32
  2009. FCSErrors uint32
  2010. SingleCollisionFrames uint32
  2011. MultipleCollisionFrames uint32
  2012. SQETestErrors uint32
  2013. DeferredTransmissions uint32
  2014. LateCollisions uint32
  2015. ExcessiveCollisions uint32
  2016. InternalMacTransmitErrors uint32
  2017. CarrierSenseErrors uint32
  2018. FrameTooLongs uint32
  2019. InternalMacReceiveErrors uint32
  2020. SymbolErrors uint32
  2021. }
  2022. func decodeEthernetCounters(data *[]byte) (SFlowEthernetCounters, error) {
  2023. ec := SFlowEthernetCounters{}
  2024. var cdf SFlowCounterDataFormat
  2025. *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  2026. ec.EnterpriseID, ec.Format = cdf.decode()
  2027. if len(*data) < 4 {
  2028. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2029. }
  2030. *data, ec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2031. if len(*data) < 4 {
  2032. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2033. }
  2034. *data, ec.AlignmentErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2035. if len(*data) < 4 {
  2036. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2037. }
  2038. *data, ec.FCSErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2039. if len(*data) < 4 {
  2040. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2041. }
  2042. *data, ec.SingleCollisionFrames = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2043. if len(*data) < 4 {
  2044. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2045. }
  2046. *data, ec.MultipleCollisionFrames = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2047. if len(*data) < 4 {
  2048. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2049. }
  2050. *data, ec.SQETestErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2051. if len(*data) < 4 {
  2052. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2053. }
  2054. *data, ec.DeferredTransmissions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2055. if len(*data) < 4 {
  2056. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2057. }
  2058. *data, ec.LateCollisions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2059. if len(*data) < 4 {
  2060. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2061. }
  2062. *data, ec.ExcessiveCollisions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2063. if len(*data) < 4 {
  2064. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2065. }
  2066. *data, ec.InternalMacTransmitErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2067. if len(*data) < 4 {
  2068. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2069. }
  2070. *data, ec.CarrierSenseErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2071. if len(*data) < 4 {
  2072. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2073. }
  2074. *data, ec.FrameTooLongs = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2075. if len(*data) < 4 {
  2076. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2077. }
  2078. *data, ec.InternalMacReceiveErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2079. if len(*data) < 4 {
  2080. return SFlowEthernetCounters{}, errors.New("ethernet counters too small")
  2081. }
  2082. *data, ec.SymbolErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2083. return ec, nil
  2084. }
  2085. // VLAN Counter
  2086. type SFlowVLANCounters struct {
  2087. SFlowBaseCounterRecord
  2088. VlanID uint32
  2089. Octets uint64
  2090. UcastPkts uint32
  2091. MulticastPkts uint32
  2092. BroadcastPkts uint32
  2093. Discards uint32
  2094. }
  2095. func decodeVLANCounters(data *[]byte) (SFlowVLANCounters, error) {
  2096. vc := SFlowVLANCounters{}
  2097. var cdf SFlowCounterDataFormat
  2098. *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  2099. vc.EnterpriseID, vc.Format = cdf.decode()
  2100. vc.EnterpriseID, vc.Format = cdf.decode()
  2101. *data, vc.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2102. *data, vc.VlanID = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2103. *data, vc.Octets = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])
  2104. *data, vc.UcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2105. *data, vc.MulticastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2106. *data, vc.BroadcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2107. *data, vc.Discards = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2108. return vc, nil
  2109. }
  2110. //SFLLACPportState : SFlow LACP Port State (All(4) - 32 bit)
  2111. type SFLLACPPortState struct {
  2112. PortStateAll uint32
  2113. }
  2114. //LACPcounters : LACP SFlow Counters ( 64 Bytes )
  2115. type SFlowLACPCounters struct {
  2116. SFlowBaseCounterRecord
  2117. ActorSystemID net.HardwareAddr
  2118. PartnerSystemID net.HardwareAddr
  2119. AttachedAggID uint32
  2120. LacpPortState SFLLACPPortState
  2121. LACPDUsRx uint32
  2122. MarkerPDUsRx uint32
  2123. MarkerResponsePDUsRx uint32
  2124. UnknownRx uint32
  2125. IllegalRx uint32
  2126. LACPDUsTx uint32
  2127. MarkerPDUsTx uint32
  2128. MarkerResponsePDUsTx uint32
  2129. }
  2130. func decodeLACPCounters(data *[]byte) (SFlowLACPCounters, error) {
  2131. la := SFlowLACPCounters{}
  2132. var cdf SFlowCounterDataFormat
  2133. *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  2134. la.EnterpriseID, la.Format = cdf.decode()
  2135. *data, la.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2136. *data, la.ActorSystemID = (*data)[6:], (*data)[:6]
  2137. *data = (*data)[2:] // remove padding
  2138. *data, la.PartnerSystemID = (*data)[6:], (*data)[:6]
  2139. *data = (*data)[2:] //remove padding
  2140. *data, la.AttachedAggID = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2141. *data, la.LacpPortState.PortStateAll = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2142. *data, la.LACPDUsRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2143. *data, la.MarkerPDUsRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2144. *data, la.MarkerResponsePDUsRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2145. *data, la.UnknownRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2146. *data, la.IllegalRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2147. *data, la.LACPDUsTx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2148. *data, la.MarkerPDUsTx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2149. *data, la.MarkerResponsePDUsTx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2150. return la, nil
  2151. }
  2152. // **************************************************
  2153. // Processor Counter Record
  2154. // **************************************************
  2155. // 0 15 31
  2156. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2157. // | 20 bit Interprise (0) |12 bit format |
  2158. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2159. // | counter length |
  2160. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2161. // | FiveSecCpu |
  2162. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2163. // | OneMinCpu |
  2164. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2165. // | GiveMinCpu |
  2166. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2167. // | TotalMemory |
  2168. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2169. // | FreeMemory |
  2170. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2171. type SFlowProcessorCounters struct {
  2172. SFlowBaseCounterRecord
  2173. FiveSecCpu uint32 // 5 second average CPU utilization
  2174. OneMinCpu uint32 // 1 minute average CPU utilization
  2175. FiveMinCpu uint32 // 5 minute average CPU utilization
  2176. TotalMemory uint64 // total memory (in bytes)
  2177. FreeMemory uint64 // free memory (in bytes)
  2178. }
  2179. func decodeProcessorCounters(data *[]byte) (SFlowProcessorCounters, error) {
  2180. pc := SFlowProcessorCounters{}
  2181. var cdf SFlowCounterDataFormat
  2182. var high32, low32 uint32
  2183. *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  2184. pc.EnterpriseID, pc.Format = cdf.decode()
  2185. *data, pc.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2186. *data, pc.FiveSecCpu = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2187. *data, pc.OneMinCpu = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2188. *data, pc.FiveMinCpu = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2189. *data, high32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2190. *data, low32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2191. pc.TotalMemory = (uint64(high32) << 32) + uint64(low32)
  2192. *data, high32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2193. *data, low32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2194. pc.FreeMemory = (uint64(high32)) + uint64(low32)
  2195. return pc, nil
  2196. }
  2197. // SFlowEthernetFrameFlowRecord give additional information
  2198. // about the sampled packet if it's available.
  2199. // An agent may or may not provide this information.
  2200. type SFlowEthernetFrameFlowRecord struct {
  2201. SFlowBaseFlowRecord
  2202. FrameLength uint32
  2203. SrcMac net.HardwareAddr
  2204. DstMac net.HardwareAddr
  2205. Type uint32
  2206. }
  2207. // Ethernet frame flow records have the following structure:
  2208. // 0 15 31
  2209. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2210. // | 20 bit Interprise (0) |12 bit format |
  2211. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2212. // | record length |
  2213. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2214. // | Source Mac Address |
  2215. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2216. // | Destination Mac Address |
  2217. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2218. // | Ethernet Packet Type |
  2219. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  2220. func decodeEthernetFrameFlowRecord(data *[]byte) (SFlowEthernetFrameFlowRecord, error) {
  2221. es := SFlowEthernetFrameFlowRecord{}
  2222. var fdf SFlowFlowDataFormat
  2223. *data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  2224. es.EnterpriseID, es.Format = fdf.decode()
  2225. *data, es.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2226. *data, es.FrameLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2227. *data, es.SrcMac = (*data)[8:], net.HardwareAddr((*data)[:6])
  2228. *data, es.DstMac = (*data)[8:], net.HardwareAddr((*data)[:6])
  2229. *data, es.Type = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2230. return es, nil
  2231. }
  2232. //SFlowOpenflowPortCounters : OVS-Sflow OpenFlow Port Counter ( 20 Bytes )
  2233. type SFlowOpenflowPortCounters struct {
  2234. SFlowBaseCounterRecord
  2235. DatapathID uint64
  2236. PortNo uint32
  2237. }
  2238. func decodeOpenflowportCounters(data *[]byte) (SFlowOpenflowPortCounters, error) {
  2239. ofp := SFlowOpenflowPortCounters{}
  2240. var cdf SFlowCounterDataFormat
  2241. *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  2242. ofp.EnterpriseID, ofp.Format = cdf.decode()
  2243. *data, ofp.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2244. *data, ofp.DatapathID = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])
  2245. *data, ofp.PortNo = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2246. return ofp, nil
  2247. }
  2248. //SFlowAppresourcesCounters : OVS_Sflow App Resources Counter ( 48 Bytes )
  2249. type SFlowAppresourcesCounters struct {
  2250. SFlowBaseCounterRecord
  2251. UserTime uint32
  2252. SystemTime uint32
  2253. MemUsed uint64
  2254. MemMax uint64
  2255. FdOpen uint32
  2256. FdMax uint32
  2257. ConnOpen uint32
  2258. ConnMax uint32
  2259. }
  2260. func decodeAppresourcesCounters(data *[]byte) (SFlowAppresourcesCounters, error) {
  2261. app := SFlowAppresourcesCounters{}
  2262. var cdf SFlowCounterDataFormat
  2263. *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  2264. app.EnterpriseID, app.Format = cdf.decode()
  2265. *data, app.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2266. *data, app.UserTime = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2267. *data, app.SystemTime = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2268. *data, app.MemUsed = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])
  2269. *data, app.MemMax = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])
  2270. *data, app.FdOpen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2271. *data, app.FdMax = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2272. *data, app.ConnOpen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2273. *data, app.ConnMax = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2274. return app, nil
  2275. }
  2276. //SFlowOVSDPCounters : OVS-Sflow DataPath Counter ( 32 Bytes )
  2277. type SFlowOVSDPCounters struct {
  2278. SFlowBaseCounterRecord
  2279. NHit uint32
  2280. NMissed uint32
  2281. NLost uint32
  2282. NMaskHit uint32
  2283. NFlows uint32
  2284. NMasks uint32
  2285. }
  2286. func decodeOVSDPCounters(data *[]byte) (SFlowOVSDPCounters, error) {
  2287. dp := SFlowOVSDPCounters{}
  2288. var cdf SFlowCounterDataFormat
  2289. *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  2290. dp.EnterpriseID, dp.Format = cdf.decode()
  2291. *data, dp.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2292. *data, dp.NHit = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2293. *data, dp.NMissed = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2294. *data, dp.NLost = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2295. *data, dp.NMaskHit = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2296. *data, dp.NFlows = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2297. *data, dp.NMasks = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2298. return dp, nil
  2299. }
  2300. //SFlowPORTNAME : OVS-Sflow PORTNAME Counter Sampletype ( 20 Bytes )
  2301. type SFlowPORTNAME struct {
  2302. SFlowBaseCounterRecord
  2303. Len uint32
  2304. Str string
  2305. }
  2306. func decodeString(data *[]byte) (len uint32, str string) {
  2307. *data, len = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2308. str = string((*data)[:len])
  2309. if (len % 4) != 0 {
  2310. len += 4 - len%4
  2311. }
  2312. *data = (*data)[len:]
  2313. return
  2314. }
  2315. func decodePortnameCounters(data *[]byte) (SFlowPORTNAME, error) {
  2316. pn := SFlowPORTNAME{}
  2317. var cdf SFlowCounterDataFormat
  2318. *data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))
  2319. pn.EnterpriseID, pn.Format = cdf.decode()
  2320. *data, pn.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])
  2321. pn.Len, pn.Str = decodeString(data)
  2322. return pn, nil
  2323. }