コード例 #1
0
/**
 * Test program looping and reading LLDP/CDP packets and exercising most of the packet
 * send/receive mechanism and a good bit of nanoprobe and CMA basic infrastructure.
 *
 * It plays both sides of the game - the CMA and the nanoprobe.
 *
 * It leaves most of the work of starting up the nanoprobe code to nano_start_full()
 */
int
main(int argc, char **argv)
{
	const guint8	loopback[] = CONST_IPV6_LOOPBACK;
	//const guint8	mcastaddrstring[] = CONST_ASSIM_DEFAULT_V4_MCAST;
	//NetAddr*	mcastaddr;
	const guint8	otheradstring[] = {127,0,0,1};
	const guint8	otheradstring2[] = {10,10,10,4};
	const guint8	anyadstring[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	guint16		testport = TESTPORT;
	SignFrame*	signature = signframe_glib_new(G_CHECKSUM_SHA256, 0);
	Listener*	otherlistener;
	ConfigContext*	config = configcontext_new(0);
	PacketDecoder*	decoder = nano_packet_decoder();
	AuthListener*	listentonanoprobes;
	ReliableUDP*	rtransport;

#if 0
#	ifdef HAVE_MCHECK_PEDANTIC
	g_assert(mcheck_pedantic(NULL) == 0);
#	else
#		ifdef HAVE_MCHECK
	g_assert(mcheck(NULL) == 0);
#		endif
#	endif
#endif
	g_setenv("G_MESSAGES_DEBUG", "all", TRUE);
#if 0
	proj_class_incr_debug(NULL);
	proj_class_incr_debug(NULL);
	proj_class_incr_debug(NULL);
	proj_class_incr_debug(NULL);
#endif
	g_log_set_fatal_mask(NULL, G_LOG_LEVEL_ERROR);

	if (argc > 1) {
		maxpkts = atol(argv[1]);
                g_debug("Max packet count is "FMT_64BIT"d", maxpkts);
	}

	if (netio_is_dual_ipv4v6_stack()) {
		g_message("Our OS supports dual ipv4/v6 sockets. Hurray!");
	}else{
		g_warning("Our OS DOES NOT support dual ipv4/v6 sockets - this may not work!!");
	}
	

	config->setframe(config, CONFIGNAME_OUTSIG, &signature->baseclass);

	// Create a network transport object for normal UDP packets
	rtransport = reliableudp_new(0, config, decoder, 0);
	rtransport->_protocol->window_size = 8;
	nettransport = &(rtransport->baseclass.baseclass);
	g_return_val_if_fail(NULL != nettransport, 2);

	// Set up the parameters the 'CMA' is going to send to our 'nanoprobe'
	// in response to their request for configuration data.
	nanoconfig = configcontext_new(0);
	nanoconfig->setint(nanoconfig, CONFIGNAME_INTERVAL, 1);
	nanoconfig->setint(nanoconfig, CONFIGNAME_TIMEOUT, 3);
	nanoconfig->setint(nanoconfig, CONFIGNAME_CMAPORT, testport);


	// Construct the NetAddr we'll talk to (i.e., ourselves) and listen from
	destaddr =  netaddr_ipv6_new(loopback, testport);
	g_return_val_if_fail(NULL != destaddr, 3);
	config->setaddr(config, CONFIGNAME_CMAINIT, destaddr);
	nanoconfig->setaddr(nanoconfig, CONFIGNAME_CMAADDR, destaddr);
	nanoconfig->setaddr(nanoconfig, CONFIGNAME_CMAFAIL, destaddr);
	nanoconfig->setaddr(nanoconfig, CONFIGNAME_CMADISCOVER, destaddr);

	// Construct another couple of NetAddrs to talk to and listen from
	// for good measure...
	otheraddr =  netaddr_ipv4_new(otheradstring, testport);
	g_return_val_if_fail(NULL != otheraddr, 4);
	otheraddr2 =  netaddr_ipv4_new(otheradstring2, testport);
	g_return_val_if_fail(NULL != otheraddr2, 4);

	// Construct another NetAddr to bind to (anything)
	anyaddr =  netaddr_ipv6_new(anyadstring, testport);
	g_return_val_if_fail(NULL != destaddr, 5);

	// Bind to ANY address (as noted above)
	g_return_val_if_fail(nettransport->bindaddr(nettransport, anyaddr, FALSE),16);
	//g_return_val_if_fail(nettransport->bindaddr(nettransport, destaddr),16);

	g_message("NOT Joining multicast address.");
#if 0
	// We can't do this because of encryption and we will likely screw up
	// others on our network even if that weren't a problem...
	mcastaddr =  netaddr_ipv4_new(mcastaddrstring, testport);
	g_return_val_if_fail(nettransport->mcastjoin(nettransport, mcastaddr, NULL), 17);
	UNREF(mcastaddr);
	g_message("multicast join succeeded.");
#endif

	// Connect up our network transport into the g_main_loop paradigm
	// so we get dispatched when packets arrive
	netpkt = netgsource_new(nettransport, NULL, G_PRIORITY_HIGH, FALSE, NULL, 0, NULL);

	// Set up so that we can observe all unclaimed packets
	otherlistener = listener_new(config, 0);
	otherlistener->got_frameset = gotnetpkt;
	netpkt->addListener(netpkt, 0, otherlistener);
	otherlistener->associate(otherlistener,netpkt);

	// Unref the "other" listener - we hold other references to it
	UNREF(otherlistener);

	// Pretend to be the CMA...
	// Listen for packets from our nanoprobes - scattered throughout space...
	listentonanoprobes = authlistener_new(0, cmalist, config, TRUE, NULL);
	listentonanoprobes->baseclass.associate(&listentonanoprobes->baseclass, netpkt);

	nano_start_full("netconfig", 900, netpkt, config, test_cma_authentication);

	g_timeout_add_seconds(1, timeout_agent, NULL);
	mainloop = g_main_loop_new(g_main_context_default(), TRUE);

	/********************************************************************
	 *	Start up the main loop - run our test program...
	 *	(the one pretending to be both the nanoprobe and the CMA)
	 ********************************************************************/
	g_main_loop_run(mainloop);

	/********************************************************************
	 *	We exited the main loop.  Shut things down.
	 ********************************************************************/

	nano_shutdown(TRUE);	// Tell it to shutdown and print stats
	g_message("Count of 'other' pkts received:\t%d", wirepktcount);

	UNREF(nettransport);

	// Main loop is over - shut everything down, free everything...
	g_main_loop_unref(mainloop); mainloop=NULL;


	// Unlink misc dispatcher - this should NOT be necessary...
	netpkt->addListener(netpkt, 0, NULL);

	// Dissociate packet actions from the packet source.
	listentonanoprobes->baseclass.dissociate(&listentonanoprobes->baseclass);

	// Unref the AuthListener object
	UNREF2(listentonanoprobes);

	g_source_destroy(&netpkt->baseclass);
	g_source_unref(&netpkt->baseclass);
	//g_main_context_unref(g_main_context_default());

	// Free signature frame
	UNREF2(signature);

	// Free misc addresses
	UNREF(destaddr);
	UNREF(otheraddr);
	UNREF(otheraddr2);
	UNREF(anyaddr);

	// Free config object
	UNREF(config);
	UNREF(nanoconfig);


	// At this point - nothing should show up - we should have freed everything
	if (proj_class_live_object_count() > 0) {
		g_warning("Too many objects (%d) alive at end of test.", 
			proj_class_live_object_count());
		proj_class_dump_live_objects();
		++errcount;
	}else{
		g_message("No objects left alive.  Awesome!");
	}
        proj_class_finalize_sys(); // Shut down object system to make valgrind happy :-D
	return(errcount <= 127 ? errcount : 127);
}
コード例 #2
0
/// Send JSON that we discovered to the CMA - with some caching going on
FSTATIC void
_discovery_sendjson(Discovery* self,	///< Our discovery object
		    char * jsonout,	///< malloced JSON output - which we free (!)
		    gsize jsonlen)	///< length of jsonout
{
	FrameSet*	fs;
	CstringFrame*	jsf;
	IntFrame*	intf;
	Frame*		fsf;
	ConfigContext*	cfg = self->_config;
	NetGSource*	io = self->_iosource;
	NetAddr*	cma;
	const char *	basename = self->instancename(self);
	ConfigContext*	jsonobject;

	g_return_if_fail(cfg != NULL && io != NULL);

	if (NULL == (jsonobject = configcontext_new_JSON_string(jsonout))) {
		g_warning("%s.%d: JSON Discovery is not legal JSON [%s]"
		,	__FUNCTION__, __LINE__, jsonout);
		return;
	}
	g_free(jsonout);
	
	jsonobject->setstring(jsonobject, CONFIGNAME_INSTANCE, basename);
	jsonout = jsonobject->baseclass.toString(&jsonobject->baseclass);
	jsonlen = strlen(jsonout);
	UNREF(jsonobject);
	
	DEBUGMSG2("%s.%d: discovering %s: _sentyet == %d"
	,	__FUNCTION__, __LINE__, basename, self->_sentyet);
	
	
	// Primitive caching - don't send what we've already sent.
	if (self->_sentyet) {
		const char *	oldvalue = cfg->getstring(cfg, basename);
		if (oldvalue != NULL && strcmp(jsonout, oldvalue) == 0) {
			DEBUGMSG2("%s.%d: %s sent this value - don't send again."
			,	__FUNCTION__, __LINE__, basename);
			g_free(jsonout);
			return;
		}
		DEBUGMSG2("%s.%d: %s this value is different from previous value"
		,	__FUNCTION__, __LINE__, basename);
	}
	DEBUGMSG2("%s.%d: Sending %"G_GSIZE_FORMAT" bytes of JSON text"
	,	__FUNCTION__, __LINE__, jsonlen);
	cfg->setstring(cfg, basename, jsonout);
	cma = cfg->getaddr(cfg, CONFIGNAME_CMADISCOVER);
	if (cma == NULL) {
	        DEBUGMSG2("%s.%d: %s address is unknown - skipping send"
		,	__FUNCTION__, __LINE__, CONFIGNAME_CMADISCOVER);
		g_free(jsonout);
		return;
	}
	self->_sentyet = TRUE;

	fs = frameset_new(FRAMESETTYPE_JSDISCOVERY);
	intf = intframe_new(FRAMETYPE_WALLCLOCK, 8);
	intf->setint(intf, self->starttime);
	frameset_append_frame(fs, &intf->baseclass);
	UNREF2(intf);
	jsf = cstringframe_new(FRAMETYPE_JSDISCOVER, 0);
	fsf = &jsf->baseclass;	// base class object of jsf
	fsf->setvalue(fsf, jsonout, jsonlen+1, frame_default_valuefinalize); // jsonlen is strlen(jsonout)
	frameset_append_frame(fs, fsf);
	DEBUGMSG2("%s.%d: Sending a %"G_GSIZE_FORMAT" bytes JSON frameset"
	,	__FUNCTION__, __LINE__, jsonlen);
	io->_netio->sendareliablefs(io->_netio, cma, DEFAULT_FSP_QID, fs);
	++ self->reportcount;
	UNREF(fsf);
	UNREF(fs);
}
コード例 #3
0
/// Routine to pretend to be the initial CMA
void
fakecma_startup(AuthListener* auth, FrameSet* ifs, NetAddr* nanoaddr)
{
	FrameSet*	pkt;
	NetGSource*	netpkt = auth->baseclass.transport;
	char *		nanostr = nanoaddr->baseclass.toString(nanoaddr);
	GSList*		thisgsf;
	const char *	keyid = NULL;

	(void)ifs;
	g_message("CMA received startup message from nanoprobe at address %s/%d."
	,	nanostr, nanoaddr->port(nanoaddr));
	g_free(nanostr); nanostr = NULL;
	check_JSON(ifs);

	netpkt->_netio->addalias(netpkt->_netio, nanoaddr, destaddr);
	
	// Set up our crypto...
	cryptframe_set_dest_key_id(nanoaddr, cryptframe_get_signing_key_id());
	cryptframe_set_dest_key_id(destaddr, cryptframe_get_signing_key_id());
	cryptframe_associate_identity(CMA_IDENTITY_NAME, cryptframe_get_signing_key_id());
	cryptframe_set_encryption_method(cryptcurve25519_new_generic);
	for (thisgsf = ifs->framelist; thisgsf; thisgsf=thisgsf->next) {
		Frame*	thisframe = CASTTOCLASS(Frame, thisgsf->data);
		if (thisframe->type == FRAMETYPE_KEYID) {
			CstringFrame* csf = CASTTOCLASS(CstringFrame, thisframe);
			keyid = (const char *)csf->baseclass.value;
		}else if (keyid && thisframe->type == FRAMETYPE_PUBKEYCURVE25519) {
			cryptcurve25519_save_public_key(keyid, thisframe->value
			,	thisframe->length);
		}
	}

	// Send the configuration data to our new "client"
	pkt = create_setconfig(nanoconfig);
	netpkt->_netio->sendareliablefs(netpkt->_netio, nanoaddr, DEFAULT_FSP_QID, pkt);
	UNREF(pkt);

	// Now tell them to send/expect heartbeats to various places
	pkt = create_sendexpecthb(auth->baseclass.config, FRAMESETTYPE_SENDEXPECTHB, destaddr, 1);
	netpkt->_netio->sendareliablefs(netpkt->_netio, nanoaddr, DEFAULT_FSP_QID, pkt);
	UNREF(pkt);

	{
		const char *	monopjson[] = { START, MONITOR, STOP};
		unsigned	j;
		// Create a frameset for a few resource operations
		pkt = frameset_new(FRAMESETTYPE_DORSCOP);
		for (j=0; j < DIMOF(monopjson); j++) {
			CstringFrame*	csf = cstringframe_new(FRAMETYPE_RSCJSON,0);
			csf->baseclass.setvalue(&csf->baseclass, g_strdup(monopjson[j])
			,	strlen(monopjson[j])+1, g_free);
			frameset_append_frame(pkt, &csf->baseclass);
			UNREF2(csf);
		}
		netpkt->_netio->sendareliablefs(netpkt->_netio, nanoaddr, DEFAULT_FSP_QID, pkt);
		UNREF(pkt);
	}
	{
		const char *	discoverjson[] = {SWITCHDISCOVER, ARPDISCOVER};
		const char *	discoverinstnm[] = {SWINSTNM, ARPINSTNM};
		unsigned	j;
		// Create a frameset for a few discovery operations
		pkt = frameset_new(FRAMESETTYPE_DODISCOVER);
		for (j=0; j < DIMOF(discoverjson); j++) {
			CstringFrame*	csf = cstringframe_new(FRAMETYPE_DISCJSON,0);
			CstringFrame*	inst = cstringframe_new(FRAMETYPE_DISCNAME,0);
			fprintf(stderr, "Creating discovery frameset: %s: %s\n"
			,	discoverinstnm[j]
			,	discoverjson[j]);
			inst->baseclass.setvalue(&inst->baseclass, g_strdup(discoverjson[j])
			,	strlen(discoverjson[j])+1, g_free);
			frameset_append_frame(pkt, &inst->baseclass);
			UNREF2(inst);
			csf->baseclass.setvalue(&csf->baseclass, g_strdup(discoverjson[j])
			,	strlen(discoverjson[j])+1, g_free);
			frameset_append_frame(pkt, &csf->baseclass);
			UNREF2(csf);
		}
		netpkt->_netio->sendareliablefs(netpkt->_netio, nanoaddr, DEFAULT_FSP_QID, pkt);
		UNREF(pkt);
	}
	pkt = frameset_new(FRAMESETTYPE_ACKSTARTUP);
	netpkt->_netio->sendareliablefs(netpkt->_netio, nanoaddr, DEFAULT_FSP_QID, pkt);
	UNREF(pkt);
	g_info("ACKSTARTUP packet queued to send");
}