示例#1
0
文件: ui_save.c 项目: cruzccl/sngrep
int
save_draw(ui_t *ui)
{
    char field_value[80];

    // Get panel information
    save_info_t *info = save_info(ui);

    // Get filter stats
    sip_stats_t stats = sip_calls_stats();

    mvwprintw(ui->win, 7, 3, "( ) all dialogs ");
    mvwprintw(ui->win, 8, 3, "( ) selected dialogs [%d]", call_group_count(info->group));
    mvwprintw(ui->win, 9, 3, "( ) filtered dialogs [%d]", stats.displayed);

    // Print 'current SIP message' field label if required
    if (info->msg != NULL)
        mvwprintw(ui->win, 10, 3, "( ) current SIP message");

    mvwprintw(ui->win, 7, 35, "( ) .pcap (SIP)");
    mvwprintw(ui->win, 8, 35, "( ) .pcap (SIP + RTP)");
    mvwprintw(ui->win, 9, 35, "( ) .txt");

    // Get filename field value.
    memset(field_value, 0, sizeof(field_value));
    strcpy(field_value, field_buffer(info->fields[FLD_SAVE_FILE], 0));
    strtrim(field_value);

    mvwprintw(ui->win, 4, 60, "     ");
    if (strstr(field_value, ".pcap")) {
        info->saveformat = (setting_enabled(SETTING_CAPTURE_RTP))? SAVE_PCAP_RTP : SAVE_PCAP;
    } else if (strstr(field_value, ".txt")) {
        info->saveformat = SAVE_TXT;
    } else {
        if (info->saveformat == SAVE_PCAP || info->saveformat == SAVE_PCAP_RTP)
            mvwprintw(ui->win, 4, 60, ".pcap");
        else
            mvwprintw(ui->win, 4, 60, ".txt ");
    }

    set_field_buffer(info->fields[FLD_SAVE_ALL], 0, (info->savemode == SAVE_ALL) ? "*" : " ");
    set_field_buffer(info->fields[FLD_SAVE_SELECTED], 0,
                     (info->savemode == SAVE_SELECTED) ? "*" : " ");
    set_field_buffer(info->fields[FLD_SAVE_DISPLAYED], 0,
                     (info->savemode == SAVE_DISPLAYED) ? "*" : " ");
    set_field_buffer(info->fields[FLD_SAVE_MESSAGE], 0,
                     (info->savemode == SAVE_MESSAGE) ? "*" : " ");
    set_field_buffer(info->fields[FLD_SAVE_PCAP], 0, (info->saveformat == SAVE_PCAP) ? "*" : " ");
    set_field_buffer(info->fields[FLD_SAVE_PCAP_RTP], 0, (info->saveformat == SAVE_PCAP_RTP) ? "*" : " ");
    set_field_buffer(info->fields[FLD_SAVE_TXT], 0, (info->saveformat == SAVE_TXT) ? "*" : " ");

    // Show disabled options with makers
    if (!setting_enabled(SETTING_CAPTURE_RTP))
        set_field_buffer(info->fields[FLD_SAVE_PCAP_RTP], 0, "-");

    set_current_field(info->form, current_field(info->form));
    form_driver(info->form, REQ_VALIDATION);

    return 0;
}
示例#2
0
sip_call_t *
call_create(char *callid, char *xcallid)
{
    sip_call_t *call;

    // Initialize a new call structure
    if (!(call = sng_malloc(sizeof(sip_call_t))))
        return NULL;

    // Create a vector to store call messages
    call->msgs = vector_create(2, 2);
    vector_set_destroyer(call->msgs, msg_destroyer);

    // Create an empty vector to store rtp packets
    if (setting_enabled(SETTING_CAPTURE_RTP)) {
        call->rtp_packets = vector_create(0, 40);
        vector_set_destroyer(call->rtp_packets, packet_destroyer);
    }

    // Create an empty vector to strore stream data
    call->streams = vector_create(0, 2);
    vector_set_destroyer(call->streams, vector_generic_destroyer);

    // Create an empty vector to store x-calls
    call->xcalls = vector_create(0, 1);

    // Initialize call filter status
    call->filtered = -1;

    // Set message callid
    call->callid = strdup(callid);
    call->xcallid = strdup(xcallid);

    return call;
}
示例#3
0
const char *
lookup_hostname(const char *address)
{
    int i;
    int hostlen;
    in_addr_t netaddress;
    struct hostent *host;
    const char *hostname;

    // No lookup enabled, return address as is
    if (!setting_enabled(SETTING_CAPTURE_LOOKUP))
        return address;

    // Check if we have already tryied resolve this address
    for (i = 0; i < capinfo.dnscache.count; i++) {
        if (!strcmp(capinfo.dnscache.addr[i], address)) {
            return capinfo.dnscache.hostname[i];
        }
    }

    // Convert the address to network byte order
    if ((netaddress = inet_addr(address)) == -1)
        return address;

    // Lookup this addres
    host = gethostbyaddr(&netaddress, sizeof(netaddress), AF_INET);
    if (!host) {
        hostname = address;
    } else {
        hostname = host->h_name;
    }

    // Max hostname length set to 16 chars
    hostlen = strlen(hostname);

    // Store this result in the dnscache
    strcpy(capinfo.dnscache.addr[capinfo.dnscache.count], address);
    strncpy(capinfo.dnscache.hostname[capinfo.dnscache.count], hostname, hostlen);
    capinfo.dnscache.count++;

    // Return the stored value
    return capinfo.dnscache.hostname[capinfo.dnscache.count - 1];
}
示例#4
0
文件: main.c 项目: cukupupas/sngrep
/**
 * @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;
}
示例#5
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;
}
示例#6
0
int
draw_message_pos(WINDOW *win, sip_msg_t *msg, int starting)
{
    int height, width, line, column, i;
    const char *cur_line, *payload;
    int syntax = setting_enabled(SETTING_SYNTAX);

    // Default text format
    int attrs = A_NORMAL | COLOR_PAIR(CP_DEFAULT);
    if (syntax)
        wattrset(win, attrs);

    // Get window of main panel
    getmaxyx(win, height, width);

    // Get packet payload
    cur_line = payload = (const char *) msg_get_payload(msg);

    // Print msg payload
    line = starting;
    column = 0;
    for (i = 0; i < strlen(payload); i++) {
        // If syntax highlighting is enabled
        if (syntax) {
            // First line highlight
            if (line == starting) {
                // Request syntax
                if (i == 0 && strncmp(cur_line, "SIP/2.0", 7))
                    attrs = A_BOLD | COLOR_PAIR(CP_YELLOW_ON_DEF);

                // Response syntax
                if (i == 8 && !strncmp(cur_line, "SIP/2.0", 7))
                    attrs = A_BOLD | COLOR_PAIR(CP_RED_ON_DEF);

                // SIP URI syntax
                if (!strncasecmp(payload + i, "sip:", 4)) {
                    attrs = A_BOLD | COLOR_PAIR(CP_CYAN_ON_DEF);
                }
            } else {

                // Header syntax
                if (strchr(cur_line, ':') && payload + i < strchr(cur_line, ':'))
                    attrs = A_NORMAL | COLOR_PAIR(CP_GREEN_ON_DEF);

                // Call-ID Header syntax
                if (!strncasecmp(cur_line, "Call-ID:", 8) && column > 8)
                    attrs = A_BOLD | COLOR_PAIR(CP_MAGENTA_ON_DEF);

                // CSeq Heaedr syntax
                if (!strncasecmp(cur_line, "CSeq:", 5) && column > 5 && !isdigit(payload[i]))
                    attrs = A_NORMAL | COLOR_PAIR(CP_YELLOW_ON_DEF);

                // tag and branch syntax
                if (i > 0 && payload[i - 1] == ';') {
                    // Highlight branch if requested
                    if (setting_enabled(SETTING_SYNTAX_BRANCH)) {
                        if (!strncasecmp(payload + i, "branch", 6)) {
                            attrs = A_BOLD | COLOR_PAIR(CP_CYAN_ON_DEF);
                        }
                    }
                    // Highlight tag if requested
                    if (setting_enabled(SETTING_SYNTAX_TAG)) {
                        if (!strncasecmp(payload + i, "tag", 3)) {
                            if (!strncasecmp(cur_line, "From:", 5)) {
                                attrs = A_BOLD | COLOR_PAIR(CP_DEFAULT);
                            } else {
                                attrs = A_BOLD | COLOR_PAIR(CP_GREEN_ON_DEF);
                            }
                        }
                    }
                }

                // SDP syntax
                if (strcspn(cur_line, "=") == 1)
                    attrs = A_NORMAL | COLOR_PAIR(CP_DEFAULT);
            }

            // Remove previous syntax
            if (strcspn(payload + i, " \n;<>") == 0) {
                wattroff(win, attrs);
                attrs = A_NORMAL | COLOR_PAIR(CP_DEFAULT);
            }

            // Syntax hightlight text!
            wattron(win, attrs);
        }

        // Dont print this characters
        if (payload[i] == '\r')
            continue;

        // Store where the line begins
        if (payload[i] == '\n')
            cur_line =payload + i + 1;

        // Move to the next line if line is filled or a we reach a line break
        if (column > width || payload[i] == '\n') {
            line++;
            column = 0;
            continue;
        }

        // Put next character in position
        mvwaddch(win, line, column++, payload[i]);

        // Stop if we've reached the bottom of the window
        if (line == height)
            break;
    }

    // Disable syntax when leaving
    if (syntax)
        wattroff(win, attrs);

    // Redraw raw win
    wnoutrefresh(win);

    return line - starting;
}
示例#7
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;
}
示例#8
0
int
call_list_handle_key(PANEL *panel, int key)
{
    int i, height, width, rnpag_steps = setting_get_intvalue(SETTING_CL_SCROLLSTEP);
    call_list_info_t *info;
    ui_t *next_panel;
    sip_call_group_t *group;
    int action = -1;
    sip_call_t *call;

    // Sanity check, this should not happen
    if (!(info  = call_list_info(panel)))
        return -1;

    // Handle form key
    if (info->form_active)
        return call_list_handle_form_key(panel, key);

    // Get window of call list panel
    WINDOW *win = info->list_win;
    getmaxyx(win, height, width);

    // Reset iterator position to current call
    vector_iterator_set_current(&info->calls, info->cur_call);

    // Check actions for this key
    while ((action = key_find_action(key, action)) != ERR) {
        // Check if we handle this action
        switch (action) {
            case ACTION_DOWN:
                // Check if there is a call below us
                if (!vector_iterator_next(&info->calls))
                    break;
                info->cur_call = vector_iterator_current(&info->calls);
                info->cur_line++;
                // If we are out of the bottom of the displayed list
                // refresh it starting in the next call
                if (info->cur_line > height) {
                    vector_iterator_set_current(&info->calls, info->first_call);
                    vector_iterator_next(&info->calls);
                    info->first_call = vector_iterator_current(&info->calls);
                    info->first_line++;
                    info->cur_line = height;
                }
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_UP:
                // Check if there is a call above us
                if (!vector_iterator_prev(&info->calls))
                    break;
                info->cur_call = vector_iterator_current(&info->calls);
                info->cur_line--;
                // If we are out of the top of the displayed list
                // refresh it starting in the previous (in fact current) call
                if (info->cur_line <= 0) {
                    info->first_call = info->cur_call;
                    info->first_line--;
                    info->cur_line = 1;
                }
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_HNPAGE:
                rnpag_steps = rnpag_steps / 2;
                /* no break */
            case ACTION_NPAGE:
                // Next page => N key down strokes
                for (i = 0; i < rnpag_steps; i++)
                    call_list_handle_key(panel, KEY_DOWN);
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_HPPAGE:
                rnpag_steps = rnpag_steps / 2;
                /* no break */
            case ACTION_PPAGE:
                // Prev page => N key up strokes
                for (i = 0; i < rnpag_steps; i++)
                    call_list_handle_key(panel, KEY_UP);
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_BEGIN:
                // Initialize structures
                info->first_call = info->cur_call = -1;
                info->first_line = info->cur_line = 0;
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_END:
                // Check if there is a call below us
                while (vector_iterator_next(&info->calls)) {
                    info->cur_call = vector_iterator_current(&info->calls);
                    info->cur_line++;
                    // If we are out of the bottom of the displayed list
                    // refresh it starting in the next call
                    if (info->cur_line > height) {
                        vector_iterator_set_current(&info->calls, info->first_call);
                        vector_iterator_next(&info->calls);
                        info->first_call = vector_iterator_current(&info->calls);
                        info->first_line++;
                        info->cur_line = height;
                        vector_iterator_set_current(&info->calls, info->cur_call);
                    }
                }
                break;
            case ACTION_DISP_FILTER:
                // Activate Form
                call_list_form_activate(panel, 1);
                // Disable Autoscroll
                info->autoscroll = 0;
                break;
            case ACTION_SHOW_FLOW:
            case ACTION_SHOW_FLOW_EX:
            case ACTION_SHOW_RAW:
                // Check we have calls in the list
                if (info->cur_call == -1)
                    break;
                // Create a new group of calls
                group = call_group_clone(info->group);
                // If not selected call, show current call flow
                if (call_group_count(info->group) == 0)
                    call_group_add(group, sip_find_by_index(info->cur_call));

                // Add xcall to the group
                if (action == ACTION_SHOW_FLOW_EX)
                    call_group_add(group, call_get_xcall(sip_find_by_index(info->cur_call)));

                if (action == ACTION_SHOW_RAW) {
                    // Create a Call Flow panel
                    ui_create_panel(PANEL_CALL_RAW);
                    call_raw_set_group(group);
                } else {
                    // Display current call flow (normal or extended)
                    ui_create_panel(PANEL_CALL_FLOW);
                    call_flow_set_group(group);
                }
                break;
            case ACTION_SHOW_FILTERS:
                ui_create_panel(PANEL_FILTER);
                break;
            case ACTION_SHOW_COLUMNS:
                ui_create_panel(PANEL_COLUMN_SELECT);
                break;
            case ACTION_SHOW_STATS:
                ui_create_panel(PANEL_STATS);
                break;
            case ACTION_SAVE:
                next_panel = ui_create_panel(PANEL_SAVE);
                save_set_group(ui_get_panel(next_panel), info->group);
                break;
            case ACTION_CLEAR:
                // Clear group calls
                vector_clear(info->group->calls);
                break;
            case ACTION_CLEAR_CALLS:
                // Remove all stored calls
                sip_calls_clear();
                // Clear List
                call_list_clear(panel);
                break;
            case ACTION_AUTOSCROLL:
                info->autoscroll = (info->autoscroll) ? 0 : 1;
                break;
            case ACTION_SHOW_SETTINGS:
                ui_create_panel(PANEL_SETTINGS);
                break;
            case ACTION_SELECT:
                call = vector_item(vector_iterator_vector(&info->calls), info->cur_call);
                if (call_group_exists(info->group, call)) {
                    call_group_del(info->group, call);
                } else {
                    call_group_add(info->group, call);
                }
                break;
            case ACTION_PREV_SCREEN:
                // Handle quit from this screen unless requested
                if (setting_enabled(SETTING_EXITPROMPT)) {
                    if (dialog_confirm("Confirm exit", "Are you sure you want to quit?", "Yes,No") == 0) {
                        return KEY_ESC;
                    } else {
                        return 0;
                    }
                } else {
                    return KEY_ESC;
                }
                break;
            default:
                // Parse next action
                continue;
        }

        // This panel has handled the key successfully
        break;
    }

    // Return if this panel has handled or not the key
    return (action == ERR) ? key : 0;
}
示例#9
0
文件: ui_save.c 项目: cruzccl/sngrep
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;

}