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