Beispiel #1
0
void switch_process_ff(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p", module, ff);

	if (ff->metaData == NULL) {
		PRINT_ERROR("Error fcf.metadata==NULL");
		exit(-1);
	}

	PRINT_WARN("TODO: switch process received frames: ff=%p, meta=%p", ff, ff->metaData);
	print_finsFrame(ff);

	if (ff->dataOrCtrl == FF_CONTROL) {
		switch_fcf(module, ff);
		PRINT_DEBUG("");
	} else if (ff->dataOrCtrl == FF_DATA) {
		if (ff->dataFrame.directionFlag == DIR_UP) {
			//switch_in_fdf(module, ff);
			PRINT_WARN("todo");
			freeFinsFrame(ff);
		} else if (ff->dataFrame.directionFlag == DIR_DOWN) {
			//switch_out_fdf(ff);
			PRINT_WARN("todo");
			freeFinsFrame(ff);
		} else {
			PRINT_ERROR("todo error");
			exit(-1);
		}
	} else {
		PRINT_ERROR("todo error: dataOrCtrl=%u", ff->dataOrCtrl);
		exit(-1);
	}
}
Beispiel #2
0
void *switch_loop(void *local) {
	struct fins_module *module = (struct fins_module *) local;
	PRINT_DEBUG("Entered: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name);
	struct switch_data *md = (struct switch_data *) module->data;

	uint32_t i;
	int ret;
	//int32_t val;
	struct finsFrame *ff;
	//uint8_t index;

	int counter = 0;

	while (module->state == FMS_RUNNING) {
		secure_sem_wait(module->event_sem); //TODO uncomment, for testing
		//secure_sem_wait(module->input_sem);
		secure_sem_wait(&md->overall->sem);
		for (i = 0; i < MAX_MODULES; i++) {
			if (md->overall->modules[i] != NULL) {
				//helgrind says is race condition, though there will always be FF when post to event_sem
				if (!IsEmpty(md->overall->modules[i]->output_queue)) { //added as optimization
					/*
					 //can possibly cause switch to be "behind"
					 ret = sem_getvalue(md->overall->modules[i]->output_sem, &val);
					 if (ret) {
					 PRINT_ERROR("sem get value prob: src module_index=%u, ret=%d", i, ret);
					 exit(-1);
					 } //*/

					//if (val != 0) {
					while ((ret = sem_wait(md->overall->modules[i]->output_sem)) && errno == EINTR)
						;
					if (ret != 0) {
						PRINT_ERROR("sem wait prob: src module_index=%u, ret=%d", i, ret);
						exit(-1);
					}
					ff = read_queue(md->overall->modules[i]->output_queue);
					sem_post(md->overall->modules[i]->output_sem);

					//if (ff != NULL) { //shouldn't occur
					counter++;

					//index = ff->destinationID;
					if (ff->destinationID < 0 || ff->destinationID > MAX_MODULES) {
						PRINT_ERROR("dropping ff: illegal destination: src module_index=%u, dst module_index=%u, ff=%p, meta=%p",
								i, ff->destinationID, ff, ff->metaData);
						//TODO if FCF set ret_val=0 & return? or free or just exit(-1)?
						freeFinsFrame(ff);
					} else { //if (i != id) //TODO add this?
						if (md->overall->modules[ff->destinationID] != NULL) {
							PRINT_DEBUG("Counter=%d, from='%s', to='%s', ff=%p, meta=%p",
									counter, md->overall->modules[i]->name, md->overall->modules[ff->destinationID]->name, ff, ff->metaData);
							//TODO decide if should drop all traffic to switch input queues, or use that as linking table requests
							if (ff->destinationID == module->index) {
								switch_process_ff(module, ff);
							} else {
								while ((ret = sem_wait(md->overall->modules[ff->destinationID]->input_sem)) && errno == EINTR)
									;
								if (ret != 0) {
									PRINT_ERROR("sem wait prob: dst index=%u, ff=%p, meta=%p, ret=%d", ff->destinationID, ff, ff->metaData, ret);
									exit(-1);
								}
								if (write_queue(ff, md->overall->modules[ff->destinationID]->input_queue)) {
									sem_post(md->overall->modules[ff->destinationID]->event_sem);
									sem_post(md->overall->modules[ff->destinationID]->input_sem);
								} else {
									sem_post(md->overall->modules[ff->destinationID]->input_sem);
									PRINT_ERROR("Write queue error: dst index=%u, ff=%p, meta=%p", ff->destinationID, ff, ff->metaData);
									freeFinsFrame(ff);
								}
							}
						} else {
							PRINT_ERROR("dropping ff: destination not registered: src index=%u, dst index=%u, ff=%p, meta=%p",
									i, ff->destinationID, ff, ff->metaData);
							print_finsFrame(ff);
							//TODO if FCF set ret_val=0 & return? or free or just exit(-1)?
							freeFinsFrame(ff);
						}
						//}
						//}
					}
				}
			}
		}
		//sem_post(module->input_sem);
		sem_post(&md->overall->sem);
	}

	PRINT_DEBUG("Exited: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name);
	return NULL;
}
void udp_out(struct finsFrame* ff)
{

	struct finsFrame* newFF;
	struct udp_metadata_parsed parsed_meta;

	/* read the FDF and make sure everything is correct*/
	if (ff->dataOrCtrl != DATA) {
		// release FDF here
		return;
	}
	if (ff->dataFrame.directionFlag != DOWN) {
		// release FDF here
		return;
	}
	if (ff->destinationID.id != UDPID) {
		// release FDF here
		return;
	}

	PRINT_DEBUG("UDP_out");

	print_finsFrame(ff);

	struct udp_header packet;
	struct udp_packet check_packet;
	u_char test[100];
	metadata* meta = (ff->dataFrame).metaData;

	u_char *udp_dataunit = (u_char *)malloc( (ff->dataFrame).pduLength + U_HEADER_LEN );

/** constructs the UDP packet from the FDF and the meta data */
	PRINT_DEBUG("%d", ff->dataFrame.pduLength);

	uint32_t dstbuf;
	uint32_t srcbuf;
	uint32_t dstip;
	uint32_t srcip;

	PRINT_DEBUG("UDP_out");
	metadata_readFromElement(meta,"dstport",&dstbuf);
	metadata_readFromElement(meta,"srcport",&srcbuf);
	metadata_readFromElement(meta,"dstip",&dstip);
	metadata_readFromElement(meta,"srcip",&srcip);
/** fixing the values because of the conflict between uint16 type and
 * the 32 bit META_INT_TYPE
 */
	packet.u_dst = dstbuf;
	packet.u_src = srcbuf;

	PRINT_DEBUG("%d, %d", (packet.u_dst),(packet.u_src));

	(packet.u_dst) = htons(packet.u_dst);
	(packet.u_src) = htons(packet.u_src);
	/* calculates the UDP length by adding the UDP header length to the length of the data */
	int packet_length;
	packet_length= ( ((ff->dataFrame).pduLength) + U_HEADER_LEN );;
	packet.u_len = htons( ((ff->dataFrame).pduLength) + U_HEADER_LEN );


 /** TODO ignore the checksum for now
 * Will be fixed later
 */
	/** Invalidation disabled value = 0xfed2*/


	parsed_meta.u_destPort = htons( packet.u_dst);
	parsed_meta.u_srcPort = htons( packet.u_src);
	parsed_meta.u_IPdst = htonl( dstip);
	parsed_meta.u_IPsrc = htonl( dstip);
	parsed_meta.u_pslen = htons( packet_length);
	parsed_meta.u_prcl = htons( UDP_PROTOCOL);
	packet.u_cksum = 0;


	memcpy(&check_packet,&packet,U_HEADER_LEN);
	memcpy(&check_packet,ff->dataFrame.pdu,ff->dataFrame.pduLength);
	packet.u_cksum = UDP_checksum(&check_packet,&parsed_meta);																			/* stores a value of zero in the checksum field so that it can be calculated */


PRINT_DEBUG("%d,%d,%d,%d", packet.u_src,packet.u_dst,packet.u_len,packet.u_cksum);

//	packet.u_cksum = UDP_checksum(&packet, meta);												/* calculates ands stores the real checksum in the checksum field */
/* need to be careful in the line ^ above ^, the metadata needs to have the source and destination IPS in order to calculate the checksum */

	//printf("The checksum Value is %d", packet.u_cksum);
	int i=0;
	while (i < ff->dataFrame.pduLength)
	{
		PRINT_DEBUG("%d",ff->dataFrame.pdu[i]);
		i++;

	}
	PRINT_DEBUG("UDP_out");
	memcpy(udp_dataunit, &packet, U_HEADER_LEN);											/* copies the UDP packet into the memory that has been allocated for the PDU */
//	PRINT_DEBUG("%d, %d",(ff->dataFrame).pdu, ff->dataFrame.pduLength);

	memcpy(udp_dataunit + U_HEADER_LEN ,(ff->dataFrame).pdu, ff->dataFrame.pduLength);		/* moves the pointer 8 bytes to account for those empty 8 bytes*/;
//	PRINT_DEBUG("%d",packet.u_len);

/**
	memcpy(test, udp_dataunit, packet_length);
	test [packet_length] = '\0';
	i=0;
	while (i < packet_length)
	{
		PRINT_DEBUG("%d",test[i]);
		i++;

	}



	//free (ff->dataFrame.pdu);
	PRINT_DEBUG("%s",test);
	PRINT_DEBUG("%d",udp_dataunit);
	*/

	ff->dataFrame.pdu = udp_dataunit;
	/* creates a new FDF to be sent out */
	PRINT_DEBUG("%d",ff->dataFrame.pdu);

	PRINT_DEBUG("UDP_out");

	newFF = create_ff(DATA, DOWN, IPV4ID, packet_length, ff->dataFrame.pdu, ff->dataFrame.metaData);

	PRINT_DEBUG("%d",newFF->dataFrame.pdu);


	print_finsFrame(newFF);
	udpStat.totalSent++;
	PRINT_DEBUG("UDP_out");

	sendToSwitch(newFF);
}