kbandla / dpkt

fast, simple packet creation / parsing, with definitions for the basic TCP/IP protocols
Other
1.09k stars 270 forks source link

BGP: Error reading NLRI label stack #482

Open amgadhanafy opened 4 years ago

amgadhanafy commented 4 years ago

While trying to open file https://packetlife.net/media/captures/bgplu.cap frame 21 image

image

using this code

    def test_bgplu_21_1_as_path(self):
        # Error processing BGP data: packet 21 : message 1 of bgplu.cap https://packetlife.net/media/captures/bgplu.cap
        _bgp = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x02\x00\x00\x00\x2b\x40\x01\x01\x00\x40\x02\x00\x40\x03\x04\x0a\x01\x01\x02\x40\x05\x04\x00\x00\x00\x64\x80\x0e\x13\x00\x01\x04\x04\x0a\x01\x01\x02\x00\x48\xdb\xc4\x30\xdb\xc4\x21\x01\x03\x00'
        bgp = BGP(_bgp)
        assert (_bgp == bytes(bgp))
        assert (len(bgp) == 66)
        assert (bgp.type == UPDATE)
        assert (len(bgp.update.withdrawn) == 0)
        assert (len(bgp.update.announced) == 0)

        assert (len(bgp.update.attributes) == 5)

        attribute = bgp.update.attributes[0]
        assert (attribute.type == ORIGIN)
        assert (attribute.optional == False)
        assert (attribute.transitive == True)
        assert (attribute.partial == False)
        assert (attribute.extended_length == False)
        assert (attribute.flags == 0x40)
        assert (attribute.len == 1)
        assert (attribute.origin.type == ORIGIN_IGP)

        attribute = bgp.update.attributes[1]
        assert (attribute.type == AS_PATH)
        assert (attribute.optional == False)
        assert (attribute.transitive == True)
        assert (attribute.partial == False)
        assert (attribute.extended_length == False)
        assert (attribute.flags == 0x40)
        assert (attribute.len == 0)
        assert (len(attribute.as_path.segments) == 0)

        attribute = bgp.update.attributes[2]
        assert (attribute.type == NEXT_HOP)
        assert (attribute.optional == False)
        assert (attribute.transitive == True)
        assert (attribute.partial == False)
        assert (attribute.extended_length == False)
        assert (attribute.flags == 0x40)
        assert (attribute.len == 4)
        assert (socket.inet_ntop(socket.AF_INET, bytes(attribute.next_hop)) == '10.1.1.2')

        attribute = bgp.update.attributes[3]
        assert (attribute.type == LOCAL_PREF)
        assert (attribute.optional == False)
        assert (attribute.transitive == True)
        assert (attribute.partial == False)
        assert (attribute.extended_length == False)
        assert (attribute.flags == 0x40)
        assert (attribute.len == 4)
        assert (attribute.local_pref.value == 100)

        attribute = bgp.update.attributes[4]
        assert (attribute.type == MP_REACH_NLRI)
        assert (attribute.optional == True)
        assert (attribute.transitive == False)
        assert (attribute.partial == False)
        assert (attribute.extended_length == False)
        assert (attribute.flags == 0x80)
        assert (attribute.len == 19)

        mp_reach_nlri = attribute.mp_reach_nlri
        assert (mp_reach_nlri.afi == AFI_IPV4)
        assert (mp_reach_nlri.safi == BGP.SAFI_LABELED_UNICAST)
        assert (socket.inet_ntop(socket.AF_INET, mp_reach_nlri.next_hop) == '10.1.1.2')
        assert (len(mp_reach_nlri.snpas) == 0)
        assert (len(mp_reach_nlri.announced) == 1)
        route = mp_reach_nlri.announced[0]
        logger.debug(route.__repr__())
        assert (route.len == 72)
        assert (socket.inet_ntop(socket.AF_INET, route.prefix) == '1.3.0.0')

this error is thrown

  File "C:\\bgp_test.py", line 477, in test_bgplu_21_1_as_path
    logger.debug(route.__repr__())
  File "D:\dpkt\dpkt\bgp.py", line 661, in __repr__
    cidr = '%s/%d' % (socket.inet_ntoa(self.prefix), self.len)
OSError: packed IP wrong length for inet_ntoa
amgadhanafy commented 4 years ago

As of rfc3107 Advertisement of Multiple Paths in BGP

  1. Carrying Label Mapping Information Label mapping information is carried as part of the Network Layer Reachability Information (NLRI) in the Multiprotocol Extensions attributes. The AFI indicates, as usual, the address family of the associated route. The fact that the NLRI contains a label is indicated by using SAFI value 4. The Network Layer Reachability information is encoded as one or more triples of the form <length, label, prefix>, whose fields are described below:
      +---------------------------+
      |   Length (1 octet)        |
      +---------------------------+
      |   Label (3 octets)        |
      +---------------------------+
      .............................
      +---------------------------+
      |   Prefix (variable)       |
      +---------------------------+

    The use and the meaning of these fields are as follows: a) Length: The Length field indicates the length in bits of the address prefix plus the label(s). b) Label: The Label field carries one or more labels (that corresponds to the stack of labels [MPLS-ENCAPS]). Each label is encoded as 3 octets, where the high-order 20 bits contain the label value, and the low order bit contains "Bottom of Stack" (as defined in [MPLS-ENCAPS]). c) Prefix: The Prefix field contains address prefixes followed by enough trailing bits to make the end of the field fall on an octet boundary. Note that the value of trailing bits is irrelevant.

The current implementation is missing this feature