Beispiel #1
0
void create_mod_pkt(unsigned char *link_pkt,struct cooking_data *flow,mapid_pkthdr_t *pkt_head) {
	
	unsigned char *ret_data;
	unsigned int ret_size;
	ether_header* eth = NULL;
	ip_header* ip = NULL;
	tcp_header* tcp = NULL;
	int ether_len = 0, ip_len = 0, tcp_len = 0;

	eth = (ether_header*)link_pkt;
	ether_len = sizeof(ether_header);
	ip = (ip_header*)(link_pkt + ether_len);
	ip_len = (ip->ver_ihl & 0xf) * 4;
	
	tcp = (tcp_header*)(link_pkt + ether_len + ip_len);
	tcp_len = tcp->off * 4;
	tcp->seq = 0;

	if (flow->client_ready && flow->server_ready && flow->collect != BOTH_SIDE) {
	    DEBUG_CMD(Debug_Message("client and server are ready but we dont collect both"));
	}

	if (flow->client_ready) {
	    ret_data = flow->ret_client_data;
	    ret_size = flow->client_size;
	}
	else {
	    ret_data = flow->ret_server_data;
	    ret_size = flow->server_size;
	}

	if (ret_size > (unsigned int)flow->threshold){
	    DEBUG_CMD(Debug_Message("Packet size is greater than Threshold : %d", ret_size - flow->threshold));
	}

	ip->tlen = ntohs(ret_size + ip_len + tcp_len);
	
	//fprintf(stderr, "flow->mod_pkt_size old %d new %d\n", flow->mod_pkt_size, (sizeof(char) * (ret_size +ether_len + ip_len + tcp_len)));
/* DEL	
	if (flow->mod_pkt_size < (sizeof(char)*(ret_size + ether_len + ip_len + tcp_len))) {
		flow->mod_pkt = realloc(flow->mod_pkt,(sizeof(char)*(ret_size + ether_len + ip_len + tcp_len)));
		flow->mod_pkt_size = (sizeof(char) * (ret_size + ether_len + ip_len + tcp_len));
	}
*/
//	memset(link_pkt, 0, (sizeof(char) * (ret_size + ether_len + ip_len + tcp_len)));
//	memcpy(link_pkt, eth, ether_len);
//	memcpy(&link_pkt[ether_len], ip, ip_len);
//	memcpy(&link_pkt[ether_len + ip_len], tcp, tcp_len);	
	memcpy(&link_pkt[ether_len + ip_len + tcp_len], ret_data, ret_size);

	//flow->client_headers = flow->ret_client_headers;
	//flow->server_headers = flow->ret_server_headers;

	pkt_head->caplen = pkt_head->wlen = ret_size + ether_len + ip_len + tcp_len;

//DEL	memcpy(link_pkt, flow->mod_pkt, pkt_head->caplen);
	flow->cooked = 1;
	//printf("create_mod_pkt: pkt_head->caplen: %d\n", pkt_head->caplen);
}
Beispiel #2
0
int dllist_test()
{

	struct mynode *mn[NUM_NODES];
	LPDL_NODE node;
	struct mynode *data;

	/* *insert */
	int i = 0;
	Debug_Message(LOG_FULL, "insert node from 1 to NUM_NODES(32): \n");
	for (; i < NUM_NODES; i++) {
		mn[i] = (struct mynode *)malloc(sizeof(struct mynode));
		mn[i]->string = (char *)malloc(sizeof(char) * 4);
		sprintf(mn[i]->string, "%d", i);
		dll_insert(&mytree, mn[i]);
	}
	
	/* *search */
	Debug_Message(LOG_FULL, "search all nodes: \n");
	for (node = dl_first(&mytree); node; node = dl_next(node)) {
		struct mynode *data;
		container_of(data, node, struct mynode, node);
		Debug_Message(LOG_TEST, "key = %s\n", data->string);
	}

	/* *delete */
	Debug_Message(LOG_FULL, "delete node 0: \n");
	data = dll_search(&mytree, "0");
	if (data) {
		dl_remove_node(&data->node, &mytree);
		dll_free(data);
	}

	/* *delete again*/
	Debug_Message(LOG_FULL, "delete node 10: \n");
	data = dll_search(&mytree, "10");
	if (data) {
		dl_remove_node(&data->node, &mytree);
		dll_free(data);
	}

	/* *delete once again*/
	Debug_Message(LOG_FULL, "delete node 31: \n");
	data = dll_search(&mytree, "31");
	if (data) {
		dl_remove_node(&data->node, &mytree);
		dll_free(data);
	}

	/* *search again*/
	Debug_Message(LOG_FULL, "search again:\n");
	for (node = dl_first(&mytree); node; node = dl_next(node)) {
		struct mynode *data;
		container_of(data, node, struct mynode, node);
		Debug_Message(LOG_TEST,"key = %s\n", data->string);
	}
	return 0;
}
Beispiel #3
0
static void
cmd_stats (char *device, int pid, MAPI_UNUSED uid_t uid, int sock)	/*removed id, id==pid here */
//dev = device
//if = IPC id used to send ack message back to client
{
  struct mapiipcbuf buf;
  char *devtype;
  mapidrv *drv;
  int err = 0;
  char* dev=device;
  struct mapi_stat stats;

  if (running_shutdown)
    err = MAPI_SHUTTING_DOWN;

  //Decide which driver to use
  for (drv = drvlist; drv != NULL; drv = drv->next)
    {
      if (drv->device != NULL)
		if (strcmp (dev, drv->device) == 0)
		  {
		    //DEBUG_CMD(Debug_Message("Using driver %s for %s", drv->name, dev));
		    break;
		  }
    }

  if (drv == NULL)
    {
      DEBUG_CMD(Debug_Message("No driver found for %s", dev));
      report_error (MAPID_NO_DRIVER, pid, sock);
      return;
    }

  //Calls driver
  if (err == 0)
    {
      mapidrv_stats = get_drv_funct (drv->handle, "mapidrv_stats");
      err = mapidrv_stats (drv->devid, &devtype, &stats);
    }

  if (err != 0)
    {
	buf.mtype = pid;
	buf.cmd = MAPI_STATS_ERR;
	buf.remote_errorcode=err;
	buf.fd = 0;
	mapiipc_daemon_write ((struct mapiipcbuf *) &buf, sock);
	return;
    }
  else
    {
      //Send ack back to user
      buf.mtype = pid;
      memcpy ((char *)buf.data, &stats, sizeof(struct mapi_stat));
      buf.cmd = MAPI_STATS_ACK;
      buf.fd = 0;
    }

  mapiipc_daemon_write (&buf, sock);
}
Beispiel #4
0
static int dist_init(mapidflib_function_instance_t *instance,
                     MAPI_UNUSED int flow_descr)
{
    mapiFunctArg* fargs=instance->args;
    int fid,fd;
    char *minstr, *maxstr, *intervalstr;
    dist_internal_t *i=instance->internal_data=malloc(sizeof(dist_internal_t));
    dist_t *dist=instance->result.data;

    fd=getargint(&fargs);
    fid=getargint(&fargs);
    minstr = getargstr(&fargs);
    maxstr = getargstr(&fargs);
    intervalstr = getargstr(&fargs);

    dist->min=fhlp_str2ull(minstr);
    dist->max=fhlp_str2ull(maxstr);
    i->interval=fhlp_str2ull(intervalstr);

    i->num=ceil(((double)(dist->max-dist->min)/(double)i->interval));
    i->res_instance=fhlp_get_function_instance(instance->hwinfo->gflist,fd,fid);
    dist->intervals=i->num;

    DEBUG_CMD(Debug_Message("Distribution: num=%lld", i->num));

    dist_reset(instance);
    return 0;
}
Beispiel #5
0
static void * load_driver(const char *dir, const char *name) {
	char *path, *msg;
	void *handle= NULL;

	if (asprintf(&path, "%s/%s", dir, name) < 0) {
		DEBUG_CMD(Debug_Message("asprintf failed"));
	}
	handle = dlopen(path, RTLD_NOW);
	if (!handle) {
		msg = dlerror();
		DEBUG_CMD(Debug_Message("Error loading driver: %s", msg ? msg
				: "unknown reason"));
	}

	free(path);
	return handle;
}
Beispiel #6
0
static void cmd_delete_offline_device(char *dev, int pid, int sock) {
	mapidrv *drv;
	struct mapiipcbuf buf;
	long file_size;

	for (drv = drvlist; drv != NULL; drv = drv->next) {
		if (drv->device != NULL)
			if (strcmp(dev, drv->device) == 0) {
				break;
			}
	}

	if (drv == NULL) {
		DEBUG_CMD(Debug_Message("No device found for %s", dev));
		report_error(MAPID_NO_DEVICE, pid, sock);
		return;
	}

	if (drv->offline != 0) {
		mapidrv_delete_device = get_drv_funct(drv->handle,
				"mapidrv_delete_device");
		mapidrv_delete_device(drv->devid);
		drv->active=0;
	}

	buf.mtype = pid;
	buf.cmd = DELETE_OFFLINE_DEVICE_ACK;
	buf.fd = -1;

	if (log_to_file) {
		file_size = acquire_write_lock(log_fd_info);
		write_to_file(log_fd_info, "MAPID: offline device %s was deleted at ",
				dev);
		write_date(log_fd_info);
		write_newline(log_fd_info, "\n");
		release_write_lock(log_fd_info, file_size);
	}
	if (log_to_syslog)
		log_message("offline device %s was deleted", dev);
    
  DEBUG_CMD(Debug_Message("Deleted offline device %s", dev));

	mapiipc_daemon_write((struct mapiipcbuf *) &buf, sock);
}
Beispiel #7
0
static int bpf_cleanup(mapidflib_function_instance_t *instance) {

  // Clear filter
  int result;
  PassFilter_t command;
  command.WriteHW = TRUE;
  sprintf(command.achFilterString, "DeleteFilter = %u", ((struct bpf_internal_data *)instance->internal_data)->filter_id);

  // Hack to see if card is closed
  char namebuff[16];
  result = NTCI_GetDeviceName(((struct bpf_internal_data *)instance->internal_data)->napatechhandle, namebuff, 16);

  if (result == NTCI_ERRCODE_SUCCESS) {
    if((result = NTCI_PacketClassification(((struct bpf_internal_data *)instance->internal_data)->napatechhandle, //((napa_nt_adapterinfo_t *)instance->hwinfo->adapterinfo)->napatechhandle,
                                           STID_PASS_FILTER,
                                           &command)) != NTCI_ERRCODE_SUCCESS) {

      FilterError_t error;
      result = NTCI_PacketClassification(((struct bpf_internal_data *)instance->internal_data)->napatechhandle, //((napa_nt_adapterinfo_t *)instance->hwinfo->adapterinfo)->napatechhandle,
                                         STID_GET_FILTER_ERROR,
                                         &error);

      DEBUG_CMD(Debug_Message("%s",error.achFilterError1)); // stderr
      DEBUG_CMD(Debug_Message("%s",error.achFilterError2)); // stderr
      DEBUG_CMD(Debug_Message("%s",error.achFilterError3)); // stderr

      return 1; // FIXME: errorcode
    }
  }
  else {
    printf("ERROR: Card closed, cannot free filter with id %u\n", ((struct bpf_internal_data *)instance->internal_data)->filter_id);
    // TODO: delete the filter anyway, maybe re-opening the card to delete and re-close. Or maybe even calling NtplTool (dirty)
  }

  if (instance->internal_data != NULL) {
    free(((struct bpf_internal_data *)instance->internal_data)->expression);
    free(instance->internal_data);
  }

  return 0;
}
Beispiel #8
0
/**
 * closes a flow described by fd
 * if send_reply is non-zero, a response is sent to client's mapi stub,
 * (send_reply=0 is used for local clean-ups)
 */
static void cmd_close_flow(int fd, int pid, int sock, int send_reply) {
	struct flow *f;
	struct client *cl;
	struct mapiipcbuf buf;
	long file_size;

	f=(struct flow*)flist_get(flowlist, fd);

	if (f) {
		/* to avoid reading memory after it's freed */
		int tmpfd = f->fd;
		/* prevent closing flows of other processes */
		if (pid != f->id) {
			DEBUG_CMD(Debug_Message(
					"Proc %d tried to close flow %d, which belongs to proc %d",
					pid, f->fd, f->id));
			report_error(MAPI_INVALID_FLOW, pid, sock);
			return;
		}

		cleanup_flow(f);

		while(__sync_lock_test_and_set(&clientlist_lock,1));
		cl = flist_get(clientlist, pid);
		f = (struct flow *) flist_remove(cl->flowlist, fd);
		cl->numflows--;
		clientlist_lock = 0;

		//send an ACK that flow closed
		if (send_reply) {

			buf.mtype = pid;
			buf.cmd = CLOSE_FLOW_ACK;
			buf.fd = tmpfd;
			mapiipc_daemon_write((struct mapiipcbuf *) &buf, sock);

			if (log_to_file) {
				file_size = acquire_write_lock(log_fd_info);
				write_to_file(log_fd_info, "MAPID: flow %d was closed at ",
						buf.fd);
				write_date(log_fd_info);
				write_newline(log_fd_info, "\n");
				release_write_lock(log_fd_info, file_size);
			}
			if (log_to_syslog)
				log_message("flow %d was closed", buf.fd);
		}
	} else {
		report_error(MAPI_INVALID_FLOW, pid, sock);
	}
}
Beispiel #9
0
/*
 * Returns a pointer to a function inside a driver
 * drv = pointer to driver
 * funct = name of function
 */
void *drv_get_funct(void *drv, const char *funct)
{
  char *msg= NULL;
  void *my_funct = (void *) dlsym(drv, funct);
  
  if (my_funct == NULL) {
    msg = (char *) dlerror();
    DEBUG_CMD(Debug_Message("ERROR: drv_get_funct: %s", msg));
    dlclose(drv);
    exit(EXIT_FAILURE);
  }

  return my_funct;
}
Beispiel #10
0
static int anonymizeip_process(mapidflib_function_instance_t *instance,
			 MAPI_UNUSED unsigned char* dev_pkt,
			 unsigned char* link_pkt,
			 MAPI_UNUSED mapid_pkthdr_t* pkt_head)
{
  struct ip *ip;
  struct ip6_hdr *ip6;
  uint64_t orig6[2], anon6[2];
  anonip_inst_t *i = instance->internal_data;
  unsigned int len = instance->hwinfo->cap_length;

  switch(instance->hwinfo->link_type) {
  case DLT_EN10MB: // Ethernet
    ip = (struct ip *)(link_pkt + sizeof(ether_header));
    len -= sizeof(ether_header);
    break;
  case DLT_CHDLC: // PoS
    ip = (struct ip *)(link_pkt + 4);
    len -= 4;
    break;
  default:
    DEBUG_CMD(Debug_Message("Link layer not supported"));
    exit(-1);
  }

  if (len < sizeof(struct ip))
    return 0;

  switch(ip->ip_v) {
  case 4:
      ip->ip_src.s_addr = htonl(anonymize(&i->anon_instance, ntohl(ip->ip_src.s_addr)));
      ip->ip_dst.s_addr = htonl(anonymize(&i->anon_instance, ntohl(ip->ip_dst.s_addr)));
      break;
  case 6:
      if (len < sizeof(struct ip6_hdr))
	return 0;
      ip6 = (struct ip6_hdr *)ip;
      //See panonymizer.h for IPv6 support
      memcpy(orig6, &ip6->ip6_src, 16);
      anonymize_v6(&i->anon_instance, orig6, anon6);
      memcpy(&ip6->ip6_src, anon6, 16);
      memcpy(orig6, &ip6->ip6_dst, 16);
      anonymize_v6(&i->anon_instance, orig6, anon6);
      memcpy(&ip6->ip6_dst, anon6, 16);
      break;
  default:
    return 0;
  }
  return 1;
}
Beispiel #11
0
static void * get_drv_funct(void *drv, const char *funct)
//Returns a pointer to a function inside a driver
//drv = pointer to driver
//funct = name of function
{
	char *msg= NULL;
	void *my_funct = dlsym(drv, funct);

	if (my_funct == NULL) {
		msg = dlerror();
		DEBUG_CMD(Debug_Message("ERROR: get_drv_funct: %s", msg));
		dlclose(drv);
		exit(EXIT_FAILURE);
	}

	return my_funct;
}
Beispiel #12
0
static void cmd_read_results(int fd, int fid, int pid, int sock)
//Read results from a function
//fd = flow descriptor
//fid = function ID
{
	mapidrv *drv = get_drv(fd);
	mapid_result_t *result;
	struct mapiipcbuf buf;
	int err;
	char *p = (char *)buf.data;

	if (drv == NULL) {
		/* driver not found(should be handled in create_flow), or invalid flow id */
		DEBUG_CMD(Debug_Message("cmd_read_results: no driver found"));
		report_error(MAPI_INVALID_FLOW, pid, sock);
		return;
	}
	mapidrv_read_results = get_drv_funct(drv->handle, "mapidrv_read_results");
	err = mapidrv_read_results(drv->devid, fd, fid, &result);
	if (err != 0) {
		report_error(err, pid, sock);
		return;
	}
	buf.mtype = get_id(fd);
	buf.cmd = READ_RESULT_ACK;
	buf.fd = fd;

	//Copy result data 
	if (result->funct_res_size + 2*sizeof(mapid_shm_t) < DATA_SIZE) {
		memcpy(p, &result->shm, sizeof(mapid_shm_t));
		p += sizeof (result->shm);
		memcpy(p, &result->shm_spinlock, sizeof(mapid_shm_t));
		if (result->funct_res_size > 0) {
			p += sizeof (result->shm);
			memcpy(p, result->funct_res, result->funct_res_size);
		}
		buf.size = result->funct_res_size + 2*sizeof(mapid_shm_t);
	} else {
		//TODO: Return proper error message
	}

	mapiipc_daemon_write(&buf, sock);

}
Beispiel #13
0
char *pc_get_param(conf_category_entry_t *entry, const char *name)
{
  conf_parameter_t *p;

  if (entry == NULL)
  {
      DEBUG_CMD(Debug_Message("pc_get_param: NULL category"));
      exit(1);
  }
  p = entry->params;
  while (p != NULL)
  {
    if (strcmp(p->name, name) == 0)
      return p->value;
    else
      p = p->next;
  }
  return NULL;
}
Beispiel #14
0
static int dist_instance(mapidflib_function_instance_t *instance,
                         MAPI_UNUSED int fd,
                         MAPI_UNUSED mapidflib_flow_mod_t *flow_mod)
{
    int afd,fid;
    unsigned long long min,max,interval;
    char *minstr, *maxstr, *intervalstr;
    mapiFunctArg* fargs=instance->args;

    afd=getargint(&fargs);
    fid=getargint(&fargs);
    minstr = getargstr(&fargs);
    maxstr = getargstr(&fargs);
    intervalstr = getargstr(&fargs);

    if(fhlp_get_function_instance(instance->hwinfo->gflist,afd,fid)==NULL)
        return MFUNCT_INVALID_ARGUMENT_1;

    if(minstr)
        min=fhlp_str2ull(minstr);
    else
        return MFUNCT_INVALID_ARGUMENT_3;
    if(maxstr)
        max=fhlp_str2ull(maxstr);
    else
        return MFUNCT_INVALID_ARGUMENT_4;
    if(interval)
        interval=fhlp_str2ull(intervalstr);
    else
        return MFUNCT_INVALID_ARGUMENT_5;

    if(min>max)
        return MFUNCT_INVALID_ARGUMENT;

    if(interval>(max-min))
        return MFUNCT_INVALID_ARGUMENT_4;

    instance->def->shm_size=sizeof(unsigned long long)*(ceil((double)(max-min)/(double)interval)+1)+sizeof(dist_t);

    DEBUG_CMD(Debug_Message("SIZE: %d", instance->def->shm_size));

    return 0;
};
Beispiel #15
0
static void cmd_load_library(char *lib, int pid, int sock) {
	struct mapiipcbuf buf;
	int err;
	mapidrv *drv = drvlist;

	//Call each driver and tell it to load the new library
	while (drv) {
		mapidrv_load_library = get_drv_funct(drv->handle,
				"mapidrv_load_library");
		err = mapidrv_load_library(lib);
		if (err != 0) {
			DEBUG_CMD(Debug_Message("Could not load library %s", lib));
		}
		drv = drv->next;
	}

	buf.mtype = pid;
	buf.cmd = LOAD_LIBRARY_ACK;
	mapiipc_daemon_write((struct mapiipcbuf *) &buf, sock);
}
Beispiel #16
0
static void cmd_connect(int fd, int pid, int sock)
//Connect to flow
//fd = flow descriptor
{
	struct mapiipcbuf buf;
	int err = 0;
	mapidrv *drv = get_drv(fd);
	long file_size;

	if (drv == NULL) {
		/* driver not found(should be handled in create_flow), or invalid flow id */
		DEBUG_CMD(Debug_Message("cmd_connect: no driver found"));
		report_error(MAPI_INVALID_FLOW, pid, sock);
		return;
	}

	if (err == 0) {
		mapidrv_connect = get_drv_funct(drv->handle, "mapidrv_connect");
		err = mapidrv_connect(drv->devid, fd);
	}
	if (err != 0) {
		report_error(err, pid, sock);
		return;
	}

	buf.cmd = CONNECT_ACK;
	buf.mtype = get_id(fd); /* should be == pid */
	buf.fd = fd;

	if (log_to_file) {
		file_size = acquire_write_lock(log_fd_info);
		write_to_file(log_fd_info, "MAPID: connect to flow %d at ", fd);
		write_date(log_fd_info);
		write_newline(log_fd_info, "\n");
		release_write_lock(log_fd_info, file_size);
	}
	if (log_to_syslog)
		log_message("connect to flow %d", fd);

	mapiipc_daemon_write((struct mapiipcbuf *) &buf, sock);
}
Beispiel #17
0
static void cmd_apply_function(struct mapiipcbuf *qbuf, int pid, int sock)
//Apply function to flow
//qbuf = IPC buffer
//(this function should be changed so that it becomes IPC independent)
{
	int functionid;
	int fd;
	mapidrv *drv;
	mapiFunctArg *args = qbuf->data;
	char *argdescr = (char *)qbuf->argdescr;
	char *function;
	long file_size;

	while (strlen(argdescr) > 0) {
		switch (*argdescr) {
		case 's':
			args += strlen((char *)args) + 1;
			break;
		case 'S': // reference to flows and functions (e.g RES2FILE)
			args += strlen((char *)args) + 1;
			break;
		case 'i':
			args += sizeof(int);
			break;
		case 'r': // reference to a flow
			args += sizeof(int);
			break;
		case 'f': // reference to a fuction
			args += sizeof(int);
			break;
		case 'c':
			args += sizeof(char);
			break;
		case 'l':
			args += sizeof(unsigned long long);
			break;
		case 'u':
			args += sizeof(int);
			break;
		case 'p':
			args += strlen((char *)args) + 1;
			break;
		case 'w':
			qbuf->mtype = get_id(qbuf->fd);
			qbuf->cmd = SEND_FD;
			mapiipc_daemon_write((struct mapiipcbuf *) qbuf, sock);
			fd = mapiipc_read_fd(sock);
			addarg(&args, &fd, INT);
			break;

		default:
			break;
		}
		argdescr++; // move to the next arg
	}

	drv = get_drv(qbuf->fd);
	if (drv == NULL) {
		DEBUG_CMD(Debug_Message(
				"cmd_apply_function: no driver found for fd=%d", qbuf->fd));
		report_error(MAPI_INVALID_FLOW, pid, sock);
		return;
	}
	mapidrv_apply_function = get_drv_funct(drv->handle,
			"mapidrv_apply_function");

	function = strdup(qbuf->function);

	functionid = mapidrv_apply_function(drv->devid, qbuf->fd, APPLY_NORMAL,
			qbuf->function, qbuf->data);

	if (functionid == -1) {
		/* error in mapid */
		report_error(mapid_get_errno(qbuf->fd), pid, sock);
		return;
	}
	qbuf->mtype = get_id(qbuf->fd);
	qbuf->cmd = APPLY_FUNCTION_ACK;
	qbuf->fid = functionid;

	if (log_to_file) {
		file_size = acquire_write_lock(log_fd_info);
		write_to_file(log_fd_info,
				"MAPID: function %s was applyed to flow %d ( fid: %d ) at ",
				function, qbuf->fd, qbuf->fid);
		write_date(log_fd_info);
		write_newline(log_fd_info, "\n");
		release_write_lock(log_fd_info, file_size);
	}
	if (log_to_syslog)
		log_message("function %s was applyed to flow %d ( fid: %d )", function,
				qbuf->fd, qbuf->fid);

	free(function);
	mapiipc_daemon_write((struct mapiipcbuf *) qbuf, sock);
}
Beispiel #18
0
static void cmd_create_flow(char *device, int pid, uid_t uid, int sock) /*removed id, id==pid here */
//Create a new flow
//dev = device
//if = IPC id used to send ack message back to client
{
	struct flow *fl = (struct flow *) malloc(sizeof(struct flow));
	struct client *cl;
	struct mapiipcbuf buf;
	char *devtype;
	mapidrv *drv;
	int err = 0;
	char* dev=device;
	long file_size;

	fl->id = pid;
	fl->fd = ++fdseed;
	fl->drv = NULL;
	fl->uid = uid;
	fl->offline = 0;

	if (running_shutdown)
		err = MAPI_SHUTTING_DOWN;

	//Decide which driver to use
	for (drv = drvlist; drv != NULL; drv = drv->next) {
		if (drv->device != NULL)
			if (strcmp(dev, drv->device) == 0) {
				fl->drv = drv;
				DEBUG_CMD(Debug_Message("Using driver %s for %s", drv->name,
						dev));
				break;
			}
	}

	if (fl->drv == NULL) {
		DEBUG_CMD(Debug_Message("No driver found for %s", dev));
		report_error(MAPID_NO_DRIVER, pid, sock);
		free(fl);
		return;
	}

	++flows; //total number of currently registered flows

	//Calls driver
	if (err == 0) {
		mapidrv_create_flow = get_drv_funct(fl->drv->handle,
				"mapidrv_create_flow");
		err = mapidrv_create_flow(drv->devid, fl->fd, &devtype);

	}

	if (err != 0) {
		/* flow wasn't created */
		/* we can't leave the flow in place, but we need it for errno... */
		/* cleanup? */
		flows--;
		report_error(err, pid, sock);
		free(fl);
		return;
	} else {
		flist_append(flowlist, fl->fd, fl);

		//check if this is the first time we hear from this client
		cl = flist_get(clientlist, pid);
		if (cl == NULL) {
			cl = (struct client *) malloc(sizeof(struct client));
			cl->pid = pid;
			cl->sock = sock;
			// init the list that holds references to the flows of this client
			if ((cl->flowlist = malloc(sizeof(flist_t))) == NULL) {
				DEBUG_CMD(Debug_Message(
						"ERROR: cmd_create_flow - malloc new client struct: %s",
						strerror(errno)));
				exit(EXIT_FAILURE);
			}
			flist_init(cl->flowlist);
			if ((cl->devicelist = malloc(sizeof(flist_t))) == NULL) {
				DEBUG_CMD(Debug_Message(
						"ERROR: cmd_create_flow - malloc new client struct: %s",
						strerror(errno)));
				exit(EXIT_FAILURE);
			}
			flist_init(cl->devicelist);
			cl->numflows = 0;
			cl->numdevs = 0;
			flist_append(clientlist, pid, cl);
		}

		// save a reference to the newly created flow to client's flow list
		cl->numflows++;
		flist_append(cl->flowlist, fl->fd, fl);

		//Send ack back to user
		buf.mtype = pid;
		strcpy((char *)buf.data, devtype);
		buf.cmd = CREATE_FLOW_ACK;
		buf.fd = fl->fd;

		if (log_to_file) {
			file_size = acquire_write_lock(log_fd_info);
			write_to_file(log_fd_info,
					"MAPID: new flow was created ( device: %s, fd: %d ) at ",
					device, fl->fd);
			write_date(log_fd_info);
			write_newline(log_fd_info, "\n");
			release_write_lock(log_fd_info, file_size);
		}
		if (log_to_syslog)
			log_message("new flow was created ( device: %s, fd: %d )", device,
					fl->fd);
	}

	mapiipc_daemon_write(&buf, sock);
}
Beispiel #19
0
static int strsearch_init(mapidflib_function_instance_t *instance,
                          MAPI_UNUSED int fd)
//Initializes the function
{
    char *str, *strbak;
    int off, dpth;

    unsigned char *tmpstr, *tstrbak;
    unsigned char *ret;	// holds the final parsed string
    int len=0;	// length of the final parsed string
    unsigned short pattern_ctr = 0;
    char hexpair[3];
    mapiFunctArg* fargs;
    struct mapid_strsearch_pattern *pattern = NULL;
    struct mapid_strsearch_pattern *lastptrn, *tmpptrn = NULL;

    fargs=instance->args;
    str = getargstr(&fargs);
    off = getargint(&fargs);
    dpth = getargint(&fargs);

    /* parse pattern
     *
     * Non printable characters or general binary content can be specified by
     * using pipes enclosing the binary data which are represented in hex
     * values for each byte.  For example, 'abcd' is the same as '|61 62 63
     * 64|' or 'ab|63 64|' or '|61|b|6364|. If the pipe character needs to be
     * searched, it should be preceeded by a '\'.
     */

    strbak = str; // backup pointer
    tstrbak = tmpstr = (unsigned char *)malloc(strlen(str)*sizeof(char));
    ret=tmpstr;
    hexpair[2]='\0';

    while(*str!='\0') {

        // Two pipes "||" separates two match strings.
        // A||B will match both a packet with either A or B in it.
        if (*str == '|' && *(str+1) == '|') // Should be safe since last char will be '\0'
        {
            if (!isEscaped(str))
            {
                len=tmpstr-ret;
                if (len <= 0)
                {
                    // Empty OR node, skip
                    str += 2;
                    continue;
                }
                if((dpth > 0) && (dpth < len))
                {
                    DEBUG_CMD(Debug_Message("The depth (%d) is less than the size of the pattern (%d)", dpth, len));
                    return MDLIB_STRSEARCH_DEPTH_LESS_THAN_PTRN_ERR;
                }

                tmpptrn = malloc(sizeof(struct mapid_strsearch_pattern));

                tmpptrn->str = (unsigned char *)malloc(len * sizeof(char));
                tmpptrn->slen = len;
                tmpptrn->offset = off;
                tmpptrn->depth = dpth;
                memcpy(tmpptrn->str, ret, len);
                //compute Boyer-Moore's shift and skip tables
                tmpptrn->shift = make_shift((char *)ret, len);
                tmpptrn->skip = make_skip((char *)ret, len);
                tmpptrn->next = NULL;

                if (pattern == NULL)
                {
                    pattern = tmpptrn;
                    lastptrn = tmpptrn;
                }
                else
                {
                    lastptrn->next = tmpptrn;
                    lastptrn = tmpptrn;
                }

                tmpptrn = NULL;
                ret = tmpstr;
                pattern_ctr++;
            }
            else
            {
                *tmpstr=*str;
                tmpstr++;
            }
            str++;
        }

        // '|' means that hex mode begins unless it is escaped \|
        // every hex number consists of two characters ,e.g A is written as 0A
        else if(*str=='|') {
            if(!isEscaped(str)) {
                int hexcount=0;
                str++;
                //parse until closing '|'
                while(*str!='|') {
                    if(*str=='\0') {
                        return MDLIB_STRSEARCH_UNTERMINATED_PIPE_ERR;
                    }
                    // |AC DE| => ignore white spaces between hex numbers
                    if(*str==' ') {
                        str++;
                        continue;
                    }
                    //convert hex to character
                    hexpair[hexcount++]=*str;
                    if(hexcount==2) {
                        hexcount=0;
                        sscanf(hexpair,"%x",(int *)tmpstr);
                        tmpstr++;
                    }
                    str++;
                }
            }
            else {
                *tmpstr=*str;
                tmpstr++;
            }
        }
        // special case for escape character '\\'
        else if(*str=='\\') {
            if(isEscaped(str)) {
                *tmpstr=*str;
                tmpstr++;
            }
        }
        else {
            *tmpstr=*str;
            tmpstr++;
        }
        str++;
    }
    len=tmpstr-ret;
    /* end of pattern parsing */

    /*
      Arne: Will fix it later

    funct = fhlp_get_first();
    while (funct) {
      if(strcmp(funct->name,"STR_SEARCH")==0)
        if(funct->internal_data)
    if(memcmp(((struct mapid_strsearch *)funct->internal_data)->str, ret,
    	  ((struct mapid_strsearch *)funct->internal_data)->slen) == 0)
      if(((struct mapid_strsearch *)funct->internal_data)->offset == off &&
         ((struct mapid_strsearch *)funct->internal_data)->depth == dpth){
        instance->internal_data = funct->internal_data;
        printf("added optimised string search: %s offset: %d depth: %d\n",strbak, off, dpth);
        return 0;
      }
      funct = funct->next;
    }
    */

    if((dpth > 0) && (dpth < len)) {
        DEBUG_CMD(Debug_Message("The depth (%d) is less than the size of the pattern (%d)", dpth, len));
        return MDLIB_STRSEARCH_DEPTH_LESS_THAN_PTRN_ERR;
    }

    if (len > 0)
    {
        tmpptrn = malloc(sizeof(struct mapid_strsearch_pattern));

        tmpptrn->str = (unsigned char *)malloc(len * sizeof(char));
        tmpptrn->slen = len;
        tmpptrn->offset = off;
        tmpptrn->depth = dpth;
        memcpy(tmpptrn->str, ret, len);
        //compute Boyer-Moore's shift and skip tables
        tmpptrn->shift = make_shift((char *)ret, len);
        tmpptrn->skip = make_skip((char *)ret, len);
        tmpptrn->next = NULL;

        if (pattern == NULL)
            pattern = tmpptrn;
        else
            lastptrn->next = tmpptrn;

        pattern_ctr++;
    }

    if (pattern == NULL)
    {
        // Invalid search term
        return MDLIB_STRSEARCH_NOT_A_VALID_SEARCH_STRING;
    }

    instance->internal_data = malloc(sizeof(struct mapid_strsearch));
    /*
      ((struct mapid_strsearch *)instance->internal_data)->str = (unsigned char *)malloc(len * sizeof(char));
      ((struct mapid_strsearch *)instance->internal_data)->slen = len;
      ((struct mapid_strsearch *)instance->internal_data)->offset = off;
      ((struct mapid_strsearch *)instance->internal_data)->depth = dpth;
      memcpy(((struct mapid_strsearch *)instance->internal_data)->str, ret, len);
      //compute Boyer-Moore's shift and skip tables
      ((struct mapid_strsearch *)instance->internal_data)->shift = make_shift((char *)ret, len);
      ((struct mapid_strsearch *)instance->internal_data)->skip = make_skip((char *)ret, len);
    */
    ((struct mapid_strsearch *)instance->internal_data)->pattern = pattern;
    ((struct mapid_strsearch *)instance->internal_data)->num_patterns = pattern_ctr;
    ((struct mapid_strsearch *)instance->internal_data)->currentIteration = 0;
    DEBUG_CMD(Debug_Message("added string search: %s offset: %d depth: %d nodes: %u", strbak, off, dpth, pattern_ctr));

    free(tstrbak);

    return 0;
}
Beispiel #20
0
void mapi_tcp_callback(struct tcp_stream *a_tcp, MAPI_UNUSED void **param)
{
	struct tcp_flow_data *td = a_tcp->user;
	struct cooking_data *flow = td->flow;

	//printf("tcp_callback : ");

	if (a_tcp->nids_state == NIDS_JUST_EST) {
	    //fprintf(stderr, "callback: established\n");
	    switch (flow->collect) {
		case SERVER_SIDE:
		    a_tcp->server.collect++;
		    a_tcp->client.collect--;
		    break;
		case CLIENT_SIDE:
		    a_tcp->client.collect++;
		    a_tcp->server.collect--;
		    break;
		case BOTH_SIDE:
		    a_tcp->server.collect++;
		    a_tcp->client.collect++;
		    break;
		default:
		    ;
	    }
		//printf("callback: just established\n");
	    return;
	}
	
	if (a_tcp->nids_state == NIDS_DATA) {
	//	printf("data\n");
	    struct half_stream *hlf;
	    //flist_t **heads;
	    unsigned char **ret_data;
	    unsigned int *ret_size;
	    int *ready;

	    if (a_tcp->client.count_new) {
			hlf = &a_tcp->client;
			//heads = &flow->ret_client_headers;
			ret_data = &flow->ret_client_data;
			ret_size = &flow->client_size;
			ready = &flow->client_ready;
			if (flow->collect == SERVER_SIDE)
		    	DEBUG_CMD(Debug_Message("Asked for server data but got client's"));
	    }
	    else {
			hlf = &a_tcp->server;
			//heads = &flow->ret_server_headers;
			ret_data = &flow->ret_server_data;
			ret_size = &flow->server_size;
			ready = &flow->server_ready;
			if (flow->collect == CLIENT_SIDE)
		    	DEBUG_CMD(Debug_Message("Asked for client data but got server's"));
	    }

	    if (td->discard) {
			return;
	    }

	    if (hlf->count - hlf->offset >= flow->threshold) { //we have enough data
		//*heads = hlf->headers;
			memcpy(*ret_data, hlf->data, flow->threshold);
			*ret_size = flow->threshold;
			*ready = 1;
			nids_discard(a_tcp, flow->threshold);
			if (flow->ret_once)
		    	td->discard = 1;
	    }
	    else { //keep them
			nids_discard(a_tcp, 0);
	    }
	    return;
	}

	if (a_tcp->nids_state == NIDS_CLOSE || a_tcp->nids_state == NIDS_RESET || a_tcp->nids_state == NIDS_TIMED_OUT || a_tcp->nids_state == NIDS_EXITING) {
	    int server_bytes, client_bytes;

		//printf("call_back: close\n");
	    
	    //flow->ret_server_headers = a_tcp->server.headers;
	    //flow->ret_client_headers = a_tcp->client.headers;
	    server_bytes = a_tcp->server.count - a_tcp->server.offset;
	    client_bytes = a_tcp->client.count - a_tcp->client.offset;
	    
	    if (server_bytes > 0 && flow->collect != CLIENT_SIDE) {
			//flow->ret_server_data = malloc(sizeof(unsigned char) * server_bytes);
			memcpy(flow->ret_server_data, a_tcp->server.data, flow->threshold);
			flow->server_size = server_bytes;
			flow->server_ready = 1;
	    }

	    if (client_bytes > 0 && flow->collect != SERVER_SIDE) {
		//flow->ret_client_data = malloc(sizeof(unsigned char) * client_bytes);
			memcpy(flow->ret_client_data, a_tcp->client.data, flow->threshold);
			flow->client_size = client_bytes;
			flow->client_ready = 1;
	    }
	}
}
Beispiel #21
0
static int cook_init(mapidflib_function_instance_t *instance, MAPI_UNUSED int fd)
{
	struct cooking_data *data;

	if (nids_not_inited) {
		pcap_t *desc;
		struct nids_chksum_ctl *nochksumchk;

		desc = malloc(sizeof(pcap_t));
		desc->fd = 1;
		desc->linktype = instance->hwinfo->link_type;
		desc->bufsize = instance->hwinfo->cap_length;

		nids_params.pcap_desc = desc;
		nids_params.tcp_workarounds = 1;

		/* disable checksum checking for all packets */
		nochksumchk = malloc(sizeof(struct nids_chksum_ctl));
		nochksumchk->netaddr = 0;
		nochksumchk->mask = 0;
	    nochksumchk->action = NIDS_DONT_CHKSUM;
		nids_register_chksum_ctl(nochksumchk, 1);

		if (!nids_init()) {
			DEBUG_CMD(Debug_Message("NIDS Error: %s", nids_errbuf));
			return -1;
		}

		nids_register_tcp(mapi_tcp_callback);
		nids_not_inited = 0;
	}

	data = (struct cooking_data *)(instance->internal_data);


/*	//check if uncook is applied
	functs = flist_get(instance->hwinfo->gflist->fflist, fd);
	for (fid=1; (funct=flist_get(functs, fid)); fid++) {
	    if (!strcmp(funct->instance->def->name, "UNCOOK"))
		data->keep_headers = 1;
	}
*/
	//printf("Cooking : %s keeping headers %d \n", (data->keep_headers)?"":"NOT", fd);

	if (data->threshold <= 0) {
	    data->threshold = 32000; //default value 32K
	}

	if (data->threshold < 1600) 
	    instance->hwinfo->cap_length = 1600;
	else 
	    instance->hwinfo->cap_length = data->threshold + 100;//+100 for headers


	data->ret_client_data = malloc(sizeof(char) * data->threshold);
	data->ret_server_data = malloc(sizeof(char) * data->threshold);
	data->client_ready = 0;
	data->server_ready = 0;
	

	//data->ni = nids_mapi_init(&desc, instance->hwinfo->link_type);
	//data->ni = nids_create();

	return 0;
}
Beispiel #22
0
static int continue_as_daemon() {
	int nullfd;

	printf("Closing stdin, stdout, stderr and going into background.\n");

	switch (fork()) {
	case 0:
		break;
	case -1:
		DEBUG_CMD(Debug_Message("ERROR: fork() failed %d - %s", errno,
				strerror(errno)));
		return EXIT_FAILURE;
		break;
	default:
		_exit(0);
		break;
	}
	if (setsid() == -1) {
		DEBUG_CMD(Debug_Message("ERROR: setsid() failed %d - %s", errno,
				strerror(errno)));
		return EXIT_FAILURE;
	}

	setpgrp();

	switch (fork()) {
	case 0:
		break;
	case -1:
		DEBUG_CMD(Debug_Message("ERROR: fork() failed %d - %s", errno,
				strerror(errno)));
		return EXIT_FAILURE;
		break;
	default:
		_exit(0);
		break;
	}

	if (!check_pid(PIDFILE)) {
		if (write_pid(PIDFILE)) {
			(void) atexit(remove_pidfile);
		} else {
			printf("Could not write pidfile\n");
		}
	} else {
		/* A mapid already running and owning pidfile */
		printf("A mapid is already running. Leaving pidfile alone\n");
		
	}
	
	chdir("/");

	nullfd = open("/dev/null", O_RDONLY);
	dup2(nullfd, STDIN_FILENO);
	close(nullfd);
	nullfd = open("/dev/null", O_WRONLY);
	dup2(nullfd, STDOUT_FILENO);
	dup2(nullfd, STDERR_FILENO);
	close(nullfd);

	return EXIT_SUCCESS;
}
Beispiel #23
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 #24
0
// sends an IPC message back to the client
static void mapiipc_daemon_write(struct mapiipcbuf *qbuf, int socket) {
	if (send(socket, qbuf, sizeof(struct mapiipcbuf), 0) == -1) {
		DEBUG_CMD(Debug_Message("mapiipc_daemon_write - send:  %s",
				strerror(errno)));
	}
}
Beispiel #25
0
static int bpf_instance(mapidflib_function_instance_t *instance,
			MAPI_UNUSED int fd,
			MAPI_UNUSED mapidflib_flow_mod_t *flow_mod)
{

  mapiFunctArg* fargs=instance->args;
  char *str = getargstr(&fargs);
  
  if (instance->hwinfo->offline != 0) // Cant use packet classification on offline streams
    return -1; // FIXME: errorcode
  
  /* 
   *	Checking Arguments
   */
  if(str == NULL)
    return MFUNCT_INVALID_ARGUMENT_1;

  if(strlen(str) < 1)  // could also force a maximum length for the filter expression
    return MFUNCT_INVALID_ARGUMENT_1;

  /*
   *	Dummy BPF filter compilation in order to check filter is OK.
   */
 /* if((pcap = pcap_open_dead(instance->hwinfo->link_type, instance->hwinfo->cap_length)) == NULL){
    DEBUG_CMD(Debug_Message("pcap_open_dead failed"));
    return PCAP_OPEN_DEAD_ERR;
  }
  
  temp = malloc(sizeof(struct bpf_filter));

  if(pcap_compile(pcap, ((struct bpf_program*)&((struct bpf_filter *)temp)->compiled), str, 1, 0)) {
    DEBUG_CMD(Debug_Message("bpf compilation error: %s str: \"%s\"", pcap_geterr(pcap), str));
    free(temp);
    return PCAP_BPF_ERR;
  }

  pcap_close(pcap);
  pcap_freecode((struct bpf_program *)&((struct bpf_filter *)temp)->compiled);
  free(temp);
*/


  /*
    NOTE: The filter should really be applied in init() and only checked for validity here,
    but as there is no way to test-compile the expression and check for resources
    it's done here.
  */
  int result;
  PassFilter_t command;
  command.WriteHW = TRUE;
  sprintf(command.achFilterString, str); //"Capture[Priority=0;Feed=0]=ALL");

  if((result = NTCI_PacketClassification(((napa_nt_adapterinfo_t *)instance->hwinfo->adapterinfo)->napatechhandle,
                                         STID_PASS_FILTER,
                                         &command)) != NTCI_ERRCODE_SUCCESS) {
                 printf("----got errorcode %d\n",result);
    FilterError_t error;
    result = NTCI_PacketClassification(((napa_nt_adapterinfo_t *)instance->hwinfo->adapterinfo)->napatechhandle,
                                       STID_GET_FILTER_ERROR,
                                       &error);
    DEBUG_CMD(Debug_Message("%s",error.achFilterError1)); // stderr
    DEBUG_CMD(Debug_Message("%s",error.achFilterError2)); // stderr
    DEBUG_CMD(Debug_Message("%s",error.achFilterError3)); // stderr

    return MFUNCT_COULD_NOT_APPLY_FUNCT; // FIXME: errorcode
  }

  instance->internal_data = malloc(sizeof(struct bpf_internal_data));
  struct bpf_internal_data *idata = (struct bpf_internal_data *)instance->internal_data;
  idata->napatechhandle = ((napa_nt_adapterinfo_t *)instance->hwinfo->adapterinfo)->napatechhandle;
  idata->expression = strdup(command.achFilterString);
  idata->filter_id = command.ReturnData.u.FilterIndex.FilterId;
  idata->group_index = command.ReturnData.u.FilterIndex.u.GroupIndex;

  DEBUG_CMD(Debug_Message("BPF_NTPL: %s\n\tFilterId: %u GroupIndex: 0x%lx", idata->expression, idata->filter_id, idata->group_index));

  return 0;
}
Beispiel #26
0
static int res2file_instance(mapidflib_function_instance_t *instance,
			     MAPI_UNUSED int flow_descr,
			     mapidflib_flow_mod_t *flow_mod)
{
  char *head, *savestr;
  int file;
  char *fids,*s;
  int type,fd,fid,save;
  char buf[DATA_SIZE],*cfids;
  char *types,*t,*t2,buf2[DATA_SIZE];
  int min=0;
  int reset = -1;
  mapiFunctArg* fargs=instance->args;

  if(!(types = getargstr(&fargs)))
	return(MFUNCT_INVALID_ARGUMENT_1);
  if(!(fids = getargstr(&fargs)))
	return(MFUNCT_INVALID_ARGUMENT_2);
  if(!(head = getargstr(&fargs)))
	  return(MFUNCT_INVALID_ARGUMENT_3);
  if((file = getargint(&fargs)) < 0)
	  return(MFUNCT_INVALID_ARGUMENT_4);
  else
  {
	  struct stat sbuf;
	  if(fstat(file, &sbuf) == -1)
	  {
		  DEBUG_CMD(Debug_Message("Cannot fstat() file descriptor %d", file));
		  return(MFUNCT_INVALID_ARGUMENT_4);
	  }
  }

  if((savestr = getargstr(&fargs)) == NULL)
  	return(MFUNCT_INVALID_ARGUMENT_5);

  if((save=parse_save(savestr))<0)
    return MFUNCT_INVALID_ARGUMENT_5;

  reset = getargint(&fargs);
  if(!(reset == 0 || reset == 1))
	  return(MFUNCT_INVALID_ARGUMENT_6);
  
  //Loop through fids and types and verify
  strncpy(buf,fids,DATA_SIZE);
  cfids=buf;
  strncpy(buf2,types,DATA_SIZE);
  t=buf2;

  while((s=strchr(cfids,','))!=NULL) {
    *s='\0';
    if((t2=strchr(t,','))==NULL)
      return MFUNCT_INVALID_ARGUMENT_1;
    *t2='\0';
    sscanf(cfids,"%d@%d",&fid,&fd);
    if(fhlp_get_function_instance(instance->hwinfo->gflist,fd,fid)==NULL)
      return MFUNCT_INVALID_ARGUMENT_2;
    if(min==0 || min>fid)
      min=fid;
    sscanf(t,"%d",&type);
    if(type!=R2F_RAW && type!=R2F_ULLSTR && type!=R2F_ULLSEC && 
       type!=R2F_STATS)
      return MFUNCT_INVALID_ARGUMENT_2;    
    
    cfids=s+1;
    t=t2+1;
  }
  sscanf(cfids,"%d@%d",&fid,&fd);
  if(fhlp_get_function_instance(instance->hwinfo->gflist,fd,fid)==NULL)
   return MFUNCT_INVALID_ARGUMENT_2; 
  
  if(save==PERIODIC) {
    //Move res2file in front of the other functions results are read from
    flow_mod->reorder=min;
  }

  return 0;
};
Beispiel #27
0
static void cmd_create_offline_device(char *dev, int format, int pid, int sock)
//Create a new flow
//dev = device
//if = IPC id used to send ack message back to client
{
	struct mapiipcbuf buf;
	mapidrv *drv, *drv2, *lok;
	int err;
	int file;
	struct client *cl;
	char *format_;
	long file_size;

	//Get file descriptor
	buf.mtype = pid;
	buf.cmd = SEND_FD;
	mapiipc_daemon_write((struct mapiipcbuf *) &buf, sock);
	file = mapiipc_read_fd(sock);

	//Decide which driver to use
	for (drv = drvlist; drv != NULL; drv = drv->next) {
		if (drv->format == format) {
			DEBUG_CMD(Debug_Message("Using driver %s for %s", drv->name, dev));
			break;
		}
	}

	if (drv == NULL) {
		DEBUG_CMD(Debug_Message("ERROR: No driver found for %s", dev));
		report_error(MAPID_NO_DRIVER, pid, sock);
		return;
	}

	//Calls driver
	//First create new "device" for the file 
	drv2 = malloc(sizeof(mapidrv));
	drv2->device = malloc(strlen(dev)+7);
	sprintf(drv2->device, "%s@%d", dev, deviceid);
	lok=drvlist;

	while (lok->next!=NULL)
		lok = lok->next;
	lok->next = drv2;
	drv2->next=NULL;
	drv2->handle = drv->handle;
	drv2->name = strdup(drv->name);
	drv2->format = drv->format;
	drv2->devid = -deviceid++;
	drv2->offline = 1;
	drv2->active = 1;
	drv2->description = strdup(drv->description);
	drv2->offline_status = DEVICE_SETUP;

	mapidrv_add_device = get_drv_funct(drv->handle, "mapidrv_add_device");
	err = mapidrv_add_device(dev, file, drv2->devid, gflist,
			&drv2->offline_status);

	if (err != 0) {
		report_error(err, pid, sock);
		return;
	}

	// save a reference to the newly created flow to client's flow list
	cl = flist_get(clientlist, pid);
	if (cl == NULL) {
		cl = (struct client *) malloc(sizeof(struct client));
		cl->pid = pid;
		cl->sock = sock;
		// init the list that holds references to the flows of this client
		if ((cl->flowlist = malloc(sizeof(flist_t))) == NULL) {
			DEBUG_CMD(Debug_Message(
					"ERROR: cmd_create_flow - malloc new client struct: %s",
					strerror(errno)));
			exit(EXIT_FAILURE);
		}
		if ((cl->devicelist = malloc(sizeof(flist_t))) == NULL) {
			DEBUG_CMD(Debug_Message(
					"ERROR: cmd_create_flow - malloc new client struct: %s",
					strerror(errno)));
			exit(EXIT_FAILURE);
		}
		flist_init(cl->flowlist);
		flist_init(cl->devicelist);
		cl->numflows = 0;
		flist_append(clientlist, pid, cl);
	}

	flist_append(cl->devicelist, drv2->devid, drv->handle);
	cl->numdevs++;

	//Send ack back to user
	buf.mtype = pid;
	buf.cmd = CREATE_OFFLINE_DEVICE_ACK;
	strcpy((char *)buf.data, drv2->device);
	buf.fd = -1;

	if (format == 0)
		format_ = strdup("MFF_PCAP");
	else if (format == 1)
		format_ = strdup("MFF_RAW");
	else if (format == 2)
		format_ = strdup("MFF_DAG_ERF");
	else if (format == 4)
		format_ = strdup("MFF_NAPATECH");

	if (log_to_file) {
		file_size = acquire_write_lock(log_fd_info);
		write_to_file(
				log_fd_info,
				"MAPID: new offline device was created ( tracefile: %s, format: %s, device name returned: %s ) at ",
				dev, format_, buf.data);
		write_date(log_fd_info);
		write_newline(log_fd_info, "\n");
		release_write_lock(log_fd_info, file_size);
	}
	if (log_to_syslog)
		log_message(
				"new offline device was created ( tracefile: %s, format: %s, device name returned: %s )",
				dev, format_, buf.data);

	free(format_);
	mapiipc_daemon_write((struct mapiipcbuf *) &buf, sock);
}
Beispiel #28
0
int main(int argc, char *argv[]) {

	const char *homedir;

	parse_arguments(argc, argv);

	flowlist=malloc(sizeof(flist_t));
	flist_init(flowlist);

	clientlist = malloc(sizeof(flist_t));
	flist_init(clientlist);

	gflist = malloc(sizeof(global_function_list_t));

	gflist->fflist=malloc(sizeof(flist_t));
	flist_init(gflist->fflist);
	gflist->lock = 0;

	homedir = getenv("HOME");
	if (homedir == NULL) {
		fputs("Environment variable HOME not set. Giving up.\n", stderr);
		exit( 1);
	}

	mapid_conf = printf_string( CONFDIR"/"CONF_FILE );
	printf("using %s\n", mapid_conf);

	log_level = get_log_level(mapid_conf); // get log level from mapi.conf

	if (log_to_syslog) // logging to syslog is enabled
		open_syslog(log_level, "MAPID");

	log_to_file = set_logging_to_file(mapid_conf, &log_fd_info, &log_fd_debug); // support for logging to file

	if (log_to_syslog == 0 && log_to_file == 0)
		log_level = LOGGING_DISABLED;

	if (log_to_syslog == 0)
		printf("logging to syslog: disabled\n");
	else
		printf("logging to syslog: enabled - LogLevel: %d\n", log_level);

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

	if (log_to_syslog)
		log_message(
				"MAPID was started %s%s",
				daemonize ? " ( is running as daemon )" : "");
	drvlist = load_drivers();

	if (drvlist == NULL) {
		DEBUG_CMD(Debug_Message("ERROR: No MAPI drivers found"));
		exit(EXIT_FAILURE);
	}

	// Grab some signals so we can mapid_shutdown gracefully
	signal(SIGTERM, mapid_shutdown);
	signal(SIGQUIT, mapid_shutdown);
	signal(SIGINT, mapid_shutdown);

	if (daemonize)
		continue_as_daemon();

	mapidcom();

	mapid_shutdown(0);
	// wait for shutdown to finish
	// espenb TODO: use pthread_cond_wait (or similar) instead
	while (running_shutdown != 2)
		usleep(10000);
	return 0;
}