Beispiel #1
0
void module_create_structs(struct fins_module *module) {
    PRINT_DEBUG("Entered: module=%p, id=%d, name='%s'", module, module->id, module->name);
    char buf[MOD_NAME_SIZE + 10];

    sprintf(buf, "switch_to_%s", module->name);
    module->input_queue = init_queue(buf, MAX_QUEUE_SIZE);
    module->input_sem = (sem_t *) secure_malloc(sizeof(sem_t));
    sem_init(module->input_sem, 0, 1);

    sprintf(buf, "%s_to_switch", module->name);
    module->output_queue = init_queue(buf, MAX_QUEUE_SIZE);
    module->output_sem = (sem_t *) secure_malloc(sizeof(sem_t));
    sem_init(module->output_sem, 0, 1);

    module->event_sem = (sem_t *) secure_malloc(sizeof(sem_t));
    sem_init(module->event_sem, 0, 0);

    module->knobs = (metadata *) secure_malloc(sizeof(metadata));
    metadata_create(module->knobs);

    /*metadata_element *root = config_root_setting(module->knobs);
    secure_config_setting_add(root, OP_EXEC_STR, META_TYPE_GROUP);
    secure_config_setting_add(root, OP_GET_STR, META_TYPE_GROUP);
    secure_config_setting_add(root, OP_SET_STR, META_TYPE_GROUP);
    secure_config_setting_add(root, OP_LISTEN_STR, META_TYPE_GROUP);
    */
}
Beispiel #2
0
struct finsFrame* create_ff(int dataOrCtrl, int direction, int destID, int PDU_length, uint8_t* PDU, metadata *meta) {
	struct finsFrame *ff = (struct finsFrame *) secure_malloc(sizeof(struct finsFrame));

	uint8_t *data;
	data = (uint8_t *) secure_malloc(PDU_length);
	memcpy(data, PDU, PDU_length);

	if (dataOrCtrl == FF_DATA) {
		ff->dataOrCtrl = FF_DATA;
		ff->destinationID = destID;

		ff->dataFrame.directionFlag = direction;
		ff->dataFrame.pduLength = PDU_length;
		ff->dataFrame.pdu = data;
		ff->metaData = meta;
		//	memcpy(&ff.metaData, metadata, MAX_METADATASIZE);
	} else if (dataOrCtrl == FF_CONTROL) {
		ff->dataOrCtrl = FF_CONTROL;
		ff->destinationID = destID;
		ff->metaData = meta;
		// fill the important FCF data in here
	} else {
		PRINT_ERROR("todo error");
	}
	//print_finsFrame(ff);
	return ff;
}
Beispiel #3
0
struct finsFrame* create_ff(int dataOrCtrl, int direction, int destID, int PDU_length, uint8_t* PDU, metadata *params) {
	struct finsFrame *ff = (struct finsFrame *) secure_malloc(sizeof(struct finsFrame));

	char *data;
	data = (char *) secure_malloc(PDU_length);
	memcpy(data, PDU, PDU_length);

	if (dataOrCtrl == DATA) {
		ff->dataOrCtrl = DATA;
		ff->destinationID.id = destID;
		ff->destinationID.next = NULL;

		ff->dataFrame.directionFlag = direction;
		ff->dataFrame.pduLength = PDU_length;
		ff->dataFrame.pdu = (u_char *) data;
		ff->metaData = params;
		//	memcpy(&ff.metaData, metadata, MAX_METADATASIZE);
	}

	if (dataOrCtrl == CONTROL) {
		ff->dataOrCtrl = CONTROL;
		ff->destinationID.id = destID;

		ff->destinationID.next = NULL;
		ff->metaData = params;
		// fill the important FCF data in here
	}
	//print_finsFrame(ff);
	return ff;
}
struct ip4_routing_table *IP4_get_routing_table() {
	struct ip4_routing_table *routing_table;

	//TODO remove/fix, is just for compiling
	uint32_t my_host_ip_addr = 0;
	uint32_t my_host_mask = 0;
	uint32_t loopback_ip_addr = 0;
	uint32_t loopback_mask = 0;
	uint32_t any_ip_addr = 0;

	struct ip4_routing_table *row0 = (struct ip4_routing_table*) secure_malloc(sizeof(struct ip4_routing_table));
	struct ip4_routing_table *row1 = (struct ip4_routing_table*) secure_malloc(sizeof(struct ip4_routing_table));
	struct ip4_routing_table *row2 = (struct ip4_routing_table*) secure_malloc(sizeof(struct ip4_routing_table));

	if (0) { //laptop eth0, wired interface
		row0->dst = loopback_ip_addr; //local loopback
		row0->gw = any_ip_addr;
		row0->mask = loopback_mask;
		row0->metric = 0;
		row0->interface = 0;
		row0->next_entry = row1;

		row1->dst = my_host_ip_addr; //within subnet
		row1->gw = any_ip_addr;
		row1->mask = my_host_mask;
		row1->metric = 1;
		row1->interface = my_host_ip_addr;
		row1->next_entry = row2;

		row2->dst = any_ip_addr; //default gateway
		row2->gw = (my_host_ip_addr & my_host_mask) | 1;
		row2->mask = my_host_mask;
		row2->metric = 2;
		row2->interface = my_host_ip_addr;
		row2->next_entry = NULL;
	}

	if (1) { //laptop wlan4, wireless interface
		row0->dst = loopback_ip_addr; //local loopback
		row0->gw = any_ip_addr;
		row0->mask = loopback_mask;
		row0->metric = 0;
		row0->interface = 0;
		row0->next_entry = row1;

		row1->dst = any_ip_addr; //default gateway
		row1->gw = (my_host_ip_addr & my_host_mask) | 1;
		row1->mask = my_host_mask;
		row1->metric = 1;
		row1->interface = my_host_ip_addr; //TODO change back to number? so looks up in interface list
		row1->next_entry = NULL;

		free(row2);
	}

	routing_table = row0;
	return routing_table;
}
Beispiel #5
0
void * secure_realloc(
    SecureAllocator allocator,
    void * ptr,
    size_t new_size)
{
    /* TODO: THIS IS A NAIVE IMPLEMENTATION, which always allocates new
       memory, and copies the memory, then frees the old memory. */

    /* Allocate new memory. */
    void * new_ptr = secure_malloc(allocator, new_size);
    /* If memory allocation failed, abort. */
    if (new_ptr == NULL) {
        return NULL;
    }

    /* Passing NULL as ptr is legal, realloc acts as malloc then. */
    if (ptr) {
        /* Get the size of the ptr memory. */
        size_t size = ((MEMP *) ((uint32_t) ptr - sizeof(MEMP)))->len;
        /* Copy the memory to the new location, min(new_size, size). */
        memcpy(new_ptr, ptr, new_size < size ? new_size : size);
        /* Free the previous memory. */
        secure_free(allocator, ptr);
    }
    return new_ptr;
}
Beispiel #6
0
struct pool_controller *controller_create(struct thread_pool *pool) {
	PRINT_DEBUG("Entered: pool=%p", pool);

	struct pool_controller *controller = (struct pool_controller *) secure_malloc(sizeof(struct pool_controller));
	controller->pool = pool;
	controller->period = 1000.000; //observe queue add rates & change time

	controller->id = 0;
	controller->running = 1;

#ifndef BUILD_FOR_ANDROID
	controller->fd = timerfd_create(CLOCK_REALTIME, 0);
	if (controller->fd == -1) {
		PRINT_ERROR("ERROR: unable to create to_fd.");
		exit(-1);
	}
#endif

	//sem_init(&worker->activate_sem, 0, 0);
	//change back to normal? if fails don't crash
	secure_pthread_create(&controller->thread, NULL, controller_thread, (void *) controller);
	//pthread_detach(&controller->thread);

	//start_timer(controller->fd, 0.5);

	return controller;
}
Beispiel #7
0
struct fins_library *library_load(uint8_t *lib, uint8_t *base_path) {
	PRINT_IMPORTANT("Entered: lib='%s', base_path='%s'", lib, base_path);

	struct fins_library *library = (struct fins_library *) secure_malloc(sizeof(struct fins_library));
	strcpy((char *) library->name, (char *) lib);

	uint8_t *error;
	uint8_t lib_path[MAX_BASE_PATH + MOD_NAME_SIZE + 7]; // +7 for "/lib<>.so"
	sprintf((char *) lib_path, "%s/lib%s.so", (char *) base_path, (char *) lib);
	library->handle = dlopen((char *) lib_path, RTLD_NOW); //RTLD_LAZY | RTLD_GLOBAL?
	if (library->handle == NULL) {
		fputs(dlerror(), stderr);
		PRINT_IMPORTANT("Entered: lib='%s', base_path='%s', library=%p", lib, base_path, NULL);
		return NULL;
	}

	uint8_t lib_create[MOD_NAME_SIZE + 7]; // +7 for "_create"
	sprintf((char *) lib_create, "%s_create", (char *) lib);
	library->create = (mod_create_type) dlsym(library->handle, (char *) lib_create);
	if ((error = (uint8_t *) dlerror()) != NULL) {
		fputs((char *) error, stderr);
		PRINT_IMPORTANT("Entered: lib='%s', base_path='%s', library=%p", lib, base_path, NULL);
		return NULL;
	}

	library->num_mods = 0;

	PRINT_IMPORTANT("Entered: lib='%s', base_path='%s', library=%p", lib, base_path, library);
	return library;
}
Beispiel #8
0
struct fins_library *library_load(uint8_t *lib, uint8_t *base_path) {
    PRINT_DEBUG("Entered: lib='%s', base_path='%s'", lib, base_path);

    struct fins_library *library = (struct fins_library *) secure_malloc(sizeof(struct fins_library));
    strcpy((char *) library->name, (char *) lib);

    uint8_t *error;
    uint8_t lib_path[MAX_BASE_PATH + MOD_NAME_SIZE + 7]; // +7 for "/lib<>.so"
    sprintf((char *) lib_path, "%s/lib%s.so", (char *) base_path, (char *) lib);
    library->handle = dlopen((char *) lib_path, RTLD_NOW); //RTLD_LAZY | RTLD_GLOBAL?
    if (library->handle == NULL) {
        error = (uint8_t *) dlerror();
        free(library);
        PRINT_ERROR("Exited: unable to open library: lib='%s', base_path='%s', error='%s'", lib, base_path, error);
        return NULL;
    }

    uint8_t lib_create[MOD_NAME_SIZE + 7]; // +7 for "_create"
    sprintf((char *) lib_create, "%s_create", (char *) lib);
    library->create = (mod_create_type) dlsym(library->handle, (char *) lib_create);
    error = (uint8_t *) dlerror();
    if (error != NULL) {
        dlclose(library->handle);
        free(library);
        PRINT_ERROR("Exited: unable to grab create() function: lib='%s', base_path='%s', error='%s'", lib, base_path, error);
        return NULL;
    }

    library->num_mods = 0;

