Ejemplo n.º 1
0
IUserPacket::IUserPacket(LPCTSTR xUserId, LPCTSTR xPass) : IPacket( ICP_USER )
{
	MD5 ctx; BYTE xMD5Hash[16];
	ctx.update( (LPBYTE)xPass, _tcslen(xPass) );
	ctx.finalize(); ctx.raw_digest( xMD5Hash );
	
	CopyMemory( UserId, xUserId, 21 );
	ctx.tostring( (LPBYTE)MD5Hashing );
}
Ejemplo n.º 2
0
int CalcHashBytes(LPTSTR xHashing, LPCTSTR xString)
{
	MD5 ctx; BYTE pHash[16];
	ctx.update( (LPBYTE)xString, _tcslen(xString) );
	ctx.finalize(); ctx.raw_digest( pHash );
	
	ctx.tostring( (LPBYTE)xHashing );
	return 32;
}
Ejemplo n.º 3
0
void FileCodeWriter::WriteBuffer()
{
	const static unsigned char MICROSOFT_BOM[3] = { 0xEF, 0xBB, 0xBF };

	// Compare buffer with existing file (if any) to determine if
	// writing the file is necessary
	bool shouldWrite = true;
	std::ifstream fileIn(m_filename.mb_str(wxConvFile), std::ios::binary | std::ios::in);

	std::string buf;

	if (fileIn)
	{
		MD5 diskHash(fileIn);
		unsigned char* diskDigest = diskHash.raw_digest();

		MD5 bufferHash;
		if (m_useMicrosoftBOM) {
			bufferHash.update(MICROSOFT_BOM, 3);
		}
		const std::string& data = m_useUtf8 ? _STDSTR( m_buffer ) : _ANSISTR( m_buffer );

		if (!m_useUtf8) buf = data;

		bufferHash.update( reinterpret_cast< const unsigned char* >( data.c_str() ), data.size() );

		bufferHash.finalize();

		unsigned char* bufferDigest = bufferHash.raw_digest();

		shouldWrite = ( 0 != std::memcmp( diskDigest, bufferDigest, 16 ) );

		delete [] diskDigest;

		delete [] bufferDigest;
	}

	if ( shouldWrite )
	{
		wxFile fileOut;
		if (!fileOut.Create(m_filename, true))
		{
			wxLogError( _("Unable to create file: %s"), m_filename.c_str() );
			return;
		}

		if (m_useMicrosoftBOM)
		{
			fileOut.Write(MICROSOFT_BOM, 3);
		}

		if (!m_useUtf8)
			fileOut.Write(buf.c_str(), buf.length());
		else
			fileOut.Write(m_buffer);
	}
}
Ejemplo n.º 4
0
/**
 * Generate BMP router HASH
 *
 * \param [in,out] client   Reference to client info used to generate the hash.
 *
 * \return client.hash_id will be updated with the generated hash
 */
void BMPListener::hashRouter(ClientInfo &client) {
    string c_hash_str;
    MsgBusInterface::hash_toStr(cfg->c_hash_id, c_hash_str);

    MD5 hash;
    hash.update((unsigned char *)client.c_ip, strlen(client.c_ip));
    hash.update((unsigned char *)c_hash_str.c_str(), c_hash_str.length());
    hash.finalize();

    // Save the hash
    unsigned char *hash_bin = hash.raw_digest();
    memcpy(client.hash_id, hash_bin, 16);
    delete[] hash_bin;
}
Ejemplo n.º 5
0
/**
 * Run Server loop
 *
 * \param [in]  cfg    Reference to the config options
 */
