예제 #1
0
void ipv4_error(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);

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

		//should we separate icmp & error messages? what about disabling ICMP, what errors should it stop?
		//if yes, eth->ip->icmp or ip->proto
		//if no, eth->icmp->proto
		//if partial, eth->ip->icmp->proto (allows for similar to iptables)
		//Sending to ICMP mimic kernel func, if remove icmp stops error

		//if doing routing tables, factor in and process

		ff->ctrlFrame.sender_id = module->index;
		ff->ctrlFrame.param_id = IPV4_ERROR_GET_ADDR;

		//reroute to icmp, though could go directly
		int sent = module_send_flow(module, ff, IPV4_FLOW_ICMP);
		if (sent == 0) {
			freeFinsFrame(ff);
		}
		break;
	default:
		PRINT_DEBUG("param_id=default (%d)", ff->ctrlFrame.param_id);
		PRINT_WARN("todo");
		freeFinsFrame(ff);
		break;
	}

}
예제 #2
0
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;
	}
}
예제 #3
0
void udp_in_fdf(struct fins_module *module, struct finsFrame* ff) {
	struct udp_data *md = (struct udp_data *) module->data;
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);

	/* point to the necessary data in the FDF */
	PRINT_DEBUG("%d", (int)ff);
	struct udp_header* packet = (struct udp_header*) ff->dataFrame.pdu;

	uint32_t protocol;
	secure_metadata_readFromElement(ff->metaData, "recv_protocol", &protocol);
	uint32_t family;
	secure_metadata_readFromElement(ff->metaData, "recv_family", &family);
	uint32_t src_ip;
	secure_metadata_readFromElement(ff->metaData, "recv_src_ipv4", &src_ip);
	uint32_t dst_ip;
	secure_metadata_readFromElement(ff->metaData, "recv_dst_ipv4", &dst_ip);

	if (protocol != UDP_PT_UDP) {
		md->stats.wrongProtocol++;
		md->stats.totalBadDatagrams++;

		PRINT_WARN("wrong protocol: expected=%u, proto=%u", UDP_PT_UDP, protocol);
		freeFinsFrame(ff);
		return;
	}

	/* begins checking the UDP packets integrity */
	/** TODO Fix the length check below , I will highlighted for now */
	uint32_t hlen = ntohs(packet->u_len);
	if (ff->dataFrame.pduLength != hlen) {
		md->stats.mismatchingLengths++;
		md->stats.totalBadDatagrams++;

		PRINT_DEBUG("UDP_in");
		freeFinsFrame(ff);
		return;
	}

	/* the packet is does have an "Ignore checksum" value and fails the checksum, it is thrown away */
	uint16_t checksum = UDP_checksum((struct udp_packet*) packet, htonl(src_ip), htonl(dst_ip));

	uint32_t src_port = ntohs(packet->u_src);
	uint32_t dst_port = ntohs(packet->u_dst);

	PRINT_DEBUG("proto=%u, src=%u:%u, dst=%u:%u", protocol, src_ip, (uint16_t)src_port, dst_ip, (uint16_t)dst_port);
	PRINT_DEBUG("UDP_checksum=%u, checksum=%u", checksum, ntohs(packet->u_cksum));

	if (packet->u_cksum != IGNORE_CHEKSUM) {
		if (checksum != 0) {
			md->stats.badChecksum++;
			md->stats.totalBadDatagrams++;
			PRINT_ERROR("bad checksum=0x%x, calc=0x%x", packet->u_cksum, checksum);
			freeFinsFrame(ff);
			return;
		}
	} else {
		md->stats.noChecksum++;
		PRINT_DEBUG("ignore checksum=%d", md->stats.noChecksum);
	}

	secure_metadata_writeToElement(ff->metaData, "recv_src_port", &src_port, META_TYPE_INT32);
	secure_metadata_writeToElement(ff->metaData, "recv_dst_port", &dst_port, META_TYPE_INT32);

	PRINT_DEBUG("PDU Length including UDP header %d", ff->dataFrame.pduLength);
	PRINT_DEBUG("PDU Length %d", (int)(ff->dataFrame.pduLength - U_HEADER_LEN));

	int leng = ff->dataFrame.pduLength;
	ff->dataFrame.pduLength = leng - U_HEADER_LEN;

	uint8_t *old = ff->dataFrame.pdu;
	uint8_t *pdu = (uint8_t *) secure_malloc(ff->dataFrame.pduLength);
	memcpy(pdu, old + U_HEADER_LEN, ff->dataFrame.pduLength);
	ff->dataFrame.pdu = pdu;

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

	md->stats.totalRecieved++;
	PRINT_DEBUG("UDP total recv'd=%d, ff=%p, meta=%p", md->stats.totalRecieved, ff, ff->metaData);
	if (!module_send_flow(module, ff, UDP_FLOW_DAEMON)) {
		PRINT_ERROR("send to switch error, ff=%p", ff);
		freeFinsFrame(ff);
	}

	PRINT_DEBUG("Freeing: pdu=%p", old);
	free(old);
}
예제 #4
0
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);
}