ospf.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  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. package layers
  7. import (
  8. "encoding/binary"
  9. "fmt"
  10. "github.com/google/gopacket"
  11. )
  12. // OSPFType denotes what kind of OSPF type it is
  13. type OSPFType uint8
  14. // Potential values for OSPF.Type.
  15. const (
  16. OSPFHello OSPFType = 1
  17. OSPFDatabaseDescription OSPFType = 2
  18. OSPFLinkStateRequest OSPFType = 3
  19. OSPFLinkStateUpdate OSPFType = 4
  20. OSPFLinkStateAcknowledgment OSPFType = 5
  21. )
  22. // LSA Function Codes for LSAheader.LSType
  23. const (
  24. RouterLSAtypeV2 = 0x1
  25. RouterLSAtype = 0x2001
  26. NetworkLSAtypeV2 = 0x2
  27. NetworkLSAtype = 0x2002
  28. SummaryLSANetworktypeV2 = 0x3
  29. InterAreaPrefixLSAtype = 0x2003
  30. SummaryLSAASBRtypeV2 = 0x4
  31. InterAreaRouterLSAtype = 0x2004
  32. ASExternalLSAtypeV2 = 0x5
  33. ASExternalLSAtype = 0x4005
  34. NSSALSAtype = 0x2007
  35. LinkLSAtype = 0x0008
  36. IntraAreaPrefixLSAtype = 0x2009
  37. )
  38. // String conversions for OSPFType
  39. func (i OSPFType) String() string {
  40. switch i {
  41. case OSPFHello:
  42. return "Hello"
  43. case OSPFDatabaseDescription:
  44. return "Database Description"
  45. case OSPFLinkStateRequest:
  46. return "Link State Request"
  47. case OSPFLinkStateUpdate:
  48. return "Link State Update"
  49. case OSPFLinkStateAcknowledgment:
  50. return "Link State Acknowledgment"
  51. default:
  52. return ""
  53. }
  54. }
  55. // Prefix extends IntraAreaPrefixLSA
  56. type Prefix struct {
  57. PrefixLength uint8
  58. PrefixOptions uint8
  59. Metric uint16
  60. AddressPrefix []byte
  61. }
  62. // IntraAreaPrefixLSA is the struct from RFC 5340 A.4.10.
  63. type IntraAreaPrefixLSA struct {
  64. NumOfPrefixes uint16
  65. RefLSType uint16
  66. RefLinkStateID uint32
  67. RefAdvRouter uint32
  68. Prefixes []Prefix
  69. }
  70. // LinkLSA is the struct from RFC 5340 A.4.9.
  71. type LinkLSA struct {
  72. RtrPriority uint8
  73. Options uint32
  74. LinkLocalAddress []byte
  75. NumOfPrefixes uint32
  76. Prefixes []Prefix
  77. }
  78. // ASExternalLSAV2 is the struct from RFC 2328 A.4.5.
  79. type ASExternalLSAV2 struct {
  80. NetworkMask uint32
  81. ExternalBit uint8
  82. Metric uint32
  83. ForwardingAddress uint32
  84. ExternalRouteTag uint32
  85. }
  86. // ASExternalLSA is the struct from RFC 5340 A.4.7.
  87. type ASExternalLSA struct {
  88. Flags uint8
  89. Metric uint32
  90. PrefixLength uint8
  91. PrefixOptions uint8
  92. RefLSType uint16
  93. AddressPrefix []byte
  94. ForwardingAddress []byte
  95. ExternalRouteTag uint32
  96. RefLinkStateID uint32
  97. }
  98. // InterAreaRouterLSA is the struct from RFC 5340 A.4.6.
  99. type InterAreaRouterLSA struct {
  100. Options uint32
  101. Metric uint32
  102. DestinationRouterID uint32
  103. }
  104. // InterAreaPrefixLSA is the struct from RFC 5340 A.4.5.
  105. type InterAreaPrefixLSA struct {
  106. Metric uint32
  107. PrefixLength uint8
  108. PrefixOptions uint8
  109. AddressPrefix []byte
  110. }
  111. // NetworkLSA is the struct from RFC 5340 A.4.4.
  112. type NetworkLSA struct {
  113. Options uint32
  114. AttachedRouter []uint32
  115. }
  116. // RouterV2 extends RouterLSAV2
  117. type RouterV2 struct {
  118. Type uint8
  119. LinkID uint32
  120. LinkData uint32
  121. Metric uint16
  122. }
  123. // RouterLSAV2 is the struct from RFC 2328 A.4.2.
  124. type RouterLSAV2 struct {
  125. Flags uint8
  126. Links uint16
  127. Routers []RouterV2
  128. }
  129. // Router extends RouterLSA
  130. type Router struct {
  131. Type uint8
  132. Metric uint16
  133. InterfaceID uint32
  134. NeighborInterfaceID uint32
  135. NeighborRouterID uint32
  136. }
  137. // RouterLSA is the struct from RFC 5340 A.4.3.
  138. type RouterLSA struct {
  139. Flags uint8
  140. Options uint32
  141. Routers []Router
  142. }
  143. // LSAheader is the struct from RFC 5340 A.4.2 and RFC 2328 A.4.1.
  144. type LSAheader struct {
  145. LSAge uint16
  146. LSType uint16
  147. LinkStateID uint32
  148. AdvRouter uint32
  149. LSSeqNumber uint32
  150. LSChecksum uint16
  151. Length uint16
  152. LSOptions uint8
  153. }
  154. // LSA links LSAheader with the structs from RFC 5340 A.4.
  155. type LSA struct {
  156. LSAheader
  157. Content interface{}
  158. }
  159. // LSUpdate is the struct from RFC 5340 A.3.5.
  160. type LSUpdate struct {
  161. NumOfLSAs uint32
  162. LSAs []LSA
  163. }
  164. // LSReq is the struct from RFC 5340 A.3.4.
  165. type LSReq struct {
  166. LSType uint16
  167. LSID uint32
  168. AdvRouter uint32
  169. }
  170. // DbDescPkg is the struct from RFC 5340 A.3.3.
  171. type DbDescPkg struct {
  172. Options uint32
  173. InterfaceMTU uint16
  174. Flags uint16
  175. DDSeqNumber uint32
  176. LSAinfo []LSAheader
  177. }
  178. // HelloPkg is the struct from RFC 5340 A.3.2.
  179. type HelloPkg struct {
  180. InterfaceID uint32
  181. RtrPriority uint8
  182. Options uint32
  183. HelloInterval uint16
  184. RouterDeadInterval uint32
  185. DesignatedRouterID uint32
  186. BackupDesignatedRouterID uint32
  187. NeighborID []uint32
  188. }
  189. // HelloPkgV2 extends the HelloPkg struct with OSPFv2 information
  190. type HelloPkgV2 struct {
  191. HelloPkg
  192. NetworkMask uint32
  193. }
  194. // OSPF is a basic OSPF packet header with common fields of Version 2 and Version 3.
  195. type OSPF struct {
  196. Version uint8
  197. Type OSPFType
  198. PacketLength uint16
  199. RouterID uint32
  200. AreaID uint32
  201. Checksum uint16
  202. Content interface{}
  203. }
  204. //OSPFv2 extend the OSPF head with version 2 specific fields
  205. type OSPFv2 struct {
  206. BaseLayer
  207. OSPF
  208. AuType uint16
  209. Authentication uint64
  210. }
  211. // OSPFv3 extend the OSPF head with version 3 specific fields
  212. type OSPFv3 struct {
  213. BaseLayer
  214. OSPF
  215. Instance uint8
  216. Reserved uint8
  217. }
  218. // getLSAsv2 parses the LSA information from the packet for OSPFv2
  219. func getLSAsv2(num uint32, data []byte) ([]LSA, error) {
  220. var lsas []LSA
  221. var i uint32 = 0
  222. var offset uint32 = 0
  223. for ; i < num; i++ {
  224. lstype := uint16(data[offset+3])
  225. lsalength := binary.BigEndian.Uint16(data[offset+18 : offset+20])
  226. content, err := extractLSAInformation(lstype, lsalength, data[offset:])
  227. if err != nil {
  228. return nil, fmt.Errorf("Could not extract Link State type.")
  229. }
  230. lsa := LSA{
  231. LSAheader: LSAheader{
  232. LSAge: binary.BigEndian.Uint16(data[offset : offset+2]),
  233. LSOptions: data[offset+2],
  234. LSType: lstype,
  235. LinkStateID: binary.BigEndian.Uint32(data[offset+4 : offset+8]),
  236. AdvRouter: binary.BigEndian.Uint32(data[offset+8 : offset+12]),
  237. LSSeqNumber: binary.BigEndian.Uint32(data[offset+12 : offset+16]),
  238. LSChecksum: binary.BigEndian.Uint16(data[offset+16 : offset+18]),
  239. Length: lsalength,
  240. },
  241. Content: content,
  242. }
  243. lsas = append(lsas, lsa)
  244. offset += uint32(lsalength)
  245. }
  246. return lsas, nil
  247. }
  248. // extractLSAInformation extracts all the LSA information
  249. func extractLSAInformation(lstype, lsalength uint16, data []byte) (interface{}, error) {
  250. if lsalength < 20 {
  251. return nil, fmt.Errorf("Link State header length %v too short, %v required", lsalength, 20)
  252. }
  253. if len(data) < int(lsalength) {
  254. return nil, fmt.Errorf("Link State header length %v too short, %v required", len(data), lsalength)
  255. }
  256. var content interface{}
  257. switch lstype {
  258. case RouterLSAtypeV2:
  259. var routers []RouterV2
  260. links := binary.BigEndian.Uint16(data[22:24])
  261. content = RouterLSAV2{
  262. Flags: data[20],
  263. Links: links,
  264. Routers: routers,
  265. }
  266. case ASExternalLSAtypeV2:
  267. content = ASExternalLSAV2{
  268. NetworkMask: binary.BigEndian.Uint32(data[20:24]),
  269. ExternalBit: data[24] & 0x80,
  270. Metric: binary.BigEndian.Uint32(data[24:28]) & 0x00FFFFFF,
  271. ForwardingAddress: binary.BigEndian.Uint32(data[28:32]),
  272. ExternalRouteTag: binary.BigEndian.Uint32(data[32:36]),
  273. }
  274. case RouterLSAtype:
  275. var routers []Router
  276. var j uint32
  277. for j = 24; j < uint32(lsalength); j += 16 {
  278. router := Router{
  279. Type: uint8(data[j]),
  280. Metric: binary.BigEndian.Uint16(data[j+2 : j+4]),
  281. InterfaceID: binary.BigEndian.Uint32(data[j+4 : j+8]),
  282. NeighborInterfaceID: binary.BigEndian.Uint32(data[j+8 : j+12]),
  283. NeighborRouterID: binary.BigEndian.Uint32(data[j+12 : j+16]),
  284. }
  285. routers = append(routers, router)
  286. }
  287. content = RouterLSA{
  288. Flags: uint8(data[20]),
  289. Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
  290. Routers: routers,
  291. }
  292. case NetworkLSAtype:
  293. var routers []uint32
  294. var j uint32
  295. for j = 24; j < uint32(lsalength); j += 4 {
  296. routers = append(routers, binary.BigEndian.Uint32(data[j:j+4]))
  297. }
  298. content = NetworkLSA{
  299. Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
  300. AttachedRouter: routers,
  301. }
  302. case InterAreaPrefixLSAtype:
  303. content = InterAreaPrefixLSA{
  304. Metric: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
  305. PrefixLength: uint8(data[24]),
  306. PrefixOptions: uint8(data[25]),
  307. AddressPrefix: data[28:uint32(lsalength)],
  308. }
  309. case InterAreaRouterLSAtype:
  310. content = InterAreaRouterLSA{
  311. Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
  312. Metric: binary.BigEndian.Uint32(data[24:28]) & 0x00FFFFFF,
  313. DestinationRouterID: binary.BigEndian.Uint32(data[28:32]),
  314. }
  315. case ASExternalLSAtype:
  316. fallthrough
  317. case NSSALSAtype:
  318. flags := uint8(data[20])
  319. prefixLen := uint8(data[24]) / 8
  320. var forwardingAddress []byte
  321. if (flags & 0x02) == 0x02 {
  322. forwardingAddress = data[28+uint32(prefixLen) : 28+uint32(prefixLen)+16]
  323. }
  324. content = ASExternalLSA{
  325. Flags: flags,
  326. Metric: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
  327. PrefixLength: prefixLen,
  328. PrefixOptions: uint8(data[25]),
  329. RefLSType: binary.BigEndian.Uint16(data[26:28]),
  330. AddressPrefix: data[28 : 28+uint32(prefixLen)],
  331. ForwardingAddress: forwardingAddress,
  332. }
  333. case LinkLSAtype:
  334. var prefixes []Prefix
  335. var prefixOffset uint32 = 44
  336. var j uint32
  337. numOfPrefixes := binary.BigEndian.Uint32(data[40:44])
  338. for j = 0; j < numOfPrefixes; j++ {
  339. prefixLen := uint8(data[prefixOffset])
  340. prefix := Prefix{
  341. PrefixLength: prefixLen,
  342. PrefixOptions: uint8(data[prefixOffset+1]),
  343. AddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8],
  344. }
  345. prefixes = append(prefixes, prefix)
  346. prefixOffset = prefixOffset + 4 + uint32(prefixLen)/8
  347. }
  348. content = LinkLSA{
  349. RtrPriority: uint8(data[20]),
  350. Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
  351. LinkLocalAddress: data[24:40],
  352. NumOfPrefixes: numOfPrefixes,
  353. Prefixes: prefixes,
  354. }
  355. case IntraAreaPrefixLSAtype:
  356. var prefixes []Prefix
  357. var prefixOffset uint32 = 32
  358. var j uint16
  359. numOfPrefixes := binary.BigEndian.Uint16(data[20:22])
  360. for j = 0; j < numOfPrefixes; j++ {
  361. prefixLen := uint8(data[prefixOffset])
  362. prefix := Prefix{
  363. PrefixLength: prefixLen,
  364. PrefixOptions: uint8(data[prefixOffset+1]),
  365. Metric: binary.BigEndian.Uint16(data[prefixOffset+2 : prefixOffset+4]),
  366. AddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8],
  367. }
  368. prefixes = append(prefixes, prefix)
  369. prefixOffset = prefixOffset + 4 + uint32(prefixLen)
  370. }
  371. content = IntraAreaPrefixLSA{
  372. NumOfPrefixes: numOfPrefixes,
  373. RefLSType: binary.BigEndian.Uint16(data[22:24]),
  374. RefLinkStateID: binary.BigEndian.Uint32(data[24:28]),
  375. RefAdvRouter: binary.BigEndian.Uint32(data[28:32]),
  376. Prefixes: prefixes,
  377. }
  378. default:
  379. return nil, fmt.Errorf("Unknown Link State type.")
  380. }
  381. return content, nil
  382. }
  383. // getLSAs parses the LSA information from the packet for OSPFv3
  384. func getLSAs(num uint32, data []byte) ([]LSA, error) {
  385. var lsas []LSA
  386. var i uint32 = 0
  387. var offset uint32 = 0
  388. for ; i < num; i++ {
  389. var content interface{}
  390. lstype := binary.BigEndian.Uint16(data[offset+2 : offset+4])
  391. lsalength := binary.BigEndian.Uint16(data[offset+18 : offset+20])
  392. content, err := extractLSAInformation(lstype, lsalength, data[offset:])
  393. if err != nil {
  394. return nil, fmt.Errorf("Could not extract Link State type.")
  395. }
  396. lsa := LSA{
  397. LSAheader: LSAheader{
  398. LSAge: binary.BigEndian.Uint16(data[offset : offset+2]),
  399. LSType: lstype,
  400. LinkStateID: binary.BigEndian.Uint32(data[offset+4 : offset+8]),
  401. AdvRouter: binary.BigEndian.Uint32(data[offset+8 : offset+12]),
  402. LSSeqNumber: binary.BigEndian.Uint32(data[offset+12 : offset+16]),
  403. LSChecksum: binary.BigEndian.Uint16(data[offset+16 : offset+18]),
  404. Length: lsalength,
  405. },
  406. Content: content,
  407. }
  408. lsas = append(lsas, lsa)
  409. offset += uint32(lsalength)
  410. }
  411. return lsas, nil
  412. }
  413. // DecodeFromBytes decodes the given bytes into the OSPF layer.
  414. func (ospf *OSPFv2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  415. if len(data) < 24 {
  416. return fmt.Errorf("Packet too smal for OSPF Version 2")
  417. }
  418. ospf.Version = uint8(data[0])
  419. ospf.Type = OSPFType(data[1])
  420. ospf.PacketLength = binary.BigEndian.Uint16(data[2:4])
  421. ospf.RouterID = binary.BigEndian.Uint32(data[4:8])
  422. ospf.AreaID = binary.BigEndian.Uint32(data[8:12])
  423. ospf.Checksum = binary.BigEndian.Uint16(data[12:14])
  424. ospf.AuType = binary.BigEndian.Uint16(data[14:16])
  425. ospf.Authentication = binary.BigEndian.Uint64(data[16:24])
  426. switch ospf.Type {
  427. case OSPFHello:
  428. var neighbors []uint32
  429. for i := 44; uint16(i+4) <= ospf.PacketLength; i += 4 {
  430. neighbors = append(neighbors, binary.BigEndian.Uint32(data[i:i+4]))
  431. }
  432. ospf.Content = HelloPkgV2{
  433. NetworkMask: binary.BigEndian.Uint32(data[24:28]),
  434. HelloPkg: HelloPkg{
  435. HelloInterval: binary.BigEndian.Uint16(data[28:30]),
  436. Options: uint32(data[30]),
  437. RtrPriority: uint8(data[31]),
  438. RouterDeadInterval: binary.BigEndian.Uint32(data[32:36]),
  439. DesignatedRouterID: binary.BigEndian.Uint32(data[36:40]),
  440. BackupDesignatedRouterID: binary.BigEndian.Uint32(data[40:44]),
  441. NeighborID: neighbors,
  442. },
  443. }
  444. case OSPFDatabaseDescription:
  445. var lsas []LSAheader
  446. for i := 32; uint16(i+20) <= ospf.PacketLength; i += 20 {
  447. lsa := LSAheader{
  448. LSAge: binary.BigEndian.Uint16(data[i : i+2]),
  449. LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
  450. LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),
  451. AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
  452. LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),
  453. LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]),
  454. Length: binary.BigEndian.Uint16(data[i+18 : i+20]),
  455. }
  456. lsas = append(lsas, lsa)
  457. }
  458. ospf.Content = DbDescPkg{
  459. InterfaceMTU: binary.BigEndian.Uint16(data[24:26]),
  460. Options: uint32(data[26]),
  461. Flags: uint16(data[27]),
  462. DDSeqNumber: binary.BigEndian.Uint32(data[28:32]),
  463. LSAinfo: lsas,
  464. }
  465. case OSPFLinkStateRequest:
  466. var lsrs []LSReq
  467. for i := 24; uint16(i+12) <= ospf.PacketLength; i += 12 {
  468. lsr := LSReq{
  469. LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
  470. LSID: binary.BigEndian.Uint32(data[i+4 : i+8]),
  471. AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
  472. }
  473. lsrs = append(lsrs, lsr)
  474. }
  475. ospf.Content = lsrs
  476. case OSPFLinkStateUpdate:
  477. num := binary.BigEndian.Uint32(data[24:28])
  478. lsas, err := getLSAsv2(num, data[28:])
  479. if err != nil {
  480. return fmt.Errorf("Cannot parse Link State Update packet: %v", err)
  481. }
  482. ospf.Content = LSUpdate{
  483. NumOfLSAs: num,
  484. LSAs: lsas,
  485. }
  486. case OSPFLinkStateAcknowledgment:
  487. var lsas []LSAheader
  488. for i := 24; uint16(i+20) <= ospf.PacketLength; i += 20 {
  489. lsa := LSAheader{
  490. LSAge: binary.BigEndian.Uint16(data[i : i+2]),
  491. LSOptions: data[i+2],
  492. LSType: uint16(data[i+3]),
  493. LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),
  494. AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
  495. LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),
  496. LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]),
  497. Length: binary.BigEndian.Uint16(data[i+18 : i+20]),
  498. }
  499. lsas = append(lsas, lsa)
  500. }
  501. ospf.Content = lsas
  502. }
  503. return nil
  504. }
  505. // DecodeFromBytes decodes the given bytes into the OSPF layer.
  506. func (ospf *OSPFv3) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  507. if len(data) < 16 {
  508. return fmt.Errorf("Packet too smal for OSPF Version 3")
  509. }
  510. ospf.Version = uint8(data[0])
  511. ospf.Type = OSPFType(data[1])
  512. ospf.PacketLength = binary.BigEndian.Uint16(data[2:4])
  513. ospf.RouterID = binary.BigEndian.Uint32(data[4:8])
  514. ospf.AreaID = binary.BigEndian.Uint32(data[8:12])
  515. ospf.Checksum = binary.BigEndian.Uint16(data[12:14])
  516. ospf.Instance = uint8(data[14])
  517. ospf.Reserved = uint8(data[15])
  518. switch ospf.Type {
  519. case OSPFHello:
  520. var neighbors []uint32
  521. for i := 36; uint16(i+4) <= ospf.PacketLength; i += 4 {
  522. neighbors = append(neighbors, binary.BigEndian.Uint32(data[i:i+4]))
  523. }
  524. ospf.Content = HelloPkg{
  525. InterfaceID: binary.BigEndian.Uint32(data[16:20]),
  526. RtrPriority: uint8(data[20]),
  527. Options: binary.BigEndian.Uint32(data[21:25]) >> 8,
  528. HelloInterval: binary.BigEndian.Uint16(data[24:26]),
  529. RouterDeadInterval: uint32(binary.BigEndian.Uint16(data[26:28])),
  530. DesignatedRouterID: binary.BigEndian.Uint32(data[28:32]),
  531. BackupDesignatedRouterID: binary.BigEndian.Uint32(data[32:36]),
  532. NeighborID: neighbors,
  533. }
  534. case OSPFDatabaseDescription:
  535. var lsas []LSAheader
  536. for i := 28; uint16(i+20) <= ospf.PacketLength; i += 20 {
  537. lsa := LSAheader{
  538. LSAge: binary.BigEndian.Uint16(data[i : i+2]),
  539. LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
  540. LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),
  541. AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
  542. LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),
  543. LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]),
  544. Length: binary.BigEndian.Uint16(data[i+18 : i+20]),
  545. }
  546. lsas = append(lsas, lsa)
  547. }
  548. ospf.Content = DbDescPkg{
  549. Options: binary.BigEndian.Uint32(data[16:20]) & 0x00FFFFFF,
  550. InterfaceMTU: binary.BigEndian.Uint16(data[20:22]),
  551. Flags: binary.BigEndian.Uint16(data[22:24]),
  552. DDSeqNumber: binary.BigEndian.Uint32(data[24:28]),
  553. LSAinfo: lsas,
  554. }
  555. case OSPFLinkStateRequest:
  556. var lsrs []LSReq
  557. for i := 16; uint16(i+12) <= ospf.PacketLength; i += 12 {
  558. lsr := LSReq{
  559. LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
  560. LSID: binary.BigEndian.Uint32(data[i+4 : i+8]),
  561. AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
  562. }
  563. lsrs = append(lsrs, lsr)
  564. }
  565. ospf.Content = lsrs
  566. case OSPFLinkStateUpdate:
  567. num := binary.BigEndian.Uint32(data[16:20])
  568. lsas, err := getLSAs(num, data[20:])
  569. if err != nil {
  570. return fmt.Errorf("Cannot parse Link State Update packet: %v", err)
  571. }
  572. ospf.Content = LSUpdate{
  573. NumOfLSAs: num,
  574. LSAs: lsas,
  575. }
  576. case OSPFLinkStateAcknowledgment:
  577. var lsas []LSAheader
  578. for i := 16; uint16(i+20) <= ospf.PacketLength; i += 20 {
  579. lsa := LSAheader{
  580. LSAge: binary.BigEndian.Uint16(data[i : i+2]),
  581. LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
  582. LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),
  583. AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
  584. LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),
  585. LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]),
  586. Length: binary.BigEndian.Uint16(data[i+18 : i+20]),
  587. }
  588. lsas = append(lsas, lsa)
  589. }
  590. ospf.Content = lsas
  591. default:
  592. }
  593. return nil
  594. }
  595. // LayerType returns LayerTypeOSPF
  596. func (ospf *OSPFv2) LayerType() gopacket.LayerType {
  597. return LayerTypeOSPF
  598. }
  599. func (ospf *OSPFv3) LayerType() gopacket.LayerType {
  600. return LayerTypeOSPF
  601. }
  602. // NextLayerType returns the layer type contained by this DecodingLayer.
  603. func (ospf *OSPFv2) NextLayerType() gopacket.LayerType {
  604. return gopacket.LayerTypeZero
  605. }
  606. func (ospf *OSPFv3) NextLayerType() gopacket.LayerType {
  607. return gopacket.LayerTypeZero
  608. }
  609. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  610. func (ospf *OSPFv2) CanDecode() gopacket.LayerClass {
  611. return LayerTypeOSPF
  612. }
  613. func (ospf *OSPFv3) CanDecode() gopacket.LayerClass {
  614. return LayerTypeOSPF
  615. }
  616. func decodeOSPF(data []byte, p gopacket.PacketBuilder) error {
  617. if len(data) < 14 {
  618. return fmt.Errorf("Packet too smal for OSPF")
  619. }
  620. switch uint8(data[0]) {
  621. case 2:
  622. ospf := &OSPFv2{}
  623. return decodingLayerDecoder(ospf, data, p)
  624. case 3:
  625. ospf := &OSPFv3{}
  626. return decodingLayerDecoder(ospf, data, p)
  627. default:
  628. }
  629. return fmt.Errorf("Unable to determine OSPF type.")
  630. }