void runServer(Cfg_Options &cfg) {
    msgBus_kafka *kafka;
    int active_connections = 0;                 // Number of active connections/threads
    time_t last_heartbeat_time = 0;

    LOG_INFO("Initializing server");

    try {
        // Define the collector hash
        MD5 hash;
        hash.update((unsigned char *)cfg.admin_id, strlen(cfg.admin_id));
        hash.finalize();

        // Save the hash
        unsigned char *hash_raw = hash.raw_digest();
        memcpy(cfg.c_hash_id, hash_raw, 16);
        delete[] hash_raw;


        // Kafka connection
        kafka = new msgBus_kafka(logger, cfg.kafka_brokers, cfg.c_hash_id);

        // allocate and start a new bmp server
        BMPListener *bmp_svr = new BMPListener(logger, &cfg);

        BMPListener::ClientInfo client;
        collector_update_msg(kafka, cfg, client, MsgBusInterface::COLLECTOR_ACTION_STARTED);
        last_heartbeat_time = time(NULL);

        LOG_INFO("Ready. Waiting for connections");

        // Loop to accept new connections
        while (run) {
            /*
             * Check for any stale threads/connections
             */
             for (size_t i=0; i < thr_list.size(); i++) {

                // If thread is not running, it means it terminated, so close it out
                if (!thr_list.at(i)->running) {

                    // Join the thread to clean up
                    pthread_join(thr_list.at(i)->thr, NULL);
                    --active_connections;

                    collector_update_msg(kafka, cfg, thr_list.at(i)->client,
                                         MsgBusInterface::COLLECTOR_ACTION_CHANGE);

                    // free the vector entry
                    delete thr_list.at(i);
                    thr_list.erase(thr_list.begin() + i);
                }

                //TODO: Add code to check for a socket that is open, but not really connected/half open
            }

            /*
             * Create a new client thread if we aren't at the max number of active sessions
             */
            if (active_connections <= MAX_THREADS) {
                ThreadMgmt *thr = new ThreadMgmt;
                thr->cfg = &cfg;
                thr->log = logger;

                // wait for a new connection and accept
                if (bmp_svr->wait_and_accept_connection(thr->client, 500)) {
                    // Bump the current thread count
                    ++active_connections;

                    LOG_INFO("Accepted new connection; active connections = %d", active_connections);

                    /*
                     * Start a new thread for every new router connection
                     */
                    LOG_INFO("Client Connected => %s:%s, sock = %d",
                             thr->client.c_ip, thr->client.c_port, thr->client.c_sock);

                    pthread_attr_t thr_attr;            // thread attribute
                    pthread_attr_init(&thr_attr);
                    //pthread_attr_setdetachstate(&thr.thr_attr, PTHREAD_CREATE_DETACHED);
                    pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_JOINABLE);
                    thr->running = 1;

                    // Start the thread to handle the client connection
                    pthread_create(&thr->thr, &thr_attr,
                                   ClientThread, thr);

                    // Add thread to vector
                    thr_list.insert(thr_list.end(), thr);

                    // Free attribute
                    pthread_attr_destroy(&thr_attr);

                    collector_update_msg(kafka, cfg, thr->client,
                                         MsgBusInterface::COLLECTOR_ACTION_CHANGE);

                    last_heartbeat_time = time(NULL);
                }
                else {
                    delete thr;

                    // Send heartbeat if needed
                    if ( (time(NULL) - last_heartbeat_time) >= cfg.heartbeat_interval) {
                        BMPListener::ClientInfo client;
                        collector_update_msg(kafka, cfg, client, MsgBusInterface::COLLECTOR_ACTION_HEARTBEAT);
                        last_heartbeat_time = time(NULL);
                    }

                    usleep(10000);
                }

            } else {
                LOG_WARN("Reached max number of threads, cannot accept new BMP connections at this time.");
                sleep (1);
            }
        }

        collector_update_msg(kafka, cfg, client, MsgBusInterface::COLLECTOR_ACTION_STOPPED);
        delete kafka;

    } catch (char const *str) {
        LOG_WARN(str);
    }
}
Ejemplo n.º 6
0
/**
* Parses the BGP attributes in the update
*
* \details
*     Parses all attributes.  Decoded values are updated in 'parsed_data'
*
* \param [in]   data       Pointer to the start of the prefixes to be parsed
* \param [in]   len        Length of the data in bytes to be read
* \param [out]  parsed_update  Reference to parsed_update; will be updated with all parsed data
*/
void parseBgpLib::parseBgpAttr(u_char *data, uint16_t len, parsed_update &update) {
    /*
     * Per RFC4271 Section 4.3, flag indicates if the length is 1 or 2 octets
     */
    u_char attr_flags;
    u_char attr_type;
    uint16_t attr_len;

    if (len == 0)
        return;

    else if (len < 3) {
        LOG_WARN("%sCannot parse the attributes due to the data being too short, error in update message. len=%d",
                 debug_prepend_string.c_str(), len);
        return;
    }

        // Generate the hash
        MD5 hash;

     /*
     * Iterate through all attributes and parse them
     */
    for (int read_size = 0; read_size < len; read_size += 2) {
        attr_flags = *data++;
        attr_type = *data++;

        // Check if the length field is 1 or two bytes
        if (ATTR_FLAG_EXTENDED(attr_flags)) {
            SELF_DEBUG("%sExtended length path attribute bit set for an entry", debug_prepend_string.c_str());
            memcpy(&attr_len, data, 2);
            data += 2;
            read_size += 2;
            parse_bgp_lib::SWAP_BYTES(&attr_len);
        } else
            attr_len = *data++;
        read_size++;

        // Get the attribute data, if we have any; making sure to not overrun buffer
        if (attr_len > 0 and (read_size + attr_len) <= len) {
            // Data pointer is currently at the data position of the attribute

            /*
             * Parse data based on attribute type
             */
            parseAttrData(attr_type, attr_len, data, update, hash);
            data += attr_len;
            read_size += attr_len;

            SELF_DEBUG("%sParsed attr Type=%d, size=%hu", debug_prepend_string.c_str(), attr_type, attr_len);
        } else if (attr_len) {
            LOG_NOTICE("%sAttribute data len of %hu is larger than available data in update message of %hu",
                       debug_prepend_string.c_str(), attr_len, (len - read_size));
            return;
        }
    }
        //Now save the generate hash
        hash.finalize();

        // Save the hash
        unsigned char *hash_raw = hash.raw_digest();
        update.attrs[LIB_ATTR_BASE_ATTR_HASH].name = parse_bgp_lib::parse_bgp_lib_attr_names[LIB_ATTR_BASE_ATTR_HASH];
        update.attrs[LIB_ATTR_BASE_ATTR_HASH].value.push_back(parse_bgp_lib::hash_toStr(hash_raw));
        delete[] hash_raw;

    }
