MCPcopy
hub / github.com/google/gopacket / DecodeFromBytes

Method DecodeFromBytes

layers/bfd.go:329–397  ·  view source on GitHub ↗

DecodeFromBytes analyses a byte slice and attempts to decode it as a BFD control packet. Upon succeeds, it loads the BFD object with information about the packet and returns nil. Upon failure, it returns an error (non nil).

(data []byte, df gopacket.DecodeFeedback)

Source from the content-addressed store, hash-verified

327// and returns nil.
328// Upon failure, it returns an error (non nil).
329func (d *BFD) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
330
331 // If the data block is too short to be a BFD record, then return an error.
332 if len(data) < bfdMinimumRecordSizeInBytes {
333 df.SetTruncated()
334 return errors.New("BFD packet too short")
335 }
336
337 pLen := uint8(data[3])
338 if len(data) != int(pLen) {
339 return errors.New("BFD packet length does not match")
340 }
341
342 // BFD type embeds type BaseLayer which contains two fields:
343 // Contents is supposed to contain the bytes of the data at this level.
344 // Payload is supposed to contain the payload of this level.
345 // Here we set the baselayer to be the bytes of the BFD record.
346 d.BaseLayer = BaseLayer{Contents: data[:len(data)]}
347
348 // Extract the fields from the block of bytes.
349 // To make sense of this, refer to the packet diagram
350 // above and the section on endian conventions.
351
352 // The first few fields are all packed into the first 32 bits. Unpack them.
353 d.Version = BFDVersion(((data[0] & 0xE0) >> 5))
354 d.Diagnostic = BFDDiagnostic(data[0] & 0x1F)
355 data = data[1:]
356
357 d.State = BFDState((data[0] & 0xC0) >> 6)
358 d.Poll = data[0]&0x20 != 0
359 d.Final = data[0]&0x10 != 0
360 d.ControlPlaneIndependent = data[0]&0x08 != 0
361 d.AuthPresent = data[0]&0x04 != 0
362 d.Demand = data[0]&0x02 != 0
363 d.Multipoint = data[0]&0x01 != 0
364 data = data[1:]
365
366 data, d.DetectMultiplier = data[1:], BFDDetectMultiplier(data[0])
367 data, _ = data[1:], uint8(data[0]) // Consume length
368
369 // The remaining fields can just be copied in big endian order.
370 data, d.MyDiscriminator = data[4:], BFDDiscriminator(binary.BigEndian.Uint32(data[:4]))
371 data, d.YourDiscriminator = data[4:], BFDDiscriminator(binary.BigEndian.Uint32(data[:4]))
372 data, d.DesiredMinTxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))
373 data, d.RequiredMinRxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))
374 data, d.RequiredMinEchoRxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))
375
376 if d.AuthPresent && (len(data) > 2) {
377 d.AuthHeader = &BFDAuthHeader{}
378 data, d.AuthHeader.AuthType = data[1:], BFDAuthType(data[0])
379 data, _ = data[1:], uint8(data[0]) // Consume length
380 data, d.AuthHeader.KeyID = data[1:], BFDAuthKeyID(data[0])
381
382 switch d.AuthHeader.AuthType {
383 case BFDAuthTypePassword:
384 d.AuthHeader.Data = BFDAuthData(data)
385 case BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5:
386 // Skipped reserved byte

Callers 1

decodeBFDFunction · 0.95

Calls 12

BFDVersionTypeAlias · 0.85
BFDDiagnosticTypeAlias · 0.85
BFDStateTypeAlias · 0.85
BFDDetectMultiplierTypeAlias · 0.85
BFDDiscriminatorTypeAlias · 0.85
BFDTimeIntervalTypeAlias · 0.85
BFDAuthTypeTypeAlias · 0.85
BFDAuthKeyIDTypeAlias · 0.85
BFDAuthDataTypeAlias · 0.85
BFDAuthSequenceNumberTypeAlias · 0.85
SetTruncatedMethod · 0.65
NewMethod · 0.65

Tested by

no test coverage detected