void settings_dump() { int i; for (i = 1; i < SETTING_COUNT; i++) { printf("SettingId: %d\t SettingName: %-20s Value: %s\n", i, setting_name(i), setting_get_value(i)); } }
/** * @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]; const char *keyfile; const char *match_expr; int match_insensitive = 0, match_invert = 0; int no_interface = 0, quiet = 0, rtp_capture = 0; vector_t *infiles = vector_create(0, 1); // Program otptions 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", no_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' }, #ifdef USE_EEP { "eep-listen", required_argument, 0, 'L' }, { "eep-send", required_argument, 0, 'H' }, #endif { "quiet", no_argument, 0, 'q' }, }; // Initialize configuration options init_options(); // Get initial values for configurable arguments device = setting_get_value(SETTING_CAPTURE_DEVICE); outfile = setting_get_value(SETTING_CAPTURE_OUTFILE); keyfile = setting_get_value(SETTING_CAPTURE_KEYFILE); 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); // Parse command line arguments opterr = 0; char *options = "hVd:I:O:pqtW:k:crl:ivNqDL:H:"; while ((opt = getopt_long(argc, argv, options, long_options, &idx)) != -1) { switch (opt) { case 'h': usage(); return 0; case 'V': version(); return 0; case 'd': device = 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; #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) case 'k': keyfile = optarg; break; #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; // Dark options for dummy ones case 'p': case 't': case 'W': break; #ifdef USE_EEP case 'L': capture_eep_set_server_url(optarg); break; case 'H': capture_eep_set_client_url(optarg); break; #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); #ifdef USE_EEP // Initialize EEP if enabled capture_eep_init(); #endif // If we have an input file, load it if (vector_count(infiles)) { for (i = 0; i < vector_count(infiles); i++) { // Try to load file if (capture_offline(vector_item(infiles, i), outfile) != 0) return 1; } } else { // Check if all capture data is valid if (capture_online(device, 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); wait_for_input(); } else { setbuf(stdout, NULL); while(capture_get_status() != CAPTURE_OFFLINE) { 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; }
int capture_eep_init() { struct addrinfo *ai, hints[1] = { { 0 } }; // Setting for EEP client if (setting_enabled(SETTING_EEP_SEND)) { // Fill configuration structure eep_cfg.capt_version = setting_get_intvalue(SETTING_EEP_SEND_VER); eep_cfg.capt_host = setting_get_value(SETTING_EEP_SEND_ADDR); eep_cfg.capt_port = setting_get_value(SETTING_EEP_SEND_PORT); eep_cfg.capt_password = setting_get_value(SETTING_EEP_SEND_PASS); eep_cfg.capt_id = 2002; hints->ai_flags = AI_NUMERICSERV; hints->ai_family = AF_UNSPEC; hints->ai_socktype = SOCK_DGRAM; hints->ai_protocol = IPPROTO_UDP; if (getaddrinfo(eep_cfg.capt_host, eep_cfg.capt_port, hints, &ai)) { fprintf(stderr, "EEP client: failed getaddrinfo() for %s:%s\n", eep_cfg.capt_host, eep_cfg.capt_port); return 1; } eep_cfg.client_sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (eep_cfg.client_sock < 0) { fprintf(stderr, "Sender socket creation failed: %s\n", strerror(errno)); return 1; } if (connect(eep_cfg.client_sock, ai->ai_addr, (socklen_t) (ai->ai_addrlen)) == -1) { if (errno != EINPROGRESS) { fprintf(stderr, "Sender socket creation failed: %s\n", strerror(errno)); return 1; } } } if (setting_enabled(SETTING_EEP_LISTEN)) { // Fill configuration structure eep_cfg.capt_srv_version = setting_get_intvalue(SETTING_EEP_LISTEN_VER); eep_cfg.capt_srv_host = setting_get_value(SETTING_EEP_LISTEN_ADDR); eep_cfg.capt_srv_port = setting_get_value(SETTING_EEP_LISTEN_PORT); eep_cfg.capt_srv_password = setting_get_value(SETTING_EEP_LISTEN_PASS); hints->ai_flags = AI_NUMERICSERV; hints->ai_family = AF_UNSPEC; hints->ai_socktype = SOCK_DGRAM; hints->ai_protocol = IPPROTO_UDP; if (getaddrinfo(eep_cfg.capt_srv_host, eep_cfg.capt_srv_port, hints, &ai)) { fprintf(stderr, "EEP server: failed getaddrinfo() for %s:%s\n", eep_cfg.capt_srv_host, eep_cfg.capt_srv_port); return 1; } // Create a socket for a new TCP IPv4 connection eep_cfg.server_sock = socket(AF_INET, SOCK_DGRAM, 0); if (eep_cfg.client_sock < 0) { fprintf(stderr, "Error creating server socket: %s\n", strerror(errno)); return 1; } // Bind that socket to the requested address and port if (bind(eep_cfg.server_sock, ai->ai_addr, ai->ai_addrlen) == -1) { fprintf(stderr, "Error binding address: %s\n", strerror(errno)); return 1; } // Create a new thread for accepting client connections if (pthread_create(&eep_cfg.server_thread, NULL, accept_eep_client, NULL) != 0) { fprintf(stderr, "Error creating accept thread: %s\n", strerror(errno)); return 1; } } // Settings for EEP server return 0; }
PANEL * call_list_create() { PANEL *panel; WINDOW *win; int height, width, i, attrid, collen; call_list_info_t *info; char option[80]; const char *field, *title; // Create a new panel that fill all the screen panel = new_panel(newwin(LINES, COLS, 0, 0)); // Initialize Call List specific data info = sng_malloc(sizeof(call_list_info_t)); // Store it into panel userptr set_panel_userptr(panel, (void*) info); // Add configured columns for (i = 0; i < SIP_ATTR_COUNT; i++) { // Get column attribute name from options sprintf(option, "cl.column%d", i); if ((field = get_option_value(option))) { if ((attrid = sip_attr_from_name(field)) == -1) continue; // Get column width from options sprintf(option, "cl.column%d.width", i); if ((collen = get_option_int_value(option)) == -1) collen = sip_attr_get_width(attrid); // Get column title title = sip_attr_get_title(attrid); // Add column to the list call_list_add_column(panel, attrid, field, title, collen); } } // Let's draw the fixed elements of the screen win = panel_window(panel); getmaxyx(win, height, width); // Initialize the fields info->fields[FLD_LIST_FILTER] = new_field(1, width - 19, 2, 18, 0, 0); info->fields[FLD_LIST_COUNT] = NULL; // Create the form and post it info->form = new_form(info->fields); set_form_sub(info->form, win); // Form starts inactive call_list_form_activate(panel, 0); // Calculate available printable area info->list_win = subwin(win, height - 5, width, 4, 0); info->group = call_group_create(); // Get current call list info->calls = sip_calls_iterator(); vector_iterator_set_filter(&info->calls, filter_check_call); info->cur_call = info->first_call = -1; // Set autoscroll default status info->autoscroll = setting_enabled(SETTING_CL_AUTOSCROLL); // Apply initial configured method filters filter_method_from_setting(setting_get_value(SETTING_FILTER_METHODS)); // Return the created panel return panel; }
PANEL * filter_create() { PANEL *panel; WINDOW *win; int height, width; filter_info_t *info; const char *method; // Calculate window dimensions height = 16; width = 50; // Cerate a new indow for the panel and form win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2); // Create a new panel panel = new_panel(win); // Initialize Filter panel specific data info = sng_malloc(sizeof(filter_info_t)); // Store it into panel userptr set_panel_userptr(panel, (void*) info); // Initialize the fields info->fields[FLD_FILTER_SIPFROM] = new_field(1, 28, 3, 18, 0, 0); info->fields[FLD_FILTER_SIPTO] = new_field(1, 28, 4, 18, 0, 0); info->fields[FLD_FILTER_SRC] = new_field(1, 18, 5, 18, 0, 0); info->fields[FLD_FILTER_DST] = new_field(1, 18, 6, 18, 0, 0); info->fields[FLD_FILTER_PAYLOAD] = new_field(1, 28, 7, 18, 0, 0); info->fields[FLD_FILTER_REGISTER] = new_field(1, 1, 9, 15, 0, 0); info->fields[FLD_FILTER_INVITE] = new_field(1, 1, 10, 15, 0, 0); info->fields[FLD_FILTER_SUBSCRIBE] = new_field(1, 1, 11, 15, 0, 0); info->fields[FLD_FILTER_NOTIFY] = new_field(1, 1, 12, 15, 0, 0); info->fields[FLD_FILTER_OPTIONS] = new_field(1, 1, 9, 37, 0, 0); info->fields[FLD_FILTER_PUBLISH] = new_field(1, 1, 10, 37, 0, 0); info->fields[FLD_FILTER_MESSAGE] = new_field(1, 1, 11, 37, 0, 0); info->fields[FLD_FILTER_FILTER] = new_field(1, 10, height - 2, 11, 0, 0); info->fields[FLD_FILTER_CANCEL] = new_field(1, 10, height - 2, 30, 0, 0); info->fields[FLD_FILTER_COUNT] = NULL; // Set fields options field_opts_off(info->fields[FLD_FILTER_SIPFROM], O_AUTOSKIP); field_opts_off(info->fields[FLD_FILTER_SIPTO], O_AUTOSKIP); field_opts_off(info->fields[FLD_FILTER_SRC], O_AUTOSKIP); field_opts_off(info->fields[FLD_FILTER_DST], O_AUTOSKIP); field_opts_off(info->fields[FLD_FILTER_PAYLOAD], O_AUTOSKIP); field_opts_off(info->fields[FLD_FILTER_REGISTER], O_AUTOSKIP); field_opts_off(info->fields[FLD_FILTER_INVITE], O_AUTOSKIP); field_opts_off(info->fields[FLD_FILTER_SUBSCRIBE], O_AUTOSKIP); field_opts_off(info->fields[FLD_FILTER_NOTIFY], O_AUTOSKIP); field_opts_off(info->fields[FLD_FILTER_OPTIONS], O_AUTOSKIP); field_opts_off(info->fields[FLD_FILTER_PUBLISH], O_AUTOSKIP); field_opts_off(info->fields[FLD_FILTER_MESSAGE], O_AUTOSKIP); field_opts_off(info->fields[FLD_FILTER_FILTER], O_EDIT); field_opts_off(info->fields[FLD_FILTER_CANCEL], O_EDIT); // Change background of input fields set_field_back(info->fields[FLD_FILTER_SIPFROM], A_UNDERLINE); set_field_back(info->fields[FLD_FILTER_SIPTO], A_UNDERLINE); set_field_back(info->fields[FLD_FILTER_SRC], A_UNDERLINE); set_field_back(info->fields[FLD_FILTER_DST], A_UNDERLINE); set_field_back(info->fields[FLD_FILTER_PAYLOAD], A_UNDERLINE); // Create the form and post it info->form = new_form(info->fields); set_form_sub(info->form, win); post_form(info->form); // Fields labels mvwprintw(win, 3, 3, "SIP From:"); mvwprintw(win, 4, 3, "SIP To:"); mvwprintw(win, 5, 3, "Source:"); mvwprintw(win, 6, 3, "Destination:"); mvwprintw(win, 7, 3, "Payload:"); mvwprintw(win, 9, 3, "REGISTER [ ]"); mvwprintw(win, 10, 3, "INVITE [ ]"); mvwprintw(win, 11, 3, "SUBSCRIBE [ ]"); mvwprintw(win, 12, 3, "NOTIFY [ ]"); mvwprintw(win, 9, 25, "OPTIONS [ ]"); mvwprintw(win, 10, 25, "PUBLISH [ ]"); mvwprintw(win, 11, 25, "MESSAGE [ ]"); // Get Method filter if (!(method = filter_get(FILTER_METHOD))) method = setting_get_value(SETTING_FILTER_METHODS); // Set Default field values set_field_buffer(info->fields[FLD_FILTER_SIPFROM], 0, filter_get(FILTER_SIPFROM)); set_field_buffer(info->fields[FLD_FILTER_SIPTO], 0, filter_get(FILTER_SIPTO)); set_field_buffer(info->fields[FLD_FILTER_SRC], 0, filter_get(FILTER_SOURCE)); set_field_buffer(info->fields[FLD_FILTER_DST], 0, filter_get(FILTER_DESTINATION)); set_field_buffer(info->fields[FLD_FILTER_PAYLOAD], 0, filter_get(FILTER_PAYLOAD)); set_field_buffer(info->fields[FLD_FILTER_REGISTER], 0, strcasestr(method, sip_method_str(SIP_METHOD_REGISTER)) ? "*" : ""); set_field_buffer(info->fields[FLD_FILTER_INVITE], 0, strcasestr(method, sip_method_str(SIP_METHOD_INVITE)) ? "*" : ""); set_field_buffer(info->fields[FLD_FILTER_SUBSCRIBE], 0, strcasestr(method,sip_method_str(SIP_METHOD_SUBSCRIBE)) ? "*" : ""); set_field_buffer(info->fields[FLD_FILTER_NOTIFY], 0, strcasestr(method, sip_method_str(SIP_METHOD_NOTIFY)) ? "*" : ""); set_field_buffer(info->fields[FLD_FILTER_OPTIONS], 0, strcasestr(method, sip_method_str(SIP_METHOD_OPTIONS)) ? "*" : ""); set_field_buffer(info->fields[FLD_FILTER_PUBLISH], 0, strcasestr(method, sip_method_str(SIP_METHOD_PUBLISH)) ? "*" : ""); set_field_buffer(info->fields[FLD_FILTER_MESSAGE], 0, strcasestr(method, sip_method_str(SIP_METHOD_MESSAGE)) ? "*" : ""); set_field_buffer(info->fields[FLD_FILTER_FILTER], 0, "[ Filter ]"); set_field_buffer(info->fields[FLD_FILTER_CANCEL], 0, "[ Cancel ]"); // Set the window title and boxes mvwprintw(win, 1, 18, "Filter options"); wattron(win, COLOR_PAIR(CP_BLUE_ON_DEF)); title_foot_box(panel); mvwhline(win, 8, 1, ACS_HLINE, 49); mvwaddch(win, 8, 0, ACS_LTEE); mvwaddch(win, 8, 49, ACS_RTEE); wattroff(win, COLOR_PAIR(CP_BLUE_ON_DEF)); // Set default cursor position set_current_field(info->form, info->fields[FLD_FILTER_SIPFROM]); wmove(win, 3, 18); curs_set(1); return panel; }
void save_create(ui_t *ui) { save_info_t *info; char savepath[128]; // Pause the capture while saving capture_set_paused(1); // Cerate a new indow for the panel and form ui_panel_create(ui, 15, 68); // Initialize save panel specific data info = sng_malloc(sizeof(save_info_t)); // Store it into panel userptr set_panel_userptr(ui->panel, (void*) info); // Initialize the fields int total, displayed; info->fields[FLD_SAVE_PATH] = new_field(1, 52, 3, 13, 0, 0); info->fields[FLD_SAVE_FILE] = new_field(1, 47, 4, 13, 0, 0); info->fields[FLD_SAVE_ALL] = new_field(1, 1, 7, 4, 0, 0); info->fields[FLD_SAVE_SELECTED] = new_field(1, 1, 8, 4, 0, 0); info->fields[FLD_SAVE_DISPLAYED] = new_field(1, 1, 9, 4, 0, 0); info->fields[FLD_SAVE_MESSAGE] = new_field(1, 1, 10, 4, 0, 0); info->fields[FLD_SAVE_PCAP] = new_field(1, 1, 7, 36, 0, 0); info->fields[FLD_SAVE_PCAP_RTP] = new_field(1, 1, 8, 36, 0, 0); info->fields[FLD_SAVE_TXT] = new_field(1, 1, 9, 36, 0, 0); info->fields[FLD_SAVE_SAVE] = new_field(1, 10, ui->height - 2, 20, 0, 0); info->fields[FLD_SAVE_CANCEL] = new_field(1, 10, ui->height - 2, 40, 0, 0); info->fields[FLD_SAVE_COUNT] = NULL; // Set fields options field_opts_off(info->fields[FLD_SAVE_PATH], O_AUTOSKIP); field_opts_off(info->fields[FLD_SAVE_FILE], O_AUTOSKIP); field_opts_off(info->fields[FLD_SAVE_ALL], O_AUTOSKIP); field_opts_off(info->fields[FLD_SAVE_SELECTED], O_AUTOSKIP); field_opts_off(info->fields[FLD_SAVE_DISPLAYED], O_AUTOSKIP); field_opts_off(info->fields[FLD_SAVE_MESSAGE], O_VISIBLE); // Change background of input fields set_field_back(info->fields[FLD_SAVE_PATH], A_UNDERLINE); set_field_back(info->fields[FLD_SAVE_FILE], A_UNDERLINE); // Disable Save RTP if RTP packets are not being captured if (!setting_enabled(SETTING_CAPTURE_RTP)) field_opts_off(info->fields[FLD_SAVE_PCAP_RTP], O_ACTIVE); // Create the form and post it info->form = new_form(info->fields); set_form_sub(info->form, ui->win); post_form(info->form); form_opts_off(info->form, O_BS_OVERLOAD); // Set Default field values sprintf(savepath, "%s", setting_get_value(SETTING_SAVEPATH)); set_field_buffer(info->fields[FLD_SAVE_PATH], 0, savepath); set_field_buffer(info->fields[FLD_SAVE_SAVE], 0, "[ Save ]"); set_field_buffer(info->fields[FLD_SAVE_CANCEL], 0, "[ Cancel ]"); // Set window boxes wattron(ui->win, COLOR_PAIR(CP_BLUE_ON_DEF)); // Window border title_foot_box(ui->panel); // Header and footer lines mvwhline(ui->win, ui->height - 3, 1, ACS_HLINE, ui->width - 1); mvwaddch(ui->win, ui->height - 3, 0, ACS_LTEE); mvwaddch(ui->win, ui->height - 3, ui->width - 1, ACS_RTEE); // Save mode box mvwaddch(ui->win, 6, 2, ACS_ULCORNER); mvwhline(ui->win, 6, 3, ACS_HLINE, 30); mvwaddch(ui->win, 6, 32, ACS_URCORNER); mvwvline(ui->win, 7, 2, ACS_VLINE, 4); mvwvline(ui->win, 7, 32, ACS_VLINE, 4); mvwaddch(ui->win, 11, 2, ACS_LLCORNER); mvwhline(ui->win, 11, 3, ACS_HLINE, 30); mvwaddch(ui->win, 11, 32, ACS_LRCORNER); // Save mode box mvwaddch(ui->win, 6, 34, ACS_ULCORNER); mvwhline(ui->win, 6, 35, ACS_HLINE, 30); mvwaddch(ui->win, 6, 64, ACS_URCORNER); mvwvline(ui->win, 7, 34, ACS_VLINE, 3); mvwvline(ui->win, 7, 64, ACS_VLINE, 3); mvwaddch(ui->win, 10, 34, ACS_LLCORNER); mvwhline(ui->win, 10, 35, ACS_HLINE, 30); mvwaddch(ui->win, 10, 64, ACS_LRCORNER); wattroff(ui->win, COLOR_PAIR(CP_BLUE_ON_DEF)); // Set screen labels mvwprintw(ui->win, 1, 27, "Save capture"); mvwprintw(ui->win, 3, 3, "Path:"); mvwprintw(ui->win, 4, 3, "Filename:"); wattron(ui->win, COLOR_PAIR(CP_BLUE_ON_DEF)); mvwprintw(ui->win, 6, 4, " Dialogs "); mvwprintw(ui->win, 6, 36, " Format "); wattroff(ui->win, COLOR_PAIR(CP_BLUE_ON_DEF)); // Set default cursor position set_current_field(info->form, info->fields[FLD_SAVE_FILE]); form_driver(info->form, REQ_END_LINE); curs_set(1); // Get filter stats sip_stats_t stats = sip_calls_stats(); // Set default save modes info->savemode = (stats.displayed == stats.total) ? SAVE_ALL : SAVE_DISPLAYED; info->saveformat = (setting_enabled(SETTING_CAPTURE_RTP))? SAVE_PCAP_RTP : SAVE_PCAP; }
void sip_init(int limit, int only_calls, int no_incomplete) { int match_flags, reg_rule_len, reg_rule_err; char reg_rule[SIP_ATTR_MAXLEN]; const char *setting = NULL; // Store capture limit calls.limit = limit; calls.only_calls = only_calls; calls.ignore_incomplete = no_incomplete; calls.last_index = 0; // Create a vector to store calls calls.list = vector_create(200, 50); vector_set_destroyer(calls.list, call_destroyer); vector_set_sorter(calls.list, sip_list_sorter); calls.active = vector_create(10, 10); // Create hash table for callid search calls.callids = htable_create(calls.limit); // Set default sorting field if (sip_attr_from_name(setting_get_value(SETTING_CL_SORTFIELD)) >= 0) { calls.sort.by = sip_attr_from_name(setting_get_value(SETTING_CL_SORTFIELD)); calls.sort.asc = (!strcmp(setting_get_value(SETTING_CL_SORTORDER), "asc")); } else { // Fallback to default sorting field calls.sort.by = SIP_ATTR_CALLINDEX; calls.sort.asc = true; } // Initialize payload parsing regexp match_flags = REG_EXTENDED | REG_ICASE | REG_NEWLINE; regcomp(&calls.reg_method, "^([a-zA-Z]+) [a-zA-Z]+:.+ SIP/2.0[ ]*\r", match_flags & ~REG_NEWLINE); regcomp(&calls.reg_callid, "^(Call-ID|i):[ ]*([^ ]+)[ ]*\r$", match_flags); setting = setting_get_value(SETTING_SIP_HEADER_X_CID); reg_rule_len = strlen(setting) + 22; if (reg_rule_len >= SIP_ATTR_MAXLEN) { setting = "X-Call-ID|X-CID"; reg_rule_len = strlen(setting) + 22; fprintf(stderr, "%s setting too long, using default.\n", setting_name(SETTING_SIP_HEADER_X_CID)); } snprintf(reg_rule, reg_rule_len, "^(%s):[ ]*([^ ]+)[ ]*\r$", setting); reg_rule_err = regcomp(&calls.reg_xcallid, reg_rule, match_flags); if(reg_rule_err != 0) { regerror(reg_rule_err, &calls.reg_xcallid, reg_rule, SIP_ATTR_MAXLEN); regfree(&calls.reg_xcallid); fprintf(stderr, "%s setting produces regex compilation error: %s" "using default value instead\n", setting_name(SETTING_SIP_HEADER_X_CID), reg_rule); regcomp(&calls.reg_xcallid, "^(X-Call-ID|X-CID):[ ]*([^ ]+)[ ]*\r$", match_flags); } regcomp(&calls.reg_response, "^SIP/2.0[ ]*(([0-9]{3}) [^\r]*)[ ]*\r", match_flags & ~REG_NEWLINE); regcomp(&calls.reg_cseq, "^CSeq:[ ]*([0-9]{1,10}) .+\r$", match_flags); regcomp(&calls.reg_from, "^(From|f):[ ]*[^:]*:(([^@>]+)@?[^\r>;]+)", match_flags); regcomp(&calls.reg_to, "^(To|t):[ ]*[^:]*:(([^@>]+)@?[^\r>;]+)", match_flags); regcomp(&calls.reg_valid, "^([A-Z]+ [a-zA-Z]+:|SIP/2.0 [0-9]{3})", match_flags & ~REG_NEWLINE); regcomp(&calls.reg_cl, "^(Content-Length|l):[ ]*([0-9]+)[ ]*\r$", match_flags); regcomp(&calls.reg_body, "\r\n\r\n(.*)", match_flags & ~REG_NEWLINE); regcomp(&calls.reg_reason, "Reason:[ ]*[^\r]*;text=\"([^\r]+)\"", match_flags); regcomp(&calls.reg_warning, "Warning:[ ]*([0-9]*)", match_flags); }