mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-28 19:59:57 +00:00
TUN-6666: Define packet package
This package defines IP and ICMP packet, decoders, encoder and flow
This commit is contained in:
715
vendor/github.com/google/gopacket/layers/ospf.go
generated
vendored
Normal file
715
vendor/github.com/google/gopacket/layers/ospf.go
generated
vendored
Normal file
@@ -0,0 +1,715 @@
|
||||
// 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"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
)
|
||||
|
||||
// OSPFType denotes what kind of OSPF type it is
|
||||
type OSPFType uint8
|
||||
|
||||
// Potential values for OSPF.Type.
|
||||
const (
|
||||
OSPFHello OSPFType = 1
|
||||
OSPFDatabaseDescription OSPFType = 2
|
||||
OSPFLinkStateRequest OSPFType = 3
|
||||
OSPFLinkStateUpdate OSPFType = 4
|
||||
OSPFLinkStateAcknowledgment OSPFType = 5
|
||||
)
|
||||
|
||||
// LSA Function Codes for LSAheader.LSType
|
||||
const (
|
||||
RouterLSAtypeV2 = 0x1
|
||||
RouterLSAtype = 0x2001
|
||||
NetworkLSAtypeV2 = 0x2
|
||||
NetworkLSAtype = 0x2002
|
||||
SummaryLSANetworktypeV2 = 0x3
|
||||
InterAreaPrefixLSAtype = 0x2003
|
||||
SummaryLSAASBRtypeV2 = 0x4
|
||||
InterAreaRouterLSAtype = 0x2004
|
||||
ASExternalLSAtypeV2 = 0x5
|
||||
ASExternalLSAtype = 0x4005
|
||||
NSSALSAtype = 0x2007
|
||||
NSSALSAtypeV2 = 0x7
|
||||
LinkLSAtype = 0x0008
|
||||
IntraAreaPrefixLSAtype = 0x2009
|
||||
)
|
||||
|
||||
// String conversions for OSPFType
|
||||
func (i OSPFType) String() string {
|
||||
switch i {
|
||||
case OSPFHello:
|
||||
return "Hello"
|
||||
case OSPFDatabaseDescription:
|
||||
return "Database Description"
|
||||
case OSPFLinkStateRequest:
|
||||
return "Link State Request"
|
||||
case OSPFLinkStateUpdate:
|
||||
return "Link State Update"
|
||||
case OSPFLinkStateAcknowledgment:
|
||||
return "Link State Acknowledgment"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// Prefix extends IntraAreaPrefixLSA
|
||||
type Prefix struct {
|
||||
PrefixLength uint8
|
||||
PrefixOptions uint8
|
||||
Metric uint16
|
||||
AddressPrefix []byte
|
||||
}
|
||||
|
||||
// IntraAreaPrefixLSA is the struct from RFC 5340 A.4.10.
|
||||
type IntraAreaPrefixLSA struct {
|
||||
NumOfPrefixes uint16
|
||||
RefLSType uint16
|
||||
RefLinkStateID uint32
|
||||
RefAdvRouter uint32
|
||||
Prefixes []Prefix
|
||||
}
|
||||
|
||||
// LinkLSA is the struct from RFC 5340 A.4.9.
|
||||
type LinkLSA struct {
|
||||
RtrPriority uint8
|
||||
Options uint32
|
||||
LinkLocalAddress []byte
|
||||
NumOfPrefixes uint32
|
||||
Prefixes []Prefix
|
||||
}
|
||||
|
||||
// ASExternalLSAV2 is the struct from RFC 2328 A.4.5.
|
||||
type ASExternalLSAV2 struct {
|
||||
NetworkMask uint32
|
||||
ExternalBit uint8
|
||||
Metric uint32
|
||||
ForwardingAddress uint32
|
||||
ExternalRouteTag uint32
|
||||
}
|
||||
|
||||
// ASExternalLSA is the struct from RFC 5340 A.4.7.
|
||||
type ASExternalLSA struct {
|
||||
Flags uint8
|
||||
Metric uint32
|
||||
PrefixLength uint8
|
||||
PrefixOptions uint8
|
||||
RefLSType uint16
|
||||
AddressPrefix []byte
|
||||
ForwardingAddress []byte
|
||||
ExternalRouteTag uint32
|
||||
RefLinkStateID uint32
|
||||
}
|
||||
|
||||
// InterAreaRouterLSA is the struct from RFC 5340 A.4.6.
|
||||
type InterAreaRouterLSA struct {
|
||||
Options uint32
|
||||
Metric uint32
|
||||
DestinationRouterID uint32
|
||||
}
|
||||
|
||||
// InterAreaPrefixLSA is the struct from RFC 5340 A.4.5.
|
||||
type InterAreaPrefixLSA struct {
|
||||
Metric uint32
|
||||
PrefixLength uint8
|
||||
PrefixOptions uint8
|
||||
AddressPrefix []byte
|
||||
}
|
||||
|
||||
// NetworkLSA is the struct from RFC 5340 A.4.4.
|
||||
type NetworkLSA struct {
|
||||
Options uint32
|
||||
AttachedRouter []uint32
|
||||
}
|
||||
|
||||
// NetworkLSAV2 is the struct from RFC 2328 A.4.3.
|
||||
type NetworkLSAV2 struct {
|
||||
NetworkMask uint32
|
||||
AttachedRouter []uint32
|
||||
}
|
||||
|
||||
// RouterV2 extends RouterLSAV2
|
||||
type RouterV2 struct {
|
||||
Type uint8
|
||||
LinkID uint32
|
||||
LinkData uint32
|
||||
Metric uint16
|
||||
}
|
||||
|
||||
// RouterLSAV2 is the struct from RFC 2328 A.4.2.
|
||||
type RouterLSAV2 struct {
|
||||
Flags uint8
|
||||
Links uint16
|
||||
Routers []RouterV2
|
||||
}
|
||||
|
||||
// Router extends RouterLSA
|
||||
type Router struct {
|
||||
Type uint8
|
||||
Metric uint16
|
||||
InterfaceID uint32
|
||||
NeighborInterfaceID uint32
|
||||
NeighborRouterID uint32
|
||||
}
|
||||
|
||||
// RouterLSA is the struct from RFC 5340 A.4.3.
|
||||
type RouterLSA struct {
|
||||
Flags uint8
|
||||
Options uint32
|
||||
Routers []Router
|
||||
}
|
||||
|
||||
// LSAheader is the struct from RFC 5340 A.4.2 and RFC 2328 A.4.1.
|
||||
type LSAheader struct {
|
||||
LSAge uint16
|
||||
LSType uint16
|
||||
LinkStateID uint32
|
||||
AdvRouter uint32
|
||||
LSSeqNumber uint32
|
||||
LSChecksum uint16
|
||||
Length uint16
|
||||
LSOptions uint8
|
||||
}
|
||||
|
||||
// LSA links LSAheader with the structs from RFC 5340 A.4.
|
||||
type LSA struct {
|
||||
LSAheader
|
||||
Content interface{}
|
||||
}
|
||||
|
||||
// LSUpdate is the struct from RFC 5340 A.3.5.
|
||||
type LSUpdate struct {
|
||||
NumOfLSAs uint32
|
||||
LSAs []LSA
|
||||
}
|
||||
|
||||
// LSReq is the struct from RFC 5340 A.3.4.
|
||||
type LSReq struct {
|
||||
LSType uint16
|
||||
LSID uint32
|
||||
AdvRouter uint32
|
||||
}
|
||||
|
||||
// DbDescPkg is the struct from RFC 5340 A.3.3.
|
||||
type DbDescPkg struct {
|
||||
Options uint32
|
||||
InterfaceMTU uint16
|
||||
Flags uint16
|
||||
DDSeqNumber uint32
|
||||
LSAinfo []LSAheader
|
||||
}
|
||||
|
||||
// HelloPkg is the struct from RFC 5340 A.3.2.
|
||||
type HelloPkg struct {
|
||||
InterfaceID uint32
|
||||
RtrPriority uint8
|
||||
Options uint32
|
||||
HelloInterval uint16
|
||||
RouterDeadInterval uint32
|
||||
DesignatedRouterID uint32
|
||||
BackupDesignatedRouterID uint32
|
||||
NeighborID []uint32
|
||||
}
|
||||
|
||||
// HelloPkgV2 extends the HelloPkg struct with OSPFv2 information
|
||||
type HelloPkgV2 struct {
|
||||
HelloPkg
|
||||
NetworkMask uint32
|
||||
}
|
||||
|
||||
// OSPF is a basic OSPF packet header with common fields of Version 2 and Version 3.
|
||||
type OSPF struct {
|
||||
Version uint8
|
||||
Type OSPFType
|
||||
PacketLength uint16
|
||||
RouterID uint32
|
||||
AreaID uint32
|
||||
Checksum uint16
|
||||
Content interface{}
|
||||
}
|
||||
|
||||
//OSPFv2 extend the OSPF head with version 2 specific fields
|
||||
type OSPFv2 struct {
|
||||
BaseLayer
|
||||
OSPF
|
||||
AuType uint16
|
||||
Authentication uint64
|
||||
}
|
||||
|
||||
// OSPFv3 extend the OSPF head with version 3 specific fields
|
||||
type OSPFv3 struct {
|
||||
BaseLayer
|
||||
OSPF
|
||||
Instance uint8
|
||||
Reserved uint8
|
||||
}
|
||||
|
||||
// getLSAsv2 parses the LSA information from the packet for OSPFv2
|
||||
func getLSAsv2(num uint32, data []byte) ([]LSA, error) {
|
||||
var lsas []LSA
|
||||
var i uint32 = 0
|
||||
var offset uint32 = 0
|
||||
for ; i < num; i++ {
|
||||
lstype := uint16(data[offset+3])
|
||||
lsalength := binary.BigEndian.Uint16(data[offset+18 : offset+20])
|
||||
content, err := extractLSAInformation(lstype, lsalength, data[offset:])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not extract Link State type.")
|
||||
}
|
||||
lsa := LSA{
|
||||
LSAheader: LSAheader{
|
||||
LSAge: binary.BigEndian.Uint16(data[offset : offset+2]),
|
||||
LSOptions: data[offset+2],
|
||||
LSType: lstype,
|
||||
LinkStateID: binary.BigEndian.Uint32(data[offset+4 : offset+8]),
|
||||
AdvRouter: binary.BigEndian.Uint32(data[offset+8 : offset+12]),
|
||||
LSSeqNumber: binary.BigEndian.Uint32(data[offset+12 : offset+16]),
|
||||
LSChecksum: binary.BigEndian.Uint16(data[offset+16 : offset+18]),
|
||||
Length: lsalength,
|
||||
},
|
||||
Content: content,
|
||||
}
|
||||
lsas = append(lsas, lsa)
|
||||
offset += uint32(lsalength)
|
||||
}
|
||||
return lsas, nil
|
||||
}
|
||||
|
||||
// extractLSAInformation extracts all the LSA information
|
||||
func extractLSAInformation(lstype, lsalength uint16, data []byte) (interface{}, error) {
|
||||
if lsalength < 20 {
|
||||
return nil, fmt.Errorf("Link State header length %v too short, %v required", lsalength, 20)
|
||||
}
|
||||
if len(data) < int(lsalength) {
|
||||
return nil, fmt.Errorf("Link State header length %v too short, %v required", len(data), lsalength)
|
||||
}
|
||||
var content interface{}
|
||||
switch lstype {
|
||||
case RouterLSAtypeV2:
|
||||
var routers []RouterV2
|
||||
var j uint32
|
||||
for j = 24; j < uint32(lsalength); j += 12 {
|
||||
if len(data) < int(j+12) {
|
||||
return nil, errors.New("LSAtypeV2 too small")
|
||||
}
|
||||
router := RouterV2{
|
||||
LinkID: binary.BigEndian.Uint32(data[j : j+4]),
|
||||
LinkData: binary.BigEndian.Uint32(data[j+4 : j+8]),
|
||||
Type: uint8(data[j+8]),
|
||||
Metric: binary.BigEndian.Uint16(data[j+10 : j+12]),
|
||||
}
|
||||
routers = append(routers, router)
|
||||
}
|
||||
if len(data) < 24 {
|
||||
return nil, errors.New("LSAtypeV2 too small")
|
||||
}
|
||||
links := binary.BigEndian.Uint16(data[22:24])
|
||||
content = RouterLSAV2{
|
||||
Flags: data[20],
|
||||
Links: links,
|
||||
Routers: routers,
|
||||
}
|
||||
case NSSALSAtypeV2:
|
||||
fallthrough
|
||||
case ASExternalLSAtypeV2:
|
||||
content = ASExternalLSAV2{
|
||||
NetworkMask: binary.BigEndian.Uint32(data[20:24]),
|
||||
ExternalBit: data[24] & 0x80,
|
||||
Metric: binary.BigEndian.Uint32(data[24:28]) & 0x00FFFFFF,
|
||||
ForwardingAddress: binary.BigEndian.Uint32(data[28:32]),
|
||||
ExternalRouteTag: binary.BigEndian.Uint32(data[32:36]),
|
||||
}
|
||||
case NetworkLSAtypeV2:
|
||||
var routers []uint32
|
||||
var j uint32
|
||||
for j = 24; j < uint32(lsalength); j += 4 {
|
||||
routers = append(routers, binary.BigEndian.Uint32(data[j:j+4]))
|
||||
}
|
||||
content = NetworkLSAV2{
|
||||
NetworkMask: binary.BigEndian.Uint32(data[20:24]),
|
||||
AttachedRouter: routers,
|
||||
}
|
||||
case RouterLSAtype:
|
||||
var routers []Router
|
||||
var j uint32
|
||||
for j = 24; j < uint32(lsalength); j += 16 {
|
||||
router := Router{
|
||||
Type: uint8(data[j]),
|
||||
Metric: binary.BigEndian.Uint16(data[j+2 : j+4]),
|
||||
InterfaceID: binary.BigEndian.Uint32(data[j+4 : j+8]),
|
||||
NeighborInterfaceID: binary.BigEndian.Uint32(data[j+8 : j+12]),
|
||||
NeighborRouterID: binary.BigEndian.Uint32(data[j+12 : j+16]),
|
||||
}
|
||||
routers = append(routers, router)
|
||||
}
|
||||
content = RouterLSA{
|
||||
Flags: uint8(data[20]),
|
||||
Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
|
||||
Routers: routers,
|
||||
}
|
||||
case NetworkLSAtype:
|
||||
var routers []uint32
|
||||
var j uint32
|
||||
for j = 24; j < uint32(lsalength); j += 4 {
|
||||
routers = append(routers, binary.BigEndian.Uint32(data[j:j+4]))
|
||||
}
|
||||
content = NetworkLSA{
|
||||
Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
|
||||
AttachedRouter: routers,
|
||||
}
|
||||
case InterAreaPrefixLSAtype:
|
||||
content = InterAreaPrefixLSA{
|
||||
Metric: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
|
||||
PrefixLength: uint8(data[24]),
|
||||
PrefixOptions: uint8(data[25]),
|
||||
AddressPrefix: data[28:uint32(lsalength)],
|
||||
}
|
||||
case InterAreaRouterLSAtype:
|
||||
content = InterAreaRouterLSA{
|
||||
Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
|
||||
Metric: binary.BigEndian.Uint32(data[24:28]) & 0x00FFFFFF,
|
||||
DestinationRouterID: binary.BigEndian.Uint32(data[28:32]),
|
||||
}
|
||||
case ASExternalLSAtype:
|
||||
fallthrough
|
||||
case NSSALSAtype:
|
||||
flags := uint8(data[20])
|
||||
prefixLen := uint8(data[24]) / 8
|
||||
var forwardingAddress []byte
|
||||
if (flags & 0x02) == 0x02 {
|
||||
forwardingAddress = data[28+uint32(prefixLen) : 28+uint32(prefixLen)+16]
|
||||
}
|
||||
content = ASExternalLSA{
|
||||
Flags: flags,
|
||||
Metric: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
|
||||
PrefixLength: prefixLen,
|
||||
PrefixOptions: uint8(data[25]),
|
||||
RefLSType: binary.BigEndian.Uint16(data[26:28]),
|
||||
AddressPrefix: data[28 : 28+uint32(prefixLen)],
|
||||
ForwardingAddress: forwardingAddress,
|
||||
}
|
||||
case LinkLSAtype:
|
||||
var prefixes []Prefix
|
||||
var prefixOffset uint32 = 44
|
||||
var j uint32
|
||||
numOfPrefixes := binary.BigEndian.Uint32(data[40:44])
|
||||
for j = 0; j < numOfPrefixes; j++ {
|
||||
prefixLen := uint8(data[prefixOffset])
|
||||
prefix := Prefix{
|
||||
PrefixLength: prefixLen,
|
||||
PrefixOptions: uint8(data[prefixOffset+1]),
|
||||
AddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8],
|
||||
}
|
||||
prefixes = append(prefixes, prefix)
|
||||
prefixOffset = prefixOffset + 4 + uint32(prefixLen)/8
|
||||
}
|
||||
content = LinkLSA{
|
||||
RtrPriority: uint8(data[20]),
|
||||
Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
|
||||
LinkLocalAddress: data[24:40],
|
||||
NumOfPrefixes: numOfPrefixes,
|
||||
Prefixes: prefixes,
|
||||
}
|
||||
case IntraAreaPrefixLSAtype:
|
||||
var prefixes []Prefix
|
||||
var prefixOffset uint32 = 32
|
||||
var j uint16
|
||||
numOfPrefixes := binary.BigEndian.Uint16(data[20:22])
|
||||
for j = 0; j < numOfPrefixes; j++ {
|
||||
prefixLen := uint8(data[prefixOffset])
|
||||
prefix := Prefix{
|
||||
PrefixLength: prefixLen,
|
||||
PrefixOptions: uint8(data[prefixOffset+1]),
|
||||
Metric: binary.BigEndian.Uint16(data[prefixOffset+2 : prefixOffset+4]),
|
||||
AddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8],
|
||||
}
|
||||
prefixes = append(prefixes, prefix)
|
||||
prefixOffset = prefixOffset + 4 + uint32(prefixLen)
|
||||
}
|
||||
content = IntraAreaPrefixLSA{
|
||||
NumOfPrefixes: numOfPrefixes,
|
||||
RefLSType: binary.BigEndian.Uint16(data[22:24]),
|
||||
RefLinkStateID: binary.BigEndian.Uint32(data[24:28]),
|
||||
RefAdvRouter: binary.BigEndian.Uint32(data[28:32]),
|
||||
Prefixes: prefixes,
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown Link State type.")
|
||||
}
|
||||
return content, nil
|
||||
}
|
||||
|
||||
// getLSAs parses the LSA information from the packet for OSPFv3
|
||||
func getLSAs(num uint32, data []byte) ([]LSA, error) {
|
||||
var lsas []LSA
|
||||
var i uint32 = 0
|
||||
var offset uint32 = 0
|
||||
for ; i < num; i++ {
|
||||
var content interface{}
|
||||
lstype := binary.BigEndian.Uint16(data[offset+2 : offset+4])
|
||||
lsalength := binary.BigEndian.Uint16(data[offset+18 : offset+20])
|
||||
|
||||
content, err := extractLSAInformation(lstype, lsalength, data[offset:])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not extract Link State type.")
|
||||
}
|
||||
lsa := LSA{
|
||||
LSAheader: LSAheader{
|
||||
LSAge: binary.BigEndian.Uint16(data[offset : offset+2]),
|
||||
LSType: lstype,
|
||||
LinkStateID: binary.BigEndian.Uint32(data[offset+4 : offset+8]),
|
||||
AdvRouter: binary.BigEndian.Uint32(data[offset+8 : offset+12]),
|
||||
LSSeqNumber: binary.BigEndian.Uint32(data[offset+12 : offset+16]),
|
||||
LSChecksum: binary.BigEndian.Uint16(data[offset+16 : offset+18]),
|
||||
Length: lsalength,
|
||||
},
|
||||
Content: content,
|
||||
}
|
||||
lsas = append(lsas, lsa)
|
||||
offset += uint32(lsalength)
|
||||
}
|
||||
return lsas, nil
|
||||
}
|
||||
|
||||
// DecodeFromBytes decodes the given bytes into the OSPF layer.
|
||||
func (ospf *OSPFv2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
if len(data) < 24 {
|
||||
return fmt.Errorf("Packet too smal for OSPF Version 2")
|
||||
}
|
||||
|
||||
ospf.Version = uint8(data[0])
|
||||
ospf.Type = OSPFType(data[1])
|
||||
ospf.PacketLength = binary.BigEndian.Uint16(data[2:4])
|
||||
ospf.RouterID = binary.BigEndian.Uint32(data[4:8])
|
||||
ospf.AreaID = binary.BigEndian.Uint32(data[8:12])
|
||||
ospf.Checksum = binary.BigEndian.Uint16(data[12:14])
|
||||
ospf.AuType = binary.BigEndian.Uint16(data[14:16])
|
||||
ospf.Authentication = binary.BigEndian.Uint64(data[16:24])
|
||||
|
||||
switch ospf.Type {
|
||||
case OSPFHello:
|
||||
var neighbors []uint32
|
||||
for i := 44; uint16(i+4) <= ospf.PacketLength; i += 4 {
|
||||
neighbors = append(neighbors, binary.BigEndian.Uint32(data[i:i+4]))
|
||||
}
|
||||
ospf.Content = HelloPkgV2{
|
||||
NetworkMask: binary.BigEndian.Uint32(data[24:28]),
|
||||
HelloPkg: HelloPkg{
|
||||
HelloInterval: binary.BigEndian.Uint16(data[28:30]),
|
||||
Options: uint32(data[30]),
|
||||
RtrPriority: uint8(data[31]),
|
||||
RouterDeadInterval: binary.BigEndian.Uint32(data[32:36]),
|
||||
DesignatedRouterID: binary.BigEndian.Uint32(data[36:40]),
|
||||
BackupDesignatedRouterID: binary.BigEndian.Uint32(data[40:44]),
|
||||
NeighborID: neighbors,
|
||||
},
|
||||
}
|
||||
case OSPFDatabaseDescription:
|
||||
var lsas []LSAheader
|
||||
for i := 32; uint16(i+20) <= ospf.PacketLength; i += 20 {
|
||||
lsa := LSAheader{
|
||||
LSAge: binary.BigEndian.Uint16(data[i : i+2]),
|
||||
LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
|
||||
LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),
|
||||
AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
|
||||
LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),
|
||||
LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]),
|
||||
Length: binary.BigEndian.Uint16(data[i+18 : i+20]),
|
||||
}
|
||||
lsas = append(lsas, lsa)
|
||||
}
|
||||
ospf.Content = DbDescPkg{
|
||||
InterfaceMTU: binary.BigEndian.Uint16(data[24:26]),
|
||||
Options: uint32(data[26]),
|
||||
Flags: uint16(data[27]),
|
||||
DDSeqNumber: binary.BigEndian.Uint32(data[28:32]),
|
||||
LSAinfo: lsas,
|
||||
}
|
||||
case OSPFLinkStateRequest:
|
||||
var lsrs []LSReq
|
||||
for i := 24; uint16(i+12) <= ospf.PacketLength; i += 12 {
|
||||
lsr := LSReq{
|
||||
LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
|
||||
LSID: binary.BigEndian.Uint32(data[i+4 : i+8]),
|
||||
AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
|
||||
}
|
||||
lsrs = append(lsrs, lsr)
|
||||
}
|
||||
ospf.Content = lsrs
|
||||
case OSPFLinkStateUpdate:
|
||||
num := binary.BigEndian.Uint32(data[24:28])
|
||||
|
||||
lsas, err := getLSAsv2(num, data[28:])
|
||||
if err != nil {
|
||||
return fmt.Errorf("Cannot parse Link State Update packet: %v", err)
|
||||
}
|
||||
ospf.Content = LSUpdate{
|
||||
NumOfLSAs: num,
|
||||
LSAs: lsas,
|
||||
}
|
||||
case OSPFLinkStateAcknowledgment:
|
||||
var lsas []LSAheader
|
||||
for i := 24; uint16(i+20) <= ospf.PacketLength; i += 20 {
|
||||
lsa := LSAheader{
|
||||
LSAge: binary.BigEndian.Uint16(data[i : i+2]),
|
||||
LSOptions: data[i+2],
|
||||
LSType: uint16(data[i+3]),
|
||||
LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),
|
||||
AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
|
||||
LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),
|
||||
LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]),
|
||||
Length: binary.BigEndian.Uint16(data[i+18 : i+20]),
|
||||
}
|
||||
lsas = append(lsas, lsa)
|
||||
}
|
||||
ospf.Content = lsas
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DecodeFromBytes decodes the given bytes into the OSPF layer.
|
||||
func (ospf *OSPFv3) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
|
||||
if len(data) < 16 {
|
||||
return fmt.Errorf("Packet too smal for OSPF Version 3")
|
||||
}
|
||||
|
||||
ospf.Version = uint8(data[0])
|
||||
ospf.Type = OSPFType(data[1])
|
||||
ospf.PacketLength = binary.BigEndian.Uint16(data[2:4])
|
||||
ospf.RouterID = binary.BigEndian.Uint32(data[4:8])
|
||||
ospf.AreaID = binary.BigEndian.Uint32(data[8:12])
|
||||
ospf.Checksum = binary.BigEndian.Uint16(data[12:14])
|
||||
ospf.Instance = uint8(data[14])
|
||||
ospf.Reserved = uint8(data[15])
|
||||
|
||||
switch ospf.Type {
|
||||
case OSPFHello:
|
||||
var neighbors []uint32
|
||||
for i := 36; uint16(i+4) <= ospf.PacketLength; i += 4 {
|
||||
neighbors = append(neighbors, binary.BigEndian.Uint32(data[i:i+4]))
|
||||
}
|
||||
ospf.Content = HelloPkg{
|
||||
InterfaceID: binary.BigEndian.Uint32(data[16:20]),
|
||||
RtrPriority: uint8(data[20]),
|
||||
Options: binary.BigEndian.Uint32(data[21:25]) >> 8,
|
||||
HelloInterval: binary.BigEndian.Uint16(data[24:26]),
|
||||
RouterDeadInterval: uint32(binary.BigEndian.Uint16(data[26:28])),
|
||||
DesignatedRouterID: binary.BigEndian.Uint32(data[28:32]),
|
||||
BackupDesignatedRouterID: binary.BigEndian.Uint32(data[32:36]),
|
||||
NeighborID: neighbors,
|
||||
}
|
||||
case OSPFDatabaseDescription:
|
||||
var lsas []LSAheader
|
||||
for i := 28; uint16(i+20) <= ospf.PacketLength; i += 20 {
|
||||
lsa := LSAheader{
|
||||
LSAge: binary.BigEndian.Uint16(data[i : i+2]),
|
||||
LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
|
||||
LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),
|
||||
AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
|
||||
LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),
|
||||
LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]),
|
||||
Length: binary.BigEndian.Uint16(data[i+18 : i+20]),
|
||||
}
|
||||
lsas = append(lsas, lsa)
|
||||
}
|
||||
ospf.Content = DbDescPkg{
|
||||
Options: binary.BigEndian.Uint32(data[16:20]) & 0x00FFFFFF,
|
||||
InterfaceMTU: binary.BigEndian.Uint16(data[20:22]),
|
||||
Flags: binary.BigEndian.Uint16(data[22:24]),
|
||||
DDSeqNumber: binary.BigEndian.Uint32(data[24:28]),
|
||||
LSAinfo: lsas,
|
||||
}
|
||||
case OSPFLinkStateRequest:
|
||||
var lsrs []LSReq
|
||||
for i := 16; uint16(i+12) <= ospf.PacketLength; i += 12 {
|
||||
lsr := LSReq{
|
||||
LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
|
||||
LSID: binary.BigEndian.Uint32(data[i+4 : i+8]),
|
||||
AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
|
||||
}
|
||||
lsrs = append(lsrs, lsr)
|
||||
}
|
||||
ospf.Content = lsrs
|
||||
case OSPFLinkStateUpdate:
|
||||
num := binary.BigEndian.Uint32(data[16:20])
|
||||
lsas, err := getLSAs(num, data[20:])
|
||||
if err != nil {
|
||||
return fmt.Errorf("Cannot parse Link State Update packet: %v", err)
|
||||
}
|
||||
ospf.Content = LSUpdate{
|
||||
NumOfLSAs: num,
|
||||
LSAs: lsas,
|
||||
}
|
||||
|
||||
case OSPFLinkStateAcknowledgment:
|
||||
var lsas []LSAheader
|
||||
for i := 16; uint16(i+20) <= ospf.PacketLength; i += 20 {
|
||||
lsa := LSAheader{
|
||||
LSAge: binary.BigEndian.Uint16(data[i : i+2]),
|
||||
LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
|
||||
LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),
|
||||
AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
|
||||
LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),
|
||||
LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]),
|
||||
Length: binary.BigEndian.Uint16(data[i+18 : i+20]),
|
||||
}
|
||||
lsas = append(lsas, lsa)
|
||||
}
|
||||
ospf.Content = lsas
|
||||
default:
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LayerType returns LayerTypeOSPF
|
||||
func (ospf *OSPFv2) LayerType() gopacket.LayerType {
|
||||
return LayerTypeOSPF
|
||||
}
|
||||
func (ospf *OSPFv3) LayerType() gopacket.LayerType {
|
||||
return LayerTypeOSPF
|
||||
}
|
||||
|
||||
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||
func (ospf *OSPFv2) NextLayerType() gopacket.LayerType {
|
||||
return gopacket.LayerTypeZero
|
||||
}
|
||||
func (ospf *OSPFv3) NextLayerType() gopacket.LayerType {
|
||||
return gopacket.LayerTypeZero
|
||||
}
|
||||
|
||||
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||
func (ospf *OSPFv2) CanDecode() gopacket.LayerClass {
|
||||
return LayerTypeOSPF
|
||||
}
|
||||
func (ospf *OSPFv3) CanDecode() gopacket.LayerClass {
|
||||
return LayerTypeOSPF
|
||||
}
|
||||
|
||||
func decodeOSPF(data []byte, p gopacket.PacketBuilder) error {
|
||||
if len(data) < 14 {
|
||||
return fmt.Errorf("Packet too smal for OSPF")
|
||||
}
|
||||
|
||||
switch uint8(data[0]) {
|
||||
case 2:
|
||||
ospf := &OSPFv2{}
|
||||
return decodingLayerDecoder(ospf, data, p)
|
||||
case 3:
|
||||
ospf := &OSPFv3{}
|
||||
return decodingLayerDecoder(ospf, data, p)
|
||||
default:
|
||||
}
|
||||
|
||||
return fmt.Errorf("Unable to determine OSPF type.")
|
||||
}
|
Reference in New Issue
Block a user