Ejemplo n.º 7
0
    /**
* Parses the BGP prefixes (advertised and withdrawn) in the update
*
* \details
*     Parses all attributes.  Decoded values are updated in 'parsed_data'
*
* \param [in]   data       Pointer to the start of the prefixes to be parsed
* \param [in]   len        Length of the data in bytes to be read
* \param [in]   nlri_list Reference to parsed_update_data nlri list;
*/
void parseBgpLib::parseBgpNlri_v4(u_char *data, uint16_t len, std::list<parse_bgp_lib_nlri> &nlri_list) {
    u_char ipv4_raw[4];
    char ipv4_char[16];
    u_char addr_bytes;
    uint32_t path_id;
    u_char prefix_len;
    std::ostringstream numString;


    if (len <= 0 or data == NULL)
        return;

        // Loop through all prefixes
    for (size_t read_size = 0; read_size < len; read_size++) {
        parse_bgp_lib_nlri nlri;
        nlri.afi = parse_bgp_lib::BGP_AFI_IPV4;
        nlri.safi = parse_bgp_lib::BGP_SAFI_UNICAST;
        nlri.type = parse_bgp_lib::LIB_NLRI_TYPE_NONE;

        // Generate the hash
        MD5 hash;

        bzero(ipv4_raw, sizeof(ipv4_raw));

        // Parse add-paths if enabled
        bool peer_info_addpath = p_info and p_info->add_path_capability.isAddPathEnabled(bgp::BGP_AFI_IPV4, bgp::BGP_SAFI_UNICAST);

        if ((peer_info_addpath or addPathCap[BGP_AFI_IPV4_INTERNAL][BGP_SAFI_UNICAST_INTERNAL])
            and (len - read_size) >= 4) {
            memcpy(&path_id, data, 4);
            parse_bgp_lib::SWAP_BYTES(&path_id);
            data += 4;
            read_size += 4;
        } else
            path_id = 0;
        numString.str(std::string());
        numString << path_id;
        nlri.nlri[LIB_NLRI_PATH_ID].name = parse_bgp_lib::parse_bgp_lib_nlri_names[LIB_NLRI_PATH_ID];
        nlri.nlri[LIB_NLRI_PATH_ID].value.push_back(numString.str());

        if (path_id > 0)
            update_hash(&nlri.nlri[LIB_NLRI_PATH_ID].value, &hash);

        // set the address in bits length
        prefix_len = *data++;
        numString.str(std::string());
        numString << static_cast<unsigned>(prefix_len);

        nlri.nlri[LIB_NLRI_PREFIX_LENGTH].name = parse_bgp_lib::parse_bgp_lib_nlri_names[LIB_NLRI_PREFIX_LENGTH];
        nlri.nlri[LIB_NLRI_PREFIX_LENGTH].value.push_back(numString.str());
        update_hash(&nlri.nlri[LIB_NLRI_PREFIX_LENGTH].value, &hash);

        // Figure out how many bytes the bits requires
        addr_bytes = prefix_len / 8;
        if (prefix_len % 8)
            ++addr_bytes;

        SELF_DEBUG("%sReading NLRI data prefix bits=%d bytes=%d", debug_prepend_string.c_str(), prefix_len, addr_bytes);

        if (addr_bytes <= 4) {
            memcpy(ipv4_raw, data, addr_bytes);
            read_size += addr_bytes;
            data += addr_bytes;

            // Convert the IP to string printed format
            inet_ntop(AF_INET, ipv4_raw, ipv4_char, sizeof(ipv4_char));
            nlri.nlri[LIB_NLRI_PREFIX].name = parse_bgp_lib::parse_bgp_lib_nlri_names[LIB_NLRI_PREFIX];
            nlri.nlri[LIB_NLRI_PREFIX].value.push_back(ipv4_char);
            update_hash(&nlri.nlri[LIB_NLRI_PREFIX].value, &hash);
            SELF_DEBUG("%sAdding prefix %s len %d", debug_prepend_string.c_str(), ipv4_char, prefix_len);

            // set the raw/binary address
            nlri.nlri[LIB_NLRI_PREFIX_BIN].name = parse_bgp_lib::parse_bgp_lib_nlri_names[LIB_NLRI_PREFIX_BIN];
            nlri.nlri[LIB_NLRI_PREFIX_BIN].value.push_back(std::string(ipv4_raw, ipv4_raw + 4));

            //Update hash to include peer hash id
            if (p_info)
                hash.update((unsigned char *) p_info->peer_hash_str.c_str(), p_info->peer_hash_str.length());

            hash.finalize();

            // Save the hash
            unsigned char *hash_raw = hash.raw_digest();
            nlri.nlri[LIB_NLRI_HASH].name = parse_bgp_lib::parse_bgp_lib_nlri_names[LIB_NLRI_HASH];
            nlri.nlri[LIB_NLRI_HASH].value.push_back(parse_bgp_lib::hash_toStr(hash_raw));
            delete[] hash_raw;

            nlri.nlri[LIB_NLRI_IS_IPV4].name =parse_bgp_lib_nlri_names[LIB_NLRI_IS_IPV4];
            nlri.nlri[LIB_NLRI_IS_IPV4].value.push_back(string("1"));

            // Add tuple to prefix list
            nlri_list.push_back(nlri);
        } else if (addr_bytes > 4) {
            LOG_NOTICE("%sNRLI v4 address is larger than 4 bytes bytes=%d len=%d", debug_prepend_string.c_str(), addr_bytes, prefix_len);
        }
    }
}
Ejemplo n.º 8
0
/**
 * Abstract method Implementation - See DbInterface.hpp for details
 */
