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