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

📄 peer.cc

📁 BCAST Implementation for NS2
💻 CC
📖 第 1 页 / 共 3 页
字号:
"\"traffic\" or \"routeview\" or \"replay\" or \"debug\" accepted not <%s>\n[%s]",			    words[4].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;    }}/*** This method receives data from the BGP process under test via the** test_peer. The test_peer attempts to packetise the data into BGP** messages.*/voidPeer::datain(const bool& status, const TimeVal& tv,	     const vector<uint8_t>& data){    debug_msg("status: %d secs: %lu micro: %lu data length: %u\n",	      status, (unsigned long)tv.sec(), (unsigned long)tv.usec(),	      (uint32_t)data.size());    /*    ** A bgp error has occured.    */    if(false == status) {	/*	** BGP has closed the connection to the test_peer.	*/	if(0 == data.size()) {	    XLOG_WARNING("TCP connection from test_peer: %s to: %s closed",		       _peername.c_str(), _target_hostname.c_str());	    return;	}	XLOG_FATAL("Bad BGP message received by test_peer: %s from: %s",		   _peername.c_str(), _target_hostname.c_str());    }    size_t length = data.size();    uint8_t *buf = new uint8_t[length];    for(size_t i = 0; i < length; i++)	buf[i] = data[i];    const fixed_header *header = 	reinterpret_cast<const struct fixed_header *>(buf);    if (!_traffic_recv.is_empty())	_traffic_recv->dispatch(buf, length, tv);    try {	switch(header->type) {	case MESSAGETYPEOPEN: {	    debug_msg("OPEN Packet RECEIVED\n");	    OpenPacket pac(buf, length);	    debug_msg(pac.str().c_str());	    	    if(_session && !_established && _passive)		send_open();	    check_expect(&pac);	}	    break;	case MESSAGETYPEKEEPALIVE: {	    debug_msg("KEEPALIVE Packet RECEIVED %u\n", (uint32_t)length);	    KeepAlivePacket pac(buf, length);	    debug_msg(pac.str().c_str());	    /* XXX	    ** Send any received keepalive right back.	    ** At the moment we are not bothering to maintain a timer	    ** to send keepalives. An incoming keepalive prompts a	    ** keepalive response. At the beginning of a conversation	    ** this keepalive response will cause the peer to go to	    ** established. As opens must have been exchanged for the	    ** peer to send a keepalive. 	    ** 	    */	    if(_keepalive || (_session && !_established)) {		XrlTestPeerV0p1Client test_peer(_xrlrouter);		debug_msg("KEEPALIVE Packet SENT\n");		_busy++;		if(!test_peer.send_send(_peername.c_str(), data,				    callback(this, &Peer::xrl_callback,					     "keepalive")))		    XLOG_FATAL("send_send failed");	    }	    _established = true;	    check_expect(&pac);	}	    break;	case MESSAGETYPEUPDATE: {	    debug_msg("UPDATE Packet RECEIVED\n");	    UpdatePacket pac(buf, length);	    debug_msg(pac.str().c_str());	    /*	    ** Save the update message in the receive trie.	    */	    _trie_recv.process_update_packet(tv, buf, length);	    check_expect(&pac);	}	    break;	case MESSAGETYPENOTIFICATION: {	    debug_msg("NOTIFICATION Packet RECEIVED\n");	    NotificationPacket pac(buf, length);	    debug_msg(pac.str().c_str());	    check_expect(&pac);	}	    break;	default:	    /*	    ** Send a notification to the peer. This is a bad message type.	    */	    XLOG_ERROR("Unknown packet type %d", header->type);	}    } catch(CorruptMessage c) {	/*	** This peer had sent us a bad message.	*/	XLOG_WARNING("From peer %s: %s", _peername.c_str(),		     c.why().c_str());    }    delete [] buf;}void Peer::datain_error(const string& reason){    XLOG_WARNING("Error on TCP connection from test_peer: %s to %s reason: %s",		 _peername.c_str(), _target_hostname.c_str(), reason.c_str());}voidPeer::datain_closed(){    XLOG_WARNING("TCP connection from test_peer: %s to %s closed",		 _peername.c_str(), _target_hostname.c_str());    _session = false;    _established = false;}voidPeer::send_message(const uint8_t *buf, const size_t len, SMCB cb){    debug_msg("len: %u\n", (uint32_t)len);    if(!_traffic_sent.is_empty()) {	TimeVal tv;	_eventloop->current_time(tv);	_traffic_sent->dispatch(buf, len, tv);    }    vector<uint8_t> v(len);    for(size_t i = 0; i < len; i++)	v[i] = buf[i];    delete [] buf;        XrlTestPeerV0p1Client test_peer(_xrlrouter);    if(!test_peer.send_send(_peername.c_str(), v, cb))	XLOG_FATAL("send_send failed");}voidPeer::send_open(){    /*    ** Create an open packet and send it in.    */    OpenPacket bgpopen(_as, _id, _holdtime);    if(_ipv6)	bgpopen.add_parameter(		new BGPMultiProtocolCapability(AFI_IPV6, SAFI_UNICAST));    size_t len;    const uint8_t *buf = bgpopen.encode(len);    debug_msg("OPEN Packet SENT\n%s", bgpopen.str().c_str());    _busy++;    send_message(buf, len, callback(this, &Peer::xrl_callback, "open"));}/*** The standard BGP code that deals with path attributes contains** fairly stringent checking. For testing we want to be able to create** arbitary path attributes.*/class AnyAttribute : public PathAttribute {public:    /*    ** The attr string should be a comma separated list of numbers.    */    AnyAttribute(const char *attr) throw(InvalidString)	// In order to protect against accidents in the BGP code,	// PathAttribute does not have a default constructor. However,	// we need to manipulate a PathAttribute so pass in a valid	// constructor argument.	: PathAttribute(&_valid[0]) {	_init_string = attr;	string line = attr;	vector<string> v;	tokenize(line, v, ",");	_data = new uint8_t [v.size()];	for(size_t i = 0; i < v.size(); i++) {	    _data[i] = strtol(v[i].c_str(), 0, 0);// 	    fprintf(stderr, "%#x ", _data[i]);	}// 	fprintf(stderr, "\n");    };        PathAttribute *clone() const { 	return new AnyAttribute(_init_string.c_str());    }private:    static const uint8_t _valid[];    string _init_string;};const uint8_t AnyAttribute::_valid[] = {0x80|0x40, 255, 1, 1};/*** The input is a comma separated list of numbers that are turned into** an array.*/PathAttribute *Peer::path_attribute(const char *) const throw(InvalidString){    const uint8_t path[] = {0x80|0x40, 255, 1, 1};    uint16_t max_len = sizeof(path);    size_t actual_length;    return PathAttribute::create(&path[0], max_len, actual_length);}/*** Generate a BGP message from the textual description.** Note: It is up to the caller of this method to delete the packet** that has been created.*/const BGPPacket *Peer::packet(const string& line, const vector<string>& words, int index)    const throw(InvalidString){    BGPPacket *pac = 0;  try {    if("notify" == words[index]) {	switch(words.size() - (index + 1)) {	case 1:	    pac = new NotificationPacket(atoi(words[index + 1].c_str()));	    break;	case 2:	    pac = new NotificationPacket(atoi(words[index + 1].c_str()),					    atoi(words[index + 2].c_str()));	    break;	default: {	    int errlen = words.size() - (index + 3);	    if (errlen < 1)		xorp_throw(InvalidString,			   c_format(			   "Incorrect number of arguments to notify:\n[%s]",			   line.c_str()));	    uint8_t buf[errlen];	    for (int i=0; i< errlen; i++) {		int value = atoi(words[index + 3 + i].c_str());		if (value < 0 || value > 255)		    xorp_throw(InvalidString,			       c_format(			       "Incorrect byte value to notify:\n[%s]",			       line.c_str()));					buf[i] = (uint8_t)value;		pac = new NotificationPacket(atoi(words[index+1].c_str()),					     atoi(words[index+2].c_str()),					     buf, errlen);	    }	}	}    } else if("update" == words[index]) {	size_t size = words.size();	if(0 != ((size - (index + 1)) % 2))	    xorp_throw(InvalidString,	       c_format("Incorrect number of arguments to update:\n[%s]",				line.c_str()));	UpdatePacket *bgpupdate = new UpdatePacket();	MPReachNLRIAttribute<IPv6> mpipv6_nlri(SAFI_UNICAST);	MPUNReachNLRIAttribute<IPv6> mpipv6_withdraw(SAFI_UNICAST);	for(size_t i = index + 1; i < size; i += 2) {	    debug_msg("name: %s value: <%s>\n",		      words[i].c_str(),		      words[i + 1].c_str());	    if("origin" == words[i]) {		bgpupdate->add_pathatt(OriginAttribute(static_cast<OriginType>				     (atoi(words[i + 1].c_str()))));	    } else if("aspath" == words[i]) {		string aspath = words[i+1];		bgpupdate->add_pathatt(ASPathAttribute(AsPath(						       aspath.c_str())));		debug_msg("aspath: %s\n", 			  AsPath(aspath.c_str()).str().c_str());	    } else if("nexthop" == words[i]) {		bgpupdate->add_pathatt(IPv4NextHopAttribute(IPv4(						      words[i+1].c_str())));	    } else if("nexthop6" == words[i]) {		mpipv6_nlri.set_nexthop(IPv6(words[i+1].c_str()));	    } else if("localpref" == words[i]) {		bgpupdate->add_pathatt(LocalPrefAttribute(atoi(						      words[i+1].c_str())));	    } else if("nlri" == words[i]) {		bgpupdate->add_nlri(BGPUpdateAttrib(IPv4Net(						      words[i+1].c_str())));	    } else if("nlri6" == words[i]) {		mpipv6_nlri.add_nlri(words[i+1].c_str());	    } else if("withdraw" == words[i]) {		bgpupdate->add_withdrawn(BGPUpdateAttrib(IPv4Net(						      words[i+1].c_str())));	    } else if("withdraw6" == words[i]) {		mpipv6_withdraw.add_withdrawn(IPv6Net(words[i+1].c_str()));	    } else if("med" == words[i]) {		bgpupdate->add_pathatt(MEDAttribute(atoi(						      words[i+1].c_str())));	    } else if("pathattr" == words[i]) {		bgpupdate->add_pathatt(AnyAttribute(words[i+1].c_str()));	    } else		xorp_throw(InvalidString, 		       c_format("Illegal argument to update: <%s>\n[%s]",				words[i].c_str(), line.c_str()));	}	if(!mpipv6_nlri.nlri_list().empty()) { 	    mpipv6_nlri.encode();	    bgpupdate->add_pathatt(mpipv6_nlri);	}	if(!mpipv6_withdraw.wr_list().empty()) {	    mpipv6_withdraw.encode();	    bgpupdate->add_pathatt(mpipv6_withdraw);	}	pac = bgpupdate;    } else if("open" == words[index]) {	size_t size = words.size();	if(0 != ((size - (index + 1)) % 2))	    xorp_throw(InvalidString,	       c_format("Incorrect number of arguments to update:\n[%s]",				line.c_str()));	string asnum;	string bgpid;	string holdtime;	for(size_t i = index + 1; i < size; i += 2) {	    debug_msg("name: %s value: %s\n",		      words[i].c_str(),		      words[i + 1].c_str());	    if("asnum" == words[i]) {		asnum = words[i + 1];	    } else if("bgpid" == words[i]) {		bgpid = words[i + 1];	    } else if("holdtime" == words[i]) {		holdtime = words[i + 1];	    } else 		xorp_throw(InvalidString, 		       c_format("Illegal argument to open: <%s>\n[%s]",				words[i].c_str(), line.c_str()));	}	if("" == asnum) {	    xorp_throw(InvalidString,	       c_format("AS number not supplied to open:\n[%s]",				line.c_str()));	}	if("" == bgpid) {	    xorp_throw(InvalidString,	       c_format("BGP ID not supplied to open:\n[%s]",				line.c_str()));	}	if("" == holdtime) {	    xorp_throw(InvalidString,	       c_format("Holdtime not supplied to open:\n[%s]",				line.c_str()));	} 	OpenPacket *open = new OpenPacket(AsNum(				 static_cast<uint16_t>(atoi(asnum.c_str()))),					  IPv4(bgpid.c_str()),					  atoi(holdtime.c_str()));	pac = open;    } else if("keepalive" == words[index]) {	pac = new KeepAlivePacket();    } else	xorp_throw(InvalidString,		   c_format("\"notify\" or"			    " \"update\" or"			    " \"open\" or"			    " \"keepalive\" accepted"			    " not <%s>\n[%s]",			    words[index].c_str(), line.c_str()));  } catch(CorruptMessage c) {       xorp_throw(InvalidString, c_format("Unable to construct packet "					"%s\n[%s])", c.why().c_str(),					line.c_str()));  }	  debug_msg("%s\n", pac->str().c_str());    return pac;}

⌨️ 快捷键说明

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