github.com/osrg/gobgp@v2.0.0+incompatible/pkg/packet/mrt/mrt.go (about) 1 // Copyright (C) 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 mrt 17 18 import ( 19 "bytes" 20 "encoding/binary" 21 "fmt" 22 "math" 23 "net" 24 "time" 25 26 "github.com/osrg/gobgp/pkg/packet/bgp" 27 ) 28 29 const ( 30 MRT_COMMON_HEADER_LEN = 12 31 ) 32 33 type MRTType uint16 34 35 const ( 36 NULL MRTType = 0 // deprecated 37 START MRTType = 1 // deprecated 38 DIE MRTType = 2 // deprecated 39 I_AM_DEAD MRTType = 3 // deprecated 40 PEER_DOWN MRTType = 4 // deprecated 41 BGP MRTType = 5 // deprecated 42 RIP MRTType = 6 // deprecated 43 IDRP MRTType = 7 // deprecated 44 RIPNG MRTType = 8 // deprecated 45 BGP4PLUS MRTType = 9 // deprecated 46 BGP4PLUS01 MRTType = 10 // deprecated 47 OSPFv2 MRTType = 11 48 TABLE_DUMP MRTType = 12 49 TABLE_DUMPv2 MRTType = 13 50 BGP4MP MRTType = 16 51 BGP4MP_ET MRTType = 17 52 ISIS MRTType = 32 53 ISIS_ET MRTType = 33 54 OSPFv3 MRTType = 48 55 OSPFv3_ET MRTType = 49 56 ) 57 58 type MRTSubTyper interface { 59 ToUint16() uint16 60 } 61 62 type MRTSubTypeTableDumpv2 uint16 63 64 const ( 65 PEER_INDEX_TABLE MRTSubTypeTableDumpv2 = 1 66 RIB_IPV4_UNICAST MRTSubTypeTableDumpv2 = 2 67 RIB_IPV4_MULTICAST MRTSubTypeTableDumpv2 = 3 68 RIB_IPV6_UNICAST MRTSubTypeTableDumpv2 = 4 69 RIB_IPV6_MULTICAST MRTSubTypeTableDumpv2 = 5 70 RIB_GENERIC MRTSubTypeTableDumpv2 = 6 71 GEO_PEER_TABLE MRTSubTypeTableDumpv2 = 7 // RFC6397 72 RIB_IPV4_UNICAST_ADDPATH MRTSubTypeTableDumpv2 = 8 // RFC8050 73 RIB_IPV4_MULTICAST_ADDPATH MRTSubTypeTableDumpv2 = 9 // RFC8050 74 RIB_IPV6_UNICAST_ADDPATH MRTSubTypeTableDumpv2 = 10 // RFC8050 75 RIB_IPV6_MULTICAST_ADDPATH MRTSubTypeTableDumpv2 = 11 // RFC8050 76 RIB_GENERIC_ADDPATH MRTSubTypeTableDumpv2 = 12 // RFC8050 77 ) 78 79 func (t MRTSubTypeTableDumpv2) ToUint16() uint16 { 80 return uint16(t) 81 } 82 83 type MRTSubTypeBGP4MP uint16 84 85 const ( 86 STATE_CHANGE MRTSubTypeBGP4MP = 0 87 MESSAGE MRTSubTypeBGP4MP = 1 88 MESSAGE_AS4 MRTSubTypeBGP4MP = 4 89 STATE_CHANGE_AS4 MRTSubTypeBGP4MP = 5 90 MESSAGE_LOCAL MRTSubTypeBGP4MP = 6 91 MESSAGE_AS4_LOCAL MRTSubTypeBGP4MP = 7 92 MESSAGE_ADDPATH MRTSubTypeBGP4MP = 8 // RFC8050 93 MESSAGE_AS4_ADDPATH MRTSubTypeBGP4MP = 9 // RFC8050 94 MESSAGE_LOCAL_ADDPATH MRTSubTypeBGP4MP = 10 // RFC8050 95 MESSAGE_AS4_LOCAL_ADDPATH MRTSubTypeBGP4MP = 11 // RFC8050 96 ) 97 98 func (t MRTSubTypeBGP4MP) ToUint16() uint16 { 99 return uint16(t) 100 } 101 102 type BGPState uint16 103 104 const ( 105 IDLE BGPState = 1 106 CONNECT BGPState = 2 107 ACTIVE BGPState = 3 108 OPENSENT BGPState = 4 109 OPENCONFIRM BGPState = 5 110 ESTABLISHED BGPState = 6 111 ) 112 113 func packValues(values []interface{}) ([]byte, error) { 114 b := new(bytes.Buffer) 115 for _, v := range values { 116 err := binary.Write(b, binary.BigEndian, v) 117 if err != nil { 118 return nil, err 119 } 120 } 121 return b.Bytes(), nil 122 } 123 124 type MRTHeader struct { 125 Timestamp uint32 126 Type MRTType 127 SubType uint16 128 Len uint32 129 } 130 131 func (h *MRTHeader) DecodeFromBytes(data []byte) error { 132 if len(data) < MRT_COMMON_HEADER_LEN { 133 return fmt.Errorf("not all MRTHeader bytes are available. expected: %d, actual: %d", MRT_COMMON_HEADER_LEN, len(data)) 134 } 135 h.Timestamp = binary.BigEndian.Uint32(data[:4]) 136 h.Type = MRTType(binary.BigEndian.Uint16(data[4:6])) 137 h.SubType = binary.BigEndian.Uint16(data[6:8]) 138 h.Len = binary.BigEndian.Uint32(data[8:12]) 139 return nil 140 } 141 142 func (h *MRTHeader) Serialize() ([]byte, error) { 143 return packValues([]interface{}{h.Timestamp, h.Type, h.SubType, h.Len}) 144 } 145 146 func NewMRTHeader(timestamp uint32, t MRTType, subtype MRTSubTyper, l uint32) (*MRTHeader, error) { 147 return &MRTHeader{ 148 Timestamp: timestamp, 149 Type: t, 150 SubType: subtype.ToUint16(), 151 Len: l, 152 }, nil 153 } 154 155 func (h *MRTHeader) GetTime() time.Time { 156 t := int64(h.Timestamp) 157 return time.Unix(t, 0) 158 } 159 160 type MRTMessage struct { 161 Header MRTHeader 162 Body Body 163 } 164 165 func (m *MRTMessage) Serialize() ([]byte, error) { 166 buf, err := m.Body.Serialize() 167 if err != nil { 168 return nil, err 169 } 170 m.Header.Len = uint32(len(buf)) 171 bbuf, err := m.Header.Serialize() 172 if err != nil { 173 return nil, err 174 } 175 return append(bbuf, buf...), nil 176 } 177 178 func NewMRTMessage(timestamp uint32, t MRTType, subtype MRTSubTyper, body Body) (*MRTMessage, error) { 179 header, err := NewMRTHeader(timestamp, t, subtype, 0) 180 if err != nil { 181 return nil, err 182 } 183 return &MRTMessage{ 184 Header: *header, 185 Body: body, 186 }, nil 187 } 188 189 type Body interface { 190 DecodeFromBytes([]byte) error 191 Serialize() ([]byte, error) 192 } 193 194 type Peer struct { 195 Type uint8 196 BgpId net.IP 197 IpAddress net.IP 198 AS uint32 199 } 200 201 func (p *Peer) DecodeFromBytes(data []byte) ([]byte, error) { 202 notAllBytesAvail := fmt.Errorf("not all Peer bytes are available") 203 if len(data) < 5 { 204 return nil, notAllBytesAvail 205 } 206 p.Type = uint8(data[0]) 207 p.BgpId = net.IP(data[1:5]) 208 data = data[5:] 209 210 if p.Type&1 > 0 { 211 if len(data) < 16 { 212 return nil, notAllBytesAvail 213 } 214 p.IpAddress = net.IP(data[:16]) 215 data = data[16:] 216 } else { 217 if len(data) < 4 { 218 return nil, notAllBytesAvail 219 } 220 p.IpAddress = net.IP(data[:4]) 221 data = data[4:] 222 } 223 224 if p.Type&(1<<1) > 0 { 225 if len(data) < 4 { 226 return nil, notAllBytesAvail 227 } 228 p.AS = binary.BigEndian.Uint32(data[:4]) 229 data = data[4:] 230 } else { 231 if len(data) < 2 { 232 return nil, notAllBytesAvail 233 } 234 p.AS = uint32(binary.BigEndian.Uint16(data[:2])) 235 data = data[2:] 236 } 237 238 return data, nil 239 } 240 241 func (p *Peer) Serialize() ([]byte, error) { 242 var err error 243 var bbuf []byte 244 buf := make([]byte, 5) 245 buf[0] = uint8(p.Type) 246 copy(buf[1:], p.BgpId.To4()) 247 if p.Type&1 > 0 { 248 buf = append(buf, p.IpAddress.To16()...) 249 } else { 250 buf = append(buf, p.IpAddress.To4()...) 251 } 252 if p.Type&(1<<1) > 0 { 253 bbuf, err = packValues([]interface{}{p.AS}) 254 } else { 255 if p.AS > uint32(math.MaxUint16) { 256 return nil, fmt.Errorf("AS number is beyond 2 octet. %d > %d", p.AS, math.MaxUint16) 257 } 258 bbuf, err = packValues([]interface{}{uint16(p.AS)}) 259 } 260 if err != nil { 261 return nil, err 262 } 263 return append(buf, bbuf...), nil 264 } 265 266 func NewPeer(bgpid string, ipaddr string, asn uint32, isAS4 bool) *Peer { 267 t := 0 268 addr := net.ParseIP(ipaddr).To4() 269 if addr == nil { 270 t |= 1 271 addr = net.ParseIP(ipaddr).To16() 272 } 273 if isAS4 { 274 t |= (1 << 1) 275 } 276 return &Peer{ 277 Type: uint8(t), 278 BgpId: net.ParseIP(bgpid).To4(), 279 IpAddress: addr, 280 AS: asn, 281 } 282 } 283 284 func (p *Peer) String() string { 285 return fmt.Sprintf("PEER ENTRY: ID [%s] Addr [%s] AS [%d]", p.BgpId, p.IpAddress, p.AS) 286 } 287 288 type PeerIndexTable struct { 289 CollectorBgpId net.IP 290 ViewName string 291 Peers []*Peer 292 } 293 294 func (t *PeerIndexTable) DecodeFromBytes(data []byte) error { 295 notAllBytesAvail := fmt.Errorf("not all PeerIndexTable bytes are available") 296 if len(data) < 6 { 297 return notAllBytesAvail 298 } 299 t.CollectorBgpId = net.IP(data[:4]) 300 viewLen := binary.BigEndian.Uint16(data[4:6]) 301 if len(data) < 6+int(viewLen) { 302 return notAllBytesAvail 303 } 304 t.ViewName = string(data[6 : 6+viewLen]) 305 306 data = data[6+viewLen:] 307 308 if len(data) < 2 { 309 return notAllBytesAvail 310 } 311 peerNum := binary.BigEndian.Uint16(data[:2]) 312 data = data[2:] 313 t.Peers = make([]*Peer, 0, peerNum) 314 var err error 315 for i := 0; i < int(peerNum); i++ { 316 p := &Peer{} 317 data, err = p.DecodeFromBytes(data) 318 if err != nil { 319 return err 320 } 321 t.Peers = append(t.Peers, p) 322 } 323 324 return nil 325 } 326 327 func (t *PeerIndexTable) Serialize() ([]byte, error) { 328 buf := make([]byte, 8+len(t.ViewName)) 329 copy(buf, t.CollectorBgpId.To4()) 330 binary.BigEndian.PutUint16(buf[4:], uint16(len(t.ViewName))) 331 copy(buf[6:], t.ViewName) 332 binary.BigEndian.PutUint16(buf[6+len(t.ViewName):], uint16(len(t.Peers))) 333 for _, peer := range t.Peers { 334 bbuf, err := peer.Serialize() 335 if err != nil { 336 return nil, err 337 } 338 buf = append(buf, bbuf...) 339 } 340 return buf, nil 341 } 342 343 func NewPeerIndexTable(bgpid string, viewname string, peers []*Peer) *PeerIndexTable { 344 return &PeerIndexTable{ 345 CollectorBgpId: net.ParseIP(bgpid).To4(), 346 ViewName: viewname, 347 Peers: peers, 348 } 349 } 350 351 func (t *PeerIndexTable) String() string { 352 return fmt.Sprintf("PEER_INDEX_TABLE: CollectorBgpId [%s] ViewName [%s] Peers [%s]", t.CollectorBgpId, t.ViewName, t.Peers) 353 } 354 355 type RibEntry struct { 356 PeerIndex uint16 357 OriginatedTime uint32 358 PathIdentifier uint32 359 PathAttributes []bgp.PathAttributeInterface 360 isAddPath bool 361 } 362 363 func (e *RibEntry) DecodeFromBytes(data []byte) ([]byte, error) { 364 notAllBytesAvail := fmt.Errorf("not all RibEntry bytes are available") 365 if len(data) < 8 { 366 return nil, notAllBytesAvail 367 } 368 e.PeerIndex = binary.BigEndian.Uint16(data[:2]) 369 e.OriginatedTime = binary.BigEndian.Uint32(data[2:6]) 370 if e.isAddPath { 371 e.PathIdentifier = binary.BigEndian.Uint32(data[6:10]) 372 data = data[10:] 373 } else { 374 data = data[6:] 375 } 376 totalLen := binary.BigEndian.Uint16(data[:2]) 377 data = data[2:] 378 for attrLen := totalLen; attrLen > 0; { 379 p, err := bgp.GetPathAttribute(data) 380 if err != nil { 381 return nil, err 382 } 383 err = p.DecodeFromBytes(data) 384 if err != nil { 385 return nil, err 386 } 387 attrLen -= uint16(p.Len()) 388 if len(data) < p.Len() { 389 return nil, notAllBytesAvail 390 } 391 data = data[p.Len():] 392 e.PathAttributes = append(e.PathAttributes, p) 393 } 394 return data, nil 395 } 396 397 func (e *RibEntry) Serialize() ([]byte, error) { 398 pbuf := make([]byte, 0) 399 totalLen := 0 400 for _, pattr := range e.PathAttributes { 401 // TODO special modification is needed for MP_REACH_NLRI 402 // but also Quagga doesn't implement this. 403 // 404 // RFC 6396 4.3.4 405 // There is one exception to the encoding of BGP attributes for the BGP 406 // MP_REACH_NLRI attribute (BGP Type Code 14). 407 // Since the AFI, SAFI, and NLRI information is already encoded 408 // in the RIB Entry Header or RIB_GENERIC Entry Header, 409 // only the Next Hop Address Length and Next Hop Address fields are included. 410 411 pb, err := pattr.Serialize() 412 if err != nil { 413 return nil, err 414 } 415 pbuf = append(pbuf, pb...) 416 totalLen += len(pb) 417 } 418 var buf []byte 419 if e.isAddPath { 420 buf = make([]byte, 12) 421 binary.BigEndian.PutUint16(buf, e.PeerIndex) 422 binary.BigEndian.PutUint32(buf[2:], e.OriginatedTime) 423 binary.BigEndian.PutUint32(buf[6:], e.PathIdentifier) 424 binary.BigEndian.PutUint16(buf[10:], uint16(totalLen)) 425 } else { 426 buf = make([]byte, 8) 427 binary.BigEndian.PutUint16(buf, e.PeerIndex) 428 binary.BigEndian.PutUint32(buf[2:], e.OriginatedTime) 429 binary.BigEndian.PutUint16(buf[6:], uint16(totalLen)) 430 } 431 buf = append(buf, pbuf...) 432 return buf, nil 433 } 434 435 func NewRibEntry(index uint16, time uint32, pathId uint32, pathAttrs []bgp.PathAttributeInterface, isAddPath bool) *RibEntry { 436 return &RibEntry{ 437 PeerIndex: index, 438 OriginatedTime: time, 439 PathIdentifier: pathId, 440 PathAttributes: pathAttrs, 441 isAddPath: isAddPath, 442 } 443 } 444 445 func (e *RibEntry) String() string { 446 if e.isAddPath { 447 return fmt.Sprintf("RIB_ENTRY: PeerIndex [%d] OriginatedTime [%d] PathIdentifier[%d] PathAttributes [%v]", e.PeerIndex, e.OriginatedTime, e.PathIdentifier, e.PathAttributes) 448 } else { 449 return fmt.Sprintf("RIB_ENTRY: PeerIndex [%d] OriginatedTime [%d] PathAttributes [%v]", e.PeerIndex, e.OriginatedTime, e.PathAttributes) 450 } 451 452 } 453 454 type Rib struct { 455 SequenceNumber uint32 456 Prefix bgp.AddrPrefixInterface 457 Entries []*RibEntry 458 RouteFamily bgp.RouteFamily 459 isAddPath bool 460 } 461 462 func (u *Rib) DecodeFromBytes(data []byte) error { 463 if len(data) < 4 { 464 return fmt.Errorf("Not all RibIpv4Unicast message bytes available") 465 } 466 u.SequenceNumber = binary.BigEndian.Uint32(data[:4]) 467 data = data[4:] 468 afi, safi := bgp.RouteFamilyToAfiSafi(u.RouteFamily) 469 if afi == 0 && safi == 0 { 470 afi = binary.BigEndian.Uint16(data[:2]) 471 safi = data[2] 472 data = data[3:] 473 } 474 prefix, err := bgp.NewPrefixFromRouteFamily(afi, safi) 475 if err != nil { 476 return err 477 } 478 err = prefix.DecodeFromBytes(data) 479 if err != nil { 480 return err 481 } 482 u.Prefix = prefix 483 data = data[prefix.Len():] 484 entryNum := binary.BigEndian.Uint16(data[:2]) 485 data = data[2:] 486 u.Entries = make([]*RibEntry, 0, entryNum) 487 for i := 0; i < int(entryNum); i++ { 488 e := &RibEntry{ 489 isAddPath: u.isAddPath, 490 } 491 data, err = e.DecodeFromBytes(data) 492 if err != nil { 493 return err 494 } 495 u.Entries = append(u.Entries, e) 496 } 497 return nil 498 } 499 500 func (u *Rib) Serialize() ([]byte, error) { 501 buf := make([]byte, 4) 502 binary.BigEndian.PutUint32(buf, u.SequenceNumber) 503 rf := bgp.AfiSafiToRouteFamily(u.Prefix.AFI(), u.Prefix.SAFI()) 504 switch rf { 505 case bgp.RF_IPv4_UC, bgp.RF_IPv4_MC, bgp.RF_IPv6_UC, bgp.RF_IPv6_MC: 506 default: 507 bbuf := make([]byte, 2) 508 binary.BigEndian.PutUint16(bbuf, u.Prefix.AFI()) 509 buf = append(buf, bbuf...) 510 buf = append(buf, u.Prefix.SAFI()) 511 } 512 bbuf, err := u.Prefix.Serialize() 513 if err != nil { 514 return nil, err 515 } 516 buf = append(buf, bbuf...) 517 bbuf, err = packValues([]interface{}{uint16(len(u.Entries))}) 518 if err != nil { 519 return nil, err 520 } 521 buf = append(buf, bbuf...) 522 for _, entry := range u.Entries { 523 bbuf, err = entry.Serialize() 524 if err != nil { 525 return nil, err 526 } 527 buf = append(buf, bbuf...) 528 } 529 return buf, nil 530 } 531 532 func NewRib(seq uint32, prefix bgp.AddrPrefixInterface, entries []*RibEntry) *Rib { 533 rf := bgp.AfiSafiToRouteFamily(prefix.AFI(), prefix.SAFI()) 534 return &Rib{ 535 SequenceNumber: seq, 536 Prefix: prefix, 537 Entries: entries, 538 RouteFamily: rf, 539 isAddPath: entries[0].isAddPath, 540 } 541 } 542 543 func (u *Rib) String() string { 544 return fmt.Sprintf("RIB: Seq [%d] Prefix [%s] Entries [%s]", u.SequenceNumber, u.Prefix, u.Entries) 545 } 546 547 type GeoPeer struct { 548 Type uint8 549 BgpId net.IP 550 Latitude float32 551 Longitude float32 552 } 553 554 func (p *GeoPeer) DecodeFromBytes(data []byte) ([]byte, error) { 555 if len(data) < 13 { 556 return nil, fmt.Errorf("not all GeoPeer bytes are available") 557 } 558 // Peer IP Address and Peer AS should not be included 559 p.Type = uint8(data[0]) 560 if p.Type != uint8(0) { 561 return nil, fmt.Errorf("unsupported peer type for GeoPeer: %d", p.Type) 562 } 563 p.BgpId = net.IP(data[1:5]) 564 p.Latitude = math.Float32frombits(binary.BigEndian.Uint32(data[5:9])) 565 p.Longitude = math.Float32frombits(binary.BigEndian.Uint32(data[9:13])) 566 return data[13:], nil 567 } 568 569 func (p *GeoPeer) Serialize() ([]byte, error) { 570 buf := make([]byte, 13) 571 buf[0] = uint8(0) // Peer IP Address and Peer AS should not be included 572 bgpId := p.BgpId.To4() 573 if bgpId == nil { 574 return nil, fmt.Errorf("invalid BgpId: %s", p.BgpId) 575 } 576 copy(buf[1:5], bgpId) 577 binary.BigEndian.PutUint32(buf[5:9], math.Float32bits(p.Latitude)) 578 binary.BigEndian.PutUint32(buf[9:13], math.Float32bits(p.Longitude)) 579 return buf, nil 580 } 581 582 func NewGeoPeer(bgpid string, latitude float32, longitude float32) *GeoPeer { 583 return &GeoPeer{ 584 Type: 0, // Peer IP Address and Peer AS should not be included 585 BgpId: net.ParseIP(bgpid).To4(), 586 Latitude: latitude, 587 Longitude: longitude, 588 } 589 } 590 591 func (p *GeoPeer) String() string { 592 return fmt.Sprintf("PEER ENTRY: ID [%s] Latitude [%f] Longitude [%f]", p.BgpId, p.Latitude, p.Longitude) 593 } 594 595 type GeoPeerTable struct { 596 CollectorBgpId net.IP 597 CollectorLatitude float32 598 CollectorLongitude float32 599 Peers []*GeoPeer 600 } 601 602 func (t *GeoPeerTable) DecodeFromBytes(data []byte) error { 603 if len(data) < 14 { 604 return fmt.Errorf("not all GeoPeerTable bytes are available") 605 } 606 t.CollectorBgpId = net.IP(data[0:4]) 607 t.CollectorLatitude = math.Float32frombits(binary.BigEndian.Uint32(data[4:8])) 608 t.CollectorLongitude = math.Float32frombits(binary.BigEndian.Uint32(data[8:12])) 609 peerCount := binary.BigEndian.Uint16(data[12:14]) 610 data = data[14:] 611 t.Peers = make([]*GeoPeer, 0, peerCount) 612 var err error 613 for i := 0; i < int(peerCount); i++ { 614 p := &GeoPeer{} 615 if data, err = p.DecodeFromBytes(data); err != nil { 616 return err 617 } 618 t.Peers = append(t.Peers, p) 619 } 620 return nil 621 } 622 623 func (t *GeoPeerTable) Serialize() ([]byte, error) { 624 buf := make([]byte, 14) 625 collectorBgpId := t.CollectorBgpId.To4() 626 if collectorBgpId == nil { 627 return nil, fmt.Errorf("invalid CollectorBgpId: %s", t.CollectorBgpId) 628 } 629 copy(buf[0:4], collectorBgpId) 630 binary.BigEndian.PutUint32(buf[4:8], math.Float32bits(t.CollectorLatitude)) 631 binary.BigEndian.PutUint32(buf[8:12], math.Float32bits(t.CollectorLongitude)) 632 binary.BigEndian.PutUint16(buf[12:14], uint16(len(t.Peers))) 633 for _, peer := range t.Peers { 634 pbuf, err := peer.Serialize() 635 if err != nil { 636 return nil, err 637 } 638 buf = append(buf, pbuf...) 639 } 640 return buf, nil 641 } 642 643 func NewGeoPeerTable(bgpid string, latitude float32, longitude float32, peers []*GeoPeer) *GeoPeerTable { 644 return &GeoPeerTable{ 645 CollectorBgpId: net.ParseIP(bgpid).To4(), 646 CollectorLatitude: latitude, 647 CollectorLongitude: longitude, 648 Peers: peers, 649 } 650 } 651 652 func (t *GeoPeerTable) String() string { 653 return fmt.Sprintf("GEO_PEER_TABLE: CollectorBgpId [%s] CollectorLatitude [%f] CollectorLongitude [%f] Peers [%s]", t.CollectorBgpId, t.CollectorLatitude, t.CollectorLongitude, t.Peers) 654 } 655 656 type BGP4MPHeader struct { 657 PeerAS uint32 658 LocalAS uint32 659 InterfaceIndex uint16 660 AddressFamily uint16 661 PeerIpAddress net.IP 662 LocalIpAddress net.IP 663 isAS4 bool 664 } 665 666 func (m *BGP4MPHeader) decodeFromBytes(data []byte) ([]byte, error) { 667 if m.isAS4 && len(data) < 8 { 668 return nil, fmt.Errorf("Not all BGP4MPMessageAS4 bytes available") 669 } else if !m.isAS4 && len(data) < 4 { 670 return nil, fmt.Errorf("Not all BGP4MPMessageAS bytes available") 671 } 672 673 if m.isAS4 { 674 m.PeerAS = binary.BigEndian.Uint32(data[:4]) 675 m.LocalAS = binary.BigEndian.Uint32(data[4:8]) 676 data = data[8:] 677 } else { 678 m.PeerAS = uint32(binary.BigEndian.Uint16(data[:2])) 679 m.LocalAS = uint32(binary.BigEndian.Uint16(data[2:4])) 680 data = data[4:] 681 } 682 m.InterfaceIndex = binary.BigEndian.Uint16(data[:2]) 683 m.AddressFamily = binary.BigEndian.Uint16(data[2:4]) 684 switch m.AddressFamily { 685 case bgp.AFI_IP: 686 m.PeerIpAddress = net.IP(data[4:8]).To4() 687 m.LocalIpAddress = net.IP(data[8:12]).To4() 688 data = data[12:] 689 case bgp.AFI_IP6: 690 m.PeerIpAddress = net.IP(data[4:20]) 691 m.LocalIpAddress = net.IP(data[20:36]) 692 data = data[36:] 693 default: 694 return nil, fmt.Errorf("unsupported address family: %d", m.AddressFamily) 695 } 696 return data, nil 697 } 698 699 func (m *BGP4MPHeader) serialize() ([]byte, error) { 700 var values []interface{} 701 if m.isAS4 { 702 values = []interface{}{m.PeerAS, m.LocalAS, m.InterfaceIndex, m.AddressFamily} 703 } else { 704 values = []interface{}{uint16(m.PeerAS), uint16(m.LocalAS), m.InterfaceIndex, m.AddressFamily} 705 } 706 buf, err := packValues(values) 707 if err != nil { 708 return nil, err 709 } 710 var bbuf []byte 711 switch m.AddressFamily { 712 case bgp.AFI_IP: 713 bbuf = make([]byte, 8) 714 copy(bbuf, m.PeerIpAddress.To4()) 715 copy(bbuf[4:], m.LocalIpAddress.To4()) 716 case bgp.AFI_IP6: 717 bbuf = make([]byte, 32) 718 copy(bbuf, m.PeerIpAddress) 719 copy(bbuf[16:], m.LocalIpAddress) 720 default: 721 return nil, fmt.Errorf("unsupported address family: %d", m.AddressFamily) 722 } 723 return append(buf, bbuf...), nil 724 } 725 726 func newBGP4MPHeader(peeras, localas uint32, intfindex uint16, peerip, localip string, isAS4 bool) (*BGP4MPHeader, error) { 727 var af uint16 728 paddr := net.ParseIP(peerip).To4() 729 laddr := net.ParseIP(localip).To4() 730 if paddr != nil && laddr != nil { 731 af = bgp.AFI_IP 732 } else { 733 paddr = net.ParseIP(peerip).To16() 734 laddr = net.ParseIP(localip).To16() 735 if paddr != nil && laddr != nil { 736 af = bgp.AFI_IP6 737 } else { 738 return nil, fmt.Errorf("Peer IP Address and Local IP Address must have the same address family") 739 } 740 } 741 return &BGP4MPHeader{ 742 PeerAS: peeras, 743 LocalAS: localas, 744 InterfaceIndex: intfindex, 745 AddressFamily: af, 746 PeerIpAddress: paddr, 747 LocalIpAddress: laddr, 748 isAS4: isAS4, 749 }, nil 750 } 751 752 type BGP4MPStateChange struct { 753 *BGP4MPHeader 754 OldState BGPState 755 NewState BGPState 756 } 757 758 func (m *BGP4MPStateChange) DecodeFromBytes(data []byte) error { 759 rest, err := m.decodeFromBytes(data) 760 if err != nil { 761 return err 762 } 763 if len(rest) < 4 { 764 return fmt.Errorf("Not all BGP4MPStateChange bytes available") 765 } 766 m.OldState = BGPState(binary.BigEndian.Uint16(rest[:2])) 767 m.NewState = BGPState(binary.BigEndian.Uint16(rest[2:4])) 768 return nil 769 } 770 771 func (m *BGP4MPStateChange) Serialize() ([]byte, error) { 772 buf, err := m.serialize() 773 if err != nil { 774 return nil, err 775 } 776 bbuf, err := packValues([]interface{}{m.OldState, m.NewState}) 777 if err != nil { 778 return nil, err 779 } 780 return append(buf, bbuf...), nil 781 } 782 783 func NewBGP4MPStateChange(peeras, localas uint32, intfindex uint16, peerip, localip string, isAS4 bool, oldstate, newstate BGPState) *BGP4MPStateChange { 784 header, _ := newBGP4MPHeader(peeras, localas, intfindex, peerip, localip, isAS4) 785 return &BGP4MPStateChange{ 786 BGP4MPHeader: header, 787 OldState: oldstate, 788 NewState: newstate, 789 } 790 } 791 792 type BGP4MPMessage struct { 793 *BGP4MPHeader 794 BGPMessage *bgp.BGPMessage 795 BGPMessagePayload []byte 796 isLocal bool 797 isAddPath bool 798 } 799 800 func (m *BGP4MPMessage) DecodeFromBytes(data []byte) error { 801 rest, err := m.decodeFromBytes(data) 802 if err != nil { 803 return err 804 } 805 806 if len(rest) < bgp.BGP_HEADER_LENGTH { 807 return fmt.Errorf("Not all BGP4MPMessageAS4 bytes available") 808 } 809 810 msg, err := bgp.ParseBGPMessage(rest) 811 if err != nil { 812 return err 813 } 814 m.BGPMessage = msg 815 return nil 816 } 817 818 func (m *BGP4MPMessage) Serialize() ([]byte, error) { 819 buf, err := m.serialize() 820 if err != nil { 821 return nil, err 822 } 823 if m.BGPMessagePayload != nil { 824 return append(buf, m.BGPMessagePayload...), nil 825 } 826 bbuf, err := m.BGPMessage.Serialize() 827 if err != nil { 828 return nil, err 829 } 830 return append(buf, bbuf...), nil 831 } 832 833 func NewBGP4MPMessage(peeras, localas uint32, intfindex uint16, peerip, localip string, isAS4 bool, msg *bgp.BGPMessage) *BGP4MPMessage { 834 header, _ := newBGP4MPHeader(peeras, localas, intfindex, peerip, localip, isAS4) 835 return &BGP4MPMessage{ 836 BGP4MPHeader: header, 837 BGPMessage: msg, 838 } 839 } 840 841 func NewBGP4MPMessageLocal(peeras, localas uint32, intfindex uint16, peerip, localip string, isAS4 bool, msg *bgp.BGPMessage) *BGP4MPMessage { 842 header, _ := newBGP4MPHeader(peeras, localas, intfindex, peerip, localip, isAS4) 843 return &BGP4MPMessage{ 844 BGP4MPHeader: header, 845 BGPMessage: msg, 846 isLocal: true, 847 } 848 } 849 850 func NewBGP4MPMessageAddPath(peeras, localas uint32, intfindex uint16, peerip, localip string, isAS4 bool, msg *bgp.BGPMessage) *BGP4MPMessage { 851 header, _ := newBGP4MPHeader(peeras, localas, intfindex, peerip, localip, isAS4) 852 return &BGP4MPMessage{ 853 BGP4MPHeader: header, 854 BGPMessage: msg, 855 isAddPath: true, 856 } 857 } 858 859 func NewBGP4MPMessageLocalAddPath(peeras, localas uint32, intfindex uint16, peerip, localip string, isAS4 bool, msg *bgp.BGPMessage) *BGP4MPMessage { 860 header, _ := newBGP4MPHeader(peeras, localas, intfindex, peerip, localip, isAS4) 861 return &BGP4MPMessage{ 862 BGP4MPHeader: header, 863 BGPMessage: msg, 864 isLocal: true, 865 isAddPath: true, 866 } 867 } 868 869 func (m *BGP4MPMessage) String() string { 870 title := "BGP4MP_MSG" 871 if m.isAS4 { 872 title += "_AS4" 873 } 874 if m.isLocal { 875 title += "_LOCAL" 876 } 877 if m.isAddPath { 878 title += "_ADDPATH" 879 } 880 return fmt.Sprintf("%s: PeerAS [%d] LocalAS [%d] InterfaceIndex [%d] PeerIP [%s] LocalIP [%s] BGPMessage [%v]", title, m.PeerAS, m.LocalAS, m.InterfaceIndex, m.PeerIpAddress, m.LocalIpAddress, m.BGPMessage) 881 } 882 883 //This function can be passed into a bufio.Scanner.Split() to read buffered mrt msgs 884 func SplitMrt(data []byte, atEOF bool) (advance int, token []byte, err error) { 885 if atEOF && len(data) == 0 { 886 return 0, nil, nil 887 } 888 if cap(data) < MRT_COMMON_HEADER_LEN { // read more 889 return 0, nil, nil 890 } 891 //this reads the data 892 hdr := &MRTHeader{} 893 errh := hdr.DecodeFromBytes(data[:MRT_COMMON_HEADER_LEN]) 894 if errh != nil { 895 return 0, nil, errh 896 } 897 totlen := int(hdr.Len + MRT_COMMON_HEADER_LEN) 898 if len(data) < totlen { //need to read more 899 return 0, nil, nil 900 } 901 return totlen, data[0:totlen], nil 902 } 903 904 func ParseMRTBody(h *MRTHeader, data []byte) (*MRTMessage, error) { 905 if len(data) < int(h.Len) { 906 return nil, fmt.Errorf("Not all MRT message bytes available. expected: %d, actual: %d", int(h.Len), len(data)) 907 } 908 msg := &MRTMessage{Header: *h} 909 switch h.Type { 910 case TABLE_DUMPv2: 911 subType := MRTSubTypeTableDumpv2(h.SubType) 912 rf := bgp.RouteFamily(0) 913 isAddPath := false 914 switch subType { 915 case PEER_INDEX_TABLE: 916 msg.Body = &PeerIndexTable{} 917 case RIB_IPV4_UNICAST: 918 rf = bgp.RF_IPv4_UC 919 case RIB_IPV4_MULTICAST: 920 rf = bgp.RF_IPv4_MC 921 case RIB_IPV6_UNICAST: 922 rf = bgp.RF_IPv6_UC 923 case RIB_IPV6_MULTICAST: 924 rf = bgp.RF_IPv6_MC 925 case RIB_GENERIC: 926 case GEO_PEER_TABLE: 927 msg.Body = &GeoPeerTable{} 928 case RIB_IPV4_UNICAST_ADDPATH: 929 rf = bgp.RF_IPv4_UC 930 isAddPath = true 931 case RIB_IPV4_MULTICAST_ADDPATH: 932 rf = bgp.RF_IPv4_MC 933 isAddPath = true 934 case RIB_IPV6_UNICAST_ADDPATH: 935 rf = bgp.RF_IPv6_UC 936 isAddPath = true 937 case RIB_IPV6_MULTICAST_ADDPATH: 938 rf = bgp.RF_IPv6_MC 939 isAddPath = true 940 case RIB_GENERIC_ADDPATH: 941 isAddPath = true 942 default: 943 return nil, fmt.Errorf("unsupported table dumpv2 subtype: %v\n", subType) 944 } 945 946 if msg.Body == nil { 947 msg.Body = &Rib{ 948 RouteFamily: rf, 949 isAddPath: isAddPath, 950 } 951 } 952 case BGP4MP: 953 subType := MRTSubTypeBGP4MP(h.SubType) 954 isAS4 := true 955 switch subType { 956 case STATE_CHANGE: 957 isAS4 = false 958 fallthrough 959 case STATE_CHANGE_AS4: 960 msg.Body = &BGP4MPStateChange{ 961 BGP4MPHeader: &BGP4MPHeader{isAS4: isAS4}, 962 } 963 case MESSAGE: 964 isAS4 = false 965 fallthrough 966 case MESSAGE_AS4: 967 msg.Body = &BGP4MPMessage{ 968 BGP4MPHeader: &BGP4MPHeader{isAS4: isAS4}, 969 } 970 case MESSAGE_LOCAL: 971 isAS4 = false 972 fallthrough 973 case MESSAGE_AS4_LOCAL: 974 msg.Body = &BGP4MPMessage{ 975 BGP4MPHeader: &BGP4MPHeader{isAS4: isAS4}, 976 isLocal: true, 977 } 978 case MESSAGE_ADDPATH: 979 isAS4 = false 980 fallthrough 981 case MESSAGE_AS4_ADDPATH: 982 msg.Body = &BGP4MPMessage{ 983 BGP4MPHeader: &BGP4MPHeader{isAS4: isAS4}, 984 isAddPath: true, 985 } 986 case MESSAGE_LOCAL_ADDPATH: 987 isAS4 = false 988 fallthrough 989 case MESSAGE_AS4_LOCAL_ADDPATH: 990 msg.Body = &BGP4MPMessage{ 991 BGP4MPHeader: &BGP4MPHeader{isAS4: isAS4}, 992 isLocal: true, 993 isAddPath: true, 994 } 995 default: 996 return nil, fmt.Errorf("unsupported bgp4mp subtype: %v\n", subType) 997 } 998 default: 999 return nil, fmt.Errorf("unsupported type: %v\n", h.Type) 1000 } 1001 err := msg.Body.DecodeFromBytes(data) 1002 if err != nil { 1003 return nil, err 1004 } 1005 return msg, nil 1006 }