コード例 #1
0
ファイル: udp.c プロジェクト: jiangxianliang/FINS-Framework
void udp_error(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
	struct udp_data *md = (struct udp_data *) module->data;

	//uint32_t src_ip;
	//uint32_t src_port;
	//uint32_t dst_ip;
	//uint32_t dst_port;

	//uint32_t udp_len;
	//uint32_t checksum;

	switch (ff->ctrlFrame.param_id) {
	case UDP_ERROR_TTL:
		PRINT_DEBUG("param_id=UDP_ERROR_TTL (%d)", ff->ctrlFrame.param_id);

		/*
		 struct udp_packet *udp_hdr = (struct udp_packet *) ff->ctrlFrame.data;
		 struct udp_header hdr;

		 hdr.u_src = ntohs(udp_hdr->u_src);
		 hdr.u_dst = ntohs(udp_hdr->u_dst);
		 hdr.u_len = ntohs(udp_hdr->u_len);
		 hdr.u_cksum = ntohs(udp_hdr->u_cksum);
		 */

		//if recv_dst_ip==send_src_ip, recv_dst_port==send_src_port, recv_udp_len==, recv_checksum==,  \\should be unique!
		if (list_is_empty(md->sent_packet_list)) {
			PRINT_WARN("todo error");
			//TODO drop
			freeFinsFrame(ff);
		} else {
			uint8_t *pdu = ff->ctrlFrame.data;
			if (pdu != NULL) { //TODO make func!!
				struct udp_sent *sent = (struct udp_sent *) list_find2(md->sent_packet_list, udp_sent_match_test, &ff->ctrlFrame.data_len, pdu);
				if (sent != NULL) {
					metadata_copy(sent->ff->metaData, ff->metaData);

					ff->ctrlFrame.sender_id = module->index;
					//ff->ctrlFrame.param_id = UDP_ERROR_TTL; //TODO error msg code //ERROR_UDP_TTL?

					ff->ctrlFrame.data_len = sent->ff->dataFrame.pduLength;
					ff->ctrlFrame.data = sent->ff->dataFrame.pdu;
					sent->ff->dataFrame.pdu = NULL;

					if (!module_send_flow(module, ff, UDP_FLOW_DAEMON)) {
						PRINT_WARN("todo error");
						freeFinsFrame(ff);
					}

					list_remove(md->sent_packet_list, sent);
					udp_sent_free(sent);
					PRINT_DEBUG("Freeing: pdu=%p", pdu);
					free(pdu);
				} else {
					PRINT_WARN("todo error");
					freeFinsFrame(ff);
					//TODO drop?
				}
			} else {
				PRINT_WARN("todo");
				freeFinsFrame(ff);
			}
		}
		break;
	case UDP_ERROR_DEST_UNREACH:
		PRINT_DEBUG("param_id=UDP_ERROR_DEST_UNREACH (%d)", ff->ctrlFrame.param_id);

		if (list_is_empty(md->sent_packet_list)) {
			PRINT_WARN("todo error");
			//TODO drop
			freeFinsFrame(ff);
		} else {
			uint8_t *pdu = ff->ctrlFrame.data;
			if (pdu != NULL) {
				struct udp_sent *sent = (struct udp_sent *) list_find2(md->sent_packet_list, udp_sent_match_test, &ff->ctrlFrame.data_len, pdu);
				if (sent != NULL) {
					metadata_copy(sent->ff->metaData, ff->metaData);

					ff->ctrlFrame.sender_id = module->index;
					//ff->ctrlFrame.param_id = UDP_ERROR_DEST_UNREACH; //TODO error msg code //ERROR_UDP_TTL?

					ff->ctrlFrame.data_len = sent->ff->dataFrame.pduLength;
					ff->ctrlFrame.data = sent->ff->dataFrame.pdu;
					sent->ff->dataFrame.pdu = NULL;

					if (!module_send_flow(module, ff, UDP_FLOW_DAEMON)) {
						PRINT_WARN("todo error");
						freeFinsFrame(ff);
					}

					list_remove(md->sent_packet_list, sent);
					udp_sent_free(sent);
					PRINT_DEBUG("Freeing: pdu=%p", pdu);
					free(pdu);
				} else {
					PRINT_WARN("todo error");
					//TODO drop?
					freeFinsFrame(ff);
				}
			} else {
				PRINT_WARN("todo");
				freeFinsFrame(ff);
			}
		}
		break;
	case UDP_ERROR_GET_ADDR:
		PRINT_DEBUG("param_id=UDP_ERROR_GET_ADDR (%d)", ff->ctrlFrame.param_id);

		if (!list_is_empty(md->sent_packet_list)) {
			uint8_t *pdu = ff->ctrlFrame.data;
			if (pdu != NULL) { //TODO make func!!
				struct udp_sent *sent = (struct udp_sent *) list_find2(md->sent_packet_list, udp_sent_match_test, &ff->ctrlFrame.data_len, pdu);
				if (sent != NULL) {
					list_remove(md->sent_packet_list, sent);
					udp_sent_free(sent);
				}
			}
		}

		ff->ctrlFrame.sender_id = module->index;
		//ff->ctrlFrame.param_id = UDP_ERROR_GET_ADDR; //TODO error msg code //ERROR_UDP_TTL?

		if (!module_send_flow(module, ff, UDP_FLOW_DAEMON)) {
			PRINT_WARN("todo error");
			freeFinsFrame(ff);
		}
		break;
	default:
		PRINT_ERROR("Error unknown param_id=%d", ff->ctrlFrame.param_id);
		PRINT_WARN("todo error");
		freeFinsFrame(ff);
		break;
	}
}
コード例 #2
0
ファイル: udp_out.c プロジェクト: c-ong/FINS-Framework
void udp_out_fdf(struct fins_module *module, struct finsFrame* ff) {
	struct udp_data *md = (struct udp_data *) module->data;
	//struct udp_metadata_parsed parsed_meta;

	//struct udp_packet packet_host;
	struct udp_packet *packet_netw;
	uint16_t packet_length;

	/* read the FDF and make sure everything is correct*/
	PRINT_DEBUG("UDP_out, ff=%p, meta=%p", ff, ff->metaData);

	//print_finsFrame(ff);

	packet_length = ff->dataFrame.pduLength + U_HEADER_LEN;

	if (packet_length > IP_MAXLEN) {
		PRINT_ERROR("todo error, data too long max 65536, len=%d", packet_length);
	}

	uint8_t *udp_dataunit = (uint8_t *) secure_malloc(packet_length);
	packet_netw = (struct udp_packet *) udp_dataunit;
	uint8_t *pdu = ff->dataFrame.pdu;

	/** constructs the UDP packet from the FDF and the meta data */

	//#########################
#ifdef DEBUG
	if (1) {
		uint8_t *temp = (uint8_t *) secure_malloc(ff->dataFrame.pduLength + 1);
		memcpy(temp, pdu, ff->dataFrame.pduLength);
		temp[ff->dataFrame.pduLength] = '\0';
		PRINT_DEBUG("pduLen=%d, pdu='%s'", ff->dataFrame.pduLength, temp);
		free(temp);
	}
#endif
	//#########################

	uint32_t dst_port;
	uint32_t src_port;

	uint32_t dst_ip;
	uint32_t src_ip;

	uint32_t family;
	secure_metadata_readFromElement(ff->metaData, "send_family", &family);
	secure_metadata_readFromElement(ff->metaData, "send_src_ipv4", &src_ip);
	secure_metadata_readFromElement(ff->metaData, "send_src_port", &src_port);
	secure_metadata_readFromElement(ff->metaData, "send_dst_ipv4", &dst_ip);
	secure_metadata_readFromElement(ff->metaData, "send_dst_port", &dst_port);

	uint32_t protocol = UDP_PROTOCOL;
	secure_metadata_writeToElement(ff->metaData, "send_protocol", &protocol, META_TYPE_INT32);

	/** fixing the values because of the conflict between uint16 type and
	 * the 32 bit META_INT_TYPE
	 */

	//packet_host.u_src = srcbuf16;
	//packet_host.u_dst = dstbuf16;
	//packet_host.u_len = packet_length;
	//packet_host.u_cksum = 0;
	packet_netw->u_src = htons((uint16_t) src_port);
	packet_netw->u_dst = htons((uint16_t) dst_port);
	packet_netw->u_len = htons(packet_length);
	packet_netw->u_cksum = 0;
	memcpy(packet_netw->u_data, pdu, ff->dataFrame.pduLength);

	PRINT_DEBUG("src=%u:%u, dst=%u:%u, pkt_len=%u", src_ip, (uint16_t)src_port, dst_ip, (uint16_t)dst_port, packet_length);

	uint16_t checksum = UDP_checksum(packet_netw, htonl(src_ip), htonl(dst_ip));
	packet_netw->u_cksum = htons(checksum);
	//packet_netw->u_cksum = 0;
	PRINT_DEBUG("checksum (h):0x%x", checksum);

	//PRINT_DEBUG("%u,%u", src_ip, dst_ip);

	PRINT_DEBUG("pkt_netw: %d,%d,%d,0x%x", packet_netw->u_src, packet_netw->u_dst, packet_netw->u_len, packet_netw->u_cksum);

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

	ff->dataFrame.pduLength = packet_length;
	ff->dataFrame.pdu = udp_dataunit;

	md->stats.totalSent++;

	struct finsFrame *ff_clone = cloneFinsFrame(ff);

	//TODO add switch & move between ipv4/ipv6
	if (!module_send_flow(module, ff, UDP_FLOW_IPV4)) {
		PRINT_ERROR("send to switch error, ff=%p", ff);
		freeFinsFrame(ff);
	}
	struct udp_sent *sent = udp_sent_create(ff_clone, src_ip, src_port, dst_ip, dst_port);

	if (list_has_space(md->sent_packet_list)) {
		list_append(md->sent_packet_list, sent);
		PRINT_DEBUG("sent_packet_list=%p, len=%u, max=%u", md->sent_packet_list, md->sent_packet_list->len, md->sent_packet_list->max);

		gettimeofday(&sent->stamp, 0);
	} else {
		//PRINT_DEBUG("Clearing sent_packet_list");
		//udp_sent_list_gc(udp_sent_packet_list, UDP_MSL_TO_DEFAULT);

		//if (!udp_sent_list_has_space(udp_sent_packet_list)) {
		PRINT_DEBUG("Dropping head of sent_packet_list");
		struct udp_sent *old = (struct udp_sent *) list_remove_front(md->sent_packet_list);
		udp_sent_free(old);
		//}
		list_append(md->sent_packet_list, sent);
		PRINT_DEBUG("sent_packet_list=%p, len=%u, max=%u", md->sent_packet_list, md->sent_packet_list->len, md->sent_packet_list->max);

		gettimeofday(&sent->stamp, 0);
	}

	PRINT_DEBUG("Freeing: pdu=%p", pdu);
	free(pdu);
}