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  }