Beispiel #1
0
static void cmd_get_next_flow_info(int fd, int pid, int sock) {
	flist_node_t *f;
	int d = 0;
	struct mapiipcbuf buf;

	while(__sync_lock_test_and_set(&flowlist_lock,1));

	f=flist_head(flowlist);
	//Loop through flows to find the next one
	while (f!=NULL) {
		if (flist_id(f)>fd) {
			if (d==0)
				d=flist_id(f);
			else if (flist_id(f)<d)
				d=flist_id(f);
		}
		f=flist_next(f);
	}

	flowlist_lock = 0;

	if (d != 0)
		cmd_get_flow_info(d, pid, sock);
	else {
		//Send back error message
		buf.mtype = pid;
		buf.fd = fd;
		buf.cmd = GET_FLOW_INFO_NACK;
		mapiipc_daemon_write(&buf, sock);
	}
}
Beispiel #2
0
void free_header_list(flist_t * list, int method)
{
	flist_node_t   *node = flist_head(list), *node2;
	while (node) {
		struct headers_data *data = flist_data(node);
		node2 = flist_next(node);

		if (method == FLIST_FREE_DATA) {
			free(data->header);
			free(data);
		}

		free(node);
		node = node2;
	}
}
Beispiel #3
0
void do_uncook_loop(struct anonflow *flow, struct function *flist)
{
	flist_node_t   *fn;
	struct function *next_func;
	struct headers_data *frag_data;

	flow->uncook_ready = 0;

	for (fn = flist_head(flow->client_headers); fn != NULL; fn = flist_next(fn)) {
		anon_pkthdr_t   frag_pkt_head;
		flow->decoded_packet = NULL;

		frag_data = (struct headers_data *)(fn->data);
		//fprintf(stderr,"(%d) frag_data->caplen: %d %d %x\n",ff++,frag_data->caplen,flist_size(flow->headers),frag_data);

		frag_pkt_head.caplen = frag_data->caplen;
		frag_pkt_head.wlen = frag_data->wlen;
		frag_pkt_head.ts.tv_sec = frag_data->ts.tv_sec;
		frag_pkt_head.ts.tv_usec = frag_data->ts.tv_usec;

		next_func = flist->next;

		while (next_func) {
			if (next_func->function_info->
			    process(flow, next_func->internal_data, frag_data->header,
				    &frag_pkt_head) == 0) {
				break;
			}
			next_func = next_func->next;
		}

		if (next_func == NULL && flow->output_type != NONE) {	//Flow reached its end
			dump_packet(flow, frag_data->header, &frag_pkt_head);
		}
	}

	return;
}
Beispiel #4
0
static void mapidcom()
//Communicates with clients through IPC
{
	fd_set active_fd_set; // active file descriptor list
	fd_set read_fd_set; // temp file descriptor list for select()
	int fdmax; // maximum file descriptor number
	int yes = 1; // for setsockopt() SO_REUSEADDR, below
	struct sockaddr_un mapidaddr;
	struct sockaddr_un remoteaddr;
	struct mapiipcbuf qbuf;
	socklen_t addrlen;
	int nbytes, len, s;
	struct client *cl= NULL;
	flist_node_t *tmpnode;
	conf_category_entry_t *cat=NULL;
	char *local;
	struct group *mapi_group;
  conf_category_t *conf;

	mapidsocket=strdup(MAPIDSOCKGLOBAL);

	if ((conf = pc_load(mapid_conf)) != NULL) {
		cat = pc_get_category(conf, "");
		local=pc_get_param(cat, "local");
		if (local!=NULL && strcmp(local, "1")==0) {
			free(mapidsocket);
			mapidsocket=printf_string(MAPIDSOCKHOME, getenv("HOME") );
		}
		pc_close(conf);

	}
	//  create the listener socket
	if ((listenerfd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {
		DEBUG_CMD(Debug_Message("ERROR: socket: %s", strerror(errno)));
		exit(EXIT_FAILURE);
	}
	// avoid "address already in use" error message
	if (setsockopt(listenerfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int))
			== -1) {
		DEBUG_CMD(Debug_Message("ERROR: setsockopt: %s", strerror(errno)));
		exit(EXIT_FAILURE);
	}
	//  set up the address we will be binding to
	memset(&mapidaddr, 0, sizeof (mapidaddr));
	mapidaddr.sun_family = AF_LOCAL;

	memcpy(mapidaddr.sun_path, mapidsocket, strlen(mapidsocket)+1);
	unlink(mapidsocket);

	len = sizeof mapidaddr.sun_family + strlen(mapidaddr.sun_path);
	if (bind(listenerfd, (struct sockaddr *) &mapidaddr, len)) {
		DEBUG_CMD(Debug_Message("ERROR: bind: %s", strerror(errno)));
		exit(EXIT_FAILURE);
	}

	// allow any member of our own group to connect
	chmod(mapidsocket, S_IRWXU | S_IRWXG);

	// if a mapi user group exists, set group permissions accordingly,
	// otherwise the group ID will be equal to the user ID of the user that
	// invoked mapid
	mapi_group = getgrnam(MAPI_GROUP_NAME);
	if (mapi_group != NULL) {
		chown(mapidsocket, -1, mapi_group->gr_gid);
	}

	if (listen(listenerfd, BACKLOG) == -1) {
		DEBUG_CMD(Debug_Message("ERROR: listen: %s", strerror(errno)));
		exit(EXIT_FAILURE);
	}

	FD_ZERO (&active_fd_set);
	// add the listener to the active set
	FD_SET (listenerfd, &active_fd_set)
;
  // keep track of the biggest file descriptor
  		fdmax = listenerfd; // so far, it's just this one

	// wait for commands from the mapi stub, for ever...
	while (1) {
		read_fd_set = active_fd_set; // copy it
		if (select(fdmax + 1, &read_fd_set, NULL, NULL, NULL) == -1) {
			DEBUG_CMD(Debug_Message("ERROR: select: %s", strerror(errno)));
			break;
		}

		// run through the existing connections
		for (s = 0; s <= fdmax; s++) {
			if (FD_ISSET (s, &read_fd_set)) {

				// connection on the original listener socket
				if (s == listenerfd) {
					addrlen = sizeof (remoteaddr);
					if ((newfd = accept(listenerfd,
							(struct sockaddr *) &remoteaddr, &addrlen)) == -1) {
						DEBUG_CMD(Debug_Message("accept: %s", strerror(errno)));
					} else {
						FD_SET (newfd, &active_fd_set)
;						// add to active set
						if (newfd > fdmax)
						{ // keep track of the maximum
							fdmax = newfd;
						}
					}
				}
				// handle data from an existing client
				else
				{
					if ((nbytes = recv (s, &qbuf, MAX_SEND_SIZE, 0)) <= 0)
					{
						if (nbytes == 0)
						{
							// connection closed - find client's pid
							while(__sync_lock_test_and_set(&clientlist_lock,1));
							tmpnode = (flist_node_t *) flist_head (clientlist);

							cl = NULL;
							while (tmpnode != NULL)
							{
								if (((struct client *) tmpnode->data)->sock == s)
								{
									cl = (struct client *) tmpnode->data;
									break;
								}
								tmpnode = flist_next (tmpnode);
							}
							clientlist_lock = 0;

							if (cl == NULL)
							{/* This is not interesting, as it will occur upon requests from clients without flows etc.
							 WARNING_CMD (printf
							 ("WARNING: Zero bytes from socket %d [%s:%d]\n",
							 s, __FILE__, __LINE__));
							 */
								/* shouldn't really exit here? 
								 * this will cause the program to exit on errors with an empty
								 * client-list which isn't really an error (IMHO)
								 */
								//exit(EXIT_FAILURE);
							}
							else
							{
								while(__sync_lock_test_and_set(&clientlist_lock,1));
								//clean up any remaining flows
								tmpnode = (flist_node_t *) flist_head (cl->flowlist);
								while (tmpnode != NULL)
								{
									cleanup_flow ((struct flow *) tmpnode->data);
									tmpnode = flist_next (tmpnode);
								}
								tmpnode = (flist_node_t *) flist_head (cl->devicelist);
								while (tmpnode != NULL)
								{
									mapidrv_delete_device = get_drv_funct (tmpnode->data, "mapidrv_delete_device");
									mapidrv_delete_device (tmpnode->id);
									tmpnode = flist_next (tmpnode);
								}
								flist_destroy (cl->flowlist);
								flist_destroy (cl->devicelist);
								free(cl->devicelist);
								free (cl->flowlist);
								//remove this client from global client list
								free(flist_remove (clientlist, cl->pid));
								clientlist_lock = 0;
							}
						}
						else
						{
							DEBUG_CMD(Debug_Message("WARNING: recv: %s at", strerror (errno)));
						}
						close (s);
						FD_CLR (s, &active_fd_set); // remove it from active set
					}
					else
					{
						// we got some data from a client: process request
						switch (qbuf.cmd)
						{
							case GET_LIBS:
							cmd_get_libs (qbuf.pid, s);
							break;
							case GET_LIBPATH:
							cmd_get_libpath (qbuf.pid, s);
							break;
							case CREATE_FLOW:
							cmd_create_flow ((char *)qbuf.data, qbuf.pid, qbuf.uid, s);
							break;
							case CLOSE_FLOW:
							cmd_close_flow (qbuf.fd, qbuf.pid, s, 1);
							break;
							case GET_FLOW_INFO:
							cmd_get_flow_info (qbuf.fd, qbuf.pid, s);
							break;
							case GET_FUNCTION_INFO:
							cmd_get_function_info (qbuf.fd, qbuf.fid, qbuf.pid, s);
							break;
							case GET_NEXT_FUNCTION_INFO:
							cmd_get_next_function_info (qbuf.fd, qbuf.fid, qbuf.pid, s);
							break;
							case GET_NEXT_FLOW_INFO:
							cmd_get_next_flow_info (qbuf.fd, qbuf.pid, s);
							break;
							case GET_NEXT_DEVICE_INFO:
							cmd_get_next_device_info (qbuf.fd, qbuf.pid, s);
							break;
							case GET_DEVICE_INFO:
							cmd_get_device_info (qbuf.fd, qbuf.pid, s);
							break;
						case MAPI_STATS:
						  cmd_stats ((char *)qbuf.data, qbuf.pid, qbuf.uid, s);
						  break;
							case APPLY_FUNCTION:
							cmd_apply_function (&qbuf, qbuf.pid, s);
							break;
							case READ_RESULT:
							cmd_read_results (qbuf.fd, qbuf.fid, qbuf.pid, s);
							break;
							case CONNECT:
							cmd_connect (qbuf.fd, qbuf.pid, s);
							break;
							case CREATE_FLOW_ACK:
							case APPLY_FUNCTION_ACK:
							case READ_RESULT_ACK:
							case CONNECT_ACK:
							case CLOSE_FLOW_ACK:
							case SET_AUTHDATA_ACK:
							break;
							case READ_ERROR_ACK:
							break;
							case ERROR_ACK:
							break;
							case CREATE_OFFLINE_DEVICE:
							cmd_create_offline_device ((char *)qbuf.data, qbuf.fid, qbuf.pid, s);
							break;
							case CREATE_OFFLINE_DEVICE_ACK:
							break;
							case START_OFFLINE_DEVICE:
							cmd_start_offline_device ((char *)qbuf.data, qbuf.pid, s);
							break;
							case START_OFFLINE_DEVICE_ACK:
							break;
							case DELETE_OFFLINE_DEVICE:
							cmd_delete_offline_device ((char *)qbuf.data, qbuf.pid, s);
							break;
							case DELETE_OFFLINE_DEVICE_ACK:
							break;
							case CREATE_OFFLINE_FLOW_ACK:
							break;
							case LOAD_LIBRARY:
							cmd_load_library ((char *)qbuf.data, qbuf.pid, s);
							default:
							break;
						}
					}
				}
			}
		} // for
	} // while(1)
}
Beispiel #5
0
static void mapid_shutdown(int data) {
	flist_node_t *cur;
	struct client *cl;
	mapidrv *drv = drvlist;

	/* espenb TODO: use lock mechanisms instead 
	 * each thread receives signals, only one thread must execute
	 * shutdown, only one shutdown necessary
	 */
	if (running_shutdown != 0)
		return;
	running_shutdown = 1;

	//we don't want funny things to happen while freeing memory
	signal(SIGTERM, SIG_IGN);
	signal(SIGQUIT, SIG_IGN);
	signal(SIGINT, SIG_IGN);

	printf("Closing operations\n");
	//Unload drivers
	while (drv) {
		drvlist = drvlist->next;
		mapidrv_delete_device = get_drv_funct(drv->handle,
				"mapidrv_delete_device");
		if (mapidrv_delete_device)
			mapidrv_delete_device(drv->devid);

		/* if we close, we lose the symbol information associated with drivers 
		 * when running valgrind.
		 */
#ifndef VALGRIND
		printf("!!dlclose\n");
		dlclose(drv->handle);
#endif
		free(drv->device);
		if (drv->description!=NULL)
			free(drv->description);
		if (drv->name)
			free(drv->name);
		//if(drv->alias != NULL)
		//free(drv->alias);
		free(drv);
		drv = drvlist;
	}

	//Remove flowlist
	flist_destroy(flowlist);
	free(flowlist);

	//Remove clientlist
	cur = flist_head(clientlist);
	while (cur) {
		cl = flist_data(cur);
		flist_destroy(cl->flowlist);
		free(cl->flowlist);
		cur = flist_next(cur);
	}
	flist_destroy(clientlist);
	free(clientlist);

	free(gflist->fflist);
	free(gflist);
	free(mapidsocket);
	free(mapid_conf);

	if (log_to_file) {
		daemon_terminated(log_fd_info, "MAPID", daemonize, 0);
		daemon_terminated(log_fd_debug, "MAPID", daemonize, 0);
	}

	if (log_to_syslog) {
		log_message("MAPID was terminated %s%s",
				daemonize ? " ( was running as daemon )" : "");
		closelog(); // closes the descriptor being used to write to the system logger
	}
	//release socket resources
	unlink(mapidsocket);
	close(listenerfd);
	close(newfd);

	running_shutdown = 2;
	printf("mapid terminated\n");
	exit((data == 0) ? EXIT_FAILURE : EXIT_SUCCESS);
}