From bdb108782d2ca01a80ae1f24b938ff33698352b5 Mon Sep 17 00:00:00 2001 From: Oliver Herms <oliver.herms@exaring.de> Date: Fri, 5 Oct 2018 16:19:36 +0200 Subject: [PATCH] Adding route monitoring message --- protocols/bmp/packet/per_peer_header.go | 5 ++ protocols/bmp/packet/route_mirroring.go | 1 - protocols/bmp/packet/route_monitoring.go | 45 ++++++++++ protocols/bmp/packet/route_monitoring_test.go | 89 +++++++++++++++++++ 4 files changed, 139 insertions(+), 1 deletion(-) delete mode 100644 protocols/bmp/packet/route_mirroring.go create mode 100644 protocols/bmp/packet/route_monitoring_test.go diff --git a/protocols/bmp/packet/per_peer_header.go b/protocols/bmp/packet/per_peer_header.go index 87231c86..f17a9201 100644 --- a/protocols/bmp/packet/per_peer_header.go +++ b/protocols/bmp/packet/per_peer_header.go @@ -7,6 +7,11 @@ import ( "github.com/bio-routing/tflow2/convert" ) +const ( + // PerPeerHeaderLen is the length of a per peer header + PerPeerHeaderLen = 38 +) + // PerPeerHeader represents a BMP per peer header type PerPeerHeader struct { PeerType uint8 diff --git a/protocols/bmp/packet/route_mirroring.go b/protocols/bmp/packet/route_mirroring.go deleted file mode 100644 index 9c40969f..00000000 --- a/protocols/bmp/packet/route_mirroring.go +++ /dev/null @@ -1 +0,0 @@ -package packet diff --git a/protocols/bmp/packet/route_monitoring.go b/protocols/bmp/packet/route_monitoring.go index 9c40969f..d76aa453 100644 --- a/protocols/bmp/packet/route_monitoring.go +++ b/protocols/bmp/packet/route_monitoring.go @@ -1 +1,46 @@ package packet + +import ( + "bytes" + "fmt" + + "github.com/bio-routing/bio-rd/util/decoder" +) + +// RouteMonitoringMsg represents a Route Monitoring Message +type RouteMonitoringMsg struct { + CommonHeader *CommonHeader + PerPeerHeader *PerPeerHeader + BGPUpdate []byte +} + +// MsgType returns the type of this message +func (rm *RouteMonitoringMsg) MsgType() uint8 { + return rm.CommonHeader.MsgType +} + +func decodeRouteMonitoringMsg(buf *bytes.Buffer, ch *CommonHeader) (*RouteMonitoringMsg, error) { + rm := &RouteMonitoringMsg{ + CommonHeader: ch, + } + + pph, err := decodePerPeerHeader(buf) + if err != nil { + return nil, fmt.Errorf("Unable to decode per peer header: %v", err) + } + + rm.PerPeerHeader = pph + + rm.BGPUpdate = make([]byte, ch.MsgLength-CommonHeaderLen-PerPeerHeaderLen) + + fields := []interface{}{ + &rm.BGPUpdate, + } + + err = decoder.Decode(buf, fields) + if err != nil { + return nil, err + } + + return rm, nil +} diff --git a/protocols/bmp/packet/route_monitoring_test.go b/protocols/bmp/packet/route_monitoring_test.go new file mode 100644 index 00000000..c6cee1f7 --- /dev/null +++ b/protocols/bmp/packet/route_monitoring_test.go @@ -0,0 +1,89 @@ +package packet + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestDecodeRouteMonitoringMsg(t *testing.T) { + tests := []struct { + name string + input []byte + ch *CommonHeader + wantFail bool + expected *RouteMonitoringMsg + }{ + { + name: "Full", + input: []byte{ + 1, + 2, + 0, 0, 0, 3, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 0, 0, 200, 124, + 0, 0, 0, 123, + 0, 0, 0, 100, + 0, 0, 0, 200, + + 100, 110, 120, + }, + ch: &CommonHeader{ + MsgLength: CommonHeaderLen + PerPeerHeaderLen + 3, + }, + wantFail: false, + expected: &RouteMonitoringMsg{ + CommonHeader: &CommonHeader{ + MsgLength: CommonHeaderLen + PerPeerHeaderLen + 3, + }, + PerPeerHeader: &PerPeerHeader{ + PeerType: 1, + PeerFlags: 2, + PeerDistinguisher: 3, + PeerAddress: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + PeerAS: 51324, + PeerBGPID: 123, + Timestamp: 100, + TimestampMicroSeconds: 200, + }, + BGPUpdate: []byte{ + 100, 110, 120, + }, + }, + }, + { + name: "Incomplete per peer header", + input: []byte{ + 1, + 2, + 0, 0, 0, 3, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + }, + ch: &CommonHeader{ + MsgLength: CommonHeaderLen + PerPeerHeaderLen + 3, + }, + wantFail: true, + }, + } + + for _, test := range tests { + buf := bytes.NewBuffer(test.input) + r, err := decodeRouteMonitoringMsg(buf, test.ch) + if err != nil { + if test.wantFail { + continue + } + + t.Errorf("Unexpected failure for test %q: %v", test.name, err) + continue + } + + if test.wantFail { + t.Errorf("Unexpected success for test %q", test.name) + continue + } + + assert.Equalf(t, test.expected, r, "Test %q", test.name) + } +} -- GitLab