Exemplo n.º 1
0
 def send_route_refresh(self, afi, safi, res=0):
     """
     Send bgp route refresh message
     :param afi: address family
     :param safi: sub address family
     :param res: reserve, default is 0
     """
     # check if the peer support route refresh
     if 'cisco_route_refresh' in cfg.CONF.bgp.running_config['capability'][
             'remote']:
         type_code = bgp_cons.MSG_CISCOROUTEREFRESH
     elif 'route_refresh' in cfg.CONF.bgp.running_config['capability'][
             'remote']:
         type_code = bgp_cons.MSG_ROUTEREFRESH
     else:
         return False
     # check if the peer support this address family
     if (afi, safi) not in cfg.CONF.bgp.running_config['capability'][
             'remote']['afi_safi']:
         return False
     # construct message
     msg_routerefresh = RouteRefresh(afi, safi, res).construct(type_code)
     # send message
     self.transport.write(msg_routerefresh)
     self.msg_sent_stat['RouteRefresh'] += 1
     LOG.info("[%s]Send BGP RouteRefresh message to the peer.",
              self.factory.peer_addr)
     return True
Exemplo n.º 2
0
    def test_construct_cisco_route_refresh(self):

        msg = (1, 0, 128)
        msg_hex = RouteRefresh(afi=msg[0], res=msg[1],
                               safi=msg[2]).construct(MSG_CISCOROUTEREFRESH)
        msg_hoped = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x17\x80\x00\x01\x00\x80'
        self.assertEqual(msg_hoped, msg_hex)
Exemplo n.º 3
0
Arquivo: bmp.py Projeto: jumeng/yabmp
 def parse_route_monitoring_msg(msg):
     """
         Route Monitoring messages are used for initial synchronization of
     ADJ-RIBs-In. They are also used for ongoing monitoring of received
     advertisements and withdraws.
     Following the common BMP header and per-peer header is a BGP Update
     PDU.
     :param msg:
     :return:
     """
     LOG.debug('decode route monitoring message')
     bgp_msg_type = struct.unpack('!B', msg[18])[0]
     LOG.debug('bgp message type=%s' % bgp_msg_type)
     msg = msg[bgp_cons.HDR_LEN:]
     if bgp_msg_type == 2:
         # decode update message
         results = Update().parse(None, msg, asn4=True)
         if results['sub_error']:
             LOG.error(
                 'error: decode update message error!, error code: %s' %
                 results['sub_error'])
             LOG.error('Raw data: %s' % repr(results['hex']))
             return None
         return_result = {
             'attr': results['attr'],
             'nlri': results['nlri'],
             'withdraw': results['withdraw']
         }
         LOG.debug('bgp update message: %s' % return_result)
         return bgp_msg_type, return_result
     elif bgp_msg_type == 5:
         bgp_route_refresh_msg = RouteRefresh().parse(msg=msg)
         LOG.debug('bgp route refresh message: afi=%s,res=%s,safi=%s' %
                   (bgp_route_refresh_msg[0], bgp_route_refresh_msg[1],
                    bgp_route_refresh_msg[2]))
         return bgp_msg_type, {
             'afi': bgp_route_refresh_msg[0],
             'sub_type': bgp_route_refresh_msg[1],
             'safi': bgp_route_refresh_msg[2]
         }
Exemplo n.º 4
0
Arquivo: bmp.py Projeto: jumeng/yabmp
    def parse_route_mirroring_msg(msg):
        """
            Route Mirroring messages are used for verbatim duplication of
        messages as received. Following the common BMP header and per-peer
        header is a set of TLVs that contain information about a message
        or set of messages.
        :param msg:
        :return:
        """
        LOG.debug('decode route mirroring message')

        msg_dict = {}
        open_l = []
        update = []
        notification = []
        route_refresh = []
        while msg:
            mirror_type, length = struct.unpack('!HH', msg[0:4])
            mirror_value = msg[4:4 + length]
            msg = msg[4 + length:]
            if mirror_type == 0:
                # BGP message type
                bgp_msg_type = struct.unpack('!B', mirror_value[18])[0]
                LOG.debug('bgp message type=%s' % bgp_msg_type)
                bgp_msg_body = mirror_value[bgp_cons.HDR_LEN:]
                if bgp_msg_type == 2:
                    # Update message
                    bgp_update_msg = Update().parse(None,
                                                    bgp_msg_body,
                                                    asn4=True)
                    if bgp_update_msg['sub_error']:
                        LOG.error(
                            'error: decode update message error!, error code: %s'
                            % bgp_update_msg['sub_error'])
                        LOG.error('Raw data: %s' % repr(bgp_update_msg['hex']))
                    else:
                        update.append(bgp_update_msg)
                elif bgp_msg_type == 5:
                    # Route Refresh message
                    bgp_route_refresh_msg = RouteRefresh().parse(
                        msg=bgp_msg_body)
                    LOG.debug(
                        'bgp route refresh message: afi=%s,res=%s,safi=%s' %
                        (bgp_route_refresh_msg[0], bgp_route_refresh_msg[1],
                         bgp_route_refresh_msg[2]))
                    route_refresh.append(bgp_route_refresh_msg)
                elif bgp_msg_type == 1:
                    # Open message
                    open_msg = Open().parse(bgp_msg_body)
                    open_l.append(open_msg)
                elif bgp_msg_type == 3:
                    # Notification message
                    notification_msg = Notification().parse(bgp_msg_body)
                    notification.append(notification_msg)
            elif mirror_type == 1:
                # Information type.
                # Amount of this TLV is not specified but we can assume
                # only one per mirroring message is present.
                info_code_type = struct.unpack('!H', mirror_value)[0]
                msg_dict['1'] = info_code_type
            else:
                msg_dict[mirror_type] = binascii.unhexlify(
                    binascii.hexlify(mirror_value))
                LOG.info('unknow mirroring type, type = %s' % mirror_type)

        msg_dict['0'] = {
            'update': update,
            'route_refresh': route_refresh,
            'open': open_l,
            'notification': notification
        }
        return msg_dict