void mysqlBMP::add_PathAttrs(tbl_path_attr &path_entry) {
    try {
        char    buf[64000];                 // Misc working buffer
        char    buf2[24000];                // Second working buffer
        size_t  buf_len;                    // size of the query buff

        // Setup the initial MySQL query
        buf_len =
                sprintf(buf, "INSERT into %s (%s) values ", TBL_NAME_PATH_ATTRS,
                        "hash_id,peer_hash_id,origin,as_path,next_hop,med,local_pref,isAtomicAgg,aggregator,community_list,ext_community_list,cluster_list,originator_id,origin_as,as_path_count,timestamp");

        /*
         * Generate router table hash from the following fields
         *     peer_hash_id, as_path, next_hop, aggregator,
         *     origin, med, local_pref
         *
         */
        MD5 hash;

        // Generate the hash
        hash.update(path_entry.peer_hash_id, HASH_SIZE);
        hash.update((unsigned char *) path_entry.as_path,
                strlen(path_entry.as_path));
        hash.update((unsigned char *) path_entry.next_hop,
                strlen(path_entry.next_hop));
        hash.update((unsigned char *) path_entry.aggregator,
                strlen(path_entry.aggregator));
        hash.update((unsigned char *) path_entry.origin,
                strlen(path_entry.origin));
        hash.update((unsigned char *) &path_entry.med, sizeof(path_entry.med));
        hash.update((unsigned char *) &path_entry.local_pref,
                sizeof(path_entry.local_pref));
        hash.finalize();

        // Save the hash
        unsigned char *hash_raw = hash.raw_digest();
        memcpy(path_entry.hash_id, hash_raw, 16);
        delete[] hash_raw;

        // Build the query
        string path_hash_str;
        string p_hash_str;
        hash_toStr(path_entry.hash_id, path_hash_str);
        hash_toStr(path_entry.peer_hash_id, p_hash_str);

        buf_len +=
                snprintf(buf2, sizeof(buf2),
                        "('%s','%s','%s','%s','%s', %u,%u,%d,'%s','%s','%s','%s','%s','%"PRIu32"','%hu', from_unixtime(%u)),",
                        path_hash_str.c_str(), p_hash_str.c_str(),
                        path_entry.origin, path_entry.as_path,
                        path_entry.next_hop, path_entry.med,
                        path_entry.local_pref, path_entry.atomic_agg,
                        path_entry.aggregator, path_entry.community_list,
                        path_entry.ext_community_list, path_entry.cluster_list,
                        path_entry.originator_id, path_entry.origin_as,
                        path_entry.as_path_count,
                        path_entry.timestamp_secs);

        // Cat the string to our query buffer
        if (buf_len < sizeof(buf))
            strcat(buf, buf2);

        // Remove the last comma since we don't need it
        buf[buf_len - 1] = 0;

        // Add the on duplicate statement
        snprintf(buf2, sizeof(buf2),
                " ON DUPLICATE KEY UPDATE timestamp=values(timestamp)  ");
        strcat(buf, buf2);

        SELF_DEBUG("QUERY=%s\n", buf);

        // Run the query to add the record
        stmt = con->createStatement();
        stmt->execute(buf);

        // Free the query statement
        delete stmt;

    } catch (sql::SQLException &e) {
        LOG_ERR("mysql error: %s, error Code = %d, state = %s",
                e.what(), e.getErrorCode(), e.getSQLState().c_str() );
    }
}
Ejemplo n.º 9
0
/**
 * Abstract method Implementation - See DbInterface.hpp for details
 */
