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