From 954562d65a90af4e8d2e9bf29e4c2bccc4420b38 Mon Sep 17 00:00:00 2001 From: IWASE Yusuke Date: Thu, 21 Jun 2018 13:41:53 +0900 Subject: packet/bgp: Fix length calc when multiple RTM NLRIs When multiple RTM NLRIs are composed in a single MP_REACH_NLRI, the current implementation will fail to decode those NLRIs because RouteTargetMembershipNLRI.DecodeFromBytes() tests the length of the given bytes even if including the subsequent bytes. This patch fixes to cut the bytes by using the prefix length before testing the byte length. Signed-off-by: IWASE Yusuke --- packet/bgp/bgp.go | 4 ++-- packet/bgp/bgp_test.go | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go index ae62d3bf..361da392 100644 --- a/packet/bgp/bgp.go +++ b/packet/bgp/bgp.go @@ -1955,7 +1955,7 @@ func (n *RouteTargetMembershipNLRI) DecodeFromBytes(data []byte, options ...*Mar return NewMessageError(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST), nil, "prefix misses length field") } n.Length = data[0] - data = data[1:] + data = data[1 : n.Length/8+1] if len(data) == 0 { return nil } else if len(data) != 12 { @@ -1984,7 +1984,7 @@ func (n *RouteTargetMembershipNLRI) Serialize(options ...*MarshallingOption) ([] } offset := len(buf) buf = append(buf, make([]byte, 5)...) - buf[offset] = 12 * 8 + buf[offset] = 96 binary.BigEndian.PutUint32(buf[offset+1:], n.AS) ebuf, err := n.RouteTarget.Serialize() if err != nil { diff --git a/packet/bgp/bgp_test.go b/packet/bgp/bgp_test.go index 697c204b..1d6f386f 100644 --- a/packet/bgp/bgp_test.go +++ b/packet/bgp/bgp_test.go @@ -91,7 +91,7 @@ func Test_RouteTargetMembershipNLRIString(t *testing.T) { // TwoOctetAsSpecificExtended buf := make([]byte, 13) - buf[0] = 12 + buf[0] = 96 // in bit length binary.BigEndian.PutUint32(buf[1:5], 65546) buf[5] = byte(EC_TYPE_TRANSITIVE_TWO_OCTET_AS_SPECIFIC) // typehigh binary.BigEndian.PutUint16(buf[7:9], 65000) @@ -108,6 +108,7 @@ func Test_RouteTargetMembershipNLRIString(t *testing.T) { // IPv4AddressSpecificExtended buf = make([]byte, 13) + buf[0] = 96 // in bit length binary.BigEndian.PutUint32(buf[1:5], 65546) buf[5] = byte(EC_TYPE_TRANSITIVE_IP4_SPECIFIC) // typehigh ip := net.ParseIP("10.0.0.1").To4() @@ -125,6 +126,7 @@ func Test_RouteTargetMembershipNLRIString(t *testing.T) { // FourOctetAsSpecificExtended buf = make([]byte, 13) + buf[0] = 96 // in bit length binary.BigEndian.PutUint32(buf[1:5], 65546) buf[5] = byte(EC_TYPE_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC) // typehigh buf[6] = byte(EC_SUBTYPE_ROUTE_TARGET) // subtype @@ -142,6 +144,7 @@ func Test_RouteTargetMembershipNLRIString(t *testing.T) { // OpaqueExtended buf = make([]byte, 13) + buf[0] = 96 // in bit length binary.BigEndian.PutUint32(buf[1:5], 65546) buf[5] = byte(EC_TYPE_TRANSITIVE_OPAQUE) // typehigh binary.BigEndian.PutUint32(buf[9:], 1000000) @@ -157,6 +160,7 @@ func Test_RouteTargetMembershipNLRIString(t *testing.T) { // Unknown buf = make([]byte, 13) + buf[0] = 96 // in bit length binary.BigEndian.PutUint32(buf[1:5], 65546) buf[5] = 0x04 // typehigh binary.BigEndian.PutUint32(buf[9:], 1000000) -- cgit v1.2.3