Beispiel #1
0
    def parser(cls, buf):
        kwargs, rest = super(BMPPeerUpNotification, cls).parser(buf)

        (local_address,
         local_port, remote_port) = struct.unpack_from(cls._PACK_STR,
                                                       six.binary_type(rest))

        if '.' in kwargs['peer_address']:
            local_address = addrconv.ipv4.bin_to_text(local_address[:4])
        elif ':' in kwargs['peer_address']:
            local_address = addrconv.ipv6.bin_to_text(local_address)
        else:
            raise ValueError("invalid local_address: %s" % local_address)

        kwargs['local_address'] = local_address
        kwargs['local_port'] = local_port
        kwargs['remote_port'] = remote_port

        rest = rest[cls._MIN_LEN:]

        sent_open_msg, _, rest = BGPMessage.parser(rest)
        received_open_msg, _, rest = BGPMessage.parser(rest)

        kwargs['sent_open_message'] = sent_open_msg
        kwargs['received_open_message'] = received_open_msg

        return kwargs
Beispiel #2
0
Datei: bmp.py Projekt: mkfsn/ryu
    def parser(cls, buf):
        kwargs, rest = super(BMPPeerUpNotification, cls).parser(buf)

        (local_address, local_port,
         remote_port) = struct.unpack_from(cls._PACK_STR, buffer(rest))

        local_address = buffer(local_address)

        if '.' in kwargs['peer_address']:
            local_address = addrconv.ipv4.bin_to_text(local_address[:4])
        elif ':' in kwargs['peer_address']:
            local_address = addrconv.ipv6.bin_to_text(local_address)
        else:
            raise ValueError("invalid local_address: %s" % local_address)

        kwargs['local_address'] = local_address
        kwargs['local_port'] = local_port
        kwargs['remote_port'] = remote_port

        rest = rest[cls._MIN_LEN:]

        sent_open_msg, rest = BGPMessage.parser(rest)
        received_open_msg, rest = BGPMessage.parser(rest)

        kwargs['sent_open_message'] = sent_open_msg
        kwargs['received_open_message'] = received_open_msg

        return kwargs
Beispiel #3
0
    def _data_received(self, next_bytes):
        """Maintains buffer of bytes received from peer and extracts bgp
        message from this buffer if enough data is received.

        Validates bgp message marker, length, type and data and constructs
        appropriate bgp message instance and calls handler.

        :Parameters:
            - `next_bytes`: next set of bytes received from peer.
        """
        # Append buffer with received bytes.
        self._recv_buff += next_bytes

        while True:
            # If current buffer size is less then minimum bgp message size, we
            # return as we do not have a complete bgp message to work with.
            if len(self._recv_buff) < BGP_MIN_MSG_LEN:
                return

            # Parse message header into elements.
            auth, length, ptype = BgpProtocol.parse_msg_header(
                self._recv_buff[:BGP_MIN_MSG_LEN])

            # Check if we have valid bgp message marker.
            # We should get default marker since we are not supporting any
            # authentication.
            if (auth != BgpProtocol.MESSAGE_MARKER):
                LOG.error('Invalid message marker received: %s', auth)
                raise bgp.NotSync()

            # Check if we have valid bgp message length.
            check = lambda: length < BGP_MIN_MSG_LEN\
                or length > BGP_MAX_MSG_LEN

            # RFC says: The minimum length of the OPEN message is 29
            # octets (including the message header).
            check2 = lambda: ptype == BGP_MSG_OPEN\
                and length < BGPOpen._MIN_LEN

            # RFC says: A KEEPALIVE message consists of only the
            # message header and has a length of 19 octets.
            check3 = lambda: ptype == BGP_MSG_KEEPALIVE\
                and length != BGPKeepAlive._MIN_LEN

            # RFC says: The minimum length of the UPDATE message is 23
            # octets.
            check4 = lambda: ptype == BGP_MSG_UPDATE\
                and length < BGPUpdate._MIN_LEN

            if check() or check2() or check3() or check4():
                raise bgp.BadLen(ptype, length)

            # If we have partial message we wait for rest of the message.
            if len(self._recv_buff) < length:
                return
            msg, rest = BGPMessage.parser(self._recv_buff)
            self._recv_buff = rest

            # If we have a valid bgp message we call message handler.
            self._handle_msg(msg)
