Пример #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 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);
	}
}
Пример #3
0
void module_set_param_flows(struct fins_module *module, struct finsFrame *ff) {
    PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
    struct fins_module_table *mt = (struct fins_module_table *) module->data;

    if (module->flows_max < ff->ctrlFrame.data_len) {
        PRINT_WARN("todo error");
        freeFinsFrame(ff);
        return;
    }
    mt->flows_num = ff->ctrlFrame.data_len;
    struct fins_module_flow *flows = (struct fins_module_flow *) ff->ctrlFrame.data;

    int i;
    for (i = 0; i < mt->flows_num; i++) {
        mt->flows[i].link_id = flows[i].link_id;
        mt->flows[i].link = (struct link_record *) list_find1(mt->link_list, link_id_test, &mt->flows[i].link_id);
    }

#ifdef DEBUG
    uint8_t buf[1000];
    uint8_t *pt = buf;
    int ret;
    for (i = 0; i < mt->flows_num; i++) {
        //ret = sprintf((char *) pt, "%u, ", mt->flows[i].link_id);
        ret = sprintf((char *) pt, "%u (%p), ", mt->flows[i].link_id, mt->flows[i].link);
        pt += ret;
    }
    *pt = '\0';
    PRINT_DEBUG("flows: max=%u, num=%u, ['%s']", module->flows_max, mt->flows_num, buf);
#endif

    //freeFF frees flows
    freeFinsFrame(ff);
}
Пример #4
0
void module_set_param_links(struct fins_module *module, struct finsFrame *ff) {
    PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
    struct fins_module_table *mt = (struct fins_module_table *) module->data;

    if (ff->ctrlFrame.data_len != sizeof(struct linked_list)) {
        PRINT_WARN("todo error");
        freeFinsFrame(ff);
        return;
    }

    if (mt->link_list != NULL) {
        list_free(mt->link_list, free);
    }
    mt->link_list = (struct linked_list *) ff->ctrlFrame.data;

    int i;
    for (i = 0; i < mt->flows_num; i++) {
        mt->flows[i].link = (struct link_record *) list_find1(mt->link_list, link_id_test, &mt->flows[i].link_id);
    }

#ifdef DEBUG
    list_for_each(mt->link_list, link_print);
#endif

    ff->ctrlFrame.data = NULL;
    freeFinsFrame(ff);
}
Пример #5
0
void switch_fcf(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);

//TODO fill out
	switch (ff->ctrlFrame.opcode) {
	case CTRL_ALERT:
		PRINT_DEBUG("opcode=CTRL_ALERT (%d)", CTRL_ALERT);
		PRINT_WARN("todo");
		module_reply_fcf(module, ff, FCF_FALSE, 0);
		break;
	case CTRL_ALERT_REPLY:
		PRINT_DEBUG("opcode=CTRL_ALERT_REPLY (%d)", CTRL_ALERT_REPLY);
		PRINT_WARN("todo");
		freeFinsFrame(ff);
		break;
	case CTRL_READ_PARAM:
		PRINT_DEBUG("opcode=CTRL_READ_PARAM (%d)", CTRL_READ_PARAM);
		PRINT_WARN("todo");
		module_reply_fcf(module, ff, FCF_FALSE, 0);
		break;
	case CTRL_READ_PARAM_REPLY:
		PRINT_DEBUG("opcode=CTRL_READ_PARAM_REPLY (%d)", CTRL_READ_PARAM_REPLY);
		PRINT_WARN("todo");
		freeFinsFrame(ff);
		break;
	case CTRL_SET_PARAM:
		PRINT_DEBUG("opcode=CTRL_SET_PARAM (%d)", CTRL_SET_PARAM);
		switch_set_param(module, ff);
		break;
	case CTRL_SET_PARAM_REPLY:
		PRINT_DEBUG("opcode=CTRL_SET_PARAM_REPLY (%d)", CTRL_SET_PARAM_REPLY);
		PRINT_WARN("todo");
		freeFinsFrame(ff);
		break;
	case CTRL_EXEC:
		PRINT_DEBUG("opcode=CTRL_EXEC (%d)", CTRL_EXEC);
		PRINT_WARN("todo");
		module_reply_fcf(module, ff, FCF_FALSE, 0);
		break;
	case CTRL_EXEC_REPLY:
		PRINT_DEBUG("opcode=CTRL_EXEC_REPLY (%d)", CTRL_EXEC_REPLY);
		PRINT_WARN("todo");
		freeFinsFrame(ff);
		break;
	case CTRL_ERROR:
		PRINT_DEBUG("opcode=CTRL_ERROR (%d)", CTRL_ERROR);
		PRINT_WARN("todo");
		freeFinsFrame(ff);
		break;
	default:
		PRINT_ERROR("opcode=default (%d)", ff->ctrlFrame.opcode);
		exit(-1);
		break;
	}
}
Пример #6
0
void rtm_fcf(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);

