BOOLEAN ui_confirm(const ui_textline_t *text, UINTN width, UINTN height, UINTN x, UINTN y) { ui_events_t event; #ifdef USE_POWER_BUTTON UINTN line_nb, len, row_nb = 0; EFI_STATUS ret; ui_font_t *font; UINTN text_height, scaled_text_height, scaled_text_width, line_height; font = ui_font_get_default(); if (!font) { error(L"Default font not available"); return FALSE; } for (line_nb = 0; text[line_nb].str; line_nb++) { len = strlen((CHAR8 *)text[line_nb].str); row_nb = row_nb < len ? len : row_nb; } if (!line_nb || !row_nb) { error(L"Invalid text for ui_confirm"); return FALSE; } text_height = line_nb * height / (line_nb + ARRAY_SIZE(yes_no_menu)); ret = ui_textarea_display_text(text, font, x, &y, width, text_height, NULL); if (EFI_ERROR(ret)) return FALSE; ui_get_scaled_dimension((row_nb * font->cwidth), (line_nb * font->cheight), width, text_height, &scaled_text_width, &scaled_text_height); line_height = scaled_text_height / line_nb; ret = ui_confirm_draw_menu(font, x, y, scaled_text_width, line_height); if (EFI_ERROR(ret)) return FALSE; for (;;) { event = ui_wait_for_input(TIMEOUT_SECS); switch (event) { case EV_UP: case EV_DOWN: current = (current + 1) % ARRAY_SIZE(yes_no_menu); ret = ui_confirm_draw_menu(font, x, y, scaled_text_width, line_height); if (EFI_ERROR(ret)) return FALSE; break; case EV_POWER: ui_wait_for_key_release(); return !current; default: break; } } #else const ui_textline_t *texts[] = {text, yes_no_text, NULL}; ui_display_texts(texts, x, y, width, height); event = ui_wait_for_input(TIMEOUT_SECS); return event == EV_UP ? TRUE : FALSE; #endif }
/** * @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; }