void mysqlBMP::add_Rib(vector<tbl_rib> &rib_entry) {
    char    *buf = new char[800000];            // Misc working buffer
    char    buf2[4096];                         // Second working buffer
    size_t  buf_len = 0;                        // query buffer length

    try {

        // Build the initial part of the query
        //buf_len = sprintf(buf, "REPLACE into %s (%s) values ", TBL_NAME_RIB,
        //        "hash_id,path_attr_hash_id,peer_hash_id,prefix, prefix_len");
        buf_len = sprintf(buf, "INSERT into %s (%s) values ", TBL_NAME_RIB,
                "hash_id,path_attr_hash_id,peer_hash_id,prefix, prefix_len,timestamp");

        string rib_hash_str;
        string path_hash_str;
        string p_hash_str;

        // Loop through the vector array of rib entries
        for (size_t i = 0; i < rib_entry.size(); i++) {
            /*
             * Generate router table hash from the following fields
             *     rib_entry.peer_hash_id, rib_entry.prefix, rib_entry.prefix_len
             *
             */
            MD5 hash;

            // Generate the hash

            hash.update(rib_entry[i].peer_hash_id, HASH_SIZE);
            hash.update((unsigned char *) rib_entry[i].prefix,
                    strlen(rib_entry[i].prefix));
            hash.update(&rib_entry[i].prefix_len,
                    sizeof(rib_entry[i].prefix_len));
            hash.finalize();

            // Save the hash
            unsigned char *hash_raw = hash.raw_digest();
            memcpy(rib_entry[i].hash_id, hash_raw, 16);
            delete[] hash_raw;

            // Build the query
            hash_toStr(rib_entry[i].hash_id, rib_hash_str);
            hash_toStr(rib_entry[i].path_attr_hash_id, path_hash_str);
            hash_toStr(rib_entry[i].peer_hash_id, p_hash_str);

            buf_len += snprintf(buf2, sizeof(buf2),
                    " ('%s','%s','%s','%s', %d, from_unixtime(%u)),", rib_hash_str.c_str(),
                    path_hash_str.c_str(), p_hash_str.c_str(),
                    rib_entry[i].prefix, rib_entry[i].prefix_len,
                    rib_entry[i].timestamp_secs);

            // Cat the entry to the query buff
            if (buf_len < 800000 /* size of buf */)
                strcat(buf, buf2);
        }

        // Remove the last comma since we don't need it
        buf[buf_len - 1] = 0;

        // Add the on duplicate statement
        snprintf(buf2, sizeof(buf2),
                " ON DUPLICATE KEY UPDATE timestamp=values(timestamp),path_attr_hash_id=values(path_attr_hash_id),db_timestamp=current_timestamp");
        strcat(buf, buf2);


        SELF_DEBUG("QUERY=%s", buf);

        // Run the query to add the record
        stmt = con->createStatement();
        stmt->execute(buf);

        // Free the query statement
        delete stmt;

    } catch (sql::SQLException &e) {
        LOG_ERR("mysql error: %s, error Code = %d, state = %s",
                e.what(), e.getErrorCode(), e.getSQLState().c_str() );
    }

    // Free the large buffer
    delete[] buf;
}
Ejemplo n.º 10
0
/**
 * Abstract method Implementation - See DbInterface.hpp for details
 */