//TODO when recv FCF, pull params from meta to figure out connection, send through socket

	switch (ff->ctrlFrame.opcode) {
	case CTRL_ALERT:
		PRINT_DEBUG("opcode=CTRL_ALERT (%d)", CTRL_ALERT);
		PRINT_ERROR("todo");
		module_reply_fcf(module, ff, 0, 0);
		break;
	case CTRL_ALERT_REPLY:
		PRINT_DEBUG("opcode=CTRL_ALERT_REPLY (%d)", CTRL_ALERT_REPLY);
		PRINT_ERROR("todo");
		freeFinsFrame(ff);
		break;
	case CTRL_READ_PARAM:
		PRINT_DEBUG("opcode=CTRL_READ_PARAM (%d)", CTRL_READ_PARAM);
		PRINT_ERROR("todo");
		module_reply_fcf(module, ff, 0, 0);
		break;
	case CTRL_READ_PARAM_REPLY:
		PRINT_DEBUG("opcode=CTRL_READ_PARAM_REPLY (%d)", CTRL_READ_PARAM_REPLY);
		rtm_read_param_reply(module, ff);
		break;
	case CTRL_SET_PARAM:
		PRINT_DEBUG("opcode=CTRL_SET_PARAM (%d)", CTRL_SET_PARAM);
		rtm_set_param(module, ff);
		break;
	case CTRL_SET_PARAM_REPLY:
		PRINT_DEBUG("opcode=CTRL_SET_PARAM_REPLY (%d)", CTRL_SET_PARAM_REPLY);
		rtm_set_param_reply(module, ff);
		break;
	case CTRL_EXEC:
		PRINT_DEBUG("opcode=CTRL_EXEC (%d)", CTRL_EXEC);
		PRINT_ERROR("todo");
		module_reply_fcf(module, ff, 0, 0);
		break;
	case CTRL_EXEC_REPLY:
		PRINT_DEBUG("opcode=CTRL_EXEC_REPLY (%d)", CTRL_EXEC_REPLY);
		rtm_exec_reply(module, ff);
		break;
	case CTRL_ERROR:
		PRINT_DEBUG("opcode=CTRL_ERROR (%d)", CTRL_ERROR);
		PRINT_ERROR("todo");
		freeFinsFrame(ff);
		break;
	default:
		PRINT_DEBUG("opcode=default (%d)", ff->ctrlFrame.opcode);
		PRINT_ERROR("todo");
		exit(-1);
		break;
	}
}
Пример #7
0
void rtm_get_ff(struct fins_module *module) {
	struct rtm_data *md = (struct rtm_data *) module->data;
	struct finsFrame *ff;

	do {
		secure_sem_wait(module->event_sem);
		secure_sem_wait(module->input_sem);
		ff = read_queue(module->input_queue);
		sem_post(module->input_sem);
	} while (module->state == FMS_RUNNING && ff == NULL && !md->interrupt_flag); //TODO change logic here, combine with switch_to_rtm?

	if (module->state != FMS_RUNNING) {
		if (ff != NULL) {
			freeFinsFrame(ff);
		}
		return;
	}

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

		if (ff->dataOrCtrl == FF_CONTROL) {
			rtm_fcf(module, ff);
			PRINT_DEBUG("");
		} else if (ff->dataOrCtrl == FF_DATA) {
			if (ff->dataFrame.directionFlag == DIR_UP) {
				//rtm_in_fdf(module, ff);
				PRINT_WARN("todo error");
				freeFinsFrame(ff);
			} else if (ff->dataFrame.directionFlag == DIR_DOWN) {
				//rtm_out_fdf(module, ff);
				PRINT_WARN("todo error");
				freeFinsFrame(ff);
			} else {
				PRINT_ERROR("todo error");
				exit(-1);
			}
		} else {
			PRINT_ERROR("todo error");
			exit(-1);
		}
	} else if (md->interrupt_flag) {
		md->interrupt_flag = 0;

		rtm_interrupt(module); //TODO unused, implement or remove
	} else {
		PRINT_ERROR("todo error: dataOrCtrl=%u", ff->dataOrCtrl);
		exit(-1);
	}
}
Пример #8
0
void ipv4_fcf(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);

	//TODO make sure is meant for IP, filter out FCF sent through flows w/multi dest

	//TODO fill out
	switch (ff->ctrlFrame.opcode) {
	case CTRL_ALERT:
		PRINT_DEBUG("opcode=CTRL_ALERT (%d)", CTRL_ALERT);
		PRINT_WARN("todo");
		module_reply_fcf(module, ff, FCF_FALSE, 0);
		break;
	case CTRL_ALERT_REPLY:
		PRINT_DEBUG("opcode=CTRL_ALERT_REPLY (%d)", CTRL_ALERT_REPLY);
		PRINT_WARN("todo");
		freeFinsFrame(ff);
		break;
	case CTRL_READ_PARAM:
		PRINT_DEBUG("opcode=CTRL_READ_PARAM (%d)", CTRL_READ_PARAM);
		ipv4_read_param(module, ff);
		break;
	case CTRL_READ_PARAM_REPLY:
		PRINT_DEBUG("opcode=CTRL_READ_PARAM_REPLY (%d)", CTRL_READ_PARAM_REPLY);
		PRINT_WARN("todo");
		freeFinsFrame(ff);
		break;
	case CTRL_SET_PARAM:
		PRINT_DEBUG("opcode=CTRL_SET_PARAM (%d)", CTRL_SET_PARAM);
		ipv4_set_param(module, ff);
		break;
	case CTRL_SET_PARAM_REPLY:
		PRINT_DEBUG("opcode=CTRL_SET_PARAM_REPLY (%d)", CTRL_SET_PARAM_REPLY);
		PRINT_WARN("todo");
		freeFinsFrame(ff);
		break;
	case CTRL_EXEC:
		PRINT_DEBUG("opcode=CTRL_EXEC (%d)", CTRL_EXEC);
		ipv4_exec(module, ff);
		break;
	case CTRL_EXEC_REPLY:
		PRINT_DEBUG("opcode=CTRL_EXEC_REPLY (%d)", CTRL_EXEC_REPLY);
		ipv4_exec_reply(module, ff);
		break;
	case CTRL_ERROR:
		PRINT_DEBUG("opcode=CTRL_ERROR (%d)", CTRL_ERROR);
		ipv4_error(module, ff);
		break;
	default:
		PRINT_ERROR("opcode=default (%d)", ff->ctrlFrame.opcode);
		exit(-1);
		break;
	}
}
void ipv4_exec_reply_get_addr(struct finsFrame *ff, uint64_t src_mac, uint64_t dst_mac) {
	PRINT_DEBUG("Entered: ff=%p, src_mac=%llx, dst_mac=%llx", ff, src_mac, dst_mac);

	struct ip4_store *store = store_list_find(ff->ctrlFrame.serial_num);
	if (store) {
		store_list_remove(store);

		metadata *params = store->ff->metaData;

		uint32_t ether_type = IP4_ETH_TYPE;
		metadata_writeToElement(params, "send_dst_mac", &dst_mac, META_TYPE_INT64);
		metadata_writeToElement(params, "send_src_mac", &src_mac, META_TYPE_INT64);
		metadata_writeToElement(params, "send_ether_type", &ether_type, META_TYPE_INT32);

		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");
		//TODO error sending back FDF as FCF? saved pdu for that
	}
}
Пример #10
0
void rtm_set_param_reply(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
	struct rtm_data *md = (struct rtm_data *) module->data;

	secure_sem_wait(&md->shared_sem);
	struct rtm_command *cmd = (struct rtm_command *) list_find1(md->cmd_list, rtm_cmd_serial_test, &ff->ctrlFrame.serial_num);
	if (cmd != NULL) {
		list_remove(md->cmd_list, cmd);

		struct rtm_console *console = (struct rtm_console *) list_find1(md->console_list, rtm_console_id_test, &cmd->console_id);
		if (console != NULL) {
			//TODO extract answer
			if (ff->ctrlFrame.ret_val) {
				//send '' ?
				rtm_send_text(console->fd, "successful");
			} else {
				//send error
				rtm_send_text(console->fd, "unsuccessful");
			}
		} else {
			PRINT_ERROR("todo error");
		}
		sem_post(&md->shared_sem);

		free(cmd);
	} else {
		sem_post(&md->shared_sem);
		PRINT_ERROR("todo error");
		//TODO error, drop
		freeFinsFrame(ff);
	}
}
Пример #11
0
void rtm_set_param_reply(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
	struct rtm_data *md = (struct rtm_data *) module->data;

	secure_sem_wait(&md->shared_sem);
	struct rtm_command *cmd = (struct rtm_command *) list_find1(md->cmd_list, rtm_cmd_serial_test, &ff->ctrlFrame.serial_num);
	if (cmd != NULL) {
		list_remove(md->cmd_list, cmd);

		struct rtm_console *console = (struct rtm_console *) list_find1(md->console_list, rtm_console_id_test, &cmd->console_id);
		if (console != NULL) {
			if (ff->ctrlFrame.ret_val == FCF_TRUE) {
				rtm_send_text(console->fd, "successful");
			} else {
				//send error
				uint32_t ret_msg;
				secure_metadata_readFromElement(ff->metaData, "ret_msg", &ret_msg);

				char temp[100];
				sprintf(temp, "unsuccessful, returned error=%u", ret_msg);
				rtm_send_text(console->fd, temp);
			}
		} else {
			PRINT_WARN("todo error");
		}
		sem_post(&md->shared_sem);

		free(cmd);
	} else {
		sem_post(&md->shared_sem);
		PRINT_WARN("todo error");
		//TODO error, drop
		freeFinsFrame(ff);
	}
}
Пример #12
0
void udp_sent_free(struct udp_sent *sent) {
	PRINT_DEBUG("Entered: sent=%p", sent);

	if (sent->ff != NULL) {
		freeFinsFrame(sent->ff);
	}

	free(sent);
}
Пример #13
0
void udp_exec_clear_sent(struct fins_module *module, struct finsFrame *ff, uint32_t host_ip, uint16_t host_port, uint32_t rem_ip, uint16_t rem_port) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, host=%u:%u, rem=%u:%u", module, ff, host_ip, host_port, rem_ip, rem_port);
	struct udp_data *md = (struct udp_data *) module->data;

	if (!list_is_empty(md->sent_packet_list)) {
		struct linked_list *old_list = list_remove_all2(md->sent_packet_list, udp_sent_host_test, &host_ip, &host_port);
		list_free(old_list, udp_sent_free);
	}

	freeFinsFrame(ff);
}
Пример #14
0
void module_set_param_dual(struct fins_module *module, struct finsFrame *ff) {
    PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
    struct fins_module_table *mt = (struct fins_module_table *) module->data;

    if (ff->ctrlFrame.data_len != sizeof(struct fins_module_table)) {
        PRINT_WARN("todo error");
        freeFinsFrame(ff);
        return;
    }
    struct fins_module_table *table = (struct fins_module_table *) ff->ctrlFrame.data;

    if (module->flows_max < table->flows_num || table->link_list == NULL) {
        PRINT_WARN("todo error");
        freeFinsFrame(ff);
        return;
    }
    mt->link_list = table->link_list;
    mt->flows_num = table->flows_num;
    if (mt->flows_num != 0) {
        memcpy(mt->flows, table->flows, mt->flows_num * sizeof(struct fins_module_flow));
    }

#ifdef DEBUG
    uint8_t buf[1000];
    uint8_t *pt = buf;
    int ret;
    int i;
    for (i = 0; i < mt->flows_num; i++) {
        //ret = sprintf((char *) pt, "%u, ", mt->flows[i].link_id);
        ret = sprintf((char *) pt, "%u (%p), ", mt->flows[i].link_id, mt->flows[i].link);
        pt += ret;
    }
    *pt = '\0';
    PRINT_DEBUG("flows: max=%u, num=%u, ['%s']", module->flows_max, mt->flows_num, buf);

    list_for_each(mt->link_list, link_print);
#endif

    //freeFF frees table
    freeFinsFrame(ff);
}
Пример #15
0
void store_free(struct ip4_store *store) {
	PRINT_DEBUG("Entered: store=%p", store);

	if (store->pdu) {
		PRINT_DEBUG("Freeing pdu=%p", store->pdu);
		free(store->pdu);
	}

	if (store->ff)
		freeFinsFrame(store->ff);

	free(store);
}
Пример #16
0
void ipv4_get_ff(struct fins_module *module) {
	struct finsFrame *ff;
	do {
		secure_sem_wait(module->event_sem);
		secure_sem_wait(module->input_sem);
		ff = read_queue(module->input_queue);
		sem_post(module->input_sem);
	} while (module->state == FMS_RUNNING && ff == NULL); //TODO change logic here, combine with switch_to_ipv4?

	if (module->state != FMS_RUNNING) {
		if (ff != NULL) {
			freeFinsFrame(ff);
		}
		return;
	}

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

	if (ff->dataOrCtrl == FF_CONTROL) {
		ipv4_fcf(module, ff);
		PRINT_DEBUG("");
	} else if (ff->dataOrCtrl == FF_DATA) {
		if (ff->dataFrame.directionFlag == DIR_UP) {
			ipv4_in_fdf(module, ff);
			PRINT_DEBUG("");
		} else if (ff->dataFrame.directionFlag == DIR_DOWN) {
			ipv4_out_fdf(module, ff);
			PRINT_DEBUG("");
		} else {
			PRINT_ERROR("Error: Wrong value of fdf.directionFlag");
			exit(-1);
		}
	} else {
		PRINT_ERROR("Error: Wrong ff->dataOrCtrl value");
		exit(-1);
	}

}
Пример #17
0
void rtm_alert(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
	struct rtm_data *md = (struct rtm_data *) module->data;

	//Get from fcf: module index, opcode==CTRL_ALERT, param_id

	secure_sem_wait(&md->shared_sem);
	//search for consoles with type==listener/dual, & registered for module index / param_id
	struct linked_list *listening_list = list_find_all2(md->console_list, rtm_console_listening_test, &ff->ctrlFrame.sender_id, &ff->ctrlFrame.param_id);

	//for each console push the traffic
	struct rtm_console *console;
	while (!list_is_empty(listening_list)) {
		console = (struct rtm_console *) list_remove_front(listening_list);
		rtm_send_fd(console->fd, ff->ctrlFrame.data_len, ff->ctrlFrame.data);
	}
	sem_post(&md->shared_sem);
	free(listening_list);

	freeFinsFrame(ff);
}
Пример #18
0
void rtm_read_param_reply(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
	struct rtm_data *md = (struct rtm_data *) module->data;

	secure_sem_wait(&md->shared_sem);
	struct rtm_command *cmd = (struct rtm_command *) list_find1(md->cmd_list, rtm_cmd_serial_test, &ff->ctrlFrame.serial_num);
	if (cmd != NULL) {
		list_remove(md->cmd_list, cmd);

		struct rtm_console *console = (struct rtm_console *) list_find1(md->console_list, rtm_console_id_test, &cmd->console_id);
		if (console != NULL) {
			//TODO extract answer
			if (ff->ctrlFrame.ret_val == FCF_TRUE) {
				char temp[100];

				int32_t val_int32;
				int64_t val_int64;
				float val_float;
				char *val_str;

				switch (cmd->param_type) {
				case META_TYPE_INT32:
					secure_metadata_readFromElement(ff->metaData, "value", &val_int32);
					sprintf(temp, "'%s'=%d", cmd->param_str, val_int32);
					break;
				case META_TYPE_INT64:
					secure_metadata_readFromElement(ff->metaData, "value", &val_int64);
					sprintf(temp, "'%s'=%lld", cmd->param_str, val_int64);
					break;
				case META_TYPE_FLOAT:
					secure_metadata_readFromElement(ff->metaData, "value", &val_float);
					sprintf(temp, "'%s'=%f", cmd->param_str, val_float);
					break;
				case META_TYPE_STRING:
					secure_metadata_readFromElement(ff->metaData, "value", &val_str);
					sprintf(temp, "'%s'='%s'", cmd->param_str, val_str);
					break;
				default:
					PRINT_ERROR("todo error");
					exit(-1);
				}

				rtm_send_text(console->fd, temp);
			} else {
				//send error
				uint32_t ret_msg;
				secure_metadata_readFromElement(ff->metaData, "ret_msg", &ret_msg);

				char temp[100];
				sprintf(temp, "unsuccessful, returned error=%u", ret_msg);
				rtm_send_text(console->fd, temp);
			}
		} else {
			PRINT_WARN("todo error");
		}
		sem_post(&md->shared_sem);

		free(cmd);
	} else {
		sem_post(&md->shared_sem);
		PRINT_WARN("todo error");
		//TODO error, drop
		freeFinsFrame(ff);
	}
}
Пример #19
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;
	}
}
Пример #20
0
int TerminateFinsQueue(finsQueue Q) {
	PRINT_DEBUG("Entered: Q=%p, name='%s'", Q, Q->name);

	int counter = 0;
	int empty = 0;
	int size = Q->Size;
	int i;
	//ElementType X = (ElementType)malloc (sizeof(ElementType));
	int min;
	int max;

	PRINT_DEBUG("Front=%d, Rear=%d, Cap=%d", Q->Front, Q->Rear, Q->Capacity);

	if (Q->Front <= Q->Rear) {
		min = Q->Front;
		max = Q->Rear;

		for (i = min; i <= max; i++) {
			if (Q->Array[i]) {
				/*
				 if (Q->Array[i]->dataOrCtrl == FF_DATA) {
				 if (Q->Array[i]->dataFrame.pdu) {
				 free(Q->Array[i]->dataFrame.pdu);
				 }
				 }
				 */

				if (freeFinsFrame(Q->Array[i]) == 0) {
					//PRINT_DEBUG("333");

					//PRINT_DEBUG("Element number %d was already NULL before deleting",i);
					empty++;
				} else {
					counter++;
				}
			}
		}
	} else {

		max = Q->Front;
		min = Q->Rear;

		for (i = max; i < Q->Capacity; i++) {
			if (Q->Array[i]) {
				/*
				 if (Q->Array[i]->dataOrCtrl == FF_DATA) {
				 if (Q->Array[i]->dataFrame.pdu) {
				 free(Q->Array[i]->dataFrame.pdu);
				 }
				 }
				 */

				if (freeFinsFrame(Q->Array[i]) == 0) {
					//PRINT_DEBUG("333");

					//PRINT_DEBUG("Element number %d was already NULL before deleting",i);
					empty++;
				} else {
					counter++;
				}
			}
		}

		for (i = 0; i <= min; i++) {
			if (Q->Array[i]) {
				/*
				 if (Q->Array[i]->dataOrCtrl == FF_DATA) {
				 if (Q->Array[i]->dataFrame.pdu) {
				 free(Q->Array[i]->dataFrame.pdu);
				 }
				 }
				 */

				if (freeFinsFrame(Q->Array[i]) == 0) {
					//PRINT_DEBUG("333");

					//PRINT_DEBUG("Element number %d was already NULL before deleting",i);
					empty++;

				} else {
					counter++;
				}
			}
		}
	}

	//while (checkEmpty(Q))

	PRINT_DEBUG("Empty cleared=%d/%d", empty, Q->Capacity);

	Q->Size = 0;

	if (counter == size)
		return (1);
	else
		return (0);

}
Пример #21
0
void *switch_loop(void *local) {
	PRINT_DEBUG("Entered");

	int i;
	struct finsFrame *ff;

	int counter = 0;

	while (switch_running) {
		/** the receiving Queues are only the even numbers
		 * 0,2,4,6,8,10,12,14. This is why we increase the counter by 2
		 */
		for (i = 0; i < MAX_modules; i = i + 2) {
			sem_wait(IO_queues_sem[i]);
			ff = read_queue(modules_IO_queues[i]);
			sem_post(IO_queues_sem[i]);

			if (ff != NULL) {
				counter++;
				//PRINT_DEBUG("Counter %d", counter);

				switch (ff->destinationID.id) {
				case ARP_ID:
					PRINT_DEBUG("Counter=%d, from='%s' to ARP Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData);
					sem_wait(&Switch_to_ARP_Qsem);
					write_queue(ff, Switch_to_ARP_Queue);
					sem_post(&Switch_to_ARP_Qsem);
					break;
				case RTM_ID:
					PRINT_DEBUG("Counter=%d, from='%s' to RTM Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData);
					sem_wait(&Switch_to_RTM_Qsem);
					write_queue(ff, Switch_to_RTM_Queue);
					sem_post(&Switch_to_RTM_Qsem);
					break;
				case DAEMON_ID:
					PRINT_DEBUG("Counter=%d, from='%s' to Daemon Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData);
					sem_wait(&Switch_to_Daemon_Qsem);
					write_queue(ff, Switch_to_Daemon_Queue);
					sem_post(&Switch_to_Daemon_Qsem);
					break;
				case UDP_ID:
					PRINT_DEBUG("Counter=%d, from='%s' to UDP Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData);
					sem_wait(&Switch_to_UDP_Qsem);
					write_queue(ff, Switch_to_UDP_Queue);
					sem_post(&Switch_to_UDP_Qsem);
					break;
				case TCP_ID:
					PRINT_DEBUG("Counter=%d, from='%s' to TCP Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData);
					sem_wait(&Switch_to_TCP_Qsem);
					write_queue(ff, Switch_to_TCP_Queue);
					sem_post(&Switch_to_TCP_Qsem);
					break;
				case IPV4_ID:
					PRINT_DEBUG("Counter=%d, from='%s' to IPv4 Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData);
					sem_wait(&Switch_to_IPv4_Qsem);
					write_queue(ff, Switch_to_IPv4_Queue);
					sem_post(&Switch_to_IPv4_Qsem);
					break;
				case INTERFACE_ID:
					PRINT_DEBUG("Counter=%d, from='%s' to Interface Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData);
					sem_wait(&Switch_to_Interface_Qsem);
					write_queue(ff, Switch_to_Interface_Queue);
					sem_post(&Switch_to_Interface_Qsem);
					break;
				case ICMP_ID:
					PRINT_DEBUG("Counter=%d, from='%s' to ICMP Queue +1, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData);
					sem_wait(&Switch_to_ICMP_Qsem);
					write_queue(ff, Switch_to_ICMP_Queue);
					sem_post(&Switch_to_ICMP_Qsem);
					break;
				default:
					PRINT_DEBUG("Counter=%d, from='%s' to Unknown Dest, ff=%p, meta=%p", counter, modules_IO_queues[i]->name, ff, ff->metaData);
					freeFinsFrame(ff);
					break;
				} // end of Switch statement
			} // end of if (ff != NULL )
			else { //PRINT_DEBUG("No frame read from Queue # %d", i);

			}

		} //end of for For loop (Round Robin reading from Modules)

	} // end of while loop

	PRINT_DEBUG("Exited");
	pthread_exit(NULL);
} // end of switch_init Function
Пример #22
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 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);
	}

}
Пример #24
0
/**
 * @brief Function processing all the incoming packets
 *
 * Responsible for parsing, checking reassembling and passing packets out.
 */
void ipv4_in_fdf(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
	struct ipv4_data *md = (struct ipv4_data *) module->data;

	struct ip4_packet* ppacket = (struct ip4_packet*) ff->dataFrame.pdu;
	int len = ff->dataFrame.pduLength;

	md->stats.receivedtotal++;
	/* Parse the header. Some of the items only needed to be inserted into FDF meta data*/
	struct ip4_header header;
	header.source = ntohl(ppacket->ip_src);
	header.destination = ntohl(ppacket->ip_dst);
	header.version = IP4_VER(ppacket);
	header.header_length = IP4_HLEN(ppacket);
	header.differentiated_service = ppacket->ip_dif;
	header.packet_length = ntohs(ppacket->ip_len);
	header.id = ntohs(ppacket->ip_id);
	header.flags = (uint8_t) (IP4_FLG(ntohs(ppacket->ip_fragoff)));
	header.fragmentation_offset = ntohs(ppacket->ip_fragoff) & IP4_FRAGOFF;
	header.ttl = ppacket->ip_ttl;
	header.protocol = ppacket->ip_proto;
	PRINT_DEBUG("protocol number is %d", header.protocol);
	header.checksum = ntohs(ppacket->ip_cksum);
	PRINT_DEBUG("");

	/** Check packet version */
	if (header.version != IP4_VERSION) {
		md->stats.badver++;
		md->stats.droppedtotal++;
		PRINT_ERROR("Packet ID %d has a wrong IP version (%d)", header.id, header.version);
		//free ppacket
		return;
	}
	PRINT_DEBUG("");

	/* Check minimum header length */
	if (header.header_length < IP4_MIN_HLEN) {
		PRINT_ERROR("Packet header length (%d) in packet ID %d is smaller than the defined minimum (20).", header.header_length, header.id);
		md->stats.badhlen++;
		md->stats.droppedtotal++;

		//free ppacket
		freeFinsFrame(ff);
		return;
	}
	//int hlen = header.header_length; //IP4_HLEN(ppacket);
	//PRINT_DEBUG("hdr_len=%u, hlen=%u", header.header_length, IP4_HLEN(ppacket));

	/* Check the integrity of the header. Drop the packet if corrupted header.*/
	if (ipv4_checksum(ppacket, header.header_length) != 0) { //TODO check this checksum, don't think it does uneven?
		PRINT_ERROR("Checksum check failed on packet ID %d, non zero result: %d", header.id, ipv4_checksum(ppacket, header.header_length));
		md->stats.badsum++;
		md->stats.droppedtotal++;

		//free ppacket
		freeFinsFrame(ff);
		return;
	}
	PRINT_DEBUG("");

	/* Check the length of the packet. If physical shorter than the declared in the header
	 * drop the packet
	 */
	if (header.packet_length != len) {
		md->stats.badlen++;
		PRINT_DEBUG("The declared length is not equal to the actual length. pkt_len=%u len=%u", header.packet_length, len);
		if (header.packet_length > len) {
			PRINT_DEBUG("The header length is even longer than the len");
			md->stats.droppedtotal++;

			//free ppacket
			freeFinsFrame(ff);
			return;
		}
	}
	PRINT_DEBUG("");

	if (header.ttl == 0) {
		PRINT_WARN("todo");
		//TODO discard packet & send TTL icmp to sender

		freeFinsFrame(ff);
		return;
	}

	PRINT_DEBUG("src=%u, dst=%u (hostf)", header.source, header.destination);
	/* Check the destination address, if not our, forward*/
	if (header.destination != IPV4_ADDR_ANY_IP && header.destination != IPV4_ADDR_EVERY_IP) { //TODO check this
		struct addr_record *addr = (struct addr_record *) list_find1(md->addr_list, addr_ipv4_test, &header.destination);
		if (addr == NULL) {
			addr = (struct addr_record *) list_find1(md->addr_list, addr_bdcv4_test, &header.destination);
			if (addr == NULL) {
				if (ipv4_forward(module, ff, ppacket, header.destination, len)) { //TODO disabled atm
					md->stats.forwarded++;
					PRINT_DEBUG("");
				} else {
					md->stats.droppedtotal++;
					PRINT_DEBUG("");
					freeFinsFrame(ff);
				}
				return;
			}
		}
	}
	PRINT_DEBUG("");

	/* Check fragmentation errors */
	if ((header.flags & (IP4_DF | IP4_MF)) == (IP4_DF | IP4_MF)) {
		md->stats.fragerror++;
		md->stats.droppedtotal++;
		PRINT_ERROR("Packet ID %d has both DF and MF flags set", header.id);
		//free ppacket
		freeFinsFrame(ff);
		return;
	}
	/* If not fragmented, pass out. If fragmented, call reassembly algorithm.
	 * If reassembly of an entire packet completed by this frame, pass out.
	 * Otherwise return.
	 */
	PRINT_DEBUG("");

	if (((header.flags & IP4_MF) | header.fragmentation_offset) == 0) {
		md->stats.delivered++;
		PRINT_DEBUG("");

		ipv4_send_fdf_in(module, ff, &header, ppacket);
	} else {
		PRINT_WARN("todo");
		//TODO fix this!! convert to module based
		PRINT_DEBUG("Packet ID %d is fragmented", header.id);
		struct ip4_packet* ppacket_reassembled = NULL; //IP4_reass(&header, ppacket);
		//free ppacket
		if (ppacket_reassembled != NULL) {
			md->stats.delivered++;
			md->stats.reassembled++;
			ipv4_send_fdf_in(module, ff, &header, ppacket_reassembled);
		} else {

		}
	}
}
Пример #25
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);
}
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);
	}
}
Пример #27
0
void ipv4_exec_reply(struct fins_module *module, struct finsFrame *ff) {
	PRINT_DEBUG("Entered: module=%p, ff=%p, meta=%p", module, ff, ff->metaData);
	PRINT_WARN("todo");
	freeFinsFrame(ff);
}
Пример #28
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);
}