sflow.go 95 KB

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