Beispiel #4
0
    def test_20_check_withdrawal_2(self):
        g1 = self.gobgp
        g2 = self.quaggas['g2']

        dumpfile = g2.start_tcpdump()

        g1.add_route('10.40.0.0/24')

        time.sleep(1)

        paths = g2.get_global_rib('10.40.0.0/24')
        self.assertTrue(len(paths) == 1)

        g1.local('gobgp global rib del 10.40.0.0/24')

        time.sleep(1)

        paths = g2.get_global_rib('10.40.0.0/24')
        self.assertTrue(len(paths) == 0)

        g2.stop_tcpdump()
        time.sleep(1)

        cnt = 0
        for pkt in pcap.Reader(open(dumpfile)):
            last = Packet(pkt[1]).protocols[-1]
            if type(last) == str:
                pkt = BGPMessage.parser(last)[0]
                if type(pkt) == BGPUpdate:
                    cnt += len(pkt.withdrawn_routes)

        self.assertTrue(cnt == 1)
Beispiel #5
0
    def test_20_check_withdrawal_2(self):
        g1 = self.gobgp
        g2 = self.quaggas['g2']

        dumpfile = g2.start_tcpdump()

        g1.add_route('10.40.0.0/24')

        time.sleep(1)

        paths = g2.get_global_rib('10.40.0.0/24')
        self.assertTrue(len(paths) == 1)

        g1.local('gobgp global rib del 10.40.0.0/24')

        time.sleep(1)

        paths = g2.get_global_rib('10.40.0.0/24')
        self.assertTrue(len(paths) == 0)

        g2.stop_tcpdump()
        time.sleep(1)

        cnt = 0
        for pkt in pcap.Reader(open(dumpfile)):
            last = Packet(pkt[1]).protocols[-1]
            if type(last) == str:
                pkt = BGPMessage.parser(last)[0]
                cnt += len(pkt.withdrawn_routes)

        self.assertTrue(cnt == 1)
Beispiel #6
0
    def _data_received(self, next_bytes):
        """Maintains buffer of bytes received from peer and extracts bgp
        message from this buffer if enough data is received.

        Validates bgp message marker, length, type and data and constructs
        appropriate bgp message instance and calls handler.

        :Parameters:
            - `next_bytes`: next set of bytes received from peer.
        """
        # Append buffer with received bytes.
        self._recv_buff += next_bytes

        while True:
            # If current buffer size is less then minimum bgp message size, we
            # return as we do not have a complete bgp message to work with.
            if len(self._recv_buff) < BGP_MIN_MSG_LEN:
                return

            # Parse message header into elements.
            auth, length, ptype = BgpProtocol.parse_msg_header(
                self._recv_buff[:BGP_MIN_MSG_LEN])

            # Check if we have valid bgp message marker.
            # We should get default marker since we are not supporting any
            # authentication.
            if (auth != BgpProtocol.MESSAGE_MARKER):
                LOG.error('Invalid message marker received: %s', auth)
                raise bgp.NotSync()

            # Check if we have valid bgp message length.
            check = lambda: length < BGP_MIN_MSG_LEN\
                or length > BGP_MAX_MSG_LEN

            # RFC says: The minimum length of the OPEN message is 29
            # octets (including the message header).
            check2 = lambda: ptype == BGP_MSG_OPEN\
                and length < BGPOpen._MIN_LEN

            # RFC says: A KEEPALIVE message consists of only the
            # message header and has a length of 19 octets.
            check3 = lambda: ptype == BGP_MSG_KEEPALIVE\
                and length != BGPKeepAlive._MIN_LEN

            # RFC says: The minimum length of the UPDATE message is 23
            # octets.
            check4 = lambda: ptype == BGP_MSG_UPDATE\
                and length < BGPUpdate._MIN_LEN

            if check() or check2() or check3() or check4():
                raise bgp.BadLen(ptype, length)

            # If we have partial message we wait for rest of the message.
            if len(self._recv_buff) < length:
                return
            msg, rest = BGPMessage.parser(self._recv_buff)
            self._recv_buff = rest

            # If we have a valid bgp message we call message handler.
            self._handle_msg(msg)
