Beispiel #1
0
void
sip_init(int limit, int only_calls, int no_incomplete)
{
    int match_flags;

    // 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);

    // By default sort by call index ascending
    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]+) sips?:[^ ]+ SIP/2.0\r", match_flags & ~REG_NEWLINE);
    regcomp(&calls.reg_callid, "^(Call-ID|i):[ ]*([^ ]+)\r$", match_flags);
    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]+) .+\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]+ sip:|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);

}
Beispiel #2
0
vector_t *
vector_clone(vector_t *original)
{
    vector_t *clone;
    vector_iter_t it;
    void *item;

    // Check we have a valid vector pointer
    if (!original)
        return NULL;

    // Create a new vector structure
    clone = vector_create(original->limit, original->step);
    vector_set_destroyer(clone, original->destroyer);
    vector_set_sorter(clone, original->sorter);

    // Fill the clone vector with the same elements
    it = vector_iterator(original);
    while ((item = vector_iterator_next(&it)))
        vector_append(clone, item);

    // Return the cloned vector
    return clone;
}
Beispiel #3
0
int
save_to_file(ui_t *ui)
{
    char savepath[256];
    char savefile[256];
    char fullfile[512];
    sip_call_t *call = NULL;
    sip_msg_t *msg = NULL;
    pcap_dumper_t *pd = NULL;
    FILE *f = NULL;
    int cur = 0, total = 0;
    WINDOW *progress;
    vector_iter_t calls, msgs, rtps, packets;
    packet_t *packet;
    vector_t *sorted;

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

    // Get current path field value.
    memset(savepath, 0, sizeof(savepath));
    strcpy(savepath, field_buffer(info->fields[FLD_SAVE_PATH], 0));
    strtrim(savepath);
    if (strlen(savepath))
        strcat(savepath, "/");

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

    if (!strlen(savefile)) {
        dialog_run("Please enter a valid filename");
        return 1;
    }

    if (info->saveformat == SAVE_PCAP || info->saveformat == SAVE_PCAP_RTP) {
        if (!strstr(savefile, ".pcap"))
            strcat(savefile, ".pcap");
    } else {
        if (!strstr(savefile, ".txt"))
            strcat(savefile, ".txt");
    }

    // Absolute filename
    sprintf(fullfile, "%s%s", savepath, savefile);

    if (access(fullfile, R_OK) == 0) {
        if (dialog_confirm("Overwrite confirmation", "Selected file already exits.\n Do you want to overwrite it?", "Yes,No") != 0)
            return 1;
    }

    // Don't allow to save no packets!
    if (info->savemode == SAVE_SELECTED && call_group_msg_count(info->group) == 0) {
        dialog_run("Unable to save: No selected dialogs.");
        return 1;
    }

    if (info->saveformat == SAVE_PCAP || info->saveformat == SAVE_PCAP_RTP) {
        // Open dump file
        pd = dump_open(fullfile);
        if (access(fullfile, W_OK) != 0) {
            dialog_run(capture_last_error());
            return 1;
        }
    } else {
        // Open a text file
        if (!(f = fopen(fullfile, "w"))) {
            dialog_run("Error: %s", strerror(errno));
            return 0;
        }
    }

    // Get calls iterator
    switch (info->savemode) {
        case SAVE_ALL:
            // Get calls iterator
            calls = sip_calls_iterator();
            break;
        case SAVE_SELECTED:
            // Save selected packets to file
            calls = vector_iterator(info->group->calls);
            break;
        case SAVE_DISPLAYED:
            // Set filtering for this iterator
            calls = sip_calls_iterator();
            vector_iterator_set_filter(&calls, filter_check_call);
            break;
        default:
            break;
    }

    if (info->savemode == SAVE_MESSAGE) {
        if (info->saveformat == SAVE_TXT) {
            // Save selected message to file
            save_msg_txt(f, info->msg);
        } else {
            // Save selected message packet to pcap
            dump_packet(pd, info->msg->packet);
        }
    } else if (info->saveformat == SAVE_TXT) {
        // Save selected packets to file
        while ((call = vector_iterator_next(&calls))) {
            msgs = vector_iterator(call->msgs);
            // Save SIP message content
            while ((msg = vector_iterator_next(&msgs))) {
                save_msg_txt(f, msg);
            }
        }
    } else {
        // Store all messages in a time sorted vector
        sorted = vector_create(100, 50);
        vector_set_sorter(sorted, capture_packet_time_sorter);

        // Count packages for progress bar
        while ((call = vector_iterator_next(&calls))) {
            total += vector_count(call->msgs);
            if (info->saveformat == SAVE_PCAP_RTP)
                total += vector_count(call->rtp_packets);
        }
        vector_iterator_reset(&calls);

        progress = dialog_progress_run("Saving packets...");
        dialog_progress_set_value(progress, 0);

        // Save selected packets to file
        while ((call = vector_iterator_next(&calls))) {
            msgs = vector_iterator(call->msgs);
            // Save SIP message content
            while ((msg = vector_iterator_next(&msgs))) {
                // Update progress bar dialog
                dialog_progress_set_value(progress, (++cur * 100) / total);
                vector_append(sorted, msg->packet);
            }

            // Save RTP packets
            if (info->saveformat == SAVE_PCAP_RTP) {
                rtps = vector_iterator(call->rtp_packets);
                while ((packet = vector_iterator_next(&rtps))) {
                    // Update progress bar dialog
                    dialog_progress_set_value(progress, (++cur * 100) / total);
                    vector_append(sorted, packet);
                }
            }
        }

        // Save sorted packets
        packets = vector_iterator(sorted);
        while ((packet = vector_iterator_next(&packets))) {
            dump_packet(pd, packet);
        }

        dialog_progress_destroy(progress);
    }

    // Close saved file
    if (info->saveformat == SAVE_PCAP || info->saveformat == SAVE_PCAP_RTP) {
        dump_close(pd);
    } else {
        fclose(f);
    }

    // Show success popup
    if (info->savemode == SAVE_MESSAGE) {
      dialog_run("Successfully saved selected SIP message to %s", savefile);
    } else {
      dialog_run("Successfully saved %d dialogs to %s", vector_iterator_count(&calls), savefile);
    }

    return 0;
}
Beispiel #4
0
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);

}