void mysqlBMP::add_Router(tbl_router &r_entry) {
    try {
        char buf[4096]; // Misc working buffer

        /*
         * Generate router table hash from the following fields
         *     r_entry.name, r_entry.src_addr
         *
         */
        MD5 hash;

        // Generate the hash
        //hash.update (r_entry.name, strlen((char *)r_entry.name));
        hash.update(r_entry.src_addr, strlen((char *) r_entry.src_addr));
        hash.finalize();

        // Save the hash
        unsigned char *hash_raw = hash.raw_digest();
        memcpy(r_entry.hash_id, hash_raw, 16);
        delete [] hash_raw;

        // Convert binary hash to string
        string r_hash_str;
        hash_toStr(r_entry.hash_id, r_hash_str);

        // Check if we have already processed this entry, if so update it an return
        if (router_list.find(r_hash_str) != router_list.end()) {
            router_list[r_hash_str] = time(NULL);
            return;
        }

        // Insert/Update map entry
        router_list[r_hash_str] = time(NULL);

        // Convert the init data to string for storage
        string initData(r_entry.initiate_data);
        std::replace(initData.begin(), initData.end(), '\'', '"');

        // Build the query
        snprintf(buf, sizeof(buf),
                "INSERT into %s (%s) values ('%s', '%s', '%s','%s','%s')",
                TBL_NAME_ROUTERS, "hash_id,name,description,ip_address,init_data", r_hash_str.c_str(),
                r_entry.name, r_entry.descr, r_entry.src_addr, initData.c_str());

        // Add the on duplicate statement
        strcat(buf, " ON DUPLICATE KEY UPDATE timestamp=current_timestamp,isConnected=1,name=values(name),description=values(description),init_data=values(init_data)");

        // Run the query to add the record
        stmt = con->createStatement();
        stmt->execute(buf);

        // Update all peers to indicate peers are not up - till proven other wise
        snprintf(buf, sizeof(buf), "UPDATE %s SET state=0 where router_hash_id='%s'",
                TBL_NAME_BGP_PEERS, r_hash_str.c_str());
        stmt->execute(buf);

        // Free the query statement
        delete stmt;

    } catch (sql::SQLException &e) {
        LOG_ERR("mysql error: %s, error Code = %d, state = %s",
                e.what(), e.getErrorCode(), e.getSQLState().c_str() );

    }
}
Ejemplo n.º 11
0
/**
 * Abstract method Implementation - See DbInterface.hpp for details
 */
