sflow.go 84 KB

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