bfd.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. // Copyright 2017 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. package layers
  8. import (
  9. "encoding/binary"
  10. "errors"
  11. "github.com/google/gopacket"
  12. )
  13. // BFD Control Packet Format
  14. // -------------------------
  15. // The current version of BFD's RFC (RFC 5880) contains the following
  16. // diagram for the BFD Control packet format:
  17. //
  18. // 0 1 2 3
  19. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  20. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  21. // |Vers | Diag |Sta|P|F|C|A|D|M| Detect Mult | Length |
  22. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  23. // | My Discriminator |
  24. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  25. // | Your Discriminator |
  26. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  27. // | Desired Min TX Interval |
  28. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  29. // | Required Min RX Interval |
  30. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  31. // | Required Min Echo RX Interval |
  32. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  33. //
  34. // An optional Authentication Section MAY be present:
  35. //
  36. // 0 1 2 3
  37. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  38. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  39. // | Auth Type | Auth Len | Authentication Data... |
  40. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  41. //
  42. //
  43. // Simple Password Authentication Section Format
  44. // ---------------------------------------------
  45. // 0 1 2 3
  46. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  47. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  48. // | Auth Type | Auth Len | Auth Key ID | Password... |
  49. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  50. // | ... |
  51. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  52. //
  53. //
  54. // Keyed MD5 and Meticulous Keyed MD5 Authentication Section Format
  55. // ----------------------------------------------------------------
  56. // 0 1 2 3
  57. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  58. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  59. // | Auth Type | Auth Len | Auth Key ID | Reserved |
  60. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  61. // | Sequence Number |
  62. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  63. // | Auth Key/Digest... |
  64. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  65. // | ... |
  66. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  67. //
  68. //
  69. // Keyed SHA1 and Meticulous Keyed SHA1 Authentication Section Format
  70. // ------------------------------------------------------------------
  71. // 0 1 2 3
  72. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  73. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  74. // | Auth Type | Auth Len | Auth Key ID | Reserved |
  75. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  76. // | Sequence Number |
  77. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  78. // | Auth Key/Hash... |
  79. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  80. // | ... |
  81. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  82. //
  83. // From https://tools.ietf.org/rfc/rfc5880.txt
  84. const bfdMinimumRecordSizeInBytes int = 24
  85. // BFDVersion represents the version as decoded from the BFD control message
  86. type BFDVersion uint8
  87. // BFDDiagnostic represents diagnostic infomation about a BFD session
  88. type BFDDiagnostic uint8
  89. // constants that define BFDDiagnostic flags
  90. const (
  91. BFDDiagnosticNone BFDDiagnostic = 0 // No Diagnostic
  92. BFDDiagnosticTimeExpired BFDDiagnostic = 1 // Control Detection Time Expired
  93. BFDDiagnosticEchoFailed BFDDiagnostic = 2 // Echo Function Failed
  94. BFDDiagnosticNeighborSignalDown BFDDiagnostic = 3 // Neighbor Signaled Session Down
  95. BFDDiagnosticForwardPlaneReset BFDDiagnostic = 4 // Forwarding Plane Reset
  96. BFDDiagnosticPathDown BFDDiagnostic = 5 // Path Down
  97. BFDDiagnosticConcatPathDown BFDDiagnostic = 6 // Concatenated Path Down
  98. BFDDiagnosticAdminDown BFDDiagnostic = 7 // Administratively Down
  99. BFDDiagnosticRevConcatPathDown BFDDiagnostic = 8 // Reverse Concatenated Path Dow
  100. )
  101. // String returns a string version of BFDDiagnostic
  102. func (bd BFDDiagnostic) String() string {
  103. switch bd {
  104. default:
  105. return "Unknown"
  106. case BFDDiagnosticNone:
  107. return "None"
  108. case BFDDiagnosticTimeExpired:
  109. return "Control Detection Time Expired"
  110. case BFDDiagnosticEchoFailed:
  111. return "Echo Function Failed"
  112. case BFDDiagnosticNeighborSignalDown:
  113. return "Neighbor Signaled Session Down"
  114. case BFDDiagnosticForwardPlaneReset:
  115. return "Forwarding Plane Reset"
  116. case BFDDiagnosticPathDown:
  117. return "Path Down"
  118. case BFDDiagnosticConcatPathDown:
  119. return "Concatenated Path Down"
  120. case BFDDiagnosticAdminDown:
  121. return "Administratively Down"
  122. case BFDDiagnosticRevConcatPathDown:
  123. return "Reverse Concatenated Path Down"
  124. }
  125. }
  126. // BFDState represents the state of a BFD session
  127. type BFDState uint8
  128. // constants that define BFDState
  129. const (
  130. BFDStateAdminDown BFDState = 0
  131. BFDStateDown BFDState = 1
  132. BFDStateInit BFDState = 2
  133. BFDStateUp BFDState = 3
  134. )
  135. // String returns a string version of BFDState
  136. func (s BFDState) String() string {
  137. switch s {
  138. default:
  139. return "Unknown"
  140. case BFDStateAdminDown:
  141. return "Admin Down"
  142. case BFDStateDown:
  143. return "Down"
  144. case BFDStateInit:
  145. return "Init"
  146. case BFDStateUp:
  147. return "Up"
  148. }
  149. }
  150. // BFDDetectMultiplier represents the negotiated transmit interval,
  151. // multiplied by this value, provides the Detection Time for the
  152. // receiving system in Asynchronous mode.
  153. type BFDDetectMultiplier uint8
  154. // BFDDiscriminator is a unique, nonzero discriminator value used
  155. // to demultiplex multiple BFD sessions between the same pair of systems.
  156. type BFDDiscriminator uint32
  157. // BFDTimeInterval represents a time interval in microseconds
  158. type BFDTimeInterval uint32
  159. // BFDAuthType represents the authentication used in the BFD session
  160. type BFDAuthType uint8
  161. // constants that define the BFDAuthType
  162. const (
  163. BFDAuthTypeNone BFDAuthType = 0 // No Auth
  164. BFDAuthTypePassword BFDAuthType = 1 // Simple Password
  165. BFDAuthTypeKeyedMD5 BFDAuthType = 2 // Keyed MD5
  166. BFDAuthTypeMeticulousKeyedMD5 BFDAuthType = 3 // Meticulous Keyed MD5
  167. BFDAuthTypeKeyedSHA1 BFDAuthType = 4 // Keyed SHA1
  168. BFDAuthTypeMeticulousKeyedSHA1 BFDAuthType = 5 // Meticulous Keyed SHA1
  169. )
  170. // String returns a string version of BFDAuthType
  171. func (at BFDAuthType) String() string {
  172. switch at {
  173. default:
  174. return "Unknown"
  175. case BFDAuthTypeNone:
  176. return "No Authentication"
  177. case BFDAuthTypePassword:
  178. return "Simple Password"
  179. case BFDAuthTypeKeyedMD5:
  180. return "Keyed MD5"
  181. case BFDAuthTypeMeticulousKeyedMD5:
  182. return "Meticulous Keyed MD5"
  183. case BFDAuthTypeKeyedSHA1:
  184. return "Keyed SHA1"
  185. case BFDAuthTypeMeticulousKeyedSHA1:
  186. return "Meticulous Keyed SHA1"
  187. }
  188. }
  189. // BFDAuthKeyID represents the authentication key ID in use for
  190. // this packet. This allows multiple keys to be active simultaneously.
  191. type BFDAuthKeyID uint8
  192. // BFDAuthSequenceNumber represents the sequence number for this packet.
  193. // For Keyed Authentication, this value is incremented occasionally. For
  194. // Meticulous Keyed Authentication, this value is incremented for each
  195. // successive packet transmitted for a session. This provides protection
  196. // against replay attacks.
  197. type BFDAuthSequenceNumber uint32
  198. // BFDAuthData represents the authentication key or digest
  199. type BFDAuthData []byte
  200. // BFDAuthHeader represents authentication data used in the BFD session
  201. type BFDAuthHeader struct {
  202. AuthType BFDAuthType
  203. KeyID BFDAuthKeyID
  204. SequenceNumber BFDAuthSequenceNumber
  205. Data BFDAuthData
  206. }
  207. // Length returns the data length of the BFDAuthHeader based on the
  208. // authentication type
  209. func (h *BFDAuthHeader) Length() int {
  210. switch h.AuthType {
  211. case BFDAuthTypePassword:
  212. return 3 + len(h.Data)
  213. case BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5:
  214. return 8 + len(h.Data)
  215. case BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1:
  216. return 8 + len(h.Data)
  217. default:
  218. return 0
  219. }
  220. }
  221. // BFD represents a BFD control message packet whose payload contains
  222. // the control information required to for a BFD session.
  223. //
  224. // References
  225. // ----------
  226. //
  227. // Wikipedia's BFD entry:
  228. // https://en.wikipedia.org/wiki/Bidirectional_Forwarding_Detection
  229. // This is the best place to get an overview of BFD.
  230. //
  231. // RFC 5880 "Bidirectional Forwarding Detection (BFD)" (2010)
  232. // https://tools.ietf.org/html/rfc5880
  233. // This is the original BFD specification.
  234. //
  235. // RFC 5881 "Bidirectional Forwarding Detection (BFD) for IPv4 and IPv6 (Single Hop)" (2010)
  236. // https://tools.ietf.org/html/rfc5881
  237. // Describes the use of the Bidirectional Forwarding Detection (BFD)
  238. // protocol over IPv4 and IPv6 for single IP hops.
  239. type BFD struct {
  240. BaseLayer // Stores the packet bytes and payload bytes.
  241. Version BFDVersion // Version of the BFD protocol.
  242. Diagnostic BFDDiagnostic // Diagnostic code for last state change
  243. State BFDState // Current state
  244. Poll bool // Requesting verification
  245. Final bool // Responding to a received BFD Control packet that had the Poll (P) bit set.
  246. ControlPlaneIndependent bool // BFD implementation does not share fate with its control plane
  247. AuthPresent bool // Authentication Section is present and the session is to be authenticated
  248. Demand bool // Demand mode is active
  249. Multipoint bool // For future point-to-multipoint extensions. Must always be zero
  250. DetectMultiplier BFDDetectMultiplier // Detection time multiplier
  251. MyDiscriminator BFDDiscriminator // A unique, nonzero discriminator value
  252. YourDiscriminator BFDDiscriminator // discriminator received from the remote system.
  253. DesiredMinTxInterval BFDTimeInterval // Minimum interval, in microseconds, the local system would like to use when transmitting BFD Control packets
  254. RequiredMinRxInterval BFDTimeInterval // Minimum interval, in microseconds, between received BFD Control packets that this system is capable of supporting
  255. RequiredMinEchoRxInterval BFDTimeInterval // Minimum interval, in microseconds, between received BFD Echo packets that this system is capable of supporting
  256. AuthHeader *BFDAuthHeader // Authentication data, variable length.
  257. }
  258. // Length returns the data length of a BFD Control message which
  259. // changes based on the presence and type of authentication
  260. // contained in the message
  261. func (d *BFD) Length() int {
  262. if d.AuthPresent && (d.AuthHeader != nil) {
  263. return bfdMinimumRecordSizeInBytes + d.AuthHeader.Length()
  264. }
  265. return bfdMinimumRecordSizeInBytes
  266. }
  267. // LayerType returns the layer type of the BFD object, which is LayerTypeBFD.
  268. func (d *BFD) LayerType() gopacket.LayerType {
  269. return LayerTypeBFD
  270. }
  271. // decodeBFD analyses a byte slice and attempts to decode it as a BFD
  272. // control packet
  273. //
  274. // If it succeeds, it loads p with information about the packet and returns nil.
  275. // If it fails, it returns an error (non nil).
  276. //
  277. // This function is employed in layertypes.go to register the BFD layer.
  278. func decodeBFD(data []byte, p gopacket.PacketBuilder) error {
  279. // Attempt to decode the byte slice.
  280. d := &BFD{}
  281. err := d.DecodeFromBytes(data, p)
  282. if err != nil {
  283. return err
  284. }
  285. // If the decoding worked, add the layer to the packet and set it
  286. // as the application layer too, if there isn't already one.
  287. p.AddLayer(d)
  288. p.SetApplicationLayer(d)
  289. return nil
  290. }
  291. // DecodeFromBytes analyses a byte slice and attempts to decode it as a BFD
  292. // control packet.
  293. //
  294. // Upon succeeds, it loads the BFD object with information about the packet
  295. // and returns nil.
  296. // Upon failure, it returns an error (non nil).
  297. func (d *BFD) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  298. // If the data block is too short to be a BFD record, then return an error.
  299. if len(data) < bfdMinimumRecordSizeInBytes {
  300. df.SetTruncated()
  301. return errors.New("BFD packet too short")
  302. }
  303. pLen := uint8(data[3])
  304. if len(data) != int(pLen) {
  305. return errors.New("BFD packet length does not match")
  306. }
  307. // BFD type embeds type BaseLayer which contains two fields:
  308. // Contents is supposed to contain the bytes of the data at this level.
  309. // Payload is supposed to contain the payload of this level.
  310. // Here we set the baselayer to be the bytes of the BFD record.
  311. d.BaseLayer = BaseLayer{Contents: data[:len(data)]}
  312. // Extract the fields from the block of bytes.
  313. // To make sense of this, refer to the packet diagram
  314. // above and the section on endian conventions.
  315. // The first few fields are all packed into the first 32 bits. Unpack them.
  316. d.Version = BFDVersion(((data[0] & 0xE0) >> 5))
  317. d.Diagnostic = BFDDiagnostic(data[0] & 0x1F)
  318. data = data[1:]
  319. d.State = BFDState((data[0] & 0xC0) >> 6)
  320. d.Poll = data[0]&0x20 != 0
  321. d.Final = data[0]&0x10 != 0
  322. d.ControlPlaneIndependent = data[0]&0x08 != 0
  323. d.AuthPresent = data[0]&0x04 != 0
  324. d.Demand = data[0]&0x02 != 0
  325. d.Multipoint = data[0]&0x01 != 0
  326. data = data[1:]
  327. data, d.DetectMultiplier = data[1:], BFDDetectMultiplier(data[0])
  328. data, _ = data[1:], uint8(data[0]) // Consume length
  329. // The remaining fields can just be copied in big endian order.
  330. data, d.MyDiscriminator = data[4:], BFDDiscriminator(binary.BigEndian.Uint32(data[:4]))
  331. data, d.YourDiscriminator = data[4:], BFDDiscriminator(binary.BigEndian.Uint32(data[:4]))
  332. data, d.DesiredMinTxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))
  333. data, d.RequiredMinRxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))
  334. data, d.RequiredMinEchoRxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))
  335. if d.AuthPresent && (len(data) > 2) {
  336. d.AuthHeader = &BFDAuthHeader{}
  337. data, d.AuthHeader.AuthType = data[1:], BFDAuthType(data[0])
  338. data, _ = data[1:], uint8(data[0]) // Consume length
  339. data, d.AuthHeader.KeyID = data[1:], BFDAuthKeyID(data[0])
  340. switch d.AuthHeader.AuthType {
  341. case BFDAuthTypePassword:
  342. d.AuthHeader.Data = BFDAuthData(data)
  343. case BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5:
  344. // Skipped reserved byte
  345. data, d.AuthHeader.SequenceNumber = data[5:], BFDAuthSequenceNumber(binary.BigEndian.Uint32(data[1:5]))
  346. d.AuthHeader.Data = BFDAuthData(data)
  347. case BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1:
  348. // Skipped reserved byte
  349. data, d.AuthHeader.SequenceNumber = data[5:], BFDAuthSequenceNumber(binary.BigEndian.Uint32(data[1:5]))
  350. d.AuthHeader.Data = BFDAuthData(data)
  351. }
  352. }
  353. return nil
  354. }
  355. // SerializeTo writes the serialized form of this layer into the
  356. // SerializationBuffer, implementing gopacket.SerializableLayer.
  357. // See the docs for gopacket.SerializableLayer for more info.
  358. func (d *BFD) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  359. data, err := b.PrependBytes(bfdMinimumRecordSizeInBytes)
  360. if err != nil {
  361. return err
  362. }
  363. // Pack the first few fields into the first 32 bits.
  364. data[0] = byte(byte(d.Version<<5) | byte(d.Diagnostic))
  365. h := uint8(0)
  366. h |= (uint8(d.State) << 6)
  367. h |= (uint8(bool2uint8(d.Poll)) << 5)
  368. h |= (uint8(bool2uint8(d.Final)) << 4)
  369. h |= (uint8(bool2uint8(d.ControlPlaneIndependent)) << 3)
  370. h |= (uint8(bool2uint8(d.AuthPresent)) << 2)
  371. h |= (uint8(bool2uint8(d.Demand)) << 1)
  372. h |= uint8(bool2uint8(d.Multipoint))
  373. data[1] = byte(h)
  374. data[2] = byte(d.DetectMultiplier)
  375. data[3] = byte(d.Length())
  376. // The remaining fields can just be copied in big endian order.
  377. binary.BigEndian.PutUint32(data[4:], uint32(d.MyDiscriminator))
  378. binary.BigEndian.PutUint32(data[8:], uint32(d.YourDiscriminator))
  379. binary.BigEndian.PutUint32(data[12:], uint32(d.DesiredMinTxInterval))
  380. binary.BigEndian.PutUint32(data[16:], uint32(d.RequiredMinRxInterval))
  381. binary.BigEndian.PutUint32(data[20:], uint32(d.RequiredMinEchoRxInterval))
  382. if d.AuthPresent && (d.AuthHeader != nil) {
  383. auth, err := b.AppendBytes(int(d.AuthHeader.Length()))
  384. if err != nil {
  385. return err
  386. }
  387. auth[0] = byte(d.AuthHeader.AuthType)
  388. auth[1] = byte(d.AuthHeader.Length())
  389. auth[2] = byte(d.AuthHeader.KeyID)
  390. switch d.AuthHeader.AuthType {
  391. case BFDAuthTypePassword:
  392. copy(auth[3:], d.AuthHeader.Data)
  393. case BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5:
  394. auth[3] = byte(0)
  395. binary.BigEndian.PutUint32(auth[4:], uint32(d.AuthHeader.SequenceNumber))
  396. copy(auth[8:], d.AuthHeader.Data)
  397. case BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1:
  398. auth[3] = byte(0)
  399. binary.BigEndian.PutUint32(auth[4:], uint32(d.AuthHeader.SequenceNumber))
  400. copy(auth[8:], d.AuthHeader.Data)
  401. }
  402. }
  403. return nil
  404. }
  405. // CanDecode returns a set of layers that BFD objects can decode.
  406. // As BFD objects can only decide the BFD layer, we can return just that layer.
  407. // Apparently a single layer type implements LayerClass.
  408. func (d *BFD) CanDecode() gopacket.LayerClass {
  409. return LayerTypeBFD
  410. }
  411. // NextLayerType specifies the next layer that GoPacket should attempt to
  412. // analyse after this (BFD) layer. As BFD packets do not contain any payload
  413. // bytes, there are no further layers to analyse.
  414. func (d *BFD) NextLayerType() gopacket.LayerType {
  415. return gopacket.LayerTypeZero
  416. }
  417. // Payload returns an empty byte slice as BFD packets do not carry a payload
  418. func (d *BFD) Payload() []byte {
  419. return nil
  420. }
  421. // bool2uint8 converts a bool to uint8
  422. func bool2uint8(b bool) uint8 {
  423. if b {
  424. return 1
  425. }
  426. return 0
  427. }