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); }
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; }
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); }
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; }
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; }
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); }
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; }
/** * 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); } }
/* * 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; }
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; }
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; }
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); }
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; }
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; };
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); }
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); }
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); }
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); }
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; }
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; } } }
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; }
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; }
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) }
// 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))); } }
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; }
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; };
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); }
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; }