Esempio n. 1
0
int rtm_console_listening_test(struct rtm_console *console, uint32_t *index, uint32_t *param_id) {
	if (console->type == RTM_TYPE_CONSOLE) {
		return 0;
	}

	uint8_t buf[500];
	memset(buf, 0, 500);
	sprintf((char *) buf, "l%u_%d", *index, *param_id);

	int32_t val;
	if (metadata_readFromElement(console->listeners, (char *) buf, &val) == META_TRUE) {
		return val == VALUE_TRUE;
	}

	sprintf((char *) buf, "l%u_%d", *index, -1);
	if (metadata_readFromElement(console->listeners, (char *) buf, &val) == META_TRUE) {
		return val == VALUE_TRUE;
	}

	sprintf((char *) buf, "l%u_%d", 32, *param_id);
	if (metadata_readFromElement(console->listeners, (char *) buf, &val) == META_TRUE) {
		return val == VALUE_TRUE;
	}

	sprintf((char *) buf, "l%u_%d", 32, -1);
	if (metadata_readFromElement(console->listeners, (char *) buf, &val) == META_TRUE) {
		return val == VALUE_TRUE;
	}

	return 0;
}
int readFrom_fins(int senderid,int sockfd,u_char **buf,int *buflen,int symbol,struct sockaddr_in *address, int block_flag)
{

	/**TODO MUST BE FIXED LATER
	 * force symbol to become zero
	 */
	symbol = 0;
	struct finsFrame *ff=NULL;
	int index;
	uint16_t srcport;
	uint32_t srcip;
	struct sockaddr_in * addr_in= (struct sockaddr_in * )address;
	index = findjinniSocket(senderid,sockfd);
	PRINT_DEBUG("index = %d",index);
	/**
	 * It keeps looping as a bad method to implement the blocking feature
	 * of recvfrom. In case it is not blocking then the while loop should
	 * be replaced with only a single trial !
	 *
	 */

	PRINT_DEBUG();
	if (block_flag == 1)
	{
		PRINT_DEBUG();



		do
			{

					sem_wait(&(jinniSockets[index].Qs));
			//		PRINT_DEBUG();


					ff= read_queue(jinniSockets[index].dataQueue);
				//	ff = get_fake_frame();
//					PRINT_DEBUG();

					sem_post(&(jinniSockets[index].Qs));
			}
		while(ff == NULL);
			PRINT_DEBUG();


	}
	else
	{
		PRINT_DEBUG();

					sem_wait(&(jinniSockets[index].Qs));
						//ff= read_queue(jinniSockets[index].dataQueue);
					/**	ff = get_fake_frame();
						print_finsFrame(ff); */
					ff= read_queue(jinniSockets[index].dataQueue);

					sem_post(&(jinniSockets[index].Qs));

	}

	if (ff == NULL)
	{
		//free(ff);
		return(0);
	}
	PRINT_DEBUG("PDU lenght %d",ff->dataFrame.pduLength);

	//*buf = (u_char *)malloc(sizeof(ff->dataFrame.pduLength));
	//memcpy(*buf,ff->dataFrame.pdu,ff->dataFrame.pduLength);
	memcpy(buf,ff->dataFrame.pdu,ff->dataFrame.pduLength);
	*buflen = ff->dataFrame.pduLength;

	PRINT_DEBUG();

	if (symbol == 0)
		{
//		address = NULL;
		PRINT_DEBUG();
	//	freeFinsFrame(ff);

		return (1);
		}
	PRINT_DEBUG();

	if (metadata_readFromElement(ff->dataFrame.metaData,"hostport",&srcport) == 0 )
		{
			address->sin_port = 0;
					return (1);
		}
	if (metadata_readFromElement(ff->dataFrame.metaData,"hostip",&srcip) == 0 )
		{
				address->sin_addr.s_addr =0;
						return (1);
		}

	addr_in->sin_port = srcport;
	addr_in->sin_addr.s_addr = srcip;



/**TODO Free the finsFrame
 * This is the final consumer
 * call finsFrame_free(Struct finsFrame** ff)
 */
	PRINT_DEBUG();

	//freeFinsFrame(ff);

/** Finally succeeded
 *
 */
return(1);


} //end of readFrom_fins
void ipv4_exec_reply(struct finsFrame *ff) {
	PRINT_DEBUG("Entered: ff=%p, meta=%p", ff, ff->metaData);

	int ret = 0;

	metadata *params = ff->metaData;
	if (params) {
		switch (ff->ctrlFrame.param_id) {
		case EXEC_ARP_GET_ADDR:
			PRINT_DEBUG("param_id=EXEC_ARP_GET_ADDR (%d)", ff->ctrlFrame.param_id);

			if (ff->ctrlFrame.ret_val) {
				uint64_t src_mac, dst_mac;
				ret += metadata_readFromElement(params, "src_mac", &src_mac) == META_FALSE;
				ret += metadata_readFromElement(params, "dst_mac", &dst_mac) == META_FALSE;

				if (ret) {
					PRINT_ERROR("ret=%d", ret);
					//TODO send nack
				} else {
					//ipv4_exec_reply_get_addr(ff, src_mac, dst_mac);
					struct ip4_store *store = store_list_find(ff->ctrlFrame.serial_num);
					if (store) {
						PRINT_DEBUG("store=%p, ff=%p, serial_num=%u", store, store->ff, store->serial_num);
						store_list_remove(store);

						uint32_t ether_type = IP4_ETH_TYPE;
						metadata_writeToElement(store->ff->metaData, "send_ether_type", &ether_type, META_TYPE_INT32);
						metadata_writeToElement(store->ff->metaData, "send_dst_mac", &dst_mac, META_TYPE_INT64);
						metadata_writeToElement(store->ff->metaData, "send_src_mac", &src_mac, META_TYPE_INT64);

						PRINT_DEBUG("recv frame: dst=0x%12.12llx, src=0x%12.12llx, type=0x%x", dst_mac, src_mac, ether_type);

						//print_finsFrame(fins_frame);
						ipv4_to_switch(store->ff);
						store->ff = NULL;

						store_free(store);

						freeFinsFrame(ff);
					} else {
						PRINT_ERROR("todo error");
					}
				}
			} else {
				//TODO error sending back FDF as FCF? saved pdu for that
				PRINT_ERROR("todo error");
			}
			break;
		default:
			PRINT_ERROR("Error unknown param_id=%d", ff->ctrlFrame.param_id);
			//TODO implement?
			freeFinsFrame(ff);
			break;
		}
	} else {
		//TODO send nack
		PRINT_ERROR("Error fcf.metadata==NULL");
		freeFinsFrame(ff);
	}
}
void IP4_receive_fdf(void) {

	struct finsFrame* pff = NULL;
	uint32_t protocol;
	do {
		sem_wait(&Switch_to_IPv4_Qsem);
		pff = read_queue(Switch_to_IPv4_Queue);
		sem_post(&Switch_to_IPv4_Qsem);
	} while (ipv4_running && pff == NULL);

	if (!ipv4_running) {
		return;
	}

	if (pff->dataOrCtrl == CONTROL) {
		PRINT_DEBUG("Received frame: D/C: %d, DestID=%d, ff=%p, meta=%p", pff->dataOrCtrl, pff->destinationID.id, pff, pff->metaData);
		ipv4_fcf(pff);
	} else if (pff->dataOrCtrl == DATA) {
		PRINT_DEBUG("Received frame: D/C: %d, DestID=%d, ff=%p, meta=%p", pff->dataOrCtrl, pff->destinationID.id, pff, pff->metaData);
		PRINT_DEBUG("PDU Length: %d", pff->dataFrame.pduLength);
		PRINT_DEBUG("Data direction: %d", pff->dataFrame.directionFlag);
		PRINT_DEBUG("pdu=%p", pff->dataFrame.pdu);

		if (pff->dataFrame.directionFlag == UP) {
			PRINT_DEBUG("IP4_in");

			IP4_in(pff, (struct ip4_packet*) pff->dataFrame.pdu, pff->dataFrame.pduLength);

		} else if (pff->dataFrame.directionFlag == DOWN) {
			PRINT_DEBUG("IP4_out");

			metadata *params = pff->metaData;
			if (params == NULL) {
				PRINT_ERROR("todo error");
				freeFinsFrame(pff);
				return;
			}

			int ret = 0;
			ret += metadata_readFromElement(params, "send_protocol", &protocol) == META_FALSE;

			if (ret) {
				PRINT_ERROR("metadata read error: ret=%d", ret);
			}

			PRINT_DEBUG("%lu", my_ip_addr);
			PRINT_DEBUG("Transport protocol going out passed to IPv4: protocol=%u", protocol);
			switch (protocol) {
			case IP4_PT_ICMP:
				IP4_out(pff, pff->dataFrame.pduLength, my_ip_addr, IP4_PT_ICMP);
				break;
			case IP4_PT_TCP:
				IP4_out(pff, pff->dataFrame.pduLength, my_ip_addr, IP4_PT_TCP);
				break;
			case IP4_PT_UDP:
				IP4_out(pff, pff->dataFrame.pduLength, my_ip_addr, IP4_PT_UDP);
				break;
			default:
				PRINT_ERROR("invalid protocol: protocol=%u", protocol);
				/**
				 * TODO investigate why the freeFinsFrame below create segmentation fault
				 */
				freeFinsFrame(pff);
				break;
			}

		} else {
			PRINT_ERROR("Error: Wrong value of fdf.directionFlag");
			freeFinsFrame(pff);
		}
	} else {
		PRINT_ERROR("Error: Wrong pff->dataOrCtrl value");
		freeFinsFrame(pff);
	}

}
Esempio n. 5
0
//extern struct ip4_packet *construct_packet_buffer;
void IP4_out(struct finsFrame *ff, uint16_t length, IP4addr source,
		uint8_t protocol) {

	PRINT_DEBUG("");
	//print_finsFrame(ff);
	char *data = (char *) ((ff->dataFrame).pdu);
	PRINT_DEBUG("");

	uint8_t more_fragments = 1;
	uint16_t offset = 0;
	IP4addr destination;

	struct ip4_next_hop_info next_hop;
	struct ip4_fragment fragment;
	struct ip4_packet_header construct_packet;
	struct ip4_packet *construct_packet_buffer;

	//construct_packet_buffer = &construct_packet;
	construct_packet_buffer = (struct ip4_packet *)&construct_packet;
	PRINT_DEBUG("");

	metadata_readFromElement(ff->dataFrame.metaData, "dstip", &destination);

	PRINT_DEBUG("");

	IP4_const_header(construct_packet_buffer, source, destination, protocol);
	PRINT_DEBUG("");
	/** TODO
	 * finding out what is wrong with the fragmentation and reimplement it
	 * correctly
	 * Notice that the current implementation support mutlithreading
	 * while the basic opf the implemented fragmentation is based on having one
	 * global packet to hold the contents
	 */
	/**
	 while (more_fragments)
	 {
	 fragment = IP4_fragment_data(data, length, offset, IP4_PCK_LEN
	 - IP4_MIN_HLEN);
	 memcpy(fragment.data, construct_packet_buffer->ip_data,
	 fragment.data_length);
	 construct_packet_buffer->ip_fragoff = htons(fragment.first >> 3);
	 construct_packet_buffer->ip_len = htons(fragment.data_length
	 + IP4_MIN_HLEN);
	 more_fragments = fragment.more_fragments;
	 next_hop = IP4_next_hop(destination);
	 if (next_hop.interface>=0)
	 {
	 stats.outfragments++;
	 PRINT_DEBUG("");
	 print_finsFrame(ff);
	 IP4_send_fdf_out(ff, construct_packet_buffer, next_hop, fragment.data_length);
	 }
	 else
	 {
	 PRINT_DEBUG("No route to the destination, packet discarded");
	 }
	 more_fragments = fragment.more_fragments;
	 offset = fragment.last + 1;
	 }

	 */
	construct_packet_buffer->ip_fragoff = htons(0);
	construct_packet_buffer->ip_id = htons(0);
	construct_packet_buffer->ip_len = htons(length + IP4_MIN_HLEN);
	construct_packet_buffer->ip_cksum = 0;
	construct_packet_buffer->ip_cksum = IP4_checksum(construct_packet_buffer,
			IP4_MIN_HLEN);

	next_hop = IP4_next_hop(destination);
	if (next_hop.interface >= 0) {
		//stats.outfragments++;
		PRINT_DEBUG("");
		//print_finsFrame(ff);
		IP4_send_fdf_out(ff, construct_packet_buffer, next_hop, length);
	} else {
		PRINT_DEBUG("No route to the destination, packet discarded");
	}

}
Esempio n. 6
0
int UDPreadFrom_fins(unsigned long long uniqueSockID, u_char *buf, int *buflen,
		int symbol, struct sockaddr_in *address, int block_flag, int multi_flag) {

	/**TODO MUST BE FIXED LATER
	 * force symbol to become zero
	 */
	//symbol = 0;
	struct finsFrame *ff = NULL;
	struct finsFrame *ff_copy = NULL;
	int index;
	uint16_t srcport;
	uint32_t srcip;
	struct sockaddr_in * addr_in = (struct sockaddr_in *) address;
	int i;

	sem_wait(&jinniSockets_sem);
	index = findjinniSocket(uniqueSockID);
	sem_post(&jinniSockets_sem);
	PRINT_DEBUG("index = %d", index);
	/**
	 * It keeps looping as a bad method to implement the blocking feature
	 * of recvfrom. In case it is not blocking then the while loop should
	 * be replaced with only a single trial !
	 * TODO Replace the dataqueue with a pipeline (file) this will make it easier
	 * to emulate the file characteristics of the socket such as blocking and non-blocking
	 *
	 */

	PRINT_DEBUG();
	if (block_flag == 1) {
		PRINT_DEBUG();

		int value;
		sem_getvalue(&(jinniSockets[index].Qs), &value);
		PRINT_DEBUG("uniqID=%llu sem: ind=%d, val=%d", uniqueSockID, index,
				value);
		PRINT_DEBUG("block=%d, multi=%d, threads=%d", block_flag, multi_flag,
				jinniSockets[index].threads);

		do {
			sem_wait(&jinniSockets_sem);
			if (jinniSockets[index].uniqueSockID != uniqueSockID) {
				PRINT_DEBUG("Socket closed, canceling read block.");
				sem_post(&jinniSockets_sem);
				return (0);
			}
			sem_wait(&(jinniSockets[index].Qs));
			//		PRINT_DEBUG();
			ff = read_queue(jinniSockets[index].dataQueue);
			//	ff = get_fake_frame();
			//					PRINT_DEBUG();

			if (ff && multi_flag) {
				PRINT_DEBUG("index=%d threads=%d replies=%d", index,
						jinniSockets[index].threads,
						jinniSockets[index].replies);
				if (jinniSockets[index].replies) {
					jinniSockets[index].replies--;
				} else {
					jinniSockets[index].replies = jinniSockets[index].threads
							- 1;
					for (i = 0; i < jinniSockets[index].replies; i++) {
						PRINT_DEBUG("adding frame copy, threads=%d",
								jinniSockets[index].threads);
						ff_copy = (struct finsFrame *) malloc(
								sizeof(struct finsFrame));
						cpy_fins_to_fins(ff_copy, ff); //copies pointers, freeFinsFrame doesn't free pointers
						if (!write_queue_front(ff_copy,
								jinniSockets[index].dataQueue)) {
							; //error
						}
					}
				}
			}

			sem_post(&(jinniSockets[index].Qs));
			sem_post(&jinniSockets_sem);
		} while (ff == NULL);
		PRINT_DEBUG();

	} else {
		PRINT_DEBUG();

		sem_wait(&jinniSockets_sem);
		if (jinniSockets[index].uniqueSockID != uniqueSockID) {
			PRINT_DEBUG("Socket closed, canceling read block.");
			sem_post(&jinniSockets_sem);
			return (0);
		}

		sem_wait(&(jinniSockets[index].Qs));
		//ff= read_queue(jinniSockets[index].dataQueue);
		/**	ff = get_fake_frame();
		 print_finsFrame(ff); */
		ff = read_queue(jinniSockets[index].dataQueue);

		if (ff && multi_flag) {
			PRINT_DEBUG("index=%d threads=%d replies=%d", index,
					jinniSockets[index].threads, jinniSockets[index].replies);
			if (jinniSockets[index].replies) {
				jinniSockets[index].replies--;
			} else {
				jinniSockets[index].replies = jinniSockets[index].threads - 1;
				for (i = 0; i < jinniSockets[index].replies; i++) {
					PRINT_DEBUG("adding frame copy, threads=%d",
							jinniSockets[index].threads);
					ff_copy = (struct finsFrame *) malloc(
							sizeof(struct finsFrame));
					cpy_fins_to_fins(ff_copy, ff); //copies pointers, freeFinsFrame doesn't free pointers
					if (!write_queue_front(ff_copy,
							jinniSockets[index].dataQueue)) {
						; //error
					}
				}
			}
		}

		sem_post(&(jinniSockets[index].Qs));
		sem_post(&jinniSockets_sem);
	}

	if (ff == NULL) {
		//free(ff);
		return (0);
	}
	PRINT_DEBUG("recv'd uniqID=%llu ind=%d", uniqueSockID, index);
	PRINT_DEBUG("PDU length %d", ff->dataFrame.pduLength);

	if (metadata_readFromElement(ff->dataFrame.metaData, "portsrc",
			(uint16_t *) &srcport) == 0) {
		addr_in->sin_port = 0;

	}
	if (metadata_readFromElement(ff->dataFrame.metaData, "ipsrc",
			(uint32_t *) &srcip) == 0) {
		addr_in->sin_addr.s_addr = 0;

	}

	/**
	 * making sure that the datagram coming from the destination we are connected to it
	 * in case of connection previously done
	 */
	sem_wait(&jinniSockets_sem);
	if (jinniSockets[index].uniqueSockID != uniqueSockID) {
		PRINT_DEBUG("Socket closed, canceling read block.");
		sem_post(&jinniSockets_sem);
		return (0);
	}
	PRINT_DEBUG("Rest of read for index=%d.", index);

	if (jinniSockets[index].connection_status > 0) {
		if ((srcport != jinniSockets[index].dstport) || (srcip
				!= jinniSockets[index].dst_IP)) {
			PRINT_DEBUG(
					"Wrong address, the socket is already connected to another destination");
			sem_post(&jinniSockets_sem);
			return (0);
		}
	}
	sem_post(&jinniSockets_sem);

	//*buf = (u_char *)malloc(sizeof(ff->dataFrame.pduLength));
	//memcpy(*buf,ff->dataFrame.pdu,ff->dataFrame.pduLength);
	memcpy(buf, ff->dataFrame.pdu, ff->dataFrame.pduLength);
	*buflen = ff->dataFrame.pduLength;

	PRINT_DEBUG();

	if (symbol == 0) {
		//		address = NULL;
		PRINT_DEBUG();
		//	freeFinsFrame(ff);

		return (1);
	}

	PRINT_DEBUG();

	addr_in->sin_port = srcport;
	addr_in->sin_addr.s_addr = srcip;

	/**TODO Free the finsFrame
	 * This is the final consumer
	 * call finsFrame_free(Struct finsFrame** ff)
	 */
	PRINT_DEBUG();

	//freeFinsFrame(ff);

	/** Finally succeeded
	 *
	 */
	return (1);

} //end of readFrom_fins
Esempio n. 7
0
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);
}