Beispiel #7
0
Datei: bmp.py Projekt: mkfsn/ryu
    def parser(cls, buf):
        kwargs, buf = super(BMPRouteMonitoring, cls).parser(buf)

        bgp_update, buf = BGPMessage.parser(buf)

        kwargs['bgp_update'] = bgp_update

        return kwargs
Beispiel #8
0
    def parser(cls, buf):
        kwargs, buf = super(BMPRouteMonitoring, cls).parser(buf)

        bgp_update, _, buf = BGPMessage.parser(buf)

        kwargs['bgp_update'] = bgp_update

        return kwargs
Beispiel #9
0
Datei: bmp.py Projekt: mkfsn/ryu
    def parser(cls, buf):
        reason, = struct.unpack_from('!B', buffer(buf))
        buf = buf[struct.calcsize('!B'):]

        if reason == BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION:
            data, rest = BGPMessage.parser(buf)
        elif reason == BMP_PEER_DOWN_REASON_LOCAL_NO_NOTIFICATION:
            data = struct.unpack_from('!H', buffer(buf))
        elif reason == BMP_PEER_DOWN_REASON_REMOTE_BGP_NOTIFICATION:
            data, rest = BGPMessage.parser(buf)
        elif reason == BMP_PEER_DOWN_REASON_REMOTE_NO_NOTIFICATION:
            data = None
        else:
            reason = BMP_PEER_DOWN_REASON_UNKNOWN
            data = buf

        kwargs = {}
        kwargs['reason'] = reason
        kwargs['data'] = data

        return kwargs
Beispiel #10
0
    def parser(cls, buf):
        kwargs, buf = super(BMPPeerDownNotification, cls).parser(buf)
        reason, = struct.unpack_from('!B', six.binary_type(buf))
        buf = buf[struct.calcsize('!B'):]

        if reason == BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION:
            data, _, rest = BGPMessage.parser(buf)
        elif reason == BMP_PEER_DOWN_REASON_LOCAL_NO_NOTIFICATION:
            data = struct.unpack_from('!H', six.binary_type(buf))
        elif reason == BMP_PEER_DOWN_REASON_REMOTE_BGP_NOTIFICATION:
            data, _, rest = BGPMessage.parser(buf)
        elif reason == BMP_PEER_DOWN_REASON_REMOTE_NO_NOTIFICATION:
            data = None
        else:
            reason = BMP_PEER_DOWN_REASON_UNKNOWN
            data = buf

        kwargs['reason'] = reason
        kwargs['data'] = data

        return kwargs
Beispiel #11
0
    def parser(cls, buf):
        kwargs, buf = super(BMPPeerDownNotification, cls).parser(buf)
        reason, = struct.unpack_from('!B', six.binary_type(buf))
        buf = buf[struct.calcsize('!B'):]

        if reason == BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION:
            data, _, rest = BGPMessage.parser(buf)
        elif reason == BMP_PEER_DOWN_REASON_LOCAL_NO_NOTIFICATION:
            data = struct.unpack_from('!H', six.binary_type(buf))
        elif reason == BMP_PEER_DOWN_REASON_REMOTE_BGP_NOTIFICATION:
            data, _, rest = BGPMessage.parser(buf)
        elif reason == BMP_PEER_DOWN_REASON_REMOTE_NO_NOTIFICATION:
            data = None
        else:
            reason = BMP_PEER_DOWN_REASON_UNKNOWN
            data = buf

        kwargs['reason'] = reason
        kwargs['data'] = data

        return kwargs