github.com/osrg/gobgp@v2.0.0+incompatible/pkg/packet/bmp/bmp.go (about) 1 // Copyright (C) 2014,2015 Nippon Telegraph and Telephone Corporation. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 // implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package bmp 17 18 import ( 19 "encoding/binary" 20 "fmt" 21 "math" 22 "net" 23 24 "github.com/osrg/gobgp/pkg/packet/bgp" 25 ) 26 27 type BMPHeader struct { 28 Version uint8 29 Length uint32 30 Type uint8 31 } 32 33 const ( 34 BMP_VERSION = 3 35 BMP_HEADER_SIZE = 6 36 BMP_PEER_HEADER_SIZE = 42 37 ) 38 39 const ( 40 BMP_DEFAULT_PORT = 11019 41 ) 42 43 const ( 44 BMP_PEER_TYPE_GLOBAL uint8 = iota 45 BMP_PEER_TYPE_L3VPN 46 BMP_PEER_TYPE_LOCAL 47 BMP_PEER_TYPE_LOCAL_RIB 48 ) 49 50 const ( 51 BMP_PEER_FLAG_IPV6 = 1 << 7 52 BMP_PEER_FLAG_POST_POLICY = 1 << 6 53 BMP_PEER_FLAG_TWO_AS = 1 << 5 54 BMP_PEER_FLAG_FILTERED = 1 << 6 55 ) 56 57 func (h *BMPHeader) DecodeFromBytes(data []byte) error { 58 h.Version = data[0] 59 if data[0] != BMP_VERSION { 60 return fmt.Errorf("error version") 61 } 62 h.Length = binary.BigEndian.Uint32(data[1:5]) 63 h.Type = data[5] 64 return nil 65 } 66 67 func (h *BMPHeader) Serialize() ([]byte, error) { 68 buf := make([]byte, BMP_HEADER_SIZE) 69 buf[0] = h.Version 70 binary.BigEndian.PutUint32(buf[1:], h.Length) 71 buf[5] = h.Type 72 return buf, nil 73 } 74 75 type BMPPeerHeader struct { 76 PeerType uint8 77 Flags uint8 78 PeerDistinguisher uint64 79 PeerAddress net.IP 80 PeerAS uint32 81 PeerBGPID net.IP 82 Timestamp float64 83 } 84 85 func NewBMPPeerHeader(t uint8, flags uint8, dist uint64, address string, as uint32, id string, stamp float64) *BMPPeerHeader { 86 h := &BMPPeerHeader{ 87 PeerType: t, 88 Flags: flags, 89 PeerDistinguisher: dist, 90 PeerAS: as, 91 PeerBGPID: net.ParseIP(id).To4(), 92 Timestamp: stamp, 93 } 94 if net.ParseIP(address).To4() != nil { 95 h.PeerAddress = net.ParseIP(address).To4() 96 } else { 97 h.PeerAddress = net.ParseIP(address).To16() 98 h.Flags |= BMP_PEER_FLAG_IPV6 99 } 100 return h 101 } 102 103 func (h *BMPPeerHeader) IsPostPolicy() bool { 104 if h.Flags&BMP_PEER_FLAG_POST_POLICY != 0 { 105 return true 106 } else { 107 return false 108 } 109 } 110 111 func (h *BMPPeerHeader) DecodeFromBytes(data []byte) error { 112 h.PeerType = data[0] 113 h.Flags = data[1] 114 h.PeerDistinguisher = binary.BigEndian.Uint64(data[2:10]) 115 if h.Flags&BMP_PEER_FLAG_IPV6 != 0 { 116 h.PeerAddress = net.IP(data[10:26]).To16() 117 } else { 118 h.PeerAddress = net.IP(data[22:26]).To4() 119 } 120 h.PeerAS = binary.BigEndian.Uint32(data[26:30]) 121 h.PeerBGPID = data[30:34] 122 123 timestamp1 := binary.BigEndian.Uint32(data[34:38]) 124 timestamp2 := binary.BigEndian.Uint32(data[38:42]) 125 h.Timestamp = float64(timestamp1) + float64(timestamp2)*math.Pow10(-6) 126 return nil 127 } 128 129 func (h *BMPPeerHeader) Serialize() ([]byte, error) { 130 buf := make([]byte, BMP_PEER_HEADER_SIZE) 131 buf[0] = h.PeerType 132 buf[1] = h.Flags 133 binary.BigEndian.PutUint64(buf[2:10], h.PeerDistinguisher) 134 if h.Flags&BMP_PEER_FLAG_IPV6 != 0 { 135 copy(buf[10:26], h.PeerAddress) 136 } else { 137 copy(buf[22:26], h.PeerAddress.To4()) 138 } 139 binary.BigEndian.PutUint32(buf[26:30], h.PeerAS) 140 copy(buf[30:34], h.PeerBGPID) 141 t1, t2 := math.Modf(h.Timestamp) 142 t2 = math.Ceil(t2 * math.Pow10(6)) 143 binary.BigEndian.PutUint32(buf[34:38], uint32(t1)) 144 binary.BigEndian.PutUint32(buf[38:42], uint32(t2)) 145 return buf, nil 146 } 147 148 type BMPRouteMonitoring struct { 149 BGPUpdate *bgp.BGPMessage 150 BGPUpdatePayload []byte 151 } 152 153 func NewBMPRouteMonitoring(p BMPPeerHeader, update *bgp.BGPMessage) *BMPMessage { 154 return &BMPMessage{ 155 Header: BMPHeader{ 156 Version: BMP_VERSION, 157 Type: BMP_MSG_ROUTE_MONITORING, 158 }, 159 PeerHeader: p, 160 Body: &BMPRouteMonitoring{ 161 BGPUpdate: update, 162 }, 163 } 164 } 165 166 func (body *BMPRouteMonitoring) ParseBody(msg *BMPMessage, data []byte) error { 167 update, err := bgp.ParseBGPMessage(data) 168 if err != nil { 169 return err 170 } 171 body.BGPUpdate = update 172 return nil 173 } 174 175 func (body *BMPRouteMonitoring) Serialize() ([]byte, error) { 176 if body.BGPUpdatePayload != nil { 177 return body.BGPUpdatePayload, nil 178 } 179 return body.BGPUpdate.Serialize() 180 } 181 182 const ( 183 BMP_STAT_TYPE_REJECTED = iota 184 BMP_STAT_TYPE_DUPLICATE_PREFIX 185 BMP_STAT_TYPE_DUPLICATE_WITHDRAW 186 BMP_STAT_TYPE_INV_UPDATE_DUE_TO_CLUSTER_LIST_LOOP 187 BMP_STAT_TYPE_INV_UPDATE_DUE_TO_AS_PATH_LOOP 188 BMP_STAT_TYPE_INV_UPDATE_DUE_TO_ORIGINATOR_ID 189 BMP_STAT_TYPE_INV_UPDATE_DUE_TO_AS_CONFED_LOOP 190 BMP_STAT_TYPE_ADJ_RIB_IN 191 BMP_STAT_TYPE_LOC_RIB 192 BMP_STAT_TYPE_PER_AFI_SAFI_ADJ_RIB_IN 193 BMP_STAT_TYPE_PER_AFI_SAFI_LOC_RIB 194 BMP_STAT_TYPE_WITHDRAW_UPDATE 195 BMP_STAT_TYPE_WITHDRAW_PREFIX 196 BMP_STAT_TYPE_DUPLICATE_UPDATE 197 ) 198 199 type BMPStatsTLVInterface interface { 200 ParseValue([]byte) error 201 Serialize() ([]byte, error) 202 } 203 204 type BMPStatsTLV struct { 205 Type uint16 206 Length uint16 207 } 208 209 type BMPStatsTLV32 struct { 210 BMPStatsTLV 211 Value uint32 212 } 213 214 func NewBMPStatsTLV32(t uint16, v uint32) *BMPStatsTLV32 { 215 return &BMPStatsTLV32{ 216 BMPStatsTLV: BMPStatsTLV{ 217 Type: t, 218 Length: 4, 219 }, 220 Value: v, 221 } 222 } 223 224 func (s *BMPStatsTLV32) ParseValue(data []byte) error { 225 if s.Length != 4 { 226 return fmt.Errorf("invalid length: %d bytes (%d bytes expected)", s.Length, 4) 227 } 228 s.Value = binary.BigEndian.Uint32(data[:8]) 229 return nil 230 } 231 232 func (s *BMPStatsTLV32) Serialize() ([]byte, error) { 233 buf := make([]byte, 8) 234 binary.BigEndian.PutUint16(buf[0:2], s.Type) 235 binary.BigEndian.PutUint16(buf[2:4], 4) 236 binary.BigEndian.PutUint32(buf[4:8], s.Value) 237 return buf, nil 238 } 239 240 type BMPStatsTLV64 struct { 241 BMPStatsTLV 242 Value uint64 243 } 244 245 func NewBMPStatsTLV64(t uint16, v uint64) *BMPStatsTLV64 { 246 return &BMPStatsTLV64{ 247 BMPStatsTLV: BMPStatsTLV{ 248 Type: t, 249 Length: 8, 250 }, 251 Value: v, 252 } 253 } 254 255 func (s *BMPStatsTLV64) ParseValue(data []byte) error { 256 if s.Length != 8 { 257 return fmt.Errorf("invalid length: %d bytes (%d bytes expected)", s.Length, 8) 258 } 259 s.Value = binary.BigEndian.Uint64(data[:8]) 260 return nil 261 } 262 263 func (s *BMPStatsTLV64) Serialize() ([]byte, error) { 264 buf := make([]byte, 12) 265 binary.BigEndian.PutUint16(buf[0:2], s.Type) 266 binary.BigEndian.PutUint16(buf[2:4], 8) 267 binary.BigEndian.PutUint64(buf[4:12], s.Value) 268 return buf, nil 269 } 270 271 type BMPStatsTLVPerAfiSafi64 struct { 272 BMPStatsTLV 273 AFI uint16 274 SAFI uint8 275 Value uint64 276 } 277 278 func NewBMPStatsTLVPerAfiSafi64(t uint16, afi uint16, safi uint8, v uint64) *BMPStatsTLVPerAfiSafi64 { 279 return &BMPStatsTLVPerAfiSafi64{ 280 BMPStatsTLV: BMPStatsTLV{ 281 Type: t, 282 Length: 11, 283 }, 284 AFI: afi, 285 SAFI: safi, 286 Value: v, 287 } 288 } 289 290 func (s *BMPStatsTLVPerAfiSafi64) ParseValue(data []byte) error { 291 if s.Length != 11 { 292 return fmt.Errorf("invalid length: %d bytes (%d bytes expected)", s.Length, 11) 293 } 294 s.AFI = binary.BigEndian.Uint16(data[0:2]) 295 s.SAFI = data[2] 296 s.Value = binary.BigEndian.Uint64(data[3:11]) 297 return nil 298 } 299 300 func (s *BMPStatsTLVPerAfiSafi64) Serialize() ([]byte, error) { 301 buf := make([]byte, 15) 302 binary.BigEndian.PutUint16(buf[0:2], s.Type) 303 binary.BigEndian.PutUint16(buf[2:4], 11) 304 binary.BigEndian.PutUint16(buf[4:6], s.AFI) 305 buf[6] = s.SAFI 306 binary.BigEndian.PutUint64(buf[7:15], s.Value) 307 return buf, nil 308 } 309 310 type BMPStatisticsReport struct { 311 Count uint32 312 Stats []BMPStatsTLVInterface 313 } 314 315 func NewBMPStatisticsReport(p BMPPeerHeader, stats []BMPStatsTLVInterface) *BMPMessage { 316 return &BMPMessage{ 317 Header: BMPHeader{ 318 Version: BMP_VERSION, 319 Type: BMP_MSG_STATISTICS_REPORT, 320 }, 321 PeerHeader: p, 322 Body: &BMPStatisticsReport{ 323 Count: uint32(len(stats)), 324 Stats: stats, 325 }, 326 } 327 } 328 329 func (body *BMPStatisticsReport) ParseBody(msg *BMPMessage, data []byte) error { 330 body.Count = binary.BigEndian.Uint32(data[0:4]) 331 data = data[4:] 332 for len(data) >= 4 { 333 tl := BMPStatsTLV{ 334 Type: binary.BigEndian.Uint16(data[0:2]), 335 Length: binary.BigEndian.Uint16(data[2:4]), 336 } 337 data = data[4:] 338 if len(data) < int(tl.Length) { 339 return fmt.Errorf("value length is not enough: %d bytes (%d bytes expected)", len(data), tl.Length) 340 } 341 var s BMPStatsTLVInterface 342 switch tl.Type { 343 case BMP_STAT_TYPE_ADJ_RIB_IN, BMP_STAT_TYPE_LOC_RIB: 344 s = &BMPStatsTLV64{BMPStatsTLV: tl} 345 case BMP_STAT_TYPE_PER_AFI_SAFI_ADJ_RIB_IN, BMP_STAT_TYPE_PER_AFI_SAFI_LOC_RIB: 346 s = &BMPStatsTLVPerAfiSafi64{BMPStatsTLV: tl} 347 default: 348 s = &BMPStatsTLV32{BMPStatsTLV: tl} 349 } 350 if err := s.ParseValue(data); err != nil { 351 return err 352 } 353 body.Stats = append(body.Stats, s) 354 data = data[tl.Length:] 355 } 356 return nil 357 } 358 359 func (body *BMPStatisticsReport) Serialize() ([]byte, error) { 360 buf := make([]byte, 4) 361 body.Count = uint32(len(body.Stats)) 362 binary.BigEndian.PutUint32(buf[0:4], body.Count) 363 for _, tlv := range body.Stats { 364 tlvBuf, err := tlv.Serialize() 365 if err != nil { 366 return nil, err 367 } 368 buf = append(buf, tlvBuf...) 369 } 370 return buf, nil 371 } 372 373 const ( 374 BMP_peerDownByUnknownReason = iota 375 BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION 376 BMP_PEER_DOWN_REASON_LOCAL_NO_NOTIFICATION 377 BMP_PEER_DOWN_REASON_REMOTE_BGP_NOTIFICATION 378 BMP_PEER_DOWN_REASON_REMOTE_NO_NOTIFICATION 379 BMP_PEER_DOWN_REASON_PEER_DE_CONFIGURED 380 ) 381 382 type BMPPeerDownNotification struct { 383 Reason uint8 384 BGPNotification *bgp.BGPMessage 385 Data []byte 386 } 387 388 func NewBMPPeerDownNotification(p BMPPeerHeader, reason uint8, notification *bgp.BGPMessage, data []byte) *BMPMessage { 389 b := &BMPPeerDownNotification{ 390 Reason: reason, 391 } 392 switch reason { 393 case BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION, BMP_PEER_DOWN_REASON_REMOTE_BGP_NOTIFICATION: 394 b.BGPNotification = notification 395 case BMP_PEER_DOWN_REASON_LOCAL_NO_NOTIFICATION: 396 b.Data = data 397 default: 398 } 399 return &BMPMessage{ 400 Header: BMPHeader{ 401 Version: BMP_VERSION, 402 Type: BMP_MSG_PEER_DOWN_NOTIFICATION, 403 }, 404 PeerHeader: p, 405 Body: b, 406 } 407 } 408 409 func (body *BMPPeerDownNotification) ParseBody(msg *BMPMessage, data []byte) error { 410 body.Reason = data[0] 411 data = data[1:] 412 if body.Reason == BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION || body.Reason == BMP_PEER_DOWN_REASON_REMOTE_BGP_NOTIFICATION { 413 notification, err := bgp.ParseBGPMessage(data) 414 if err != nil { 415 return err 416 } 417 body.BGPNotification = notification 418 } else { 419 body.Data = data 420 } 421 return nil 422 } 423 424 func (body *BMPPeerDownNotification) Serialize() ([]byte, error) { 425 buf := make([]byte, 1) 426 buf[0] = body.Reason 427 switch body.Reason { 428 case BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION, BMP_PEER_DOWN_REASON_REMOTE_BGP_NOTIFICATION: 429 if body.BGPNotification != nil { 430 b, err := body.BGPNotification.Serialize() 431 if err != nil { 432 return nil, err 433 } else { 434 buf = append(buf, b...) 435 } 436 } 437 default: 438 if body.Data != nil { 439 buf = append(buf, body.Data...) 440 } 441 } 442 return buf, nil 443 } 444 445 type BMPPeerUpNotification struct { 446 LocalAddress net.IP 447 LocalPort uint16 448 RemotePort uint16 449 SentOpenMsg *bgp.BGPMessage 450 ReceivedOpenMsg *bgp.BGPMessage 451 } 452 453 func NewBMPPeerUpNotification(p BMPPeerHeader, lAddr string, lPort, rPort uint16, sent, recv *bgp.BGPMessage) *BMPMessage { 454 b := &BMPPeerUpNotification{ 455 LocalPort: lPort, 456 RemotePort: rPort, 457 SentOpenMsg: sent, 458 ReceivedOpenMsg: recv, 459 } 460 addr := net.ParseIP(lAddr) 461 if addr.To4() != nil { 462 b.LocalAddress = addr.To4() 463 } else { 464 b.LocalAddress = addr.To16() 465 } 466 return &BMPMessage{ 467 Header: BMPHeader{ 468 Version: BMP_VERSION, 469 Type: BMP_MSG_PEER_UP_NOTIFICATION, 470 }, 471 PeerHeader: p, 472 Body: b, 473 } 474 } 475 476 func (body *BMPPeerUpNotification) ParseBody(msg *BMPMessage, data []byte) error { 477 if msg.PeerHeader.Flags&BMP_PEER_FLAG_IPV6 != 0 { 478 body.LocalAddress = net.IP(data[:16]).To16() 479 } else { 480 body.LocalAddress = net.IP(data[12:16]).To4() 481 } 482 483 body.LocalPort = binary.BigEndian.Uint16(data[16:18]) 484 body.RemotePort = binary.BigEndian.Uint16(data[18:20]) 485 486 data = data[20:] 487 sentopen, err := bgp.ParseBGPMessage(data) 488 if err != nil { 489 return err 490 } 491 body.SentOpenMsg = sentopen 492 data = data[body.SentOpenMsg.Header.Len:] 493 body.ReceivedOpenMsg, err = bgp.ParseBGPMessage(data) 494 if err != nil { 495 return err 496 } 497 return nil 498 } 499 500 func (body *BMPPeerUpNotification) Serialize() ([]byte, error) { 501 buf := make([]byte, 20) 502 if body.LocalAddress.To4() != nil { 503 copy(buf[12:16], body.LocalAddress.To4()) 504 } else { 505 copy(buf[:16], body.LocalAddress.To16()) 506 } 507 508 binary.BigEndian.PutUint16(buf[16:18], body.LocalPort) 509 binary.BigEndian.PutUint16(buf[18:20], body.RemotePort) 510 511 m, _ := body.SentOpenMsg.Serialize() 512 buf = append(buf, m...) 513 m, _ = body.ReceivedOpenMsg.Serialize() 514 buf = append(buf, m...) 515 return buf, nil 516 } 517 518 const ( 519 BMP_INIT_TLV_TYPE_STRING = iota 520 BMP_INIT_TLV_TYPE_SYS_DESCR 521 BMP_INIT_TLV_TYPE_SYS_NAME 522 ) 523 524 type BMPInfoTLVInterface interface { 525 ParseValue([]byte) error 526 Serialize() ([]byte, error) 527 } 528 529 type BMPInfoTLV struct { 530 Type uint16 531 Length uint16 532 } 533 534 type BMPInfoTLVString struct { 535 BMPInfoTLV 536 Value string 537 } 538 539 func NewBMPInfoTLVString(t uint16, v string) *BMPInfoTLVString { 540 return &BMPInfoTLVString{ 541 BMPInfoTLV: BMPInfoTLV{Type: t}, 542 Value: v, 543 } 544 } 545 546 func (s *BMPInfoTLVString) ParseValue(data []byte) error { 547 s.Value = string(data[:s.Length]) 548 return nil 549 } 550 551 func (s *BMPInfoTLVString) Serialize() ([]byte, error) { 552 s.Length = uint16(len([]byte(s.Value))) 553 buf := make([]byte, 4) 554 binary.BigEndian.PutUint16(buf[0:2], s.Type) 555 binary.BigEndian.PutUint16(buf[2:4], s.Length) 556 buf = append(buf, []byte(s.Value)...) 557 return buf, nil 558 } 559 560 type BMPInfoTLVUnknown struct { 561 BMPInfoTLV 562 Value []byte 563 } 564 565 func NewBMPInfoTLVUnknown(t uint16, v []byte) *BMPInfoTLVUnknown { 566 return &BMPInfoTLVUnknown{ 567 BMPInfoTLV: BMPInfoTLV{Type: t}, 568 Value: v, 569 } 570 } 571 572 func (s *BMPInfoTLVUnknown) ParseValue(data []byte) error { 573 s.Value = data[:s.Length] 574 return nil 575 } 576 577 func (s *BMPInfoTLVUnknown) Serialize() ([]byte, error) { 578 s.Length = uint16(len([]byte(s.Value))) 579 buf := make([]byte, 4) 580 binary.BigEndian.PutUint16(buf[0:2], s.Type) 581 binary.BigEndian.PutUint16(buf[2:4], s.Length) 582 buf = append(buf, s.Value...) 583 return buf, nil 584 } 585 586 type BMPInitiation struct { 587 Info []BMPInfoTLVInterface 588 } 589 590 func NewBMPInitiation(info []BMPInfoTLVInterface) *BMPMessage { 591 return &BMPMessage{ 592 Header: BMPHeader{ 593 Version: BMP_VERSION, 594 Type: BMP_MSG_INITIATION, 595 }, 596 Body: &BMPInitiation{ 597 Info: info, 598 }, 599 } 600 } 601 602 func (body *BMPInitiation) ParseBody(msg *BMPMessage, data []byte) error { 603 for len(data) >= 4 { 604 tl := BMPInfoTLV{ 605 Type: binary.BigEndian.Uint16(data[0:2]), 606 Length: binary.BigEndian.Uint16(data[2:4]), 607 } 608 data = data[4:] 609 if len(data) < int(tl.Length) { 610 return fmt.Errorf("value length is not enough: %d bytes (%d bytes expected)", len(data), tl.Length) 611 } 612 var tlv BMPInfoTLVInterface 613 switch tl.Type { 614 case BMP_INIT_TLV_TYPE_STRING, BMP_INIT_TLV_TYPE_SYS_DESCR, BMP_INIT_TLV_TYPE_SYS_NAME: 615 tlv = &BMPInfoTLVString{BMPInfoTLV: tl} 616 default: 617 tlv = &BMPInfoTLVUnknown{BMPInfoTLV: tl} 618 } 619 if err := tlv.ParseValue(data); err != nil { 620 return err 621 } 622 body.Info = append(body.Info, tlv) 623 data = data[tl.Length:] 624 } 625 return nil 626 } 627 628 func (body *BMPInitiation) Serialize() ([]byte, error) { 629 buf := make([]byte, 0) 630 for _, tlv := range body.Info { 631 b, err := tlv.Serialize() 632 if err != nil { 633 return buf, err 634 } 635 buf = append(buf, b...) 636 } 637 return buf, nil 638 } 639 640 const ( 641 BMP_TERM_TLV_TYPE_STRING = iota 642 BMP_TERM_TLV_TYPE_REASON 643 ) 644 645 const ( 646 BMP_TERM_REASON_ADMIN = iota 647 BMP_TERM_REASON_UNSPEC 648 BMP_TERM_REASON_OUT_OF_RESOURCES 649 BMP_TERM_REASON_REDUNDANT_CONNECTION 650 BMP_TERM_REASON_PERMANENTLY_ADMIN 651 ) 652 653 type BMPTermTLVInterface interface { 654 ParseValue([]byte) error 655 Serialize() ([]byte, error) 656 } 657 658 type BMPTermTLV struct { 659 Type uint16 660 Length uint16 661 } 662 663 type BMPTermTLVString struct { 664 BMPTermTLV 665 Value string 666 } 667 668 func NewBMPTermTLVString(t uint16, v string) *BMPTermTLVString { 669 return &BMPTermTLVString{ 670 BMPTermTLV: BMPTermTLV{Type: t}, 671 Value: v, 672 } 673 } 674 675 func (s *BMPTermTLVString) ParseValue(data []byte) error { 676 s.Value = string(data[:s.Length]) 677 return nil 678 } 679 680 func (s *BMPTermTLVString) Serialize() ([]byte, error) { 681 s.Length = uint16(len([]byte(s.Value))) 682 buf := make([]byte, 4) 683 binary.BigEndian.PutUint16(buf[0:2], s.Type) 684 binary.BigEndian.PutUint16(buf[2:4], s.Length) 685 buf = append(buf, []byte(s.Value)...) 686 return buf, nil 687 } 688 689 type BMPTermTLV16 struct { 690 BMPTermTLV 691 Value uint16 692 } 693 694 func NewBMPTermTLV16(t uint16, v uint16) *BMPTermTLV16 { 695 return &BMPTermTLV16{ 696 BMPTermTLV: BMPTermTLV{Type: t}, 697 Value: v, 698 } 699 } 700 701 func (s *BMPTermTLV16) ParseValue(data []byte) error { 702 s.Value = binary.BigEndian.Uint16(data[:2]) 703 return nil 704 } 705 706 func (s *BMPTermTLV16) Serialize() ([]byte, error) { 707 s.Length = 2 708 buf := make([]byte, 6) 709 binary.BigEndian.PutUint16(buf[0:2], s.Type) 710 binary.BigEndian.PutUint16(buf[2:4], s.Length) 711 binary.BigEndian.PutUint16(buf[4:6], s.Value) 712 return buf, nil 713 } 714 715 type BMPTermTLVUnknown struct { 716 BMPTermTLV 717 Value []byte 718 } 719 720 func NewBMPTermTLVUnknown(t uint16, v []byte) *BMPTermTLVUnknown { 721 return &BMPTermTLVUnknown{ 722 BMPTermTLV: BMPTermTLV{Type: t}, 723 Value: v, 724 } 725 } 726 727 func (s *BMPTermTLVUnknown) ParseValue(data []byte) error { 728 s.Value = data[:s.Length] 729 return nil 730 } 731 732 func (s *BMPTermTLVUnknown) Serialize() ([]byte, error) { 733 s.Length = uint16(len([]byte(s.Value))) 734 buf := make([]byte, 4) 735 binary.BigEndian.PutUint16(buf[0:2], s.Type) 736 binary.BigEndian.PutUint16(buf[2:4], s.Length) 737 buf = append(buf, s.Value...) 738 return buf, nil 739 } 740 741 type BMPTermination struct { 742 Info []BMPTermTLVInterface 743 } 744 745 func NewBMPTermination(info []BMPTermTLVInterface) *BMPMessage { 746 return &BMPMessage{ 747 Header: BMPHeader{ 748 Version: BMP_VERSION, 749 Type: BMP_MSG_TERMINATION, 750 }, 751 Body: &BMPTermination{ 752 Info: info, 753 }, 754 } 755 } 756 757 func (body *BMPTermination) ParseBody(msg *BMPMessage, data []byte) error { 758 for len(data) >= 4 { 759 tl := BMPTermTLV{ 760 Type: binary.BigEndian.Uint16(data[0:2]), 761 Length: binary.BigEndian.Uint16(data[2:4]), 762 } 763 data = data[4:] 764 if len(data) < int(tl.Length) { 765 return fmt.Errorf("value length is not enough: %d bytes (%d bytes expected)", len(data), tl.Length) 766 } 767 var tlv BMPTermTLVInterface 768 switch tl.Type { 769 case BMP_TERM_TLV_TYPE_STRING: 770 tlv = &BMPTermTLVString{BMPTermTLV: tl} 771 case BMP_TERM_TLV_TYPE_REASON: 772 tlv = &BMPTermTLV16{BMPTermTLV: tl} 773 default: 774 tlv = &BMPTermTLVUnknown{BMPTermTLV: tl} 775 } 776 if err := tlv.ParseValue(data); err != nil { 777 return err 778 } 779 body.Info = append(body.Info, tlv) 780 data = data[tl.Length:] 781 } 782 return nil 783 } 784 785 func (body *BMPTermination) Serialize() ([]byte, error) { 786 buf := make([]byte, 0) 787 for _, tlv := range body.Info { 788 b, err := tlv.Serialize() 789 if err != nil { 790 return buf, err 791 } 792 buf = append(buf, b...) 793 } 794 return buf, nil 795 } 796 797 const ( 798 BMP_ROUTE_MIRRORING_TLV_TYPE_BGP_MSG = iota 799 BMP_ROUTE_MIRRORING_TLV_TYPE_INFO 800 ) 801 802 const ( 803 BMP_ROUTE_MIRRORING_INFO_ERR_PDU = iota 804 BMP_ROUTE_MIRRORING_INFO_MSG_LOST 805 ) 806 807 type BMPRouteMirrTLVInterface interface { 808 ParseValue([]byte) error 809 Serialize() ([]byte, error) 810 } 811 812 type BMPRouteMirrTLV struct { 813 Type uint16 814 Length uint16 815 } 816 817 type BMPRouteMirrTLVBGPMsg struct { 818 BMPRouteMirrTLV 819 Value *bgp.BGPMessage 820 } 821 822 func NewBMPRouteMirrTLVBGPMsg(t uint16, v *bgp.BGPMessage) *BMPRouteMirrTLVBGPMsg { 823 return &BMPRouteMirrTLVBGPMsg{ 824 BMPRouteMirrTLV: BMPRouteMirrTLV{Type: t}, 825 Value: v, 826 } 827 } 828 829 func (s *BMPRouteMirrTLVBGPMsg) ParseValue(data []byte) error { 830 v, err := bgp.ParseBGPMessage(data) 831 if err != nil { 832 return err 833 } 834 s.Value = v 835 return nil 836 } 837 838 func (s *BMPRouteMirrTLVBGPMsg) Serialize() ([]byte, error) { 839 m, err := s.Value.Serialize() 840 if err != nil { 841 return nil, err 842 } 843 s.Length = uint16(len(m)) 844 buf := make([]byte, 4) 845 binary.BigEndian.PutUint16(buf[0:2], s.Type) 846 binary.BigEndian.PutUint16(buf[2:4], s.Length) 847 buf = append(buf, m...) 848 return buf, nil 849 } 850 851 type BMPRouteMirrTLV16 struct { 852 BMPRouteMirrTLV 853 Value uint16 854 } 855 856 func NewBMPRouteMirrTLV16(t uint16, v uint16) *BMPRouteMirrTLV16 { 857 return &BMPRouteMirrTLV16{ 858 BMPRouteMirrTLV: BMPRouteMirrTLV{Type: t}, 859 Value: v, 860 } 861 } 862 863 func (s *BMPRouteMirrTLV16) ParseValue(data []byte) error { 864 s.Value = binary.BigEndian.Uint16(data[:2]) 865 return nil 866 } 867 868 func (s *BMPRouteMirrTLV16) Serialize() ([]byte, error) { 869 s.Length = 2 870 buf := make([]byte, 6) 871 binary.BigEndian.PutUint16(buf[0:2], s.Type) 872 binary.BigEndian.PutUint16(buf[2:4], s.Length) 873 binary.BigEndian.PutUint16(buf[4:6], s.Value) 874 return buf, nil 875 } 876 877 type BMPRouteMirrTLVUnknown struct { 878 BMPRouteMirrTLV 879 Value []byte 880 } 881 882 func NewBMPRouteMirrTLVUnknown(t uint16, v []byte) *BMPRouteMirrTLVUnknown { 883 return &BMPRouteMirrTLVUnknown{ 884 BMPRouteMirrTLV: BMPRouteMirrTLV{Type: t}, 885 Value: v, 886 } 887 } 888 889 func (s *BMPRouteMirrTLVUnknown) ParseValue(data []byte) error { 890 s.Value = data[:s.Length] 891 return nil 892 } 893 894 func (s *BMPRouteMirrTLVUnknown) Serialize() ([]byte, error) { 895 s.Length = uint16(len([]byte(s.Value))) 896 buf := make([]byte, 4) 897 binary.BigEndian.PutUint16(buf[0:2], s.Type) 898 binary.BigEndian.PutUint16(buf[2:4], s.Length) 899 buf = append(buf, s.Value...) 900 return buf, nil 901 } 902 903 type BMPRouteMirroring struct { 904 Info []BMPRouteMirrTLVInterface 905 } 906 907 func NewBMPRouteMirroring(p BMPPeerHeader, info []BMPRouteMirrTLVInterface) *BMPMessage { 908 return &BMPMessage{ 909 Header: BMPHeader{ 910 Version: BMP_VERSION, 911 Type: BMP_MSG_ROUTE_MIRRORING, 912 }, 913 PeerHeader: p, 914 Body: &BMPRouteMirroring{ 915 Info: info, 916 }, 917 } 918 } 919 920 func (body *BMPRouteMirroring) ParseBody(msg *BMPMessage, data []byte) error { 921 for len(data) >= 4 { 922 tl := BMPRouteMirrTLV{ 923 Type: binary.BigEndian.Uint16(data[0:2]), 924 Length: binary.BigEndian.Uint16(data[2:4]), 925 } 926 data = data[4:] 927 if len(data) < int(tl.Length) { 928 return fmt.Errorf("value length is not enough: %d bytes (%d bytes expected)", len(data), tl.Length) 929 } 930 var tlv BMPRouteMirrTLVInterface 931 switch tl.Type { 932 case BMP_ROUTE_MIRRORING_TLV_TYPE_BGP_MSG: 933 tlv = &BMPRouteMirrTLVBGPMsg{BMPRouteMirrTLV: tl} 934 case BMP_ROUTE_MIRRORING_TLV_TYPE_INFO: 935 tlv = &BMPRouteMirrTLV16{BMPRouteMirrTLV: tl} 936 default: 937 tlv = &BMPRouteMirrTLVUnknown{BMPRouteMirrTLV: tl} 938 } 939 if err := tlv.ParseValue(data); err != nil { 940 return err 941 } 942 body.Info = append(body.Info, tlv) 943 data = data[tl.Length:] 944 } 945 return nil 946 } 947 948 func (body *BMPRouteMirroring) Serialize() ([]byte, error) { 949 buf := make([]byte, 0) 950 for _, tlv := range body.Info { 951 b, err := tlv.Serialize() 952 if err != nil { 953 return buf, err 954 } 955 buf = append(buf, b...) 956 } 957 return buf, nil 958 } 959 960 type BMPBody interface { 961 // Sigh, some body messages need a BMPHeader to parse the body 962 // data so we need to pass BMPHeader (avoid DecodeFromBytes 963 // function name). 964 ParseBody(*BMPMessage, []byte) error 965 Serialize() ([]byte, error) 966 } 967 968 type BMPMessage struct { 969 Header BMPHeader 970 PeerHeader BMPPeerHeader 971 Body BMPBody 972 } 973 974 func (msg *BMPMessage) Serialize() ([]byte, error) { 975 buf := make([]byte, 0) 976 if msg.Header.Type != BMP_MSG_INITIATION && msg.Header.Type != BMP_MSG_TERMINATION { 977 p, err := msg.PeerHeader.Serialize() 978 if err != nil { 979 return nil, err 980 } 981 buf = append(buf, p...) 982 } 983 984 b, err := msg.Body.Serialize() 985 if err != nil { 986 return nil, err 987 } 988 buf = append(buf, b...) 989 990 if msg.Header.Length == 0 { 991 msg.Header.Length = uint32(BMP_HEADER_SIZE + len(buf)) 992 } 993 994 h, err := msg.Header.Serialize() 995 if err != nil { 996 return nil, err 997 } 998 return append(h, buf...), nil 999 } 1000 1001 func (msg *BMPMessage) Len() int { 1002 return int(msg.Header.Length) 1003 } 1004 1005 const ( 1006 BMP_MSG_ROUTE_MONITORING = iota 1007 BMP_MSG_STATISTICS_REPORT 1008 BMP_MSG_PEER_DOWN_NOTIFICATION 1009 BMP_MSG_PEER_UP_NOTIFICATION 1010 BMP_MSG_INITIATION 1011 BMP_MSG_TERMINATION 1012 BMP_MSG_ROUTE_MIRRORING 1013 ) 1014 1015 func ParseBMPMessage(data []byte) (msg *BMPMessage, err error) { 1016 defer func() { 1017 if r := recover(); r != nil { 1018 err = fmt.Errorf("not all data bytes are available") 1019 } 1020 }() 1021 1022 msg = &BMPMessage{} 1023 err = msg.Header.DecodeFromBytes(data) 1024 if err != nil { 1025 return nil, err 1026 } 1027 data = data[BMP_HEADER_SIZE:msg.Header.Length] 1028 1029 switch msg.Header.Type { 1030 case BMP_MSG_ROUTE_MONITORING: 1031 msg.Body = &BMPRouteMonitoring{} 1032 case BMP_MSG_STATISTICS_REPORT: 1033 msg.Body = &BMPStatisticsReport{} 1034 case BMP_MSG_PEER_DOWN_NOTIFICATION: 1035 msg.Body = &BMPPeerDownNotification{} 1036 case BMP_MSG_PEER_UP_NOTIFICATION: 1037 msg.Body = &BMPPeerUpNotification{} 1038 case BMP_MSG_INITIATION: 1039 msg.Body = &BMPInitiation{} 1040 case BMP_MSG_TERMINATION: 1041 msg.Body = &BMPTermination{} 1042 case BMP_MSG_ROUTE_MIRRORING: 1043 msg.Body = &BMPRouteMirroring{} 1044 default: 1045 return nil, fmt.Errorf("unsupported BMP message type: %d", msg.Header.Type) 1046 } 1047 1048 if msg.Header.Type != BMP_MSG_INITIATION && msg.Header.Type != BMP_MSG_TERMINATION { 1049 msg.PeerHeader.DecodeFromBytes(data) 1050 data = data[BMP_PEER_HEADER_SIZE:] 1051 } 1052 1053 err = msg.Body.ParseBody(msg, data) 1054 if err != nil { 1055 return nil, err 1056 } 1057 return msg, nil 1058 } 1059 1060 func SplitBMP(data []byte, atEOF bool) (advance int, token []byte, err error) { 1061 if atEOF && len(data) == 0 || len(data) < BMP_HEADER_SIZE { 1062 return 0, nil, nil 1063 } 1064 1065 msg := &BMPMessage{} 1066 msg.Header.DecodeFromBytes(data) 1067 if uint32(len(data)) < msg.Header.Length { 1068 return 0, nil, nil 1069 } 1070 1071 return int(msg.Header.Length), data[0:msg.Header.Length], nil 1072 }