Exemplo n.º 5
0
    def parse_buffer(self):
        """
        Parse TCP buffer data.

        :return: True or False
        """
        buf = self._receive_buffer

        if len(buf) < bgp_cons.HDR_LEN:
            # Every BGP message is at least 19 octets. Maybe the rest
            # hasn't arrived yet.
            return False

        # Check whether the first 16 octets of the buffer consist of
        # the BGP marker (all bits one)
        if buf[:16] != 16 * b'\xff':
            self.fsm.header_error(bgp_cons.ERR_MSG_HDR_CONN_NOT_SYNC)
            return False
            # Parse the BGP header
        try:
            marker, length, msg_type = struct.unpack('!16sHB',
                                                     buf[:bgp_cons.HDR_LEN])
        except Exception as e:
            LOG.error(e)
            error_str = traceback.format_exc()
            LOG.debug(error_str)
            self.fsm.header_error(bgp_cons.ERR_MSG_HDR_CONN_NOT_SYNC)
            return False
            # Check the length of the message, must be less than 4096, bigger than 19
        if length < bgp_cons.HDR_LEN or length > bgp_cons.MAX_LEN:
            self.fsm.header_error(bgp_cons.ERR_MSG_HDR_BAD_MSG_LEN,
                                  struct.pack('!H', length))
            # Check whether the entire message is already available
        if len(buf) < length:
            return False
        msg = buf[bgp_cons.HDR_LEN:length]
        t = time.time()  # the time when received that packet.
        try:
            if msg_type == bgp_cons.MSG_OPEN:
                try:
                    self._open_received(timestamp=t, msg=msg)
                except excep.MessageHeaderError as e:
                    LOG.error(e)
                    self.fsm.header_error(suberror=e.sub_error)
                    return False
                except excep.OpenMessageError as e:
                    LOG.error(e)
                    self.fsm.open_message_error(suberror=e.sub_error)
                    return False

            elif msg_type == bgp_cons.MSG_UPDATE:
                self._update_received(timestamp=t, msg=msg)

            elif msg_type == bgp_cons.MSG_NOTIFICATION:
                self._notification_received(Notification().parse(msg))

            elif msg_type == bgp_cons.MSG_KEEPALIVE:
                try:
                    self._keepalive_received(timestamp=t, msg=msg)
                except excep.MessageHeaderError as e:
                    LOG.error(e)
                    self.fsm.header_error(suberror=e.sub_error)
                    return False
            elif msg_type in (bgp_cons.MSG_ROUTEREFRESH,
                              bgp_cons.MSG_CISCOROUTEREFRESH):
                route_refresh_msg = RouteRefresh().parse(msg)
                self._route_refresh_received(msg=route_refresh_msg,
                                             msg_type=msg_type)
            else:
                # unknown message type
                self.fsm.header_error(bgp_cons.ERR_MSG_HDR_BAD_MSG_TYPE,
                                      struct.pack('!H', msg_type))
        except Exception as e:
            LOG.error(e)
            error_str = traceback.format_exc()
            LOG.debug(error_str)
        self._receive_buffer = self._receive_buffer[length:]
        return True
Exemplo n.º 6
0
    def test_parse(self):

        msg_hex = b'\x00\x01\x00\x80'
        msg_parsed = RouteRefresh().parse(msg_hex)
        msg_hoped = (1, 0, 128)
        self.assertEqual(msg_hoped, msg_parsed)