github.com/gopacket/gopacket@v1.1.0/layers/ospf.go (about) 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 7 package layers 8 9 import ( 10 "encoding/binary" 11 "errors" 12 "fmt" 13 14 "github.com/gopacket/gopacket" 15 ) 16 17 // OSPFType denotes what kind of OSPF type it is 18 type OSPFType uint8 19 20 // Potential values for OSPF.Type. 21 const ( 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 30 const ( 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 48 func (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 66 type 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. 74 type 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. 83 type 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. 92 type 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. 101 type 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. 114 type InterAreaRouterLSA struct { 115 Options uint32 116 Metric uint32 117 DestinationRouterID uint32 118 } 119 120 // InterAreaPrefixLSA is the struct from RFC 5340 A.4.5. 121 type 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. 129 type NetworkLSA struct { 130 Options uint32 131 AttachedRouter []uint32 132 } 133 134 // NetworkLSAV2 is the struct from RFC 2328 A.4.3. 135 type NetworkLSAV2 struct { 136 NetworkMask uint32 137 AttachedRouter []uint32 138 } 139 140 // RouterV2 extends RouterLSAV2 141 type 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. 149 type RouterLSAV2 struct { 150 Flags uint8 151 Links uint16 152 Routers []RouterV2 153 } 154 155 // Router extends RouterLSA 156 type 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. 165 type 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. 172 type 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. 184 type LSA struct { 185 LSAheader 186 Content interface{} 187 } 188 189 // LSUpdate is the struct from RFC 5340 A.3.5. 190 type LSUpdate struct { 191 NumOfLSAs uint32 192 LSAs []LSA 193 } 194 195 // LSReq is the struct from RFC 5340 A.3.4. 196 type LSReq struct { 197 LSType uint16 198 LSID uint32 199 AdvRouter uint32 200 } 201 202 // DbDescPkg is the struct from RFC 5340 A.3.3. 203 type 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. 212 type 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 224 type 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. 230 type 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 241 type 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 249 type 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 257 func 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 288 func 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 452 func 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. 484 func (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. 580 func (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 676 func (ospf *OSPFv2) LayerType() gopacket.LayerType { 677 return LayerTypeOSPF 678 } 679 func (ospf *OSPFv3) LayerType() gopacket.LayerType { 680 return LayerTypeOSPF 681 } 682 683 // NextLayerType returns the layer type contained by this DecodingLayer. 684 func (ospf *OSPFv2) NextLayerType() gopacket.LayerType { 685 return gopacket.LayerTypeZero 686 } 687 func (ospf *OSPFv3) NextLayerType() gopacket.LayerType { 688 return gopacket.LayerTypeZero 689 } 690 691 // CanDecode returns the set of layer types that this DecodingLayer can decode. 692 func (ospf *OSPFv2) CanDecode() gopacket.LayerClass { 693 return LayerTypeOSPF 694 } 695 func (ospf *OSPFv3) CanDecode() gopacket.LayerClass { 696 return LayerTypeOSPF 697 } 698 699 func 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 }