123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680 |
- // 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"
- "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
- 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
- }
- // 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
- links := binary.BigEndian.Uint16(data[22:24])
- content = RouterLSAV2{
- Flags: data[20],
- Links: links,
- Routers: routers,
- }
- 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 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.")
- }
|