void mysqlBMP::add_Peer(tbl_bgp_peer &p_entry) {
    try {
        char buf[4096]; // Misc working buffer

        /*
         * Generate peer table hash from the following fields
         *  p_entry.router_hash_id, p_entry.peer_rd, p_entry.peer_addr,
         *         p_entry.peer_bgp_id
         *
         */
        MD5 hash;

        // Generate the hash
        hash.update(p_entry.router_hash_id, HASH_SIZE);
        hash.update((unsigned char *) p_entry.peer_rd, strlen(p_entry.peer_rd));
        hash.update((unsigned char *) p_entry.peer_addr,
                strlen(p_entry.peer_addr));
        hash.update((unsigned char *) p_entry.peer_bgp_id,
                strlen(p_entry.peer_bgp_id));
        hash.finalize();

        // Save the hash
        unsigned char *hash_raw = hash.raw_digest();
        memcpy(p_entry.hash_id, hash_raw, 16);
        delete[] hash_raw;

        // Convert binary hash to string
        string p_hash_str;
        hash_toStr(p_entry.hash_id, p_hash_str);
        string r_hash_str;
        hash_toStr(p_entry.router_hash_id, r_hash_str);

        // Check if we have already processed this entry, if so update it an return
        if (peer_list.find(p_hash_str) != peer_list.end()) {
            peer_list[p_hash_str] = time(NULL);
            return;
        }

        // Insert/Update map entry
        peer_list[p_hash_str] = time(NULL);

        // Build the query
        snprintf(buf, sizeof(buf),
                "REPLACE into %s (%s) values ('%s','%s','%s',%d, '%s', '%s', %u, %d, %d, current_timestamp,1)",
                TBL_NAME_BGP_PEERS,
                "hash_id,router_hash_id, peer_rd,isIPv4,peer_addr,peer_bgp_id,peer_as,isL3VPNpeer,isPrePolicy,timestamp,state",
                p_hash_str.c_str(), r_hash_str.c_str(), p_entry.peer_rd,
                p_entry.isIPv4, p_entry.peer_addr, p_entry.peer_bgp_id,
                p_entry.peer_as, p_entry.isL3VPN, p_entry.isPrePolicy);

        SELF_DEBUG("QUERY=%s", buf);

        // Run the query to add the record
        stmt = con->createStatement();
        stmt->execute(buf);

        // Free the query statement
        delete stmt;

    } catch (sql::SQLException &e) {
        LOG_ERR("mysql error: %s, error Code = %d, state = %s",
                e.what(), e.getErrorCode(), e.getSQLState().c_str() );
    }
}