    PRINT_DEBUG("Exited: lib='%s', base_path='%s', library=%p", lib, base_path, library);
    return library;
}
Beispiel #9
0
int rtm_init(struct fins_module *module, uint32_t flows_num, uint32_t *flows, metadata_element *params, struct envi_record *envi) {
	PRINT_IMPORTANT("Entered: module=%p, params=%p, envi=%p", module, params, envi);
	module->state = FMS_INIT;
	module_create_structs(module);

	rtm_init_params(module);

	module->data = secure_malloc(sizeof(struct rtm_data));
	struct rtm_data *md = (struct rtm_data *) module->data;

	if (module->flows_max < flows_num) {
		PRINT_ERROR("todo error");
		return 0;
	}
	md->flows_num = flows_num;

	int i;
	for (i = 0; i < flows_num; i++) {
		md->flows[i] = flows[i];
	}

	struct sockaddr_un addr;
	memset(&addr, 0, sizeof(struct sockaddr_un));
	int32_t size = sizeof(addr);

	addr.sun_family = AF_UNIX;
	snprintf(addr.sun_path, UNIX_PATH_MAX, RTM_PATH);
	unlink(addr.sun_path);

	md->server_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
	if (md->server_fd < 0) {
		PRINT_ERROR("socket error: server_fd=%d, errno=%u, str='%s'", md->server_fd, errno, strerror(errno));
		return 0;
	}

	PRINT_DEBUG("binding to: addr='%s'", RTM_PATH);
	if (bind(md->server_fd, (struct sockaddr *) &addr, size) < 0) {
		PRINT_ERROR("bind error: server_fd=%d, errno=%u, str='%s'", md->server_fd, errno, strerror(errno));
		return 0;
	}
	if (listen(md->server_fd, 10) < 0) {
		PRINT_ERROR("listen error: server_fd=%d, errno=%u, str='%s'", md->server_fd, errno, strerror(errno));
		return 0;
	}

	sem_init(&md->shared_sem, 0, 1);
	for (i = 0; i < MAX_CONSOLES; i++) {
		md->console_fds[i] = 0;
	}

	md->console_list = list_create(MAX_CONSOLES);
	md->console_counter = 0;

	md->cmd_list = list_create(MAX_COMMANDS);
	md->cmd_counter = 0;

	return 1;
}
Beispiel #10
0
int rtm_init(struct fins_module *module, metadata_element *params, struct envi_record *envi) {
	PRINT_DEBUG("Entered: module=%p, params=%p, envi=%p", module, params, envi);
	module->state = FMS_INIT;
	module_create_structs(module);

	rtm_init_knobs(module);

	module->data = secure_malloc(sizeof(struct rtm_data));
	struct rtm_data *md = (struct rtm_data *) module->data;

	struct sockaddr_un addr;
	memset(&addr, 0, sizeof(struct sockaddr_un));
	int32_t size = sizeof(addr);

	addr.sun_family = AF_UNIX;
	snprintf(addr.sun_path, UNIX_PATH_MAX, CONSOLE_PATH);
	unlink(addr.sun_path);

	md->server_fd = socket(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
	if (md->server_fd < 0) {
		PRINT_ERROR("socket error: server_fd=%d, errno=%u, str='%s'", md->server_fd, errno, strerror(errno));
		return 0;
	}
	if (fchmod(md->server_fd, ACCESSPERMS) < 0) {
		PRINT_ERROR("fchmod rtm: console_path='%s', errno=%u, str='%s'", CONSOLE_PATH, errno, strerror(errno));
		close(md->server_fd);
		return 0;
	}

	mode_t old_mask = umask(0);
	PRINT_IMPORTANT("binding to: addr='%s'", CONSOLE_PATH);
	if (bind(md->server_fd, (struct sockaddr *) &addr, size) < 0) {
		PRINT_ERROR("bind error: server_fd=%d, errno=%u, str='%s'", md->server_fd, errno, strerror(errno));
		close(md->server_fd);
		return 0;
	}
	umask(old_mask);

	if (listen(md->server_fd, 10) < 0) {
		PRINT_ERROR("listen error: server_fd=%d, errno=%u, str='%s'", md->server_fd, errno, strerror(errno));
		return 0;
	}

	sem_init(&md->shared_sem, 0, 1);
	int i;
	for (i = 0; i < MAX_CONSOLES; i++) {
		md->console_fds[i] = 0;
	}

	md->console_list = list_create(MAX_CONSOLES);
	md->console_counter = 0;

	md->cmd_list = list_create(MAX_COMMANDS);
	md->cmd_counter = 0;

	return 1;
}
Beispiel #11
0
struct link_record *link_clone(struct link_record *link) {
    PRINT_DEBUG("Entered: link=%p", link);

    struct link_record *link_clone = (struct link_record *) secure_malloc(sizeof(struct link_record));
    memcpy(link_clone, link, sizeof(struct link_record)); //would need to change if linked_list

    PRINT_DEBUG("Exited: link=%p, ret=%p", link, link_clone);
    return link_clone;
}
struct ip4_routing_table *parse_nlmsg(struct nlmsghdr *msg) {
	char dst_temp[IP4_ALEN];
	char gw_temp[IP4_ALEN];
	uint32_t priority;
	uint32_t interface;
	struct ip4_routing_table *table_pointer = NULL;

	switch (msg->nlmsg_type) {
	case NLMSG_ERROR: {
		struct nlmsgerr* errorMsg = (struct nlmsgerr*) NLMSG_DATA(msg);
		PRINT_DEBUG("recvd NLMSG_ERROR error seq:%d code:%d...", msg->nlmsg_seq, errorMsg->error);
		break;
	}
	case RTM_NEWROUTE: {
		struct rtmsg* rtm = (struct rtmsg*) NLMSG_DATA(msg);
		struct rtattr* rta = RTM_RTA(rtm);
		int rtaLen = msg->nlmsg_len - NLMSG_LENGTH(sizeof(struct rtmsg));
		if (rtm->rtm_type == RTN_UNICAST) // don't consider local, broadcast and unreachable routes
				{
			table_pointer = (struct ip4_routing_table*) secure_malloc(sizeof(struct ip4_routing_table));
			for (; RTA_OK(rta, rtaLen); rta = RTA_NEXT(rta, rtaLen)) {
				switch (rta->rta_type) {
				case RTA_DST: //destination
					table_pointer->mask = rtm->rtm_dst_len;
					memcpy(dst_temp, RTA_DATA(rta), IP4_ALEN);
					//PRINT_DEBUG("received RTA_DST");
					PRINT_DEBUG("dst_str = %u.%u.%u.%u", dst_temp[0] & 0xFF, dst_temp[1] & 0xFF, dst_temp[2] & 0xFF, dst_temp[3] & 0xFF);
					table_pointer->dst = IP4_ADR_P2H(dst_temp[0]&0xFF, dst_temp[1]&0xFF, dst_temp[2]&0xFF, dst_temp[3]&0xFF);
					break;
				case RTA_GATEWAY: //next hop
					table_pointer->mask = rtm->rtm_dst_len;
					memcpy(gw_temp, RTA_DATA(rta), IP4_ALEN);
					//PRINT_DEBUG("received RTA_GATEWAY");
					PRINT_DEBUG("gw_str = %u.%u.%u.%u", gw_temp[0] & 0xFF, gw_temp[1] & 0xFF, gw_temp[2] & 0xFF, gw_temp[3] & 0xFF);
					table_pointer->gw = IP4_ADR_P2H(gw_temp[0]&0xFF, gw_temp[1]&0xFF, gw_temp[2]&0xFF, gw_temp[3]&0xFF);
					break;
				case RTA_OIF: //interface
					memcpy(&table_pointer->interface, RTA_DATA(rta), sizeof(interface)); //TODO won't work with current hack
					PRINT_DEBUG("interface:%u", table_pointer->interface);
					break;
				case RTA_PRIORITY: //metric
					memcpy(&table_pointer->metric, RTA_DATA(rta), sizeof(priority));
					PRINT_DEBUG("metric:%u", table_pointer->metric);
					break;
				} //switch(rta->)
			} // for()
		} // if RTN_UNICAST
		return (table_pointer);
	}
	} //switch (msg->nlmsg_type)
	return (NULL);
}
Beispiel #13
0
struct udp_sent *udp_sent_create(struct finsFrame *ff, uint32_t host_ip, uint16_t host_port, uint32_t rem_ip, uint16_t rem_port) {
	PRINT_DEBUG("Entered: ff=%p, meta=%p, host=%u:%u, rem=%u:%u", ff, ff->metaData, host_ip, host_port, rem_ip, rem_port);

	struct udp_sent *sent = (struct udp_sent *) secure_malloc(sizeof(struct udp_sent));
	sent->ff = ff;
	sent->host_ip = host_ip;
	sent->host_port = host_port;
	sent->rem_ip = rem_ip;
	sent->rem_port = rem_port;

	PRINT_DEBUG("Exited: ff=%p, sent=%p", ff, sent);
	return sent;
}
Beispiel #14
0
int switch_init(struct fins_module *module, metadata_element *params, struct envi_record *envi) {
	PRINT_DEBUG("Entered: module=%p, params=%p, envi=%p", module, params, envi);
	module->state = FMS_INIT;
	module_create_structs(module);

	global_switch_event_sem = module->event_sem;

	switch_init_knobs(module);

	module->data = secure_malloc(sizeof(struct switch_data));
//struct switch_data *md = (struct switch_data *) module->data;

	return 1;
}
Beispiel #15
0
int ipv4_init(struct fins_module *module, uint32_t flows_num, uint32_t *flows, metadata_element *params, struct envi_record *envi) {
	PRINT_IMPORTANT("Entered: module=%p, params=%p, envi=%p", module, params, envi);
	module->state = FMS_INIT;
	module_create_structs(module);

	ipv4_init_params(module);

	module->data = secure_malloc(sizeof(struct ipv4_data));
	struct ipv4_data *md = (struct ipv4_data *) module->data;

	if (module->flows_max < flows_num) {
		PRINT_ERROR("todo error");
		return 0;
	}
	md->flows_num = flows_num;

	int i;
	for (i = 0; i < flows_num; i++) {
		md->flows[i] = flows[i];
	}

	md->addr_list = list_create(IPV4_ADDRESS_LIST_MAX);
	list_for_each1(envi->if_list, ipv4_ifr_get_addr_func, md->addr_list);
	if (envi->if_loopback) {
		md->addr_loopback = (struct addr_record *) list_find(envi->if_loopback->addr_list, addr_is_v4);
	}
	if (envi->if_main) {
		md->addr_main = (struct addr_record *) list_find(envi->if_main->addr_list, addr_is_v4);
	}

	md->route_list = list_filter(envi->route_list, route_is_addr4, route_clone);
	if (md->route_list->len > IPV4_ROUTE_LIST_MAX) {
		PRINT_ERROR("todo");
		struct linked_list *leftover = list_split(md->route_list, IPV4_ROUTE_LIST_MAX - 1);
		list_free(leftover, free);
	}
	md->route_list->max = IPV4_ROUTE_LIST_MAX;

	//when recv pkt would need to check addresses
	//when send pkt would need to check routing table & addresses (for ip address)
	//both of these would need to be updated by switch etc

	//routing_table = IP4_get_routing_table();

	PRINT_DEBUG("after ip4 sort route table");
	memset(&md->stats, 0, sizeof(struct ipv4_stats));

	return 1;
}
Beispiel #16
0
int udp_init(struct fins_module *module, metadata_element *params, struct envi_record *envi) {
	PRINT_DEBUG("Entered: module=%p, params=%p, envi=%p", module, params, envi);
	module->state = FMS_INIT;
	module_create_structs(module);

	udp_init_knobs(module);

	module->data = secure_malloc(sizeof(struct udp_data));
	struct udp_data *md = (struct udp_data *) module->data;

	//TODO extract this from meta?
	md->sent_packet_list = list_create(UDP_SENT_LIST_MAX);

	return 1;
}
Beispiel #17
0
struct fins_module *udp_create(uint32_t index, uint32_t id, uint8_t *name) {
	PRINT_DEBUG("Entered: index=%u, id=%u, name='%s'", index, id, name);

	struct fins_module *module = (struct fins_module *) secure_malloc(sizeof(struct fins_module));

	strcpy((char *) module->lib, UDP_LIB);
	module->flows_max = UDP_MAX_FLOWS;
	module->ops = &udp_ops;
	module->state = FMS_FREE;

	module->index = index;
	module->id = id;
	strcpy((char *) module->name, (char *) name);

	PRINT_DEBUG("Exited: index=%u, id=%u, name='%s', module=%p", index, id, name, module);
	return module;
}
Beispiel #18
0
struct fins_library *library_fake_load(uint8_t *lib, uint8_t *base_path) {
	PRINT_DEBUG("Entered: lib='%s', base_path='%s'", lib, base_path);

	struct fins_library *library = (struct fins_library *) secure_malloc(sizeof(struct fins_library));
	strcpy((char *) library->name, (char *) lib);
	library->handle = NULL; //RTLD_LAZY | RTLD_GLOBAL?

	uint8_t lib_create[MOD_NAME_SIZE + 7]; // +7 for "_create"
	sprintf((char *) lib_create, "%s_create", (char *) lib);

	if (strcmp((char *) lib_create, "switch_create") == 0) {
		library->create = (mod_create_type) switch_create;
	} else if (strcmp((char *) lib_create, "interface_create") == 0) {
		library->create = (mod_create_type) interface_create;
	} else if (strcmp((char *) lib_create, "arp_create") == 0) {
		library->create = (mod_create_type) arp_create;
	} else if (strcmp((char *) lib_create, "ipv4_create") == 0) {
		library->create = (mod_create_type) ipv4_create;
	} else if (strcmp((char *) lib_create, "icmp_create") == 0) {
		library->create = (mod_create_type) icmp_create;
	} else if (strcmp((char *) lib_create, "tcp_create") == 0) {
		library->create = (mod_create_type) tcp_create;
	} else if (strcmp((char *) lib_create, "udp_create") == 0) {
		library->create = (mod_create_type) udp_create;
	} else if (strcmp((char *) lib_create, "daemon_create") == 0) {
		library->create = (mod_create_type) daemon_create;
	} else if (strcmp((char *) lib_create, "logger_create") == 0) {
		library->create = (mod_create_type) logger_create;
	} else if (strcmp((char *) lib_create, "rtm_create") == 0) {
		library->create = (mod_create_type) rtm_create;
	} else if (strcmp((char *) lib_create, "template_create") == 0) {
		library->create = (mod_create_type) template_create;
	} else if (strcmp((char *) lib_create, "logger_iperf_create") == 0) {
		library->create = (mod_create_type) logger_iperf_create;
	} else {
		PRINT_ERROR("default: unknown library: lib='%s'", lib);
		exit(-1);
	}

	library->num_mods = 0;

	PRINT_DEBUG("Exited: lib='%s', base_path='%s', library=%p", lib, base_path, library);
	return library;
}
Beispiel #19
0
struct thread_pool *pool_create(uint32_t initial, uint32_t max, uint32_t limit) {
	PRINT_DEBUG("Entered: initial=%u, max=%u, limit=%u", initial, max, limit);

	struct thread_pool *pool = (struct thread_pool *) secure_malloc(sizeof(struct thread_pool));
	pool->workers = list_create(max);
	pool->queue = list_create(limit);
	sem_init(&pool->inactive_sem, 0, 1);
	pool->inactive_num = 0;
	pool->worker_count = 0;

	//pool->controller = controller_create(pool);

	secure_sem_wait(&pool->inactive_sem);
	pool_start(pool, initial);
	sem_post(&pool->inactive_sem);

	PRINT_DEBUG("Exited: initial=%u, max=%u, pool=%p", initial, max, pool);
	return pool;
}
Beispiel #20
0
void rtm_send_fcf(struct fins_module *module, struct rtm_command *cmd, metadata *meta) {
	PRINT_DEBUG("Entered: module=%p, cmd=%p, meta=%p", module, cmd, meta);

	struct finsFrame *ff = (struct finsFrame *) secure_malloc(sizeof(struct finsFrame));
	ff->dataOrCtrl = FF_CONTROL;
	ff->destinationID = cmd->mod;
	ff->metaData = meta;

	ff->ctrlFrame.sender_id = module->index;
	ff->ctrlFrame.serial_num = cmd->serial_num;
	ff->ctrlFrame.opcode = cmd->op;
	ff->ctrlFrame.param_id = cmd->param_id;

	ff->ctrlFrame.data_len = 0;
	ff->ctrlFrame.data = NULL;

	PRINT_DEBUG("Sending ff=%p", ff);
	module_to_switch(module, ff);
}
Beispiel #21
0
void module_read_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;

    ff->ctrlFrame.data_len = sizeof(struct fins_module_table);
    ff->ctrlFrame.data = (uint8_t *) secure_malloc(ff->ctrlFrame.data_len);

    struct fins_module_table *table = (struct fins_module_table *) ff->ctrlFrame.data;
    if (mt->link_list != NULL) {
        table->link_list = list_clone(mt->link_list, link_clone);
    } else {
        table->link_list = NULL;
    }

    table->flows_num = mt->flows_num;

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

    if (mt->link_list != NULL) {
        list_for_each(mt->link_list, link_print);
    }
#endif

    module_reply_fcf(module, ff, FCF_TRUE, 0);
}
Beispiel #22
0
struct pool_worker *worker_create(sem_t *inactive_sem, uint32_t *inactive_num, struct linked_list *queue, uint32_t id) {
	PRINT_DEBUG("Entered: inactive_sem=%p, inactive_num=%p, queue=%p, id=%u", inactive_sem, inactive_num, queue, id);

