mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-28 20:10:00 +00:00
TUN-6666: Define packet package
This package defines IP and ICMP packet, decoders, encoder and flow
This commit is contained in:
481
vendor/github.com/google/gopacket/layers/bfd.go
generated
vendored
Normal file
481
vendor/github.com/google/gopacket/layers/bfd.go
generated
vendored
Normal file
@@ -0,0 +1,481 @@
|
||||
// Copyright 2017 Google, Inc. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the LICENSE file in the root of the source
|
||||
// tree.
|
||||
//
|
||||
|
||||
package layers
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
)
|
||||
|
||||
// BFD Control Packet Format
|
||||
// -------------------------
|
||||
// The current version of BFD's RFC (RFC 5880) contains the following
|
||||
// diagram for the BFD Control packet format:
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 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
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// |Vers | Diag |Sta|P|F|C|A|D|M| Detect Mult | Length |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | My Discriminator |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Your Discriminator |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Desired Min TX Interval |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Required Min RX Interval |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Required Min Echo RX Interval |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
//
|
||||
// An optional Authentication Section MAY be present:
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 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
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Auth Type | Auth Len | Authentication Data... |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
//
|
||||
//
|
||||
// Simple Password Authentication Section Format
|
||||
// ---------------------------------------------
|
||||
// 0 1 2 3
|
||||
// 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
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Auth Type | Auth Len | Auth Key ID | Password... |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | ... |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
//
|
||||
//
|
||||
// Keyed MD5 and Meticulous Keyed MD5 Authentication Section Format
|
||||
// ----------------------------------------------------------------
|
||||
// 0 1 2 3
|
||||
// 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
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Auth Type | Auth Len | Auth Key ID | Reserved |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Sequence Number |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Auth Key/Digest... |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | ... |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
//
|
||||
//
|
||||
// Keyed SHA1 and Meticulous Keyed SHA1 Authentication Section Format
|
||||
// ------------------------------------------------------------------
|
||||
// 0 1 2 3
|
||||
// 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
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Auth Type | Auth Len | Auth Key ID | Reserved |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Sequence Number |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Auth Key/Hash... |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | ... |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
//
|
||||
// From https://tools.ietf.org/rfc/rfc5880.txt
|
||||
const bfdMinimumRecordSizeInBytes int = 24
|
||||
|
||||
// BFDVersion represents the version as decoded from the BFD control message
|
||||
type BFDVersion uint8
|
||||
|
||||
// BFDDiagnostic represents diagnostic infomation about a BFD session
|
||||
type BFDDiagnostic uint8
|
||||
|
||||
// constants that define BFDDiagnostic flags
|
||||
const (
|
||||
BFDDiagnosticNone BFDDiagnostic = 0 // No Diagnostic
|
||||
BFDDiagnosticTimeExpired BFDDiagnostic = 1 // Control Detection Time Expired
|
||||
BFDDiagnosticEchoFailed BFDDiagnostic = 2 // Echo Function Failed
|
||||
BFDDiagnosticNeighborSignalDown BFDDiagnostic = 3 // Neighbor Signaled Session Down
|
||||
BFDDiagnosticForwardPlaneReset BFDDiagnostic = 4 // Forwarding Plane Reset
|
||||
BFDDiagnosticPathDown BFDDiagnostic = 5 // Path Down
|
||||
BFDDiagnosticConcatPathDown BFDDiagnostic = 6 // Concatenated Path Down
|
||||
BFDDiagnosticAdminDown BFDDiagnostic = 7 // Administratively Down
|
||||
BFDDiagnosticRevConcatPathDown BFDDiagnostic = 8 // Reverse Concatenated Path Dow
|
||||
)
|
||||
|
||||
// String returns a string version of BFDDiagnostic
|
||||
func (bd BFDDiagnostic) String() string {
|
||||
switch bd {
|
||||
default:
|
||||
return "Unknown"
|
||||
case BFDDiagnosticNone:
|
||||
return "None"
|
||||
case BFDDiagnosticTimeExpired:
|
||||
return "Control Detection Time Expired"
|
||||
case BFDDiagnosticEchoFailed:
|
||||
return "Echo Function Failed"
|
||||
case BFDDiagnosticNeighborSignalDown:
|
||||
return "Neighbor Signaled Session Down"
|
||||
case BFDDiagnosticForwardPlaneReset:
|
||||
return "Forwarding Plane Reset"
|
||||
case BFDDiagnosticPathDown:
|
||||
return "Path Down"
|
||||
case BFDDiagnosticConcatPathDown:
|
||||
return "Concatenated Path Down"
|
||||
case BFDDiagnosticAdminDown:
|
||||
return "Administratively Down"
|
||||
case BFDDiagnosticRevConcatPathDown:
|
||||
return "Reverse Concatenated Path Down"
|
||||
}
|
||||
}
|
||||
|
||||
// BFDState represents the state of a BFD session
|
||||
type BFDState uint8
|
||||
|
||||
// constants that define BFDState
|
||||
const (
|
||||
BFDStateAdminDown BFDState = 0
|
||||
BFDStateDown BFDState = 1
|
||||
BFDStateInit BFDState = 2
|
||||
BFDStateUp BFDState = 3
|
||||
)
|
||||
|
||||
// String returns a string version of BFDState
|
||||
func (s BFDState) String() string {
|
||||
switch s {
|
||||
default:
|
||||
return "Unknown"
|
||||
case BFDStateAdminDown:
|
||||
return "Admin Down"
|
||||
case BFDStateDown:
|
||||
return "Down"
|
||||
case BFDStateInit:
|
||||
return "Init"
|
||||
case BFDStateUp:
|
||||
return "Up"
|
||||
}
|
||||
}
|
||||
|
||||
// BFDDetectMultiplier represents the negotiated transmit interval,
|
||||
// multiplied by this value, provides the Detection Time for the
|
||||
// receiving system in Asynchronous mode.
|
||||
type BFDDetectMultiplier uint8
|
||||
|
||||
// BFDDiscriminator is a unique, nonzero discriminator value used
|
||||
// to demultiplex multiple BFD sessions between the same pair of systems.
|
||||
type BFDDiscriminator uint32
|
||||
|
||||
// BFDTimeInterval represents a time interval in microseconds
|
||||
type BFDTimeInterval uint32
|
||||
|
||||
// BFDAuthType represents the authentication used in the BFD session
|
||||
type BFDAuthType uint8
|
||||
|
||||
// constants that define the BFDAuthType
|
||||
const (
|
||||
BFDAuthTypeNone BFDAuthType = 0 // No Auth
|
||||
BFDAuthTypePassword BFDAuthType = 1 // Simple Password
|
||||
BFDAuthTypeKeyedMD5 BFDAuthType = 2 // Keyed MD5
|
||||
BFDAuthTypeMeticulousKeyedMD5 BFDAuthType = 3 // Meticulous Keyed MD5
|
||||
BFDAuthTypeKeyedSHA1 BFDAuthType = 4 // Keyed SHA1
|
||||
BFDAuthTypeMeticulousKeyedSHA1 BFDAuthType = 5 // Meticulous Keyed SHA1
|
||||
)
|
||||
|
||||
// String returns a string version of BFDAuthType
|
||||
func (at BFDAuthType) String() string {
|
||||
switch at {
|
||||
default:
|
||||
return "Unknown"
|
||||
case BFDAuthTypeNone:
|
||||
return "No Authentication"
|
||||
case BFDAuthTypePassword:
|
||||
return "Simple Password"
|
||||
case BFDAuthTypeKeyedMD5:
|
||||
return "Keyed MD5"
|
||||
case BFDAuthTypeMeticulousKeyedMD5:
|
||||
return "Meticulous Keyed MD5"
|
||||
case BFDAuthTypeKeyedSHA1:
|
||||
return "Keyed SHA1"
|
||||
case BFDAuthTypeMeticulousKeyedSHA1:
|
||||
return "Meticulous Keyed SHA1"
|
||||
}
|
||||
}
|
||||
|
||||
// BFDAuthKeyID represents the authentication key ID in use for
|
||||
// this packet. This allows multiple keys to be active simultaneously.
|
||||
type BFDAuthKeyID uint8
|
||||
|
||||
// BFDAuthSequenceNumber represents the sequence number for this packet.
|
||||
// For Keyed Authentication, this value is incremented occasionally. For
|
||||
// Meticulous Keyed Authentication, this value is incremented for each
|
||||
// successive packet transmitted for a session. This provides protection
|
||||
// against replay attacks.
|
||||
type BFDAuthSequenceNumber uint32
|
||||
|
||||
// BFDAuthData represents the authentication key or digest
|
||||
type BFDAuthData []byte
|
||||
|
||||
// BFDAuthHeader represents authentication data used in the BFD session
|
||||
type BFDAuthHeader struct {
|
||||
AuthType BFDAuthType
|
||||
KeyID BFDAuthKeyID
|
||||
SequenceNumber BFDAuthSequenceNumber
|
||||
Data BFDAuthData
|
||||
}
|
||||
|
||||
// Length returns the data length of the BFDAuthHeader based on the
|
||||
// authentication type
|
||||
func (h *BFDAuthHeader) Length() int {
|
||||
switch h.AuthType {
|
||||
case BFDAuthTypePassword:
|
||||
return 3 + len(h.Data)
|
||||
case BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5:
|
||||
return 8 + len(h.Data)
|
||||
case BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1:
|
||||
return 8 + len(h.Data)
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// BFD represents a BFD control message packet whose payload contains
|
||||
// the control information required to for a BFD session.
|
||||
//
|
||||
// References
|
||||
// ----------
|
||||
//
|
||||
// Wikipedia's BFD entry:
|
||||
// https://en.wikipedia.org/wiki/Bidirectional_Forwarding_Detection
|
||||
// This is the best place to get an overview of BFD.
|
||||
//
|
||||
// RFC 5880 "Bidirectional Forwarding Detection (BFD)" (2010)
|
||||
// https://tools.ietf.org/html/rfc5880
|
||||
// This is the original BFD specification.
|
||||
//
|
||||
// RFC 5881 "Bidirectional Forwarding Detection (BFD) for IPv4 and IPv6 (Single Hop)" (2010)
|
||||
// https://tools.ietf.org/html/rfc5881
|
||||
// Describes the use of the Bidirectional Forwarding Detection (BFD)
|
||||
// protocol over IPv4 and IPv6 for single IP hops.
|
||||
type BFD struct {
|
||||
BaseLayer // Stores the packet bytes and payload bytes.
|
||||
|
||||
Version BFDVersion // Version of the BFD protocol.
|
||||
Diagnostic BFDDiagnostic // Diagnostic code for last state change
|
||||
State BFDState // Current state
|
||||
Poll bool // Requesting verification
|
||||
Final bool // Responding to a received BFD Control packet that had the Poll (P) bit set.
|
||||
ControlPlaneIndependent bool // BFD implementation does not share fate with its control plane
|
||||
AuthPresent bool // Authentication Section is present and the session is to be authenticated
|
||||
Demand bool // Demand mode is active
|
||||
Multipoint bool // For future point-to-multipoint extensions. Must always be zero
|
||||
DetectMultiplier BFDDetectMultiplier // Detection time multiplier
|
||||
MyDiscriminator BFDDiscriminator // A unique, nonzero discriminator value
|
||||
YourDiscriminator BFDDiscriminator // discriminator received from the remote system.
|
||||
DesiredMinTxInterval BFDTimeInterval // Minimum interval, in microseconds, the local system would like to use when transmitting BFD Control packets
|
||||
RequiredMinRxInterval BFDTimeInterval // Minimum interval, in microseconds, between received BFD Control packets that this system is capable of supporting
|
||||
RequiredMinEchoRxInterval BFDTimeInterval // Minimum interval, in microseconds, between received BFD Echo packets that this system is capable of supporting
|
||||
AuthHeader *BFDAuthHeader // Authentication data, variable length.
|
||||
}
|
||||
|
||||
// Length returns the data length of a BFD Control message which
|
||||
// changes based on the presence and type of authentication
|
||||
// contained in the message
|
||||
func (d *BFD) Length() int {
|
||||
if d.AuthPresent && (d.AuthHeader != nil) {
|
||||
return bfdMinimumRecordSizeInBytes + d.AuthHeader.Length()
|
||||
}
|
||||
|
||||
return bfdMinimumRecordSizeInBytes
|
||||
}
|
||||
|
||||
// LayerType returns the layer type of the BFD object, which is LayerTypeBFD.
|
||||
func (d *BFD) LayerType() gopacket.LayerType {
|
||||
return LayerTypeBFD
|
||||
}
|
||||
|
||||
// decodeBFD analyses a byte slice and attempts to decode it as a BFD
|
||||
// control packet
|
||||
//
|
||||
// If it succeeds, it loads p with information about the packet and returns nil.
|
||||
// If it fails, it returns an error (non nil).
|
||||
//
|
||||
// This function is employed in layertypes.go to register the BFD layer.
|
||||
func decodeBFD(data []byte, p gopacket.PacketBuilder) error {
|
||||
|
||||
// Attempt to decode the byte slice.
|
||||
d := &BFD{}
|
||||
err := d.DecodeFromBytes(data, p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If the decoding worked, add the layer to the packet and set it
|
||||
// as the application layer too, if there isn't already one.
|
||||
p.AddLayer(d)
|
||||
p.SetApplicationLayer(d)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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).
|
||||
func (d *BFD) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
|
||||
// If the data block is too short to be a BFD record, then return an error.
|
||||
if len(data) < bfdMinimumRecordSizeInBytes {
|
||||
df.SetTruncated()
|
||||
return errors.New("BFD packet too short")
|
||||
}
|
||||
|
||||
pLen := uint8(data[3])
|
||||
if len(data) != int(pLen) {
|
||||
return errors.New("BFD packet length does not match")
|
||||
}
|
||||
|
||||
// BFD type embeds type BaseLayer which contains two fields:
|
||||
// Contents is supposed to contain the bytes of the data at this level.
|
||||
// Payload is supposed to contain the payload of this level.
|
||||
// Here we set the baselayer to be the bytes of the BFD record.
|
||||
d.BaseLayer = BaseLayer{Contents: data[:len(data)]}
|
||||
|
||||
// Extract the fields from the block of bytes.
|
||||
// To make sense of this, refer to the packet diagram
|
||||
// above and the section on endian conventions.
|
||||
|
||||
// The first few fields are all packed into the first 32 bits. Unpack them.
|
||||
d.Version = BFDVersion(((data[0] & 0xE0) >> 5))
|
||||
d.Diagnostic = BFDDiagnostic(data[0] & 0x1F)
|
||||
data = data[1:]
|
||||
|
||||
d.State = BFDState((data[0] & 0xC0) >> 6)
|
||||
d.Poll = data[0]&0x20 != 0
|
||||
d.Final = data[0]&0x10 != 0
|
||||
d.ControlPlaneIndependent = data[0]&0x08 != 0
|
||||
d.AuthPresent = data[0]&0x04 != 0
|
||||
d.Demand = data[0]&0x02 != 0
|
||||
d.Multipoint = data[0]&0x01 != 0
|
||||
data = data[1:]
|
||||
|
||||
data, d.DetectMultiplier = data[1:], BFDDetectMultiplier(data[0])
|
||||
data, _ = data[1:], uint8(data[0]) // Consume length
|
||||
|
||||
// The remaining fields can just be copied in big endian order.
|
||||
data, d.MyDiscriminator = data[4:], BFDDiscriminator(binary.BigEndian.Uint32(data[:4]))
|
||||
data, d.YourDiscriminator = data[4:], BFDDiscriminator(binary.BigEndian.Uint32(data[:4]))
|
||||
data, d.DesiredMinTxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))
|
||||
data, d.RequiredMinRxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))
|
||||
data, d.RequiredMinEchoRxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))
|
||||
|
||||
if d.AuthPresent && (len(data) > 2) {
|
||||
d.AuthHeader = &BFDAuthHeader{}
|
||||
data, d.AuthHeader.AuthType = data[1:], BFDAuthType(data[0])
|
||||
data, _ = data[1:], uint8(data[0]) // Consume length
|
||||
data, d.AuthHeader.KeyID = data[1:], BFDAuthKeyID(data[0])
|
||||
|
||||
switch d.AuthHeader.AuthType {
|
||||
case BFDAuthTypePassword:
|
||||
d.AuthHeader.Data = BFDAuthData(data)
|
||||
case BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5:
|
||||
// Skipped reserved byte
|
||||
data, d.AuthHeader.SequenceNumber = data[5:], BFDAuthSequenceNumber(binary.BigEndian.Uint32(data[1:5]))
|
||||
d.AuthHeader.Data = BFDAuthData(data)
|
||||
case BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1:
|
||||
// Skipped reserved byte
|
||||
data, d.AuthHeader.SequenceNumber = data[5:], BFDAuthSequenceNumber(binary.BigEndian.Uint32(data[1:5]))
|
||||
d.AuthHeader.Data = BFDAuthData(data)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SerializeTo writes the serialized form of this layer into the
|
||||
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||
// See the docs for gopacket.SerializableLayer for more info.
|
||||
func (d *BFD) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||
data, err := b.PrependBytes(bfdMinimumRecordSizeInBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Pack the first few fields into the first 32 bits.
|
||||
data[0] = byte(byte(d.Version<<5) | byte(d.Diagnostic))
|
||||
h := uint8(0)
|
||||
h |= (uint8(d.State) << 6)
|
||||
h |= (uint8(bool2uint8(d.Poll)) << 5)
|
||||
h |= (uint8(bool2uint8(d.Final)) << 4)
|
||||
h |= (uint8(bool2uint8(d.ControlPlaneIndependent)) << 3)
|
||||
h |= (uint8(bool2uint8(d.AuthPresent)) << 2)
|
||||
h |= (uint8(bool2uint8(d.Demand)) << 1)
|
||||
h |= uint8(bool2uint8(d.Multipoint))
|
||||
data[1] = byte(h)
|
||||
data[2] = byte(d.DetectMultiplier)
|
||||
data[3] = byte(d.Length())
|
||||
|
||||
// The remaining fields can just be copied in big endian order.
|
||||
binary.BigEndian.PutUint32(data[4:], uint32(d.MyDiscriminator))
|
||||
binary.BigEndian.PutUint32(data[8:], uint32(d.YourDiscriminator))
|
||||
binary.BigEndian.PutUint32(data[12:], uint32(d.DesiredMinTxInterval))
|
||||
binary.BigEndian.PutUint32(data[16:], uint32(d.RequiredMinRxInterval))
|
||||
binary.BigEndian.PutUint32(data[20:], uint32(d.RequiredMinEchoRxInterval))
|
||||
|
||||
if d.AuthPresent && (d.AuthHeader != nil) {
|
||||
auth, err := b.AppendBytes(int(d.AuthHeader.Length()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
auth[0] = byte(d.AuthHeader.AuthType)
|
||||
auth[1] = byte(d.AuthHeader.Length())
|
||||
auth[2] = byte(d.AuthHeader.KeyID)
|
||||
|
||||
switch d.AuthHeader.AuthType {
|
||||
case BFDAuthTypePassword:
|
||||
copy(auth[3:], d.AuthHeader.Data)
|
||||
case BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5:
|
||||
auth[3] = byte(0)
|
||||
binary.BigEndian.PutUint32(auth[4:], uint32(d.AuthHeader.SequenceNumber))
|
||||
copy(auth[8:], d.AuthHeader.Data)
|
||||
case BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1:
|
||||
auth[3] = byte(0)
|
||||
binary.BigEndian.PutUint32(auth[4:], uint32(d.AuthHeader.SequenceNumber))
|
||||
copy(auth[8:], d.AuthHeader.Data)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CanDecode returns a set of layers that BFD objects can decode.
|
||||
// As BFD objects can only decide the BFD layer, we can return just that layer.
|
||||
// Apparently a single layer type implements LayerClass.
|
||||
func (d *BFD) CanDecode() gopacket.LayerClass {
|
||||
return LayerTypeBFD
|
||||
}
|
||||
|
||||
// NextLayerType specifies the next layer that GoPacket should attempt to
|
||||
// analyse after this (BFD) layer. As BFD packets do not contain any payload
|
||||
// bytes, there are no further layers to analyse.
|
||||
func (d *BFD) NextLayerType() gopacket.LayerType {
|
||||
return gopacket.LayerTypeZero
|
||||
}
|
||||
|
||||
// Payload returns an empty byte slice as BFD packets do not carry a payload
|
||||
func (d *BFD) Payload() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
// bool2uint8 converts a bool to uint8
|
||||
func bool2uint8(b bool) uint8 {
|
||||
if b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
Reference in New Issue
Block a user