github.com/osrg/gobgp@v2.0.0+incompatible/pkg/packet/bmp/bmp.go (about)

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