	struct pool_worker *worker = (struct pool_worker *) secure_malloc(sizeof(struct pool_worker));
	worker->inactive_sem = inactive_sem;
	worker->inactive_num = inactive_num;
	worker->queue = queue;

	worker->id = id;
	worker->running = 1;
	sem_init(&worker->activate_sem, 0, 0);
	worker->inactive = 0;
	worker->work = NULL;
	worker->local = NULL;

	//change back to normal? if fails don't crash
	secure_pthread_create(&worker->thread, NULL, worker_thread, (void *) worker);
	//pthread_detach(&worker->thread);

	PRINT_DEBUG("Exited: inactive_sem=%p, inactive_num=%p, queue=%p, id=%u, worker=%p", inactive_sem, inactive_num, queue, id, worker);
	return worker;
}
Beispiel #23
0
void module_read_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;

    int i;
    ff->ctrlFrame.data_len = mt->flows_num;
    if (mt->flows_num != 0) {
        ff->ctrlFrame.data = (uint8_t *) secure_malloc(ff->ctrlFrame.data_len * sizeof(struct fins_module_flow));
        struct fins_module_flow *flows = (struct fins_module_flow *) ff->ctrlFrame.data;

        for (i = 0; i < ff->ctrlFrame.data_len; i++) {
            flows[i].link_id = 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), ", flows[i].link_id, flows[i].link);
            pt += ret;
        }
        *pt = '\0';
        PRINT_DEBUG("flows: max=%u, num=%u, ['%s']", module->flows_max, mt->flows_num, buf);
#endif
    } else {
        ff->ctrlFrame.data = NULL;

#ifdef DEBUG
        PRINT_DEBUG("flows: max=%u, num=%u, ['']", module->flows_max, mt->flows_num);
#endif
    }

    module_reply_fcf(module, ff, FCF_TRUE, 0);
}
Beispiel #24
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);
}
Beispiel #25
0
int pool_execute(struct thread_pool *pool, void *(*work)(void *local), void *local) {
	PRINT_DEBUG("Entered: pool=%p, work=%p, local=%p", pool, work, local);

	secure_sem_wait(&pool->inactive_sem);
	PRINT_DEBUG("inactive_num=%u", pool->inactive_num);
	if (pool->inactive_num) {
		struct pool_worker *worker = (struct pool_worker *) list_find(pool->workers, worker_inactive_test);
		PRINT_DEBUG("found worker=%p", worker);
		if (worker != NULL) {
			pool->inactive_num--;

			worker->inactive = 0;
			worker->work = work;
			worker->local = local;
			PRINT_DEBUG("activating: worker=%p, inactive_num=%u", worker, *worker->inactive_num);
			sem_post(&worker->activate_sem);
			sem_post(&pool->inactive_sem);

			return 1;
		} else {
			PRINT_WARN("todo error");
			sem_post(&pool->inactive_sem);
			//TODO shouldn't be possible

			return 0;
		}
	} else {
		//TODO change to simply queue it, have controller optimize pool size
		//TODO have execute change queue size?
		if (list_has_space(pool->queue)) {
			struct pool_request *request = (struct pool_request *) secure_malloc(sizeof(struct pool_request));
			request->work = work;
			request->local = local;

			list_append(pool->queue, request);
			sem_post(&pool->inactive_sem);

			return 1;
		} else {
			sem_post(&pool->inactive_sem);

			return 0;
		}

		if (0) {
			if (list_has_space(pool->workers)) {
				PRINT_DEBUG("Starting new worker");
				struct pool_worker *worker = worker_create(&pool->inactive_sem, &pool->inactive_num, pool->queue, pool->worker_count++);
				list_append(pool->workers, worker);

				worker->work = work;
				worker->local = local;
				PRINT_DEBUG("activating: worker=%p, inactive_num=%u", worker, *worker->inactive_num);
				sem_post(&worker->activate_sem);
				sem_post(&pool->inactive_sem);

				//TODO wait? or do the find function again? etc preload it.

				return 1;
			} else {
				sem_post(&pool->inactive_sem);

				//TODO queue it? have finishing threads check queue?
				return 0;
			}
		}
	}
}
Beispiel #26
0
//RTM's main function
//Gets information from RTM_IN pipe
//Is started as a thread in core.c
void rtm_init(pthread_attr_t *fins_pthread_attr) {

    PRINT_IMPORTANT("RTM has started");

    /*
     //added to include code from fins_daemon.sh -- mrd015 !!!!! //TODO move this to RTM module
     if (mkfifo(RTM_PIPE_IN, 0777) != 0) {
     if (errno == EEXIST) {
     PRINT_DEBUG("mkfifo(" RTM_PIPE_IN ", 0777) already exists.");
     } else {
     PRINT_ERROR("mkfifo(" RTM_PIPE_IN ", 0777) failed.");
     exit(-1);
     }
     }
     if (mkfifo(RTM_PIPE_OUT, 0777) != 0) {
     if (errno == EEXIST) {
     PRINT_DEBUG("mkfifo(" RTM_PIPE_OUT ", 0777) already exists.");
     } else {
     PRINT_ERROR("mkfifo(" RTM_PIPE_OUT ", 0777) failed.");
     exit(-1);
     }
     }
     */

    //int datalen;
    int numBytes;
    //int val_len;
    int temp_serial_cntr = 0;
    unsigned char* serialized_FCF = NULL;
    int length_serialized_FCF;

    //create a finsframe to be sent tover the queue
    struct finsFrame *fins_frame = (struct finsFrame *) secure_malloc(sizeof(struct finsFrame));
    fins_frame->dataOrCtrl = CONTROL;

    //opens the pipe from clicomm (or wherever)
    rtm_in_fd = open(RTM_PIPE_IN, O_RDWR);

    if (rtm_in_fd == -1) {
        PRINT_DEBUG("rtm_in_fd Pipe failure ");
        exit(EXIT_FAILURE);
    }

    fflush(stdout);

    while (1) {
        temp_serial_cntr++; //used as a temporary serial_number generator

        //READ FROM PIPE RTM_IN
        numBytes = 0;
        numBytes += read(rtm_in_fd, &length_serialized_FCF, sizeof(int)); //length of incoming serialized FCF
        numBytes += read(rtm_in_fd, serialized_FCF, length_serialized_FCF); //incoming serialized FCF

        fins_frame = unserializeCtrlFrame(serialized_FCF, length_serialized_FCF);

        //value, Assumption was made, notice the size
        PRINT_DEBUG("received data");
        numBytes = 0;

        //ERROR Message
        fflush(stdout);
        if (numBytes >= 0) {
            PRINT_DEBUG("numBytes written %d", numBytes);
        }

        //CHANGE SenderID and SerialNum
        fins_frame->ctrlFrame.senderID = RTM_ID;
        fins_frame->ctrlFrame.serial_num = temp_serial_cntr;

        //SEND TO QUEUE
        secure_sem_wait(&RTM_to_Switch_Qsem);
        write_queue(fins_frame, RTM_to_Switch_Queue);
        sem_post(&RTM_to_Switch_Qsem);
        PRINT_DEBUG("sent data ");

        //READ FROM QUEUE
        rtm_get_ff();
    }
}
Beispiel #27
0
void core_main(uint8_t *envi_name, uint8_t *stack_name, uint32_t seed) {
	PRINT_IMPORTANT("Core Initiation: Starting ************");

#ifdef BUILD_FOR_ANDROID
	library_dummies();
#endif

	register_to_signal(SIGRTMIN);
	if (seed == DEFAULT_SEED_NUM) {
		srand((unsigned int) time(NULL));
	} else {
		srand(seed);
	}

	sem_init(&global_control_serial_sem, 0, 1); //TODO remove after gen_control_serial_num() converted to RNG

	signal(SIGINT, core_termination_handler); //register termination handler

	int status;
	int i, j, k;
	metadata_element *list_elem;
	int list_num;
	metadata_element *elem;
	metadata_element *ip_elem;
	uint32_t ip_num;

	//######################################################################
	overall = (struct fins_overall *) secure_malloc(sizeof(struct fins_overall));
	sem_init(&overall->sem, 0, 1);

	//######################################################################
	overall->envi = (struct envi_record *) secure_malloc(sizeof(struct envi_record));

	PRINT_IMPORTANT("########################## loading environment: '%s'", (char *) envi_name);
	metadata *meta_envi = (metadata *) secure_malloc(sizeof(metadata));
	metadata_create(meta_envi);

	status = config_read_file(meta_envi, (char *) envi_name);
	if (status == META_FALSE) {
		PRINT_ERROR("file='%s', %s:%d - %s\n", envi_name, config_error_file(meta_envi), config_error_line(meta_envi), config_error_text(meta_envi));
		metadata_destroy(meta_envi);
		PRINT_ERROR("todo error");
		exit(-1);
	}

	//############# if_list
	PRINT_IMPORTANT("############# Configuring List of Interfaces");
	overall->envi->if_list = list_create(MAX_INTERFACES);

	list_elem = config_lookup(meta_envi, "environment.interfaces");
	if (list_elem == NULL) {
		PRINT_ERROR("todo error");
		exit(-1);
	}
	list_num = config_setting_length(list_elem);

	int32_t if_index;
	uint8_t *name;
	uint64_t mac;
	uint32_t mode;
	uint32_t mtu;
	uint32_t flags;

	struct if_record *ifr;

	for (i = 0; i < list_num; i++) {
		elem = config_setting_get_elem(list_elem, i);
		if (elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "index", (int *) &if_index);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_string(elem, "name", (const char **) &name);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int64(elem, "mac", (long long *) &mac);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "mode", (int *) &mode);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "mtu", (int *) &mtu);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "flags", (int *) &flags);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		//#############
		ifr = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_index);
		if (ifr == NULL) {
			ifr = (struct if_record *) secure_malloc(sizeof(struct if_record));
			ifr->index = if_index;
			strcpy((char *) ifr->name, (char *) name);
			ifr->mac = mac;

			ifr->mode = (uint8_t) mode;
			ifr->mtu = mtu;
			ifr->flags = flags;

			ifr->addr_list = list_create(MAX_FAMILIES);

			if (list_has_space(overall->envi->if_list)) {
				PRINT_IMPORTANT("Adding interface: ifr=%p, index=%u, name='%s', mac=0x%012llx", ifr, ifr->index, ifr->name, ifr->mac);
				list_append(overall->envi->if_list, ifr);
			} else {
				//TODO error
				PRINT_ERROR("todo error");
				exit(-1);
			}

			if (flags & IFF_LOOPBACK) {
				overall->envi->if_loopback = ifr;
			}
		} else {
			PRINT_ERROR("todo error");
			exit(-1);
		}
	}
	PRINT_IMPORTANT("if_list: list=%p, max=%u, len=%u", overall->envi->if_list, overall->envi->if_list->max, overall->envi->if_list->len);

	//############# if_loopback
	PRINT_IMPORTANT("############# Configuring Loopback Interface");
	if (overall->envi->if_loopback != NULL) {
		PRINT_IMPORTANT("loopback: name='%s', addr_list->len=%u", overall->envi->if_loopback->name, overall->envi->if_loopback->addr_list->len);
	} else {
		PRINT_WARN("todo error");
	}

	//############# if_main
	PRINT_IMPORTANT("############# Configuring Main Interface");
	uint32_t if_main;

	status = config_lookup_int(meta_envi, "environment.main_interface", (int *) &if_main);
	if (status == META_FALSE) {
		PRINT_ERROR("todo error");
		exit(-1);
	}

	overall->envi->if_main = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_main);
	if (overall->envi->if_main != NULL) {
		PRINT_IMPORTANT("main interface: name='%s', addr_list->len=%u", overall->envi->if_main->name, overall->envi->if_main->addr_list->len);
		if (!ifr_running_test(overall->envi->if_main)) {
			PRINT_WARN("!!!!Selected main interface is NOT running: name='%s', flagx->len=0x%x", overall->envi->if_main->name, overall->envi->if_main->flags);
		}
	} else {
		PRINT_WARN("todo error");
	}

	//############# addr_list
	PRINT_IMPORTANT("############# Configuring List of Host Addresses");
	//overall->envi->addr_list = list_create(MAX_INTERFACES * MAX_FAMILIES); //TODO use?

	list_elem = config_lookup(meta_envi, "environment.addresses");
	if (list_elem == NULL) {
		PRINT_ERROR("todo error");
		exit(-1);
	}
	list_num = config_setting_length(list_elem);

	uint32_t family; //atm only AF_INET, but eventually also AF_INET6
	uint32_t ip[4]; //SIOCGIFADDR //ip
	uint32_t mask[4]; //SIOCGIFNETMASK //mask
	uint32_t gw[4]; //? //(ip & mask) | 1;
	uint32_t bdc[4]; //SIOCGIFBRDADDR //(ip & mask) | ~mask
	uint32_t dst[4]; //SIOCGIFDSTADDR //dst

	struct addr_record *addr;

	for (i = 0; i < list_num; i++) {
		elem = config_setting_get_elem(list_elem, i);
		if (elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "if_index", (int *) &if_index);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "family", (int *) &family);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		ip_elem = config_setting_get_member(elem, "ip");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			ip[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		ip_elem = config_setting_get_member(elem, "mask");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			mask[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		ip_elem = config_setting_get_member(elem, "gw");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			gw[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		ip_elem = config_setting_get_member(elem, "bdc");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			bdc[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		ip_elem = config_setting_get_member(elem, "dst");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			dst[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		//############
		ifr = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_index);
		if (ifr != NULL) {
			if (ifr_running_test(ifr)) {
				if (family == AF_INET) {
					addr = (struct addr_record *) list_find(ifr->addr_list, addr_is_v4);
				} else {
					addr = (struct addr_record *) list_find(ifr->addr_list, addr_is_v6);
				}

				if (addr == NULL) {
					addr = (struct addr_record *) secure_malloc(sizeof(struct addr_record));
					addr->if_index = if_index;
					addr->family = AF_INET;

					if (family == AF_INET) {
						addr4_set_ip(&addr->ip, IP4_ADR_P2H(ip[0], ip[1], ip[2],ip[3]));
						addr4_set_ip(&addr->mask, IP4_ADR_P2H(mask[0], mask[1], mask[2],mask[3]));
						addr4_set_ip(&addr->gw, IP4_ADR_P2H(gw[0], gw[1], gw[2], gw[3]));
						addr4_set_ip(&addr->bdc, IP4_ADR_P2H(bdc[0], bdc[1], bdc[2], bdc[3]));
						addr4_set_ip(&addr->dst, IP4_ADR_P2H(dst[0], dst[1], dst[2], dst[3]));
					} else if (family == AF_INET6) {
						//TODO
						//addr_set_addr6(&addr->ip, ip);
						PRINT_WARN("todo");
					} else {
						//TODO error?
						PRINT_ERROR("todo error");
						exit(-1);
					}

					if (list_has_space(ifr->addr_list)) {
						PRINT_IMPORTANT(
								"Adding address: if_index=%d, family=%u, ip='%u.%u.%u.%u', mask='%u.%u.%u.%u', gw='%u.%u.%u.%u', bdc='%u.%u.%u.%u', dst='%u.%u.%u.%u'",
								if_index, family, ip[0], ip[1], ip[2], ip[3], mask[0], mask[1], mask[2], mask[3], gw[0], gw[1], gw[2], gw[3], bdc[0], bdc[1], bdc[2], bdc[3], dst[0], dst[1], dst[2], dst[3]);
						list_append(ifr->addr_list, addr);
					} else {
						//TODO error
						PRINT_ERROR("todo error");
						exit(-1);
					}
				} else {
					//TODO error
					PRINT_ERROR("todo: previous address found, replace or add new?");
				}
			} else {
				if (family == AF_INET) {
					PRINT_WARN(
							"Ignoring address, no active interface: if_index=%d, family=%u, ip='%u.%u.%u.%u', mask='%u.%u.%u.%u', gw='%u.%u.%u.%u', bdc='%u.%u.%u.%u', dst='%u.%u.%u.%u'",
							if_index, family, ip[0], ip[1], ip[2], ip[3], mask[0], mask[1], mask[2], mask[3], gw[0], gw[1], gw[2], gw[3], bdc[0], bdc[1], bdc[2], bdc[3], dst[0], dst[1], dst[2], dst[3]);
				} else if (family == AF_INET6) {
					//TODO
					PRINT_WARN("todo");
				} else {
					//TODO error?
					PRINT_ERROR("todo error");
					exit(-1);
				}
			}
		} else {
			//TODO error
			PRINT_ERROR("todo error");
			exit(-1);
		}
	}

	//############# route_list
	PRINT_IMPORTANT("############# Configuring List of Routes");
	overall->envi->route_list = list_create(MAX_ROUTES);

	list_elem = config_lookup(meta_envi, "environment.routes");
	if (list_elem == NULL) {
		PRINT_ERROR("todo error");
		exit(-1);
	}
	list_num = config_setting_length(list_elem);

	uint32_t metric; //SIOCGIFMETRIC
	uint32_t timeout;
	//struct timeval route_stamp;

	struct route_record *route;

	for (i = 0; i < list_num; i++) {
		elem = config_setting_get_elem(list_elem, i);
		if (elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "if_index", (int *) &if_index);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "family", (int *) &family);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		ip_elem = config_setting_get_member(elem, "dst");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			dst[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		ip_elem = config_setting_get_member(elem, "mask");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			mask[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		ip_elem = config_setting_get_member(elem, "gw");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			gw[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		status = config_setting_lookup_int(elem, "metric", (int *) &metric);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "timeout", (int *) &timeout);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		//############
		ifr = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_index);
		if (ifr != NULL) {
			if (ifr_running_test(ifr)) {
				route = (struct route_record *) secure_malloc(sizeof(struct route_record));
				route->if_index = if_index;
				route->family = family;

				if (family == AF_INET) {
					addr4_set_ip(&route->dst, IP4_ADR_P2H(dst[0], dst[1], dst[2], dst[3]));
					addr4_set_ip(&route->mask, IP4_ADR_P2H(mask[0], mask[1], mask[2],mask[3]));
					addr4_set_ip(&route->gw, IP4_ADR_P2H(gw[0], gw[1], gw[2], gw[3]));
					//addr4_set_addr(&route->ip, IP4_ADR_P2H(ip[0], ip[1], ip[2],ip[3]));
				} else if (family == AF_INET6) {
					//TODO
					//addr_set_addr6(&route->ip, ip);
				} else {
					//TODO error?
				}

				route->metric = metric;
				route->timeout = timeout;

				if (list_has_space(overall->envi->route_list)) {
					PRINT_IMPORTANT( "Adding route: if_index=%d, family=%u, dst='%u.%u.%u.%u', mask='%u.%u.%u.%u', gw='%u.%u.%u.%u', metric=%u, timeout=%u",
							route->if_index, route->family, dst[0], dst[1], dst[2], dst[3], mask[0], mask[1], mask[2], mask[3], gw[0], gw[1], gw[2], gw[3], metric, timeout);
					list_append(overall->envi->route_list, route);
				} else {
					//TODO error
					PRINT_ERROR("todo error");
					exit(-1);
				}
			} else {
				if (family == AF_INET) {
					PRINT_WARN(
							"Ignoring route, no active interface: if_index=%d, family=%u, dst='%u.%u.%u.%u', mask='%u.%u.%u.%u', gw='%u.%u.%u.%u', metric=%u, timeout=%u",
							if_index, family, dst[0], dst[1], dst[2], dst[3], mask[0], mask[1], mask[2], mask[3], gw[0], gw[1], gw[2], gw[3], metric, timeout);
				} else if (family == AF_INET6) {
					//TODO
					PRINT_WARN("todo");
				} else {
					//TODO error?
					PRINT_ERROR("todo error");
				}
			}
		}
	}
	PRINT_IMPORTANT("route_list: list=%p, max=%u, len=%u", overall->envi->route_list, overall->envi->route_list->max, overall->envi->route_list->len);
	metadata_destroy(meta_envi);

	//######################################################################
	PRINT_IMPORTANT("########################## loading stack: '%s'", (char *) stack_name);
	metadata *meta_stack = (metadata *) secure_malloc(sizeof(metadata));
	metadata_create(meta_stack);

	status = config_read_file(meta_stack, (char *) stack_name);
	if (status == META_FALSE) {
		PRINT_ERROR("file='%s', %s:%d - %s\n", stack_name, config_error_file(meta_stack), config_error_line(meta_stack), config_error_text(meta_stack));
		metadata_destroy(meta_stack);
		PRINT_ERROR("todo error");
		exit(-1);
	}

	//############# module_list
	PRINT_IMPORTANT("############# Configuring List of Modules");
	overall->lib_list = list_create(MAX_MODULES);
	memset(overall->modules, 0, MAX_MODULES * sizeof(struct fins_module *));
	overall->admin_list = list_create(MAX_MODULES);
	struct linked_list *mt_list = list_create(MAX_MODULES);

	uint8_t base_path[100];
	memset((char *) base_path, 0, 100);
#ifdef BUILD_FOR_ANDROID
	strcpy((char *) base_path, FINS_TMP_ROOT);
	//strcpy((char *) base_path, ".");
#else
	strcpy((char *) base_path, ".");
#endif

	metadata_element *mods_elem = config_lookup(meta_stack, "stack.modules");
	if (mods_elem == NULL) {
		PRINT_ERROR("todo error");
		exit(-1);
	}
	int mods_num = config_setting_length(mods_elem);

	metadata_element *mod_elem;
	uint32_t mod_id;
	uint8_t *mod_lib;
	uint8_t *mod_name;
	metadata_element *flows_elem;
	uint32_t mod_flows[MAX_MOD_FLOWS];
	uint32_t mod_flows_num;
	metadata_element *mod_params;
	metadata_element *mod_admin;

	struct fins_library *library;
	struct fins_module *module;
	struct fins_module_table *mt;

	for (i = 0; i < mods_num; i++) {
		mod_elem = config_setting_get_elem(mods_elem, i);
		if (mod_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(mod_elem, "id", (int *) &mod_id);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_string(mod_elem, "lib", (const char **) &mod_lib);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_string(mod_elem, "name", (const char **) &mod_name);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		flows_elem = config_setting_get_member(mod_elem, "flows");
		if (flows_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		mod_flows_num = config_setting_length(flows_elem);

		for (j = 0; j < mod_flows_num; j++) {
			mod_flows[j] = (uint32_t) config_setting_get_int_elem(flows_elem, j);
		}

		mod_params = config_setting_get_member(mod_elem, "params");
		if (mod_params == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		mod_admin = config_setting_get_member(mod_elem, "admin");
		PRINT_DEBUG("admin=%u", mod_admin != NULL);

		//############
		library = (struct fins_library *) list_find1(overall->lib_list, library_name_test, mod_lib);
		if (library == NULL) {
#ifdef BUILD_FOR_ANDROID
			library = library_fake_load(mod_lib, base_path);
#else
			//library = library_load(mod_lib, base_path);
			library = library_fake_load(mod_lib, base_path);
#endif
			if (library == NULL) {
				PRINT_ERROR("Failed in loading library: lib='%s', base_path='%s'", mod_lib, base_path);
				exit(-1);
			}

			if (list_has_space(overall->lib_list)) {
				PRINT_IMPORTANT("Adding library: library=%p, name='%s'", library, library->name);
				list_append(overall->lib_list, library);
			} else {
				PRINT_ERROR("Failed in init sequence, too many libraries: lib_list->len=%u", overall->lib_list->len);
				exit(-1);
			}
		}

		module = library->create(i, mod_id, mod_name);
		if (module == NULL) {
			//TODO error
			PRINT_ERROR("Failed to create module: library=%p, index=%u, id=%u, name='%s'", library, i, mod_id, mod_name);
			exit(-1);
		}
		library->num_mods++;

		//TODO move flow to update? or links here?
		status = module->ops->init(module, mod_params, overall->envi); //TODO merge init into create?
		if (status != 0) {
			overall->modules[i] = module;

			if (module->flows_max < mod_flows_num) {
				PRINT_ERROR("Loading module parameters failed, too many flows for this library: specified=%u, max=%u", mod_flows_num, module->flows_max);
				exit(-1);
			}

			mt = (struct fins_module_table *) secure_malloc(sizeof(struct fins_module_table));
			mt->flows_num = mod_flows_num;

			for (j = 0; j < mt->flows_num; j++) {
				mt->flows[j].link_id = mod_flows[j];
			}
			list_append(mt_list, mt);

			if (mod_admin != NULL) {
				PRINT_IMPORTANT("Adding admin module: module=%p, lib='%s', name='%s', id=%d, index=%u",
						module, module->lib, module->name, module->id, module->index);
				list_append(overall->admin_list, module);
			} else {
				PRINT_IMPORTANT("Adding module: module=%p, lib='%s', name='%s', id=%d, index=%u", module, module->lib, module->name, module->id, module->index);
			}
		} else {
			PRINT_ERROR("Initialization of module failed: module=%p, lib='%s', name='%s', flows_num=%u, flows=%p, params=%p, envi=%p",
					module, module->lib, module->name, mod_flows_num, mod_flows, mod_params, overall->envi);
			exit(-1);
		}

		//free(mod_lib); //don't free, string from libconfig points to metadata memory
		//free(mod_name);
	}

	//############# admin_list //TODO change to admin_list?
	list_for_each1(overall->admin_list, assign_overall, overall);

	//############# linking_list
	PRINT_IMPORTANT("############# Configuring Linking Table");
	overall->link_list = list_create(MAX_TABLE_LINKS);

	metadata_element *links_elem = config_lookup(meta_stack, "stack.links");
	if (links_elem == NULL) {
		PRINT_ERROR("todo error");
		exit(-1);
	}
	int links_num = config_setting_length(links_elem);

	metadata_element *link_elem;
	uint32_t link_id;
	uint32_t link_src;
	metadata_element *dsts_elem;
	uint32_t link_dsts[MAX_MODULES];
	int link_dsts_num;

	struct link_record *link;

	for (i = 0; i < links_num; i++) {
		link_elem = config_setting_get_elem(links_elem, i);
		if (link_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(link_elem, "id", (int *) &link_id);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(link_elem, "src", (int *) &link_src);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		dsts_elem = config_setting_get_member(link_elem, "dsts");
		if (dsts_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		link_dsts_num = config_setting_length(dsts_elem);

		for (j = 0; j < link_dsts_num; j++) {
			link_dsts[j] = (uint32_t) config_setting_get_int_elem(dsts_elem, j);
		}

		//############
		link = (struct link_record *) secure_malloc(sizeof(struct link_record));
		link->id = link_id;

		//module = (struct fins_module *) list_find1(overall->envi->module_list, mod_id_test, &link_src);
		link->src_index = -1;
		for (j = 0; j < MAX_MODULES; j++) {
			if (overall->modules[j] != NULL && overall->modules[j]->id == link_src) {
				link->src_index = overall->modules[j]->index;
			}
		}
		if (link->src_index == -1) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		link->dsts_num = link_dsts_num;
		for (j = 0; j < link_dsts_num; j++) {
			//module = (struct fins_module *) list_find1(overall->envi->module_list, mod_id_test, &link_dsts[j]);
			link->dsts_index[j] = -1;
			for (k = 0; k < MAX_MODULES; k++) {
				if (overall->modules[k] != NULL && overall->modules[k]->id == link_dsts[j]) {
					link->dsts_index[j] = overall->modules[k]->index;
				}
			}
			if (link->dsts_index[j] == (uint32_t) -1) {
				PRINT_ERROR("todo error");
				exit(-1);
			}
		}

		if (list_has_space(overall->link_list)) {
			uint8_t buf[1000];
			uint8_t *pt = buf;
			int ret;
			int i;
			for (i = 0; i < link->dsts_num; i++) {
				ret = sprintf((char *) pt, "%u, ", link->dsts_index[i]);
				pt += ret;
			}
			*pt = '\0';

			PRINT_IMPORTANT("Adding link: link=%p, id=%u, src_index=%u, dsts_num=%u, ['%s']", link, link->id, link->src_index, link->dsts_num, buf);
			list_append(overall->link_list, link);
		} else {
			//TODO error
			PRINT_ERROR("todo error");
			exit(-1);
		}
	}
	metadata_destroy(meta_stack);

	//######################################################################
	PRINT_IMPORTANT("############# Updating modules with correct flows & links");
	//send out subset of linking table to each module as update
	//TODO table subset update

	metadata *meta_update;
	struct finsFrame *ff_update;

	for (i = 0; i < MAX_MODULES; i++) {
		if (overall->modules[i] != NULL) {
			mt = (struct fins_module_table *) list_remove_front(mt_list);
			mt->link_list = list_filter1(overall->link_list, link_src_test, &overall->modules[i]->index, link_clone); //was link_involved_test, decide which better?
			PRINT_IMPORTANT("Module link table subset: name='%s' index=%d, link_list=%p, len=%d",
					overall->modules[i]->name, i, mt->link_list, mt->link_list->len);

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

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

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

			meta_update = (metadata *) secure_malloc(sizeof(metadata));
			metadata_create(meta_update);

			ff_update = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame));
			ff_update->dataOrCtrl = FF_CONTROL;
			ff_update->destinationID = i;
			ff_update->metaData = meta_update;

			ff_update->ctrlFrame.sender_id = 0;
			ff_update->ctrlFrame.serial_num = gen_control_serial_num();
			ff_update->ctrlFrame.opcode = CTRL_SET_PARAM;
			ff_update->ctrlFrame.param_id = MOD_SET_PARAM_DUAL;

			ff_update->ctrlFrame.data_len = sizeof(struct fins_module_table);
			ff_update->ctrlFrame.data = (uint8_t *) mt;

			module_to_switch(overall->modules[0], ff_update);
			//module_set_param_dual(overall->modules[i], ff_update);
		}
	}
	list_free(mt_list, free);

	//############ say by this point envi var completely init'd
	//assumed always connect/init to switch first

	pthread_attr_init(&overall->attr);
	pthread_attr_setdetachstate(&overall->attr, PTHREAD_CREATE_JOINABLE);

	PRINT_IMPORTANT("############# Calling run() for modules");

	for (i = 0; i < MAX_MODULES; i++) {
		if (overall->modules[i] != NULL) {
			overall->modules[i]->ops->run(overall->modules[i], &overall->attr);
		}
	}

	PRINT_IMPORTANT("Core Initiation: Finished ************");
}
Beispiel #28
0
void *accept_console(void *local) {
	struct fins_module *module = (struct fins_module *) local;
	PRINT_DEBUG("Entered: module=%p", module);
	PRINT_IMPORTANT("Thread started: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name);
	struct rtm_data *md = (struct rtm_data *) module->data;

	int32_t addr_size = sizeof(struct sockaddr_un);
	struct sockaddr_un *addr;
	int console_fd;
	struct rtm_console *console;
	int i;

	secure_sem_wait(&md->shared_sem);
	while (module->state == FMS_RUNNING) {
		if (list_has_space(md->console_list)) {
			sem_post(&md->shared_sem);

			addr = (struct sockaddr_un *) secure_malloc(addr_size);
			while (module->state == FMS_RUNNING) {
				sleep(1);
				console_fd = accept(md->server_fd, (struct sockaddr *) addr, (socklen_t *) &addr_size);
				if (console_fd > 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) {
					break;
				}
			}
			if (module->state != FMS_RUNNING) {
				free(addr);

				secure_sem_wait(&md->shared_sem);
				break;
			}

			if (console_fd < 0) {
				PRINT_ERROR("accept error: server_fd=%d, console_fd=%d, errno=%u, str='%s'", md->server_fd, console_fd, errno, strerror(errno));
				free(addr);

				secure_sem_wait(&md->shared_sem);
				continue;
			}

			secure_sem_wait(&md->shared_sem);
			console = (struct rtm_console *) secure_malloc(sizeof(struct rtm_console));
			console->id = md->console_counter++;
			console->fd = console_fd;
			console->addr = addr;
			console->type = RTM_TYPE_DEFAULT;
			console->listeners = (metadata *) secure_malloc(sizeof(metadata));
			metadata_create(console->listeners);

			PRINT_IMPORTANT("Console created: id=%u, fd=%d, addr='%s', type=%u", console->id, console->fd, console->addr->sun_path, console->type);
			list_append(md->console_list, console);

			for (i = 0; i < MAX_CONSOLES; i++) {
				if (md->console_fds[i] == 0) {
					md->console_fds[i] = console_fd;
					break;
				}
			}
		} else {
			sem_post(&md->shared_sem);
			sleep(5);
			secure_sem_wait(&md->shared_sem);
		}
	}
	sem_post(&md->shared_sem);

	PRINT_IMPORTANT("Thread exited: module=%p, index=%u, id=%u, name='%s'", module, module->index, module->id, module->name);
	PRINT_DEBUG("Exited: module=%p", module);
	return NULL;
}
Beispiel #29
0
void core_main() {
	PRINT_IMPORTANT("Entered");

	register_to_signal(SIGRTMIN);

	sem_init(&control_serial_sem, 0, 1); //TODO remove after gen_control_serial_num() converted to RNG

	signal(SIGINT, core_termination_handler); //register termination handler

	int status;
	int i, j, k;
	metadata_element *list_elem;
	int list_num;
	metadata_element *elem;
	metadata_element *ip_elem;
	uint32_t ip_num;

	//######################################################################
	overall = (struct fins_overall *) secure_malloc(sizeof(struct fins_overall));
	sem_init(&overall->sem, 0, 1);

	//######################################################################
	overall->envi = (struct envi_record *) secure_malloc(sizeof(struct envi_record));

	PRINT_IMPORTANT("loading environment");
	metadata *meta_envi = (metadata *) secure_malloc(sizeof(metadata));
	metadata_create(meta_envi);

	status = config_read_file(meta_envi, "envi.cfg");
	if (status == META_FALSE) {
		PRINT_ERROR("%s:%d - %s\n", config_error_file(meta_envi), config_error_line(meta_envi), config_error_text(meta_envi));
		metadata_destroy(meta_envi);
		PRINT_ERROR("todo error");
		exit(-1);
	}

	//############# if_list
	PRINT_IMPORTANT("interface list");
	overall->envi->if_list = list_create(MAX_INTERFACES);

	list_elem = config_lookup(meta_envi, "environment.interfaces");
	if (list_elem == NULL) {
		PRINT_ERROR("todo error");
		exit(-1);
	}
	list_num = config_setting_length(list_elem);

	uint32_t if_index;
	uint8_t *name;
	uint64_t mac;
	uint32_t type;
	uint32_t if_status;
	uint32_t mtu;
	uint32_t flags;

	struct if_record *ifr;

	for (i = 0; i < list_num; i++) {
		elem = config_setting_get_elem(list_elem, i);
		if (elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "index", (int *) &if_index);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_string(elem, "name", (const char **) &name);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int64(elem, "mac", (long long *) &mac);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "type", (int *) &type);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "status", (int *) &if_status);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "mtu", (int *) &mtu);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "flags", (int *) &flags);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		//#############
		ifr = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_index);
		if (ifr == NULL) {
			ifr = (struct if_record *) secure_malloc(sizeof(struct if_record));
			ifr->index = if_index;
			strcpy((char *) ifr->name, (char *) name);
			ifr->mac = mac;
			ifr->type = (uint16_t) type;

			ifr->status = (uint8_t) if_status;
			ifr->mtu = mtu;
			ifr->flags = flags;

			ifr->addr_list = list_create(MAX_FAMILIES);

			if (list_has_space(overall->envi->if_list)) {
				list_append(overall->envi->if_list, ifr);
			} else {
				//TODO error
				PRINT_ERROR("todo error");
				exit(-1);
			}

			if (flags & IFF_LOOPBACK) {
				overall->envi->if_loopback = ifr;
			}
		} else {
			PRINT_ERROR("todo error");
			exit(-1);
		}
	}

	//############# if_main
	PRINT_IMPORTANT("main interface");
	uint32_t if_main;

	status = config_lookup_int(meta_envi, "environment.main_interface", (int *) &if_main);
	if (status == META_FALSE) {
		PRINT_ERROR("todo error");
		exit(-1);
	}

	overall->envi->if_main = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_main);
	if (overall->envi->if_main == NULL) {
		PRINT_ERROR("todo");
	}

	//############# addr_list
	PRINT_IMPORTANT("address list");
	//overall->envi->addr_list = list_create(MAX_INTERFACES * MAX_FAMILIES); //TODO use?

	list_elem = config_lookup(meta_envi, "environment.addresses");
	if (list_elem == NULL) {
		PRINT_ERROR("todo error");
		exit(-1);
	}
	list_num = config_setting_length(list_elem);

	uint32_t family; //atm only AF_INET, but eventually also AF_INET6
	uint32_t ip[4]; //SIOCGIFADDR //ip
	uint32_t mask[4]; //SIOCGIFNETMASK //mask
	uint32_t gw[4]; //? //(ip & mask) | 1;
	uint32_t bdc[4]; //SIOCGIFBRDADDR //(ip & mask) | ~mask
	uint32_t dst[4]; //SIOCGIFDSTADDR //dst

	struct addr_record *addr;

	for (i = 0; i < list_num; i++) {
		elem = config_setting_get_elem(list_elem, i);
		if (elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "if_index", (int *) &if_index);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "family", (int *) &family);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		ip_elem = config_setting_get_member(elem, "ip");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			ip[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		ip_elem = config_setting_get_member(elem, "mask");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			mask[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		ip_elem = config_setting_get_member(elem, "gw");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			gw[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		ip_elem = config_setting_get_member(elem, "bdc");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			bdc[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		ip_elem = config_setting_get_member(elem, "dst");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			dst[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		//############
		ifr = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_index);
		if (ifr != NULL) {
			if (ifr->flags & IFF_RUNNING) {
				if (family == AF_INET) {
					addr = (struct addr_record *) list_find(ifr->addr_list, addr_is_v4);
				} else {
					addr = (struct addr_record *) list_find(ifr->addr_list, addr_is_v6);
				}

				if (addr == NULL) {
					addr = (struct addr_record *) secure_malloc(sizeof(struct addr_record));
					addr->if_index = if_index;
					addr->family = AF_INET;

					if (family == AF_INET) {
						addr4_set_addr(&addr->ip, IP4_ADR_P2H(ip[0], ip[1], ip[2],ip[3]));
						addr4_set_addr(&addr->mask, IP4_ADR_P2H(mask[0], mask[1], mask[2],mask[3]));
						addr4_set_addr(&addr->gw, IP4_ADR_P2H(gw[0], gw[1], gw[2], gw[3]));
						addr4_set_addr(&addr->bdc, IP4_ADR_P2H(bdc[0], bdc[1], bdc[2], bdc[3]));
						addr4_set_addr(&addr->dst, IP4_ADR_P2H(dst[0], dst[1], dst[2], dst[3]));
					} else if (family == AF_INET6) {
						//TODO
						//addr_set_addr6(&addr->ip, ip);
						PRINT_ERROR("todo");
					} else {
						//TODO error?
						PRINT_ERROR("todo error");
						exit(-1);
					}

					if (list_has_space(ifr->addr_list)) {
						list_append(ifr->addr_list, addr);
					} else {
						//TODO error
						PRINT_ERROR("todo error");
						exit(-1);
					}
				} else {
					//TODO error
					PRINT_ERROR("todo: replace or add new?");
				}
			} else {
				//TODO error
				PRINT_ERROR("todo: decide just drop or add?");
			}
		} else {
			//TODO error
			PRINT_ERROR("todo error");
			exit(-1);
		}
	}

	//############# route_list
	PRINT_IMPORTANT("route list");
	overall->envi->route_list = list_create(MAX_ROUTES);

	list_elem = config_lookup(meta_envi, "environment.routes");
	if (list_elem == NULL) {
		PRINT_ERROR("todo error");
		exit(-1);
	}
	list_num = config_setting_length(list_elem);

	uint32_t metric; //SIOCGIFMETRIC
	uint32_t timeout;
	//struct timeval route_stamp;

	struct route_record *route;

	for (i = 0; i < list_num; i++) {
		elem = config_setting_get_elem(list_elem, i);
		if (elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "if_index", (int *) &if_index);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "family", (int *) &family);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		ip_elem = config_setting_get_member(elem, "dst");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			dst[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		ip_elem = config_setting_get_member(elem, "mask");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			mask[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}

		ip_elem = config_setting_get_member(elem, "gw");
		if (ip_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		ip_num = config_setting_length(ip_elem);

		for (j = 0; j < ip_num; j++) {
			gw[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j);
		}
		////ip = IP4_ADR_P2H(192,168,1,5);

		status = config_setting_lookup_int(elem, "metric", (int *) &metric);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(elem, "timeout", (int *) &timeout);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		//############
		ifr = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_index);
		if (ifr != NULL) {
			if (ifr->flags & IFF_RUNNING) {
				route = (struct route_record *) secure_malloc(sizeof(struct route_record));
				route->if_index = if_index;
				route->family = family;

				if (family == AF_INET) {
					addr4_set_addr(&route->dst, IP4_ADR_P2H(dst[0], dst[1], dst[2], dst[3]));
					addr4_set_addr(&route->mask, IP4_ADR_P2H(mask[0], mask[1], mask[2],mask[3]));
					addr4_set_addr(&route->gw, IP4_ADR_P2H(gw[0], gw[1], gw[2], gw[3]));
					//addr4_set_addr(&route->ip, IP4_ADR_P2H(ip[0], ip[1], ip[2],ip[3]));
				} else if (family == AF_INET6) {
					//TODO
					//addr_set_addr6(&route->ip, ip);
				} else {
					//TODO error?
				}

				route->metric = metric;
				route->timeout = timeout;

				if (list_has_space(overall->envi->route_list)) {
					list_append(overall->envi->route_list, route);
				} else {
					//TODO error
					PRINT_ERROR("todo error");
					exit(-1);
				}
			} else {
				//TODO error
				PRINT_ERROR("todo: decide just drop or add?");
			}
		}
	}
	metadata_destroy(meta_envi);

	//######################################################################
	PRINT_IMPORTANT("loading stack");
	metadata *meta_stack = (metadata *) secure_malloc(sizeof(metadata));
	metadata_create(meta_stack);

	status = config_read_file(meta_stack, "stack.cfg");
	if (status == META_FALSE) {
		PRINT_ERROR("%s:%d - %s\n", config_error_file(meta_stack), config_error_line(meta_stack), config_error_text(meta_stack));
		metadata_destroy(meta_stack);
		PRINT_ERROR("todo error");
		exit(-1);
	}

	//############# module_list
	PRINT_IMPORTANT("module list");
	overall->lib_list = list_create(MAX_MODULES);
	memset(overall->modules, 0, MAX_MODULES * sizeof(struct fins_module *));
	overall->admin_list = list_create(MAX_MODULES);

	uint8_t base_path[100];
	memset((char *) base_path, 0, 100);
	strcpy((char *) base_path, ".");

	metadata_element *mods_elem = config_lookup(meta_stack, "stack.modules");
	if (mods_elem == NULL) {
		PRINT_ERROR("todo error");
		exit(-1);
	}
	int mods_num = config_setting_length(mods_elem);

	metadata_element *mod_elem;
	uint32_t mod_id;
	uint8_t *mod_lib;
	uint8_t *mod_name;
	metadata_element *flows_elem;
	uint32_t mod_flows[MAX_MOD_FLOWS];
	uint32_t mod_flows_num;
	metadata_element *mod_params;
	metadata_element *mod_admin;

	struct fins_library *library;
	struct fins_module *module;

	for (i = 0; i < mods_num; i++) {
		mod_elem = config_setting_get_elem(mods_elem, i);
		if (mod_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(mod_elem, "id", (int *) &mod_id);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_string(mod_elem, "lib", (const char **) &mod_lib);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_string(mod_elem, "name", (const char **) &mod_name);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		flows_elem = config_setting_get_member(mod_elem, "flows");
		if (flows_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		mod_flows_num = config_setting_length(flows_elem);

		for (j = 0; j < mod_flows_num; j++) {
			mod_flows[j] = (uint32_t) config_setting_get_int_elem(flows_elem, j);
		}

		mod_params = config_setting_get_member(mod_elem, "params");
		if (mod_params == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		mod_admin = config_setting_get_member(mod_elem, "admin");
		PRINT_DEBUG("admin=%u", mod_admin != NULL)

		//############
		library = (struct fins_library *) list_find1(overall->lib_list, lib_name_test, mod_lib);
		if (library == NULL) {
			library = library_load(mod_lib, base_path);
			if (library == NULL) {
				PRINT_ERROR("todo error");
				exit(-1);
			}

			if (list_has_space(overall->lib_list)) {
				list_append(overall->lib_list, library);
			} else {
				PRINT_ERROR("todo error");
				exit(-1);
			}
		}

		module = library->create(i, mod_id, mod_name);
		if (module == NULL) {
			//TODO error
			PRINT_ERROR("todo error");
			exit(-1);
		}
		library->num_mods++;

		//TODO move flow to update? or links here?
		status = module->ops->init(module, mod_flows_num, mod_flows, mod_params, overall->envi); //TODO merge init into create?
		if (status != 0) {
			overall->modules[i] = module;

			if (mod_admin != NULL) {
				list_append(overall->admin_list, module);
			}
		} else {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		//free(mod_lib); //don't free, string from libconfig points to metadata memory
		//free(mod_name);
	}

	//############# admin_list //TODO change to admin_list?
	//list_for_each(overall->admin_list, register_all);
	list_for_each1(overall->admin_list, assign_overall, overall);

	//############# linking_list
	PRINT_IMPORTANT("link list");
	overall->link_list = list_create(MAX_TABLE_LINKS);

	metadata_element *links_elem = config_lookup(meta_stack, "stack.links");
	if (links_elem == NULL) {
		PRINT_ERROR("todo error");
		exit(-1);
	}
	int links_num = config_setting_length(links_elem);

	metadata_element *link_elem;
	uint32_t link_id;
	uint32_t link_src;
	metadata_element *dsts_elem;
	uint32_t link_dsts[MAX_MODULES];
	int link_dsts_num;

	struct link_record *link;

	for (i = 0; i < links_num; i++) {
		link_elem = config_setting_get_elem(links_elem, i);
		if (link_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(link_elem, "id", (int *) &link_id);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		status = config_setting_lookup_int(link_elem, "src", (int *) &link_src);
		if (status == META_FALSE) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		dsts_elem = config_setting_get_member(link_elem, "dsts");
		if (dsts_elem == NULL) {
			PRINT_ERROR("todo error");
			exit(-1);
		}
		link_dsts_num = config_setting_length(dsts_elem);

		for (j = 0; j < link_dsts_num; j++) {
			link_dsts[j] = (uint32_t) config_setting_get_int_elem(dsts_elem, j);
		}

		//############
		link = (struct link_record *) secure_malloc(sizeof(struct link_record));
		link->id = link_id;

		//module = (struct fins_module *) list_find1(overall->envi->module_list, mod_id_test, &link_src);
		link->src_index = -1;
		for (j = 0; j < MAX_MODULES; j++) {
			if (overall->modules[j] != NULL && overall->modules[j]->id == link_src) {
				link->src_index = overall->modules[j]->index;
			}
		}
		if (link->src_index == -1) {
			PRINT_ERROR("todo error");
			exit(-1);
		}

		link->dsts_num = link_dsts_num;
		for (j = 0; j < link_dsts_num; j++) {
			//module = (struct fins_module *) list_find1(overall->envi->module_list, mod_id_test, &link_dsts[j]);
			link->dsts_index[j] = -1;
			for (k = 0; k < MAX_MODULES; k++) {
				if (overall->modules[k] != NULL && overall->modules[k]->id == link_dsts[j]) {
					link->dsts_index[j] = overall->modules[k]->index;
				}
			}
			if (link->dsts_index[j] == (uint32_t) -1) {
				PRINT_ERROR("todo error");
				exit(-1);
			}
		}

		if (list_has_space(overall->link_list)) {
			list_append(overall->link_list, link);
		} else {
			//TODO error
			PRINT_ERROR("todo error");
			exit(-1);
		}
	}
	metadata_destroy(meta_stack);

	//######################################################################
	PRINT_IMPORTANT("update modules");
	//send out subset of linking table to each module as update
	//TODO table subset update

	struct linked_list *link_subset_list;
	metadata *meta_update;
	struct finsFrame *ff_update;

	for (i = 0; i < MAX_MODULES; i++) {
		if (overall->modules[i] != NULL) {
			link_subset_list = list_filter1(overall->link_list, link_involved_test, &overall->modules[i]->index, link_clone); //TODO is mem leak
			PRINT_IMPORTANT("i=%d, link_subset_list=%p, len=%d", i, link_subset_list, link_subset_list->len);

			meta_update = (metadata *) secure_malloc(sizeof(metadata));
			metadata_create(meta_update);

			//TODO decide on metadata params?
			//uint32_t host_ip = IP4_ADR_P2H(192,168,1,8);
			//secure_metadata_writeToElement(meta_update, "send_src_ip", &host_ip, META_TYPE_INT32);

			ff_update = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame));
			ff_update->dataOrCtrl = FF_CONTROL;
			ff_update->destinationID = i;
			ff_update->metaData = meta_update;

			ff_update->ctrlFrame.sender_id = 0;
			ff_update->ctrlFrame.serial_num = gen_control_serial_num();
			ff_update->ctrlFrame.opcode = CTRL_SET_PARAM;
			ff_update->ctrlFrame.param_id = MOD_SET_PARAM_LINKS;

			ff_update->ctrlFrame.data_len = sizeof(struct linked_list);
			ff_update->ctrlFrame.data = (uint8_t *) link_subset_list;

			module_to_switch(overall->modules[0], ff_update);
		}
	}

	//############ say by this point envi var completely init'd
	//assumed always connect/init to switch first

	pthread_attr_t attr;
	pthread_attr_init(&attr);

	PRINT_IMPORTANT("modules: run");

	for (i = 0; i < MAX_MODULES; i++) {
		if (overall->modules[i] != NULL) {
			overall->modules[i]->ops->run(overall->modules[i], &attr);
		}
	}

	//############ mini test
	//sleep(5);
	char recv_data[4000];

	//while (1) {
	PRINT_IMPORTANT("waiting...");
	gets(recv_data);

	if (0) {
		metadata *meta = (metadata *) secure_malloc(sizeof(metadata));
		metadata_create(meta);

		uint32_t host_ip = IP4_ADR_P2H(192,168,1,8);
		uint32_t host_port = 55454;
		uint32_t dst_ip = IP4_ADR_P2H(192,168,1,3);
		uint32_t dst_port = 44444;
		uint32_t ttl = 64;
		uint32_t tos = 64;

		secure_metadata_writeToElement(meta, "send_src_ip", &host_ip, META_TYPE_INT32);
		secure_metadata_writeToElement(meta, "send_src_port", &host_port, META_TYPE_INT32);
		secure_metadata_writeToElement(meta, "send_dst_ip", &dst_ip, META_TYPE_INT32);
		secure_metadata_writeToElement(meta, "send_dst_port", &dst_port, META_TYPE_INT32);
		secure_metadata_writeToElement(meta, "send_ttl", &ttl, META_TYPE_INT32);
		secure_metadata_writeToElement(meta, "send_tos", &tos, META_TYPE_INT32);

		struct finsFrame *ff = (struct finsFrame *) secure_malloc(sizeof(struct finsFrame));
		ff->dataOrCtrl = FF_DATA;
		ff->destinationID = 1;
		ff->metaData = meta;

		ff->dataFrame.directionFlag = DIR_UP;
		ff->dataFrame.pduLength = 10;
		ff->dataFrame.pdu = (uint8_t *) secure_malloc(10);

		PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff, meta, overall->modules[0]->name, overall->modules[1]->name);
		module_to_switch(overall->modules[0], ff);
	}

	if (0) {
		PRINT_DEBUG("Sending ARP req");

		metadata *meta_req = (metadata *) secure_malloc(sizeof(metadata));
		metadata_create(meta_req);

		uint32_t dst_ip = IP4_ADR_P2H(192, 168, 1, 1);
		//uint32_t dst_ip = IP4_ADR_P2H(172, 31, 54, 169);
		uint32_t src_ip = IP4_ADR_P2H(192, 168, 1, 20);
		//uint32_t src_ip = IP4_ADR_P2H(172, 31, 50, 160);

		secure_metadata_writeToElement(meta_req, "dst_ip", &dst_ip, META_TYPE_INT32);
		secure_metadata_writeToElement(meta_req, "src_ip", &src_ip, META_TYPE_INT32);

		struct finsFrame *ff_req = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame));
		ff_req->dataOrCtrl = FF_CONTROL;
		ff_req->destinationID = 1; //arp
		ff_req->metaData = meta_req;

		ff_req->ctrlFrame.sender_id = 4; //ipv4
		ff_req->ctrlFrame.serial_num = gen_control_serial_num();
		ff_req->ctrlFrame.opcode = CTRL_EXEC;
		ff_req->ctrlFrame.param_id = 0; //EXEC_ARP_GET_ADDR;

		ff_req->ctrlFrame.data_len = 0;
		ff_req->ctrlFrame.data = NULL;

		PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff_req, meta_req, overall->modules[0]->name, overall->modules[1]->name);
		module_to_switch(overall->modules[0], ff_req);
	}

	if (0) {
		PRINT_DEBUG("Sending data");

		metadata *meta_req = (metadata *) secure_malloc(sizeof(metadata));
		metadata_create(meta_req);

		uint32_t ether_type = 0x0800; //ipv4
		if_index = 3; //wlan0
		uint32_t src_ip = IP4_ADR_P2H(192, 168, 1, 5); //wlan0
		uint32_t dst_ip = IP4_ADR_P2H(192, 168, 1, 1); //gw

		secure_metadata_writeToElement(meta_req, "send_ether_type", &ether_type, META_TYPE_INT32);
		secure_metadata_writeToElement(meta_req, "send_if_index", &if_index, META_TYPE_INT32);
		secure_metadata_writeToElement(meta_req, "send_src_ipv4", &src_ip, META_TYPE_INT32);
		secure_metadata_writeToElement(meta_req, "send_dst_ipv4", &dst_ip, META_TYPE_INT32);

		struct finsFrame *ff = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame));
		ff->dataOrCtrl = FF_DATA;
		ff->destinationID = 1; //arp
		ff->metaData = meta_req;

		ff->dataFrame.directionFlag = DIR_DOWN;
		ff->dataFrame.pduLength = 100;
		ff->dataFrame.pdu = (uint8_t *) secure_malloc(ff->dataFrame.pduLength);
		memset(ff->dataFrame.pdu, 59, ff->dataFrame.pduLength);

		PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff, meta_req, overall->modules[0]->name, overall->modules[1]->name);
		module_to_switch(overall->modules[0], ff);
	}

	if (0) {
		PRINT_DEBUG("Sending data");

		metadata *meta = (metadata *) secure_malloc(sizeof(metadata));
		metadata_create(meta);

		uint32_t src_ip = IP4_ADR_P2H(192, 168, 1, 5); //wlan0
		uint32_t src_port = 6666;
		uint32_t dst_ip = IP4_ADR_P2H(192, 168, 1, 1); //gw
		uint32_t dst_port = 5555;

		secure_metadata_writeToElement(meta, "send_src_ipv4", &src_ip, META_TYPE_INT32);
		secure_metadata_writeToElement(meta, "send_src_port", &src_port, META_TYPE_INT32);
		secure_metadata_writeToElement(meta, "send_dst_ipv4", &dst_ip, META_TYPE_INT32);
		secure_metadata_writeToElement(meta, "send_dst_port", &dst_port, META_TYPE_INT32);

		uint32_t dst_index = 4;
		struct finsFrame *ff = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame));
		ff->dataOrCtrl = FF_DATA;
		ff->destinationID = dst_index; //arp
		ff->metaData = meta;

		ff->dataFrame.directionFlag = DIR_DOWN;
		ff->dataFrame.pduLength = 10;
		ff->dataFrame.pdu = (uint8_t *) secure_malloc(ff->dataFrame.pduLength);
		memset(ff->dataFrame.pdu, 65, ff->dataFrame.pduLength);

		PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff, meta, overall->modules[0]->name, overall->modules[dst_index]->name);
		module_to_switch(overall->modules[0], ff);
	}

	if (1) {
		PRINT_DEBUG("Sending data");

		metadata *meta = (metadata *) secure_malloc(sizeof(metadata));
		metadata_create(meta);

		uint32_t src_ip = IP4_ADR_P2H(192, 168, 1, 5); //wlan0
		uint32_t dst_ip = IP4_ADR_P2H(192, 168, 1, 1); //gw

		secure_metadata_writeToElement(meta, "send_src_ipv4", &src_ip, META_TYPE_INT32);
		secure_metadata_writeToElement(meta, "send_dst_ipv4", &dst_ip, META_TYPE_INT32);

		uint32_t dst_index = 4;
		struct finsFrame *ff = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame));
		ff->dataOrCtrl = FF_DATA;
		ff->destinationID = dst_index;
		ff->metaData = meta;

		ff->dataFrame.directionFlag = DIR_DOWN;
		ff->dataFrame.pduLength = 10;
		ff->dataFrame.pdu = (uint8_t *) secure_malloc(ff->dataFrame.pduLength);
		memset(ff->dataFrame.pdu, 65, ff->dataFrame.pduLength);

		PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff, meta, overall->modules[0]->name, overall->modules[dst_index]->name);
		module_to_switch(overall->modules[0], ff);
	}

	while (1)
		;

	sleep(5);
	PRINT_IMPORTANT("waiting...");
	char recv_data2[4000];
	gets(recv_data2);

	//############ terminating
	core_termination_handler(0);
}
Beispiel #30
0
void core_tests(void) {
	int i = 0;
	while (1) {
		PRINT_IMPORTANT("waiting...");
		//sleep(10);
		//char recv_data[4000];
		//gets(recv_data);
		fgetc(stdin); //wait until user enters
		PRINT_IMPORTANT("active");

		i++;
		if (i == 1) {
			metadata *meta = (metadata *) secure_malloc(sizeof(metadata));
			metadata_create(meta);

			uint32_t host_ip = IP4_ADR_P2H(192,168,1,8);
			uint32_t host_port = 55454;
			uint32_t dst_ip = IP4_ADR_P2H(192,168,1,3);
			uint32_t dst_port = 44444;
			uint32_t ttl = 64;
			uint32_t tos = 64;

			secure_metadata_writeToElement(meta, "send_src_ip", &host_ip, META_TYPE_INT32);
			secure_metadata_writeToElement(meta, "send_src_port", &host_port, META_TYPE_INT32);
			secure_metadata_writeToElement(meta, "send_dst_ip", &dst_ip, META_TYPE_INT32);
			secure_metadata_writeToElement(meta, "send_dst_port", &dst_port, META_TYPE_INT32);
			secure_metadata_writeToElement(meta, "send_ttl", &ttl, META_TYPE_INT32);
			secure_metadata_writeToElement(meta, "send_tos", &tos, META_TYPE_INT32);

			uint32_t src_index = 1;
			uint32_t dst_index = 2;
			struct finsFrame *ff = (struct finsFrame *) secure_malloc(sizeof(struct finsFrame));
			ff->dataOrCtrl = FF_DATA;
			ff->destinationID = dst_index;
			ff->metaData = meta;

			ff->dataFrame.directionFlag = DIR_UP;
			ff->dataFrame.pduLength = 10;
			ff->dataFrame.pdu = (uint8_t *) secure_malloc(10);

			PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff, meta, overall->modules[src_index]->name, overall->modules[dst_index]->name);
			module_to_switch(overall->modules[src_index], ff);
		}

		if (0) {
			PRINT_DEBUG("Sending ARP req");

			metadata *meta_req = (metadata *) secure_malloc(sizeof(metadata));
			metadata_create(meta_req);

			uint32_t dst_ip = IP4_ADR_P2H(192, 168, 1, 1);
			//uint32_t dst_ip = IP4_ADR_P2H(172, 31, 54, 169);
			uint32_t src_ip = IP4_ADR_P2H(192, 168, 1, 20);
			//uint32_t src_ip = IP4_ADR_P2H(172, 31, 50, 160);

			secure_metadata_writeToElement(meta_req, "dst_ip", &dst_ip, META_TYPE_INT32);
			secure_metadata_writeToElement(meta_req, "src_ip", &src_ip, META_TYPE_INT32);

			struct finsFrame *ff_req = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame));
			ff_req->dataOrCtrl = FF_CONTROL;
			ff_req->destinationID = 1; //arp
			ff_req->metaData = meta_req;

			ff_req->ctrlFrame.sender_id = 4; //ipv4
			ff_req->ctrlFrame.serial_num = gen_control_serial_num();
			ff_req->ctrlFrame.opcode = CTRL_EXEC;
			ff_req->ctrlFrame.param_id = 0; //EXEC_ARP_GET_ADDR;

			ff_req->ctrlFrame.data_len = 0;
			ff_req->ctrlFrame.data = NULL;

			PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff_req, meta_req, overall->modules[0]->name, overall->modules[1]->name);
			module_to_switch(overall->modules[0], ff_req);
		}

		if (i == 2) {
			PRINT_DEBUG("Sending data");

			metadata *meta_req = (metadata *) secure_malloc(sizeof(metadata));
			metadata_create(meta_req);

			uint32_t ether_type = 0x0800; //ipv4
			int32_t if_index = 3; //wlan0
			uint32_t src_ip = IP4_ADR_P2H(192, 168, 1, 5); //wlan0
			uint32_t dst_ip = IP4_ADR_P2H(192, 168, 1, 1); //gw

			uint32_t src_index = 2;
			uint32_t dst_index = 1;
			secure_metadata_writeToElement(meta_req, "send_ether_type", &ether_type, META_TYPE_INT32);
			secure_metadata_writeToElement(meta_req, "send_if_index", &if_index, META_TYPE_INT32);
			secure_metadata_writeToElement(meta_req, "send_src_ipv4", &src_ip, META_TYPE_INT32);
			secure_metadata_writeToElement(meta_req, "send_dst_ipv4", &dst_ip, META_TYPE_INT32);

			struct finsFrame *ff = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame));
			ff->dataOrCtrl = FF_DATA;
			ff->destinationID = dst_index; //arp
			ff->metaData = meta_req;

			ff->dataFrame.directionFlag = DIR_DOWN;
			ff->dataFrame.pduLength = 100;
			ff->dataFrame.pdu = (uint8_t *) secure_malloc(ff->dataFrame.pduLength);
			memset(ff->dataFrame.pdu, 59, ff->dataFrame.pduLength);

			PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'",
					ff, meta_req, overall->modules[src_index]->name, overall->modules[dst_index]->name);
			module_to_switch(overall->modules[src_index], ff);
		}

		if (0) {
			PRINT_DEBUG("Sending data");

			metadata *meta = (metadata *) secure_malloc(sizeof(metadata));
			metadata_create(meta);

			uint32_t src_ip = IP4_ADR_P2H(192, 168, 1, 4); //wlan0
			uint32_t src_port = 6666;
			uint32_t dst_ip = IP4_ADR_P2H(192, 168, 1, 1); //gw
			uint32_t dst_port = 5555;

			secure_metadata_writeToElement(meta, "send_src_ipv4", &src_ip, META_TYPE_INT32);
			secure_metadata_writeToElement(meta, "send_src_port", &src_port, META_TYPE_INT32);
			secure_metadata_writeToElement(meta, "send_dst_ipv4", &dst_ip, META_TYPE_INT32);
			secure_metadata_writeToElement(meta, "send_dst_port", &dst_port, META_TYPE_INT32);

			uint32_t dst_index = 8;
			struct finsFrame *ff = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame));
			ff->dataOrCtrl = FF_DATA;
			ff->destinationID = dst_index; //arp
			ff->metaData = meta;

			ff->dataFrame.directionFlag = DIR_DOWN;
			ff->dataFrame.pduLength = 10;
			ff->dataFrame.pdu = (uint8_t *) secure_malloc(ff->dataFrame.pduLength);
			memset(ff->dataFrame.pdu, 65, ff->dataFrame.pduLength);

			PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff, meta, overall->modules[0]->name, overall->modules[dst_index]->name);
			module_to_switch(overall->modules[0], ff);
		}

		if (0) {
			PRINT_DEBUG("Sending data");

			metadata *meta = (metadata *) secure_malloc(sizeof(metadata));
			metadata_create(meta);

			uint32_t family = AF_INET;
			uint32_t src_ip = IP4_ADR_P2H(192, 168, 1, 15); //wlan0
			uint32_t dst_ip = IP4_ADR_P2H(172, 168, 1, 1); //gw

			secure_metadata_writeToElement(meta, "send_family", &family, META_TYPE_INT32);
			secure_metadata_writeToElement(meta, "send_src_ipv4", &src_ip, META_TYPE_INT32);
			secure_metadata_writeToElement(meta, "send_dst_ipv4", &dst_ip, META_TYPE_INT32);

			uint32_t dst_index = 4;
			struct finsFrame *ff = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame));
			ff->dataOrCtrl = FF_DATA;
			ff->destinationID = dst_index;
			ff->metaData = meta;

			ff->dataFrame.directionFlag = DIR_DOWN;
			ff->dataFrame.pduLength = 10;
			ff->dataFrame.pdu = (uint8_t *) secure_malloc(ff->dataFrame.pduLength);
			memset(ff->dataFrame.pdu, 65, ff->dataFrame.pduLength);

			PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff, meta, overall->modules[0]->name, overall->modules[dst_index]->name);
			module_to_switch(overall->modules[0], ff);
		}
		//break;
	}
}