⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 peer.cc

📁 xorp源码hg
💻 CC
📖 第 1 页 / 共 4 页
字号:
    mrt_update update;    memset(&update, 0, sizeof(update));    update.af = htons(1);	/* IPv4 */    if(fwrite(&update, sizeof(update), 1, fp) != 1)	XLOG_FATAL("fwrite of %s failed: %s", fname.c_str(), strerror(errno));    if(fwrite(buf, len, 1, fp) != 1)	XLOG_FATAL("fwrite of %s failed: %s", fname.c_str(), strerror(errno));    fclose(fp);}template <class A>voidmrtd_routview_dump(const  UpdatePacket* p, const IPNet<A>& net,		   const TimeVal tv, const string fname, const int sequence){    FILE *fp = fopen(fname.c_str(), "a");    if(0 == fp)	XLOG_FATAL("fopen of %s failed: %s", fname.c_str(), strerror(errno));    /*    ** Figure out the total length of the attributes.    */    uint16_t length = 0;        list <PathAttribute*>::const_iterator pai;    for (pai = p->pa_list().begin(); pai != p->pa_list().end(); pai++) {	const PathAttribute* pa;	pa = *pai;	length += pa->wire_size();    }    /*    ** Due to alignment problems I can't use a structure overlay.    */    uint8_t viewbuf[18 + A::addr_bytelen()], *ptr;    mrt_header header;    header.time = /*htonl(tv.sec())*/0;    header.type = htons(12);    if(4 == A::ip_version())	header.subtype = htons(AFI_IPV4);    else if(6 == A::ip_version())	header.subtype = htons(AFI_IPV6);    else	XLOG_FATAL("unknown ip version %d", XORP_UINT_CAST(A::ip_version()));    header.length = htonl(length + sizeof(viewbuf));        if(fwrite(&header, sizeof(header), 1, fp) != 1)	XLOG_FATAL("fwrite of %s failed: %s", fname.c_str(), strerror(errno));    memset(&viewbuf[0], 0, sizeof(viewbuf));    ptr = &viewbuf[0];    // View number    embed_16(ptr, 0);    ptr += 2;    // Sequence number    embed_16(ptr, sequence);    ptr += 2;    // Prefix    net.masked_addr().copy_out(ptr);    ptr += A::addr_bytelen();    // Prefix length    *reinterpret_cast<uint8_t *>(ptr) = net.prefix_len();    ptr += 1;    // Status    *reinterpret_cast<uint8_t *>(ptr) = 0x1;    ptr += 1;    // Uptime    embed_32(ptr, tv.sec());    ptr += 4;    // Peer address    embed_32(ptr, 0);    ptr += 4;    // Peer AS    embed_16(ptr, 0);    ptr += 2;    // Attribute length    embed_16(ptr, length);    ptr += 2;    XLOG_ASSERT(ptr == &viewbuf[sizeof(viewbuf)]);    if(fwrite(&viewbuf[0], sizeof(viewbuf), 1, fp) != 1)	XLOG_FATAL("fwrite of %s failed: %s", fname.c_str(), strerror(errno));    for (pai = p->pa_list().begin(); pai != p->pa_list().end(); pai++) {	const PathAttribute* pa;	pa = *pai;	if(fwrite(pa->data(), pa->wire_size(), 1, fp) != 1)	    XLOG_FATAL("fwrite of %s failed: %s", fname.c_str(),		       strerror(errno));    }    fclose(fp);}voidtext_traffic_dump(const uint8_t *buf, const size_t len, const TimeVal, 	  const string fname){    FILE *fp = fopen(fname.c_str(), "a");    if(0 == fp)	XLOG_FATAL("fopen of %s failed: %s", fname.c_str(), strerror(errno));    fprintf(fp, bgppp(buf, len).c_str());    fclose(fp);}template <class A>voidmrtd_routeview_dump(const UpdatePacket* p, const IPNet<A>& net,		const TimeVal& tv,		const string fname, int *sequence){    mrtd_routview_dump<A>(p, net, tv, fname, *sequence);    (*sequence)++;}template <class A>voidmrtd_debug_dump(const UpdatePacket* p, const IPNet<A>& /*net*/,		const TimeVal& tv,		const string fname){    size_t len;    const uint8_t *buf = p->encode(len);    mrtd_traffic_dump(buf, len , tv, fname);    delete [] buf;}template <class A>voidtext_debug_dump(const UpdatePacket* p, const IPNet<A>& net,		const TimeVal& tv,		const string fname){    FILE *fp = fopen(fname.c_str(), "a");    if(0 == fp)	XLOG_FATAL("fopen of %s failed: %s", fname.c_str(), strerror(errno));    fprintf(fp, "%s\n%s\n%s\n", net.str().c_str(), tv.pretty_print().c_str(),	    p->str().c_str());    fclose(fp);}voidmrtd_replay_dump(const UpdatePacket* p,		const TimeVal& tv,		const string fname){    size_t len;    const uint8_t *buf = p->encode(len);    mrtd_traffic_dump(buf, len , tv, fname);    delete [] buf;}voidtext_replay_dump(const UpdatePacket* p,		const TimeVal& /*tv*/,		const string fname){    FILE *fp = fopen(fname.c_str(), "a");    if(0 == fp)	XLOG_FATAL("fopen of %s failed: %s", fname.c_str(), strerror(errno));    fprintf(fp, "%s\n", p->str().c_str());    fclose(fp);}/*** peer dump <recv/sent> <mtrd/text> <ipv4/ipv6> ** 0    1    2           3           4           **** 	<traffic/routeview/replay/debug> <fname>** 	5				  6*/voidPeer::dump(const string& line, const vector<string>& words)    throw(InvalidString){        if(words.size() < 6)	xorp_throw(InvalidString,		   c_format("Insufficient arguments:\n[%s]", line.c_str()));    /*    ** Each peer holds two tries. One holds updates sent the other    ** holds updates received. Determine which trie we are about to    ** operate on.    */    Trie *op;    Dumper *dumper;    if("sent" == words[2]) {	op = &_trie_sent;	dumper = &_traffic_sent;    } else if("recv" == words[2]) {	op = &_trie_recv;	dumper = &_traffic_recv;    } else	xorp_throw(InvalidString,		   c_format("\"sent\" or \"recv\" accepted not <%s>\n[%s]",			    words[2].c_str(), line.c_str()));    bool mrtd;    if("mrtd" == words[3]) {	mrtd = true;    } else if("text" == words[3]) {	mrtd = false;    } else	xorp_throw(InvalidString,		   c_format("\"mrtd\" or \"text\" accepted not <%s>\n[%s]",			    words[3].c_str(), line.c_str()));    bool ipv4 = true;    if("ipv4" == words[4]) {	ipv4 = true;    } else if("ipv6" == words[4]) {	ipv4 = false;    } else	xorp_throw(InvalidString,		   c_format("\"ipv4\" or \"ipv6\" accepted not <%s>\n[%s]",			    words[4].c_str(), line.c_str()));        string filename;    if(words.size() == 7)	filename = words[6];#ifdef HOST_OS_WINDOWS    //    // If run from an MSYS shell, we need to perform UNIX->NT path    // conversion and expansion of /tmp by ourselves.    //    filename = unix_path_to_native(filename);    static const char tmpdirprefix[] = "\\tmp\\";    if (0 == _strnicmp(filename.c_str(), tmpdirprefix,		       strlen(tmpdirprefix))) {    	char tmpexp[MAXPATHLEN];    	size_t size = GetTempPathA(sizeof(tmpexp), tmpexp);    	if (size == 0 || size >= sizeof(tmpexp)) {		xorp_throw(InvalidString,        	   c_format("Internal error during tmpdir expansion"));	}	filename.replace(0, strlen(tmpdirprefix), string(tmpexp));    }#endif    if("traffic" == words[5]) {	if("" == filename) {	    dumper->release();	    return;	} 	if(mrtd) 	    *dumper = callback(mrtd_traffic_dump, filename); 	else	    *dumper = callback(text_traffic_dump, filename);    } else if("routeview" == words[5]) {	if("" == filename) {	    xorp_throw(InvalidString,		       c_format("no filename provided\n[%s]", line.c_str()));	}	int sequence = 0;	if(ipv4) {	    Trie::TreeWalker_ipv4 tw_ipv4;	    if(mrtd)		tw_ipv4 = callback(mrtd_routeview_dump<IPv4>, filename,				   &sequence);	    else		tw_ipv4 = callback(text_debug_dump<IPv4>, filename);	    op->tree_walk_table(tw_ipv4);	} else {	    Trie::TreeWalker_ipv6 tw_ipv6;	    if(mrtd)		tw_ipv6 = callback(mrtd_routeview_dump<IPv6>, filename,				   &sequence);	    else		tw_ipv6 = callback(text_debug_dump<IPv6>, filename);	    op->tree_walk_table(tw_ipv6);	}    } else if("replay" == words[5]) {	if("" == filename) {	    xorp_throw(InvalidString,		       c_format("no filename provided\n[%s]", line.c_str()));	}	Trie::ReplayWalker rw;	if(mrtd)	    rw = callback(mrtd_replay_dump, filename);	else	    rw = callback(text_replay_dump, filename);	op->replay_walk(rw);    } else if("debug" == words[5]) {	if("" == filename) {	    xorp_throw(InvalidString,		       c_format("no filename provided\n[%s]", line.c_str()));	}	if(ipv4) {	    Trie::TreeWalker_ipv4 tw_ipv4;	    if(mrtd)		tw_ipv4 = callback(mrtd_debug_dump<IPv4>, filename);	    else		tw_ipv4 = callback(text_debug_dump<IPv4>, filename);	    op->tree_walk_table(tw_ipv4);	} else {	    Trie::TreeWalker_ipv6 tw_ipv6;	    if(mrtd)		tw_ipv6 = callback(mrtd_debug_dump<IPv6>, filename);	    else		tw_ipv6 = callback(text_debug_dump<IPv6>, filename);	    op->tree_walk_table(tw_ipv6);	}    } else	xorp_throw(InvalidString,		   c_format("\"traffic\" or \"routeview\" or \"replay\" or \"debug\" accepted not <%s>\n[%s]",			    words[5].c_str(), line.c_str()));}boolcompare_packets(const BGPPacket *base_one, const BGPPacket *base_two){    if(base_one->type() != base_two->type())	return false;    switch(base_one->type()) {	case MESSAGETYPEOPEN:	    {		const OpenPacket *one =		    dynamic_cast<const OpenPacket *>(base_one);		const OpenPacket *two =		    dynamic_cast<const OpenPacket *>(base_two);		return *one == *two;	    }	    break;	case MESSAGETYPEUPDATE:	    {		const UpdatePacket *one =		    dynamic_cast<const UpdatePacket *>(base_one);		const UpdatePacket *two =		    dynamic_cast<const UpdatePacket *>(base_two);		return *one == *two;	    }	    break;	case MESSAGETYPENOTIFICATION:	    {		const NotificationPacket *one =		    dynamic_cast<const NotificationPacket *>(base_one);		const NotificationPacket *two =		    dynamic_cast<const NotificationPacket *>(base_two);		return *one == *two;	    }	    break;	case MESSAGETYPEKEEPALIVE:	    {		const KeepAlivePacket *one =		    dynamic_cast<const KeepAlivePacket *>(base_one);		const KeepAlivePacket *two =		    dynamic_cast<const KeepAlivePacket *>(base_two);		return *one == *two;	    }	    break;	default:	    XLOG_FATAL("Unexpected BGP message type %d", base_one->type());    }    return false;}/*** We just received a BGP message. Check our expected queue for a match.*/voidPeer::check_expect(BGPPacket *rec){    /*    ** If its already gone bad just return.    */    if(!_expect._ok)	return;    /*    ** If there is nothing on the queue return.    */    if(_expect._list.empty())	return;    const BGPPacket *exp = _expect._list.front();    debug_msg("Expecting: %s\n", exp->str().c_str());    if(compare_packets(rec, exp)) {	_expect._list.pop_front();	delete exp;    } else {	debug_msg("Received packet %s did not match Expected\n",		  rec->str().c_str());	_expect._ok = false;	/*	** Need to go through this performance in order to copy a	** packet.	*/	size_t rec_len;	const uint8_t *rec_buf = rec->encode(rec_len);	switch(rec->type()) {	case MESSAGETYPEOPEN:	    {	    OpenPacket *pac = new OpenPacket(rec_buf, rec_len);	    _expect._bad = pac;	    }	    break;	case MESSAGETYPEUPDATE:	    {	    UpdatePacket *pac = new UpdatePacket(rec_buf, rec_len);	    _expect._bad = pac;	    }	    break;	case MESSAGETYPENOTIFICATION:	    {	    NotificationPacket *pac =		new NotificationPacket(rec_buf, rec_len);	    _expect._bad = pac;	    }	    break;	case MESSAGETYPEKEEPALIVE:	    _expect._bad = new KeepAlivePacket(rec_buf, rec_len);	    break;	default:	    XLOG_FATAL("Unexpected BGP message type %d", rec->type());	}	delete [] rec_buf;    }}voidPeer::xrl_callback(const XrlError& error, const char *comment){    debug_msg("callback %s %s\n", comment, error.str().c_str());    XLOG_ASSERT(0 != _busy);    _busy--;    if(XrlError::OKAY() != error) {	XLOG_WARNING("callback: %s %s",  comment, error.str().c_str()); 	_session = false; 	_established = false;    }}voidPeer::xrl_callback_connected(const XrlError& error, const char *comment){    debug_msg("callback_connected %s %s\n", comment, error.str().c_str());    if(XrlError::OKAY() == error) {	_connected = true;    } else {	_connected = false;    }    xrl_callback(error, comment);}/*** This method receives data from the BGP process under test via the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -