int status_client_ncurses(enum action act, struct conf **confs) { int csin=-1; int csout=-1; int ret=-1; pid_t childpid=-1; struct async *as=NULL; const char *monitor_logfile=get_string(confs[OPT_MONITOR_LOGFILE]); #ifdef HAVE_NCURSES_H actg=act; // So that the sighandler can call endwin(). #else if(act==ACTION_STATUS) { printf("To use the live status monitor, you need to recompile with ncurses support.\n"); goto end; } #endif setup_signals(); // Fork a burp child process that will contact the server over SSL. // We will read and write from and to its stdout and stdin. if((childpid=fork_monitor(&csin, &csout, confs))<0) goto end; //printf("childpid: %d\n", childpid); set_non_blocking(csin); set_non_blocking(csout); if(!(as=async_alloc()) || as->init(as, 0) || !setup_asfd(as, "monitor stdin", &csin, NULL, ASFD_STREAM_LINEBUF, ASFD_FD_CLIENT_MONITOR_WRITE, -1, confs) || !setup_asfd(as, "monitor stdout", &csout, NULL, ASFD_STREAM_LINEBUF, ASFD_FD_CLIENT_MONITOR_READ, -1, confs)) goto end; //printf("ml: %s\n", monitor_logfile); #ifdef HAVE_NCURSES_H if(actg==ACTION_STATUS) { int stdinfd=fileno(stdin); if(!setup_asfd(as, "stdin", &stdinfd, NULL, ASFD_STREAM_NCURSES_STDIN, ASFD_FD_CLIENT_NCURSES_READ, -1, confs)) goto end; ncurses_init(); } #endif if(monitor_logfile && !(lfp=open_file(monitor_logfile, "wb"))) goto end; set_logfp_direct(lfp); ret=main_loop(as, act, confs); end: #ifdef HAVE_NCURSES_H if(actg==ACTION_STATUS) endwin(); #endif if(ret) logp("%s exiting with error: %d\n", __func__, ret); close_fp(&lfp); async_asfd_free_all(&as); close_fd(&csin); close_fd(&csout); return ret; }
int main(int argc, char **argv) /* {{{ */ { /* declare variables */ int c; bool debug = false; char *debugopts = NULL; char *logpath; /* open log */ asprintf(&logpath, LOGFILE, getenv("USER")); logfp = fopen(logpath, "a"); free(logpath); tnc_fprintf(logfp, LOG_DEBUG, "%s started", PROGNAME); /* set defaults */ cfg.loglvl = LOGLVL_DEFAULT; setlocale(LC_ALL, ""); /* handle arguments */ static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"debug", required_argument, 0, 'd'}, {"version", no_argument, 0, 'v'}, {"loglevel", required_argument, 0, 'l'}, {"filter", required_argument, 0, 'f'}, {0, 0, 0, 0} }; int option_index = 0; while ((c = getopt_long(argc, argv, "l:hvd:f:", long_options, &option_index)) != -1) { switch (c) { case 'l': cfg.loglvl = (char) atoi(optarg); printf("loglevel: %d\n", (int)cfg.loglvl); break; case 'v': print_version(); return 0; break; case 'd': debug = true; debugopts = strdup(optarg); break; case 'f': active_filter = strdup(optarg); break; case 'h': case '?': help(); return 0; break; default: return 1; } } /* run ncurses */ if (!debug) { tnc_fprintf(logfp, LOG_DEBUG, "running gui"); ncurses_init(); cols = COLS; rows = LINES; umvaddstr(stdscr, 0, 0, "%s %s", PROGNAME, PROGVERSION); umvaddstr(stdscr, 1, 0, "configuring..."); wrefresh(stdscr); tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "configuring..."); configure(); tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "configuration complete"); umvaddstr(stdscr, 1, 0, "loading tasks..."); wrefresh(stdscr); tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "loading tasks..."); head = get_tasks(NULL); tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "%d tasks loaded", taskcount); mvwhline(stdscr, 0, 0, ' ', COLS); mvwhline(stdscr, 1, 0, ' ', COLS); tasklist_window(); ncurses_end(0); } /* debug mode */ else { configure(); head = get_tasks(NULL); test(debugopts); free(debugopts); } /* done */ tnc_fprintf(logfp, LOG_DEBUG, "exiting"); return 0; } /* }}} */
/** * @brief Main function logic * * Parse command line options and start running threads */ int main(int argc, char* argv[]) { int opt, idx, limit, only_calls, no_incomplete, i; const char *device, *outfile; char bpf[512]; #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) const char *keyfile; #endif const char *match_expr; int match_insensitive = 0, match_invert = 0; int no_interface = 0, quiet = 0, rtp_capture = 0, rotate = 0, no_config = 0; vector_t *infiles = vector_create(0, 1); vector_t *indevices = vector_create(0, 1); // Program options static struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'V' }, { "device", required_argument, 0, 'd' }, { "input", required_argument, 0, 'I' }, { "output", required_argument, 0, 'O' }, #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) { "keyfile", required_argument, 0, 'k' }, #endif { "calls", no_argument, 0, 'c' }, { "rtp", no_argument, 0, 'r' }, { "limit", required_argument, 0, 'l' }, { "icase", no_argument, 0, 'i' }, { "invert", no_argument, 0, 'v' }, { "no-interface", no_argument, 0, 'N' }, { "dump-config", no_argument, 0, 'D' }, { "rotate", no_argument, 0, 'R' }, { "config", required_argument, 0, 'f' }, { "no-config", no_argument, 0, 'F' }, #ifdef USE_EEP { "eep-listen", required_argument, 0, 'L' }, { "eep-send", required_argument, 0, 'H' }, #endif { "quiet", no_argument, 0, 'q' }, }; // Parse command line arguments that have high priority opterr = 0; char *options = "hVd:I:O:pqtW:k:crl:ivNqDL:H:Rf:F"; while ((opt = getopt_long(argc, argv, options, long_options, &idx)) != -1) { switch (opt) { case 'h': usage(); return 0; case 'V': version(); return 0; case 'F': no_config = 1; break; default: break; } } // Initialize configuration options init_options(no_config); // Get initial values for configurable arguments device = setting_get_value(SETTING_CAPTURE_DEVICE); outfile = setting_get_value(SETTING_CAPTURE_OUTFILE); #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) keyfile = setting_get_value(SETTING_CAPTURE_KEYFILE); #endif limit = setting_get_intvalue(SETTING_CAPTURE_LIMIT); only_calls = setting_enabled(SETTING_SIP_CALLS); no_incomplete = setting_enabled(SETTING_SIP_NOINCOMPLETE); rtp_capture = setting_enabled(SETTING_CAPTURE_RTP); rotate = setting_enabled(SETTING_CAPTURE_ROTATE); // Parse the rest of command line arguments opterr = 0; optind = 1; /* reset getopt index */ while ((opt = getopt_long(argc, argv, options, long_options, &idx)) != -1) { switch (opt) { case 'h': /* handled before with higher priority options */ break; case 'V': /* handled before with higher priority options */ break; case 'd': vector_append(indevices, optarg); break; case 'I': vector_append(infiles, optarg); break; case 'O': outfile = optarg; break; case 'l': if(!(limit = atoi(optarg))) { fprintf(stderr, "Invalid limit value.\n"); return 0; } break; case 'k': #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) keyfile = optarg; break; #else fprintf(stderr, "sngrep is not compiled with SSL support."); exit(1); #endif case 'c': only_calls = 1; setting_set_value(SETTING_SIP_CALLS, SETTING_ON); break; case 'r': rtp_capture = 1; setting_set_value(SETTING_CAPTURE_RTP, SETTING_ON); break; case 'i': match_insensitive++; break; case 'v': match_invert++; break; case 'N': no_interface = 1; setting_set_value(SETTING_CAPTURE_STORAGE, "none"); break; case 'q': quiet = 1; break; case 'D': key_bindings_dump(); settings_dump(); return 0; case 'f': read_options(optarg); break; case 'F': /* handled before with higher priority options */ break; case 'R': rotate = 1; setting_set_value(SETTING_CAPTURE_ROTATE, SETTING_ON); break; // Dark options for dummy ones case 'p': case 't': case 'W': break; case 'L': #ifdef USE_EEP capture_eep_set_server_url(optarg); break; #else fprintf(stderr, "sngrep is not compiled with HEP/EEP support."); exit(1); #endif case 'H': #ifdef USE_EEP capture_eep_set_client_url(optarg); break; #else fprintf(stderr, "sngrep is not compiled with HEP/EEP support."); exit(1); #endif case '?': if (strchr(options, optopt)) { fprintf(stderr, "-%c option requires an argument.\n", optopt); } else if (isprint(optopt)) { fprintf(stderr, "Unknown option -%c.\n", optopt); } else { fprintf(stderr, "Unknown option character '\\x%x'.\n", optopt); } return 1; default: break; } } #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) // Set capture decrypt key file capture_set_keyfile(keyfile); // Check if we have a keyfile and is valid if (keyfile && !tls_check_keyfile(keyfile)) { fprintf(stderr, "%s does not contain a valid RSA private key.\n", keyfile); return 1; } #endif // Check if given argument is a file if (argc == 2 && (access(argv[1], F_OK) == 0)) { // Old legacy option to open pcaps without other arguments printf("%s seems to be a file: You forgot -I flag?\n", argv[1]); return 0; } // Initialize SIP Messages Storage sip_init(limit, only_calls, no_incomplete); // Set capture options capture_init(limit, rtp_capture, rotate); #ifdef USE_EEP // Initialize EEP if enabled capture_eep_init(); #endif // If no device or files has been specified in command line, use default if (vector_count(indevices) == 0 && vector_count(infiles) == 0) { vector_append(indevices, (char *) device); } // If we have an input file, load it for (i = 0; i < vector_count(infiles); i++) { // Try to load file if (capture_offline(vector_item(infiles, i), outfile) != 0) return 1; } // If we have an input device, load it for (i = 0; i < vector_count(indevices); i++) { // Check if all capture data is valid if (capture_online(vector_item(indevices, i), outfile) != 0) return 1; } // Remove Input files vector vector_destroy(infiles); // More arguments pending! if (argv[optind]) { // Assume first pending argument is match expression match_expr = argv[optind++]; // Try to build the bpf filter string with the rest memset(bpf, 0, sizeof(bpf)); for (i = optind; i < argc; i++) sprintf(bpf + strlen(bpf), "%s ", argv[i]); // Check if this BPF filter is valid if (capture_set_bpf_filter(bpf) != 0) { // BPF Filter invalid, check incluiding match_expr match_expr = 0; // There is no need to parse all payload at this point // Build the bpf filter string memset(bpf, 0, sizeof(bpf)); for (i = optind - 1; i < argc; i++) sprintf(bpf + strlen(bpf), "%s ", argv[i]); // Check bpf filter is valid again if (capture_set_bpf_filter(bpf) != 0) { fprintf(stderr, "Couldn't install filter %s: %s\n", bpf, capture_last_error()); return 1; } } // Set the capture filter if (match_expr) if (sip_set_match_expression(match_expr, match_insensitive, match_invert)) { fprintf(stderr, "Unable to parse expression %s\n", match_expr); return 1; } } // Start a capture thread if (capture_launch_thread() != 0) { ncurses_deinit(); fprintf(stderr, "Failed to launch capture thread.\n"); return 1; } if (!no_interface) { // Initialize interface ncurses_init(); // This is a blocking call. // Create the first panel and wait for user input ui_create_panel(PANEL_CALL_LIST); ui_wait_for_input(); } else { setbuf(stdout, NULL); while(capture_is_running()) { if (!quiet) printf("\rDialog count: %d", sip_calls_count()); usleep(500 * 1000); } if (!quiet) printf("\rDialog count: %d\n", sip_calls_count()); } // Capture deinit capture_deinit(); // Deinitialize interface ncurses_deinit(); // Deinitialize configuration options deinit_options(); // Deallocate sip stored messages sip_deinit(); // Leaving! return 0; }