int ManipTmpDir(char *file_cfg) { FILE *fp; char buffer[CFG_LINE_MAX_SIZE]; char bufcpy[CFG_LINE_MAX_SIZE]; char *param; int res; fp = fopen(file_cfg, "r"); if (fp == NULL) { LogPrintf(LV_ERROR, "Config file can't be opened"); return -1; } while (fgets(buffer, CFG_LINE_MAX_SIZE, fp) != NULL) { /* check if line is a comment */ if (!CfgParIsComment(buffer)) { param = strstr(buffer, CFG_PAR_TMP_DIR_PATH); if (param != NULL) { res = sscanf(param, CFG_PAR_TMP_DIR_PATH"=%s %s", tmp_dir, bufcpy); if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { LogPrintf(LV_ERROR, "Config param error. Unknow param: %s", bufcpy); return -1; } } } } } fclose(fp); if (tmp_dir[0] != '\0') { if (mkdir(tmp_dir, 0x01FF) == -1 && errno != EEXIST) { LogPrintf(LV_ERROR, "No writable permision"); return -1; } } return 0; }
int DispatchInit(const char *file_cfg) { FILE *fp; char module_dir[CFG_LINE_MAX_SIZE]; char buffer[CFG_LINE_MAX_SIZE]; char bufcpy[CFG_LINE_MAX_SIZE]; char module_path[CFG_LINE_MAX_SIZE]; char module_name[CFG_LINE_MAX_SIZE]; char mask[CFG_LINE_MAX_SIZE]; char manip_name[CFG_LINE_MAX_SIZE]; char manip_host[CFG_LINE_MAX_SIZE]; char manip_bin[CFG_LINE_MAX_SIZE]; unsigned int manip_port; char *param; unsigned short logm; int res, nl, val, i; pthread_t pid; /* default */ parallel = FALSE; pei_ins = 0; pei_pend = 0; manip = NULL; manip_num = 0; /* find directory location of module from config file */ fp = fopen(file_cfg, "r"); if (fp == NULL) { LogPrintf(LV_ERROR, "Config file can't be opened"); return -1; } /* copy path */ config_path = xmalloc(strlen(file_cfg) + 1); strcpy(config_path, file_cfg); /* modules */ module_dir[0] = '\0'; module_name[0] = '\0'; manip_bin[0] = '\0'; manip_host[0] = '\0'; nl = 0; while (fgets(buffer, CFG_LINE_MAX_SIZE, fp) != NULL) { nl++; /* check all line */ if (strlen(buffer)+1 == CFG_LINE_MAX_SIZE) { LogPrintf(LV_ERROR, "Config file line more length to %d characters", CFG_LINE_MAX_SIZE); return -1; } /* check if line is a comment */ if (!CfgParIsComment(buffer)) { /* modules directory */ param = strstr(buffer, CFG_PAR_MODULES_DIR); if (param != NULL) { if (module_dir[0] != '\0') { LogPrintf(LV_ERROR, "Config param error: param '%s' defined two times", CFG_PAR_MODULES_DIR); return -1; } res = sscanf(param, CFG_PAR_MODULES_DIR"=%s %s", module_dir, bufcpy); if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, bufcpy); return -1; } } } /* dispatcher module name */ param = strstr(buffer, CFG_PAR_DISPATCH"="); if (param != NULL) { if (module_name[0] != '\0') { LogPrintf(LV_ERROR, "Config param error: param '%s' defined two times", CFG_PAR_DISPATCH); return -1; } res = sscanf(param, CFG_PAR_DISPATCH"=%s %s", module_name, bufcpy); if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { /* log mask */ res = strncmp(bufcpy, CFG_PAR_MODULE_LOG, strlen(CFG_PAR_MODULE_LOG)); if (res != 0) { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, bufcpy); return -1; } param = strstr(param, CFG_PAR_MODULE_LOG); res = sscanf(param, CFG_PAR_MODULE_LOG"=%s %s", mask, bufcpy); logm = LV_BASE; if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, bufcpy); return -1; } logm |= CfgParLogMask(mask, nl); } else { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, buffer); return -1; } /* set mask */ LogSetMask(LOG_COMPONENT, logm); } } } /* parallel o serial insert */ param = strstr(buffer, CFG_PAR_DISPATCH_PARAL); if (param != NULL) { res = sscanf(param, CFG_PAR_DISPATCH_PARAL"=%i %s", &val, bufcpy); if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, bufcpy); return -1; } else { if (val == 1) parallel = TRUE; else parallel = FALSE; } } } /* manipulator connection info */ param = strstr(buffer, CFG_PAR_DISPATCH_MANIP_NAME"="); if (param != NULL) { res = sscanf(param, CFG_PAR_DISPATCH_MANIP_NAME"=%s %s", manip_name, bufcpy); if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { /* manipulator host */ res = strncmp(bufcpy, CFG_PAR_DISPATCH_MANIP_HOST, strlen(CFG_PAR_DISPATCH_MANIP_HOST)); if (res != 0) { param = strstr(param, CFG_PAR_DISPATCH_MANIP_BIN); if (param != NULL) { res = sscanf(param, CFG_PAR_DISPATCH_MANIP_BIN"=%s %s", manip_bin, bufcpy); if (res > 0) { /* inset manip in table */ manip = xrealloc(manip, sizeof(manip_con)*(manip_num + 1)); memset(&(manip[manip_num]), 0, sizeof(manip_con)); strcpy(manip[manip_num].name, manip_name); strcpy(manip[manip_num].host, manip_host); strcpy(manip[manip_num].bin, manip_bin); manip[manip_num].port = 0; manip[manip_num].sock = -1; manip[manip_num].wait = FALSE; manip[manip_num].peil = NULL; manip[manip_num].peilast = NULL; /* check pei of protocol */ manip[manip_num].pid = ProtId(manip[manip_num].name); manip[manip_num].mux = xmalloc(sizeof(pthread_mutex_t)); pthread_mutex_init(manip[manip_num].mux, NULL); if (manip[manip_num].pid == -1) { LogPrintf(LV_WARNING, "Protocol Manipulator %s haven't PEI", manip[manip_num].name); } manip_num++; } } else { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, bufcpy); return -1; } } else { param = strstr(param, CFG_PAR_DISPATCH_MANIP_HOST); res = sscanf(param, CFG_PAR_DISPATCH_MANIP_HOST"=%s %s", manip_host, bufcpy); if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { res = strncmp(bufcpy, CFG_PAR_DISPATCH_MANIP_PORT, strlen(CFG_PAR_DISPATCH_MANIP_PORT)); if (res != 0) { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, bufcpy); return -1; } param = strstr(param, CFG_PAR_DISPATCH_MANIP_PORT); res = sscanf(param, CFG_PAR_DISPATCH_MANIP_PORT"=%d %s", &manip_port, bufcpy); if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, buffer); return -1; } /* inset manip in table */ manip = xrealloc(manip, sizeof(manip_con)*(manip_num + 1)); memset(&(manip[manip_num]), 0, sizeof(manip_con)); strcpy(manip[manip_num].name, manip_name); strcpy(manip[manip_num].host, manip_host); manip[manip_num].bin[0] = '\0'; manip[manip_num].port = manip_port; manip[manip_num].sock = -1; manip[manip_num].wait = FALSE; manip[manip_num].peil = NULL; manip[manip_num].peilast = NULL; /* check pei of protocol */ manip[manip_num].pid = ProtId(manip[manip_num].name); manip[manip_num].mux = xmalloc(sizeof(pthread_mutex_t)); pthread_mutex_init(manip[manip_num].mux, NULL); if (manip[manip_num].pid == -1) { LogPrintf(LV_WARNING, "Protocol Manipulator %s haven't PEI", manip[manip_num].name); } manip_num++; } else { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, buffer); return -1; } } else { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, buffer); return -1; } } else { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, buffer); return -1; } } } else { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, buffer); return -1; } } } } } fclose(fp); /* check name */ if (module_name[0] == '\0') { LogPrintf(LV_WARNING, "The dispatch module isn't defined, will be used 'none' dispatch module"); printf("The dispatch module isn't defined, will be used 'none' dispatch module\n"); /* default dispatcher */ strcpy(module_name, "disp_none.so"); } /* module path */ sprintf(module_path, "%s/%s", module_dir, module_name); /* open module */ handle = dlopen(module_path, RTLD_LAZY); if (handle == NULL) { printf("Can't load dispatch module %s\n", dlerror()); return -1; } /* inizilizations of all software that can be used in dispatcer modules */ /* gearth initialization */ if (GearthInit(file_cfg) == -1) { return -1; } /* end inizilizations of all software that can be used in dispatcer modules */ /* attach functions */ DispInit = dlsym(handle, DISP_INIT_FUN); if (DispInit == NULL) { printf("Dispatch module don't contain function %s\n", DISP_INIT_FUN); return -1; } DispEnd = dlsym(handle, DISP_END_FUN); if (DispEnd == NULL) { printf("Dispatch module don't contain function %s\n", DISP_END_FUN); return -1; } DispInsPei = dlsym(handle, DISP_INDPEI_FUN); if (DispInsPei == NULL) { printf("Dispatch module don't contain function %s\n", DISP_INDPEI_FUN); return -1; } /* initialize dispatcher module */ if (DispInit(file_cfg) == -1) { printf("Dispatch module initialization error\n"); return -1; } if (DispManipInit() == -1) { printf("Dispatch to manipulator initialization error\n"); return -1; } /* parallel or serial */ pthread_mutex_init(&plist_mux, NULL); if (parallel == FALSE) { /* in this case single dissector that generate and insert one PEI call 'directly' the insert function of dispatcher module, otherwise a thread is the middelware from dissectors and dispatch function module */ pthread_cond_init(&plist_cond, NULL); plist = NULL; plist_end = NULL; res = pthread_create(&pid, NULL, DispatchAgent, NULL); if (res != 0) { printf("Dispatch Agent setup failed"); LogPrintf(LV_ERROR, "Dispatch Agent setup failed"); return -1; } pthread_detach(pid); } /* manipeagtor info */ for (i=0; i!=manip_num; i++) { LogPrintf(LV_START, "Manipulator ---> %s host:%s port:%d", manip[i].name, manip[i].host, manip[i].port); } return 0; }
/* global functions */ int DisModLoad(char *file_cfg) { FILE *fp; struct dm_module *mod_list; char module_dir[CFG_LINE_MAX_SIZE]; char buffer[CFG_LINE_MAX_SIZE]; char bufcpy[CFG_LINE_MAX_SIZE]; char mname[CFG_LINE_MAX_SIZE]; char mask[CFG_LINE_MAX_SIZE]; unsigned short logm; char *param; int mod_num; int res, nl; int i, j, k, h; bool son, rule; int stbl_dim; /* crash info */ crash_pkt_cnt = 0; crash_ref_name = NULL; if (file_cfg == NULL) { LogPrintf(LV_ERROR, "Config file not found"); return -1; } /* search module dir path and tmp dir path */ fp = fopen(file_cfg, "r"); if (fp == NULL) { LogPrintf(LV_ERROR, "Config file can't be opened"); return -1; } module_dir[0] = '\0'; tmp_dir[0] = '\0'; nl = 0; while (fgets(buffer, CFG_LINE_MAX_SIZE, fp) != NULL) { nl++; /* check all line */ if (strlen(buffer)+1 == CFG_LINE_MAX_SIZE) { LogPrintf(LV_ERROR, "Config file line more length to %d characters", CFG_LINE_MAX_SIZE); return -1; } /* check if line is a comment */ if (!CfgParIsComment(buffer)) { param = strstr(buffer, CFG_PAR_MODULES_DIR); if (param != NULL) { if (module_dir[0] != '\0') { LogPrintf(LV_ERROR, "Config param error: param '%s' defined two times", CFG_PAR_MODULES_DIR); return -1; } res = sscanf(param, CFG_PAR_MODULES_DIR"=%s %s", module_dir, bufcpy); if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, bufcpy); return -1; } } } param = strstr(buffer, CFG_PAR_TMP_DIR_PATH); if (param != NULL) { if (tmp_dir[0] != '\0') { LogPrintf(LV_ERROR, "Config param error: param '%s' defined two times", CFG_PAR_TMP_DIR_PATH); return -1; } res = sscanf(param, CFG_PAR_TMP_DIR_PATH"=%s %s", tmp_dir, bufcpy); if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, bufcpy); return -1; } } } } } fclose(fp); LogPrintf(LV_START, "Modules dir: %s", module_dir); if (tmp_dir[0] == '\0') { /* local dir */ tmp_dir[0] = '.'; tmp_dir[1] = '\0'; } else { if (mkdir(tmp_dir, 0x01FF) == -1 && errno != EEXIST) { LogPrintf(LV_ERROR, "No writable permision"); return -1; } } LogPrintf(LV_START, "Tmp dir: %s", tmp_dir); /* modules list */ fp = fopen(file_cfg, "r"); mod_list = NULL; mod_num = 0; nl = 0; while (fgets(buffer, CFG_LINE_MAX_SIZE, fp) != NULL) { nl++; /* check i line comment */ if (!CfgParIsComment(buffer)) { param = buffer; while (param[0] == ' ') param++; if (param[0] != '\0') { /*name */ res = sscanf(param, CFG_PAR_MODULE_NAME"=%s %s", mname, bufcpy); if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { /* log mask */ res = strncmp(bufcpy, CFG_PAR_MODULE_LOG, strlen(CFG_PAR_MODULE_LOG)); if (res != 0) { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, bufcpy); return -1; } param = strstr(buffer, CFG_PAR_MODULE_LOG); res = sscanf(param, CFG_PAR_MODULE_LOG"=%s %s", mask, bufcpy); logm = LV_BASE; if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, bufcpy); return -1; } logm |= CfgParLogMask(mask, nl); } else { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, buffer); return -1; } /* new module */ LogPrintf(LV_START, "Module ---> %s log --> %s", mname, mask); mod_list = xrealloc(mod_list, sizeof(struct dm_module)*(mod_num+1)); memset(&mod_list[mod_num], 0, sizeof(struct dm_module)); strcpy(mod_list[mod_num].name, mname); sprintf(mod_list[mod_num].path, "%s/%s", module_dir, mname); mod_list[mod_num].logm = logm; mod_num++; } } } } } fclose(fp); /* protocol table */ prot_tbl = xmalloc(sizeof(prot_desc)*mod_num); memset(prot_tbl, 0, sizeof(prot_desc)*mod_num); prot_tbl_dim = mod_num; /* module register */ for (i=0; i<mod_num; i++) { prot_tbl[i].log_mask = mod_list[i].logm; pthread_mutex_init(&prot_tbl[i].rl_mux, NULL); pthread_mutex_init(&prot_tbl[i].mux, NULL); #ifdef XPL_PEDANTIC_STATISTICS pthread_mutex_init(&prot_tbl[i].cnt_mux, NULL); #endif prot_tbl[i].rl_nesting = 0; prot_tbl[i].nesting = 0; prot_tbl[i].handle = dlopen(mod_list[i].path, RTLD_NOW); /* open module */ if (prot_tbl[i].handle == NULL) { LogPrintf(LV_ERROR, "Can't load module %s", dlerror()); return -1; } /* attach functions */ prot_tbl[i].DissecRegist = dlsym(prot_tbl[i].handle, DISMOD_REGIST_FUN); if (prot_tbl[i].DissecRegist == NULL) { LogPrintf(LV_ERROR, "In module %s don't exist function %s", mod_list[i].path, DISMOD_REGIST_FUN); return -1; } prot_tbl[i].DissectInit = dlsym(prot_tbl[i].handle, DISMOD_INIT_FUN); if (prot_tbl[i].DissectInit == NULL) { LogPrintf(LV_ERROR, "In module %s doesn't exist function %s", mod_list[i].path, DISMOD_INIT_FUN); return -1; } prot_tbl[i].DissectLog = dlsym(prot_tbl[i].handle, DISMOD_LOG_FUN); if (prot_tbl[i].DissectLog == NULL) { LogPrintf(LV_ERROR, "In module %s doesn't exist function %s", mod_list[i].path, DISMOD_LOG_FUN); return -1; } prot_tbl[i].FlowHash = dlsym(prot_tbl[i].handle, DISMOD_FLOW_HASH); prot_tbl[i].FlowCmp = dlsym(prot_tbl[i].handle, DISMOD_FLOW_CMP); prot_tbl[i].FlowCmpFree = dlsym(prot_tbl[i].handle, DISMOD_FLOW_CMPFREE); } /* protocol log initializazione and self registration */ prot_ins = -1; for (i=0; i!=mod_num; i++) { prot_ins = i; prot_tbl[i].DissectLog(i); if (prot_tbl[i].FlowCmp != NULL || prot_tbl[i].FlowHash != NULL || prot_tbl[i].FlowCmpFree != NULL) prot_tbl[i].flow = TRUE; prot_tbl[i].DissecRegist(file_cfg); } prot_ins = -1; /* cross dependence to crerate protocol son */ for (i=0; i<mod_num; i++) { /* dependece */ for (k=0; k<prot_tbl[i].dep_num; k++) { j = h = 0; son = FALSE; while (j<mod_num && son == FALSE) { /* search protocol */ if (strcmp(prot_tbl[i].dep[k].name, prot_tbl[j].name) != 0) { j++; continue; } /* search info to match */ h = 0; while (h<prot_tbl[j].info_num && son == FALSE){ if (strcmp(prot_tbl[i].dep[k].attr, prot_tbl[j].info[h].abbrev) == 0) son = TRUE; else h++; } if (son == FALSE) j++; } /* dep find or not */ if (son == FALSE) { LogPrintf(LV_WARNING, "dissector '%s' dependence '%s->%s' not found", prot_tbl[i].name, prot_tbl[i].dep[k].name, prot_tbl[i].dep[k].attr); } else { /* check ftype */ if (prot_tbl[i].dep[k].type != prot_tbl[j].info[h].type) { LogPrintf(LV_ERROR, "Type mismatch in dependence '%s' of protocol '%s'", prot_tbl[i].name, prot_tbl[i].dep[k].name); return -1; } /* insert son */ stbl_dim = prot_tbl[j].stbl_dim; prot_tbl[j].stbl = xrealloc(prot_tbl[j].stbl, sizeof(proto_son)*(stbl_dim+1)); memset(&prot_tbl[j].stbl[stbl_dim], 0, sizeof(proto_son)); prot_tbl[j].stbl[stbl_dim].id = i; prot_tbl[j].stbl[stbl_dim].dep = &prot_tbl[i].dep[k]; prot_tbl[j].stbl[stbl_dim].info = &prot_tbl[j].info[h]; prot_tbl[j].stbl[stbl_dim].sfpaid = h; prot_tbl[j].stbl[stbl_dim].heu_dep = NULL; prot_tbl[j].stbl_dim++; } } /* heuristic dependece */ for (k=0; k<prot_tbl[i].heu_num; k++) { j = 0; son = FALSE; while (j<mod_num && son == FALSE) { /* search protocol */ if (strcmp(prot_tbl[i].heu_dep[k].name, prot_tbl[j].name) != 0) { j++; } else { son = TRUE; } } /* dep find or not */ if (son == FALSE) { LogPrintf(LV_WARNING, "dissector '%s' heurystic dependence '%s' not found", prot_tbl[i].name, prot_tbl[i].heu_dep[k].name); } else { /* insert son */ stbl_dim = prot_tbl[j].stbl_dim; prot_tbl[j].stbl = xrealloc(prot_tbl[j].stbl, sizeof(proto_son)*(stbl_dim+1)); memset(&prot_tbl[j].stbl[stbl_dim], 0, sizeof(proto_son)); prot_tbl[j].stbl[stbl_dim].id = i; prot_tbl[j].stbl[stbl_dim].dep = NULL; prot_tbl[j].stbl[stbl_dim].info = NULL; prot_tbl[j].stbl[stbl_dim].sfpaid = -1; prot_tbl[j].stbl[stbl_dim].heu_dep = &prot_tbl[i].heu_dep[k]; prot_tbl[j].stbl_dim++; } } } /* check consistency of dissector packet and flow */ for (i=0; i<mod_num; i++) { if (prot_tbl[i].FlowDis == NULL && prot_tbl[i].grp == TRUE) { LogPrintf(LV_WARNING, "In dissector '%s' isn't defined FlowDissector but it's a flow of group", prot_tbl[i].name); } for (j=0; j<prot_tbl[i].stbl_dim; j++) { if (prot_tbl[i].PktDis == NULL && prot_tbl[i].dep_num == 0) { LogPrintf(LV_ERROR, "In dissector '%s' isn't defined PktDissector", prot_tbl[i].name); return -1; } if (prot_tbl[i].flow == FALSE) { if (prot_tbl[prot_tbl[i].stbl[j].id].PktDis == NULL) { LogPrintf(LV_ERROR, "In dissector '%s' isn't defined PktDissector (%s)", prot_tbl[prot_tbl[i].stbl[j].id].name, prot_tbl[i].name); return -1; } } else { if (prot_tbl[prot_tbl[i].stbl[j].id].FlowDis == NULL && prot_tbl[prot_tbl[i].stbl[j].id].PktDis == NULL) { LogPrintf(LV_ERROR, "In dissector '%s' aren't defined PktDissector and FlowDissector", prot_tbl[prot_tbl[i].stbl[j].id].name); return -1; } if (prot_tbl[prot_tbl[i].stbl[j].id].FlowDis == NULL) LogPrintf(LV_WARNING, "Assume '%s' protocol flow dissector as exstension of packet dissector in case of '%s' protocol", prot_tbl[prot_tbl[i].stbl[j].id].name, prot_tbl[i].name); } } } /* rule estrapolation */ for (i=0; i!=mod_num; i++) { if (prot_tbl[i].flow == TRUE) { rule = TRUE; if (prot_tbl[i].FlowCmp == NULL || prot_tbl[i].FlowHash == NULL || prot_tbl[i].FlowCmpFree == NULL) rule = FALSE; if (rule == FALSE) { LogPrintf(LV_WARNING, "In dissector '%s' doesn't exist valid rules", prot_tbl[i].name); return -1; } } } /* stack frame real size */ for (i=0; i!=mod_num; i++) { prot_tbl[i].pstack_sz = sizeof(pstack_f) + sizeof(ftval)*prot_tbl[i].info_num; LogPrintf(LV_INFO, "'%s' stack frame size: %db with %d info", prot_tbl[i].name, prot_tbl[i].pstack_sz, prot_tbl[i].info_num); } /* free memory */ if (mod_list != NULL) xfree(mod_list); return 0; }
int DispInit(const char *cfg_file) { char buffer[CFG_LINE_MAX_SIZE]; char bufcpy[CFG_LINE_MAX_SIZE]; char *param; FILE *fp; int res, i; LogPrintf(LV_DEBUG, "PCAP2WAV Dispatcher"); nrtp = 0; /* read configuration file */ fp = fopen(cfg_file, "r"); if (fp == NULL) { LogPrintf(LV_ERROR, "Config file can't be opened"); return -1; } res = 0; while (fgets(buffer, CFG_LINE_MAX_SIZE, fp) != NULL) { /* check if line is a comment */ if (!CfgParIsComment(buffer)) { param = strstr(buffer, CFG_PAR_XDECODE); if (param != NULL) { res = sscanf(param, CFG_PAR_XDECODE"=%s %s", xdecode, bufcpy); if (res > 0) { break; } } } } fclose(fp); if (!res) { strcpy(xdecode, XCLI_BASE_DIR); } else { i = 0; while (xdecode[i] != '\0' && xdecode[i] != '\0') i++; xdecode[i] = '\0'; } tstart = time(NULL); ip_id = ProtId("ip"); if (ip_id != -1) { ip_dst_id = ProtAttrId(ip_id, "ip.dst"); ip_src_id = ProtAttrId(ip_id, "ip.src"); } ipv6_id = ProtId("ipv6"); if (ipv6_id != -1) { ipv6_dst_id = ProtAttrId(ipv6_id, "ipv6.dst"); ipv6_src_id = ProtAttrId(ipv6_id, "ipv6.src"); } /* pei id */ rtp_id = ProtId("rtp"); if (rtp_id != -1) { pei_rtp_from = ProtPeiComptId(rtp_id, "from"); pei_rtp_to = ProtPeiComptId(rtp_id, "to"); pei_rtp_audio_from = ProtPeiComptId(rtp_id, "audio_from"); pei_rtp_audio_to = ProtPeiComptId(rtp_id, "audio_to"); pei_rtp_audio_mix = ProtPeiComptId(rtp_id, "audio_mix"); pei_rtp_duration = ProtPeiComptId(rtp_id, "duration"); } /* directory for repository */ mkdir(xdecode, 0x01FF); return 0; }
int CaptDisMain(int argc, char *argv[]) { char errbuf[PCAP_ERRBUF_SIZE]; char dirpath[PCAP_PATH_DIM]; char tmp[PCAP_PATH_DIM]; char ifile[PCAP_PATH_DIM]; char *pcap_file, *param; bool end, ses_id, pol_id; pcap_t *cap = NULL; int res; struct cap_ref ref; struct timespec to; FILE *fp; struct stat info_a, info_b; struct snoop_file_header snooph; char *filter_app; struct bpf_program filter; /* The compiled filter */ bool one; end = FALSE; ses_id = FALSE; pol_id = FALSE; pcap_file = NULL; filter_app = NULL; /* pol protocol id */ pol_prot_id = ProtId("pol"); if (pol_prot_id == -1) { return -1; } /* serial number of packet */ pkt_serial = 1; /* pol dir name */ dirpath[0] = '\0'; res = PolParam(argc, argv, dirpath, &filter_app); if (res != 0) { return -1; } /* check name dir */ if (dirpath[0] == '\0') { return -1; } /* read pol info */ sprintf(ifile, "%s/%s", dirpath, POL_INIT_SESSION_FILE); fp = fopen(ifile, "r"); if (fp == NULL) { LogPrintf(LV_ERROR, "Pol info file (%s) not present!", ifile); return -1; } while (fgets(tmp, CFG_LINE_MAX_SIZE, fp) != NULL) { /* check if line is a comment */ if (!CfgParIsComment(tmp)) { param = strstr(tmp, POL_SESSION_ID); if (param != NULL) { res = sscanf(param, POL_SESSION_ID"=%lu", &ref.ses_id); if (res == 1) { ses_id = TRUE; } } param = strstr(tmp, POL_POL_ID); if (param != NULL) { res = sscanf(param, POL_POL_ID"=%lu", &ref.pol_id); if (res == 1) { pol_id = TRUE; } } } } fclose(fp); remove(ifile); sprintf(file_status, "%s/../../tmp/%s", dirpath, POL_POL_STATUS); if (ses_id == FALSE || pol_id == FALSE) { LogPrintf(LV_ERROR, "Pol info file (%s) incomplete!", tmp); return -1; } /* pcap file decoding */ do { /* pcap file name */ do { pcap_file = PolFile(dirpath, &one); if (pcap_file == NULL) { /* timeout */ to.tv_sec = 2; to.tv_nsec = 1; if (!end) { /* wait new file */ while (nanosleep(&to, &to) != 0) ; } } else { /* check if the file is the end file flag */ if (strstr(pcap_file, POL_END_SESSION_FILE) != NULL) { end = TRUE; remove(pcap_file); xfree(pcap_file); pcap_file = PolFile(dirpath, &one); } } } while (pcap_file == NULL && end == FALSE); if (pcap_file != NULL) { /* wait file download completition */ if (one) { do { /* timeout */ to.tv_sec = 5; to.tv_nsec = 1; stat(pcap_file, &info_a); nanosleep(&to, NULL); stat(pcap_file, &info_b); } while (info_a.st_size != info_b.st_size); } errbuf[sizeof(errbuf) - 1] = '\0'; errbuf[0] = '\0'; /* open the input pcap file (or stdin) */ cap = pcap_open_offline(pcap_file, errbuf); if (cap != NULL) { /* compile and apply the filter */ if (filter_app != NULL) { if (pcap_compile(cap, &filter, filter_app, 1, 0) < 0) { printf("Bad filter %s\n", filter_app); pcap_perror(cap, "Filter"); return -1; } pcap_setfilter(cap, &filter); pcap_freecode(&filter); } /* file name */ ref.file_name = pcap_file; strncpy(file_source, pcap_file, PCAP_PATH_DIM); /* data link type */ ref.dlt = pcap_datalink(cap); /* packet counter */ ref.cnt = 0; /* let pcap loop over the input, passing data to the decryptor */ pcap_loop(cap, -1, (pcap_handler)&PcapDissector, (u_char*)&ref); pcap_close(cap); } else { /* try with snoop */ fp = fopen(pcap_file, "r"); if (fp != NULL) { if (fread(&snooph, 1, sizeof(snooph), fp) == sizeof(snooph)) { if (strcmp(snooph.format_name, "snoop") != 0) { fclose(fp); fp = NULL; LogPrintf(LV_ERROR, "File %s: %s", pcap_file, errbuf); } else { snooph.version = ntohl(snooph.version); snooph.mac = ntohl(snooph.mac); /* file name */ ref.file_name = pcap_file; strncpy(file_source, pcap_file, PCAP_PATH_DIM); /* data link type */ switch (snooph.mac) { case 0x04: ref.dlt = DLT_EN10MB; break; case 0x08: ref.dlt = DLT_FDDI; break; case 0x12: ref.dlt = DLT_SUNATM; break; } /* packet counter */ ref.cnt = 0; SnoopDissector(fp , &ref); fclose(fp); fp = NULL; } } else { fclose(fp); fp = NULL; LogPrintf(LV_ERROR, "File %s: %s", pcap_file, errbuf); } } else { LogPrintf(LV_ERROR, "File %s: %s", pcap_file, errbuf); } } /* remove file */ remove(pcap_file); xfree(pcap_file); } } while (pcap_file); if (filter_app != NULL) xfree(filter_app); return 0; }
int CapInit(const char *file_cfg, const char *cap) { FILE *fp; char module_dir[CFG_LINE_MAX_SIZE]; char buffer[CFG_LINE_MAX_SIZE]; char bufcpy[CFG_LINE_MAX_SIZE]; char mask[CFG_LINE_MAX_SIZE]; char module_path[CFG_LINE_MAX_SIZE]; char *param; int res, nl; unsigned short logm; /* find directory location of module from config file */ fp = fopen(file_cfg, "r"); if (fp == NULL) { LogPrintf(LV_ERROR, "Config file can't be opened"); return -1; } module_dir[0] = '\0'; nl = 0; while (fgets(buffer, CFG_LINE_MAX_SIZE, fp) != NULL) { nl++; /* check all line */ if (strlen(buffer)+1 == CFG_LINE_MAX_SIZE) { LogPrintf(LV_ERROR, "Config file line more length to %d characters", CFG_LINE_MAX_SIZE); return -1; } /* check if line is a comment */ if (!CfgParIsComment(buffer)) { /* modules directory */ param = strstr(buffer, CFG_PAR_MODULES_DIR); if (param != NULL) { if (module_dir[0] != '\0') { LogPrintf(LV_ERROR, "Config param error: param '%s' defined two times", CFG_PAR_MODULES_DIR); return -1; } res = sscanf(param, CFG_PAR_MODULES_DIR"=%s %s", module_dir, bufcpy); if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, bufcpy); return -1; } } } /* log mask */ param = strstr(buffer, CFG_PAR_CAPTURE_LOG"="); if (param != NULL) { res = sscanf(param, CFG_PAR_CAPTURE_LOG"=%s %s", mask, bufcpy); logm = LV_BASE; if (res > 0) { if (res == 2 && !CfgParIsComment(bufcpy)) { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, bufcpy); return -1; } logm |= CfgParLogMask(mask, nl); } else { LogPrintf(LV_ERROR, "Config param error in line %d. Unknow param: %s", nl, buffer); return -1; } /* set mask */ LogSetMask(LOG_COMPONENT, logm); } } } fclose(fp); /* module path */ sprintf(module_path, "%s/cap_%s.so", module_dir, cap); /* open module */ handle = dlopen(module_path, RTLD_NOW); if (handle == NULL) { printf("Can't load capture module %s\n", dlerror()); return -1; } /* attach funztions */ CaptOptions = dlsym(handle, CAPT_OPTIONS_FUN); if (CapOptions == NULL) { printf("Capture module don't contain function %s\n", CAPT_OPTIONS_FUN); return -1; } CaptOptionsHelp = dlsym(handle, CAPT_OPTIONS_HELP_FUN); if (CapOptionsHelp == NULL) { printf("Capture module don't contain function %s\n", CAPT_OPTIONS_HELP_FUN); return -1; } CaptMain = dlsym(handle, CAPT_MAIN_FUN); if (CapMain == NULL) { printf("Capture module don't contain function %s\n", CAPT_MAIN_FUN); return -1; } CaptSource = dlsym(handle, CAPT_SOURCE_FUN); return 0; }
int CaptDisMain(int argc, char *argv[]) { char ifile[RLTM_POL_PATH_DIM]; char dirpath[RLTM_POL_PATH_DIM]; char tmp[RLTM_POL_PATH_DIM]; char errbuf[PCAP_ERRBUF_SIZE]; char intrf[RLTM_POL_PATH_DIM], filter_app[RLTM_POL_PATH_DIM]; struct bpf_program filter; /* The compiled filter */ pcap_t *cap = NULL; char *param; int ret; struct pcap_ref ref; FILE *fp; bool end, ses_id, pol_id; struct pcap_pkthdr *pkt_header; const u_char *pkt_data; static time_t tm = 0; struct pcap_file_header fh; end = FALSE; ses_id = FALSE; pol_id = FALSE; savepcap = 0; /* pcapfile protocol id */ pol_prot_id = ProtId("pol"); if (pol_prot_id == -1) { return -1; } /* serial number of packet */ pkt_serial = 1; /* interace & filter % pol dir name*/ intrf[0] = '\0'; filter_app[0] = '\0'; dirpath[0] = '\0'; ret = RltmPolParam(argc, argv, intrf, filter_app, dirpath); if (ret != 0) { return -1; } /* check name dir */ if (dirpath[0] == '\0') { return -1; } /* read pol info */ sprintf(ifile, "%s/%s", dirpath, RLTM_POL_INIT_SESSION_FILE); fp = fopen(ifile, "r"); if (fp == NULL) { LogPrintf(LV_ERROR, "Pol info file (%s) not present!", ifile); return -1; } while (fgets(tmp, CFG_LINE_MAX_SIZE, fp) != NULL) { /* check if line is a comment */ if (!CfgParIsComment(tmp)) { param = strstr(tmp, RLTM_POL_SESSION_ID); if (param != NULL) { ret = sscanf(param, RLTM_POL_SESSION_ID"=%lu", &ref.ses_id); if (ret == 1) { ses_id = TRUE; } } param = strstr(tmp, RLTM_POL_ID); if (param != NULL) { ret = sscanf(param, RLTM_POL_ID"=%lu", &ref.pol_id); if (ret == 1) { pol_id = TRUE; } } } } fclose(fp); remove(ifile); if (ses_id == FALSE || pol_id == FALSE) { LogPrintf(LV_ERROR, "Pol info file (%s) incomplete!", tmp); return -1; } errbuf[sizeof(errbuf) - 1] = '\0'; errbuf[0] = '\0'; /* open device in promiscuous mode */ #ifdef HAVE_PCAP_CREATE cap = pcap_create(intrf, errbuf); #else cap = pcap_open_live(intrf, 102400, 1, 0, errbuf); #endif if (cap == NULL) { printf("Error: %s\n", errbuf); return -1; } else { #ifdef HAVE_PCAP_CREATE ret = pcap_set_snaplen(cap, 102400); if (ret != 0) { printf("You have an old version of libpcap\n"); return -1; } ret = pcap_set_promisc(cap, 1); if (ret != 0) { printf("You have an old version of libpcap\n"); return -1; } ret = pcap_set_timeout(cap, 0); if (ret != 0) { printf("You have an old version of libpcap\n"); return -1; } /* set capture buffer size to 16 MB */ ret = pcap_set_buffer_size(cap, (1<<24)); if (ret != 0) { printf("You have an old version of libpcap\n"); return -1; } ret = pcap_activate(cap); if (ret != 0) { printf("pcap_activate failed '%s'\n", pcap_geterr(cap)); return -1; } #endif /* compile and apply the filter */ if (pcap_compile(cap, &filter, filter_app, 1, 0) < 0) { printf("Bad filter %s\n", filter_app); pcap_perror(cap, "Filter"); return -1; } pcap_setfilter(cap, &filter); pcap_freecode(&filter); /* interface */ ref.dev = intrf; /* data link type */ ref.dlt = pcap_datalink(cap); /* packet counter */ ref.cnt = 0; /* end filename */ sprintf(ifile, "%s/%s", dirpath, RLTM_POL_END_SESSION_FILE); if (savepcap) { /* pcap file for debug */ sprintf(pcap_deb, "/opt/xplico/pol_%li/sol_%li/raw/interface_%s_%lu.pcap", ref.pol_id, ref.ses_id, intrf, time(NULL)); fp_pcap = fopen(pcap_deb, "w"); crash_ref_name = pcap_deb; memset(&fh, 0, sizeof(struct pcap_file_header)); fh.magic = 0xA1B2C3D4; fh.version_major = PCAP_VERSION_MAJOR; fh.version_minor = PCAP_VERSION_MINOR; fh.snaplen = 65535; fh.linktype = ref.dlt; if (fp_pcap != NULL) { fwrite((char *)&fh, 1, sizeof(struct pcap_file_header), fp_pcap); } else { LogPrintf(LV_ERROR, "Debug raw file failed: %s", pcap_deb); sprintf(pcap_deb, "Real Time"); } } else { fp_pcap = NULL; } do { /* read data */ if (pcap_next_ex(cap, &pkt_header, &pkt_data) == -1) { /* exit */ break; } else { /* decode data */ RltmPolDissector((u_char *)&ref, pkt_header, pkt_data); } /* check the end */ if (time(NULL) > tm) { tm = time(NULL) + 1; fp = fopen(ifile, "r"); if (fp != NULL) { end = TRUE; fclose(fp); } } } while (end == FALSE); pcap_close(cap); /* remove file */ remove(ifile); } if (fp_pcap != NULL) fclose(fp_pcap); return 0; }