예제 #1
0
파일: group.c 프로젝트: romkazor/sngrep
sip_msg_t *
call_group_get_next_msg(sip_call_group_t *group, sip_msg_t *msg)
{
    sip_msg_t *next = NULL;
    sip_msg_t *cand;
    vector_iter_t msgs;
    sip_call_t *call;
    int i;

    for (i = 0; i < vector_count(group->calls); i++) {

        call = vector_item(group->calls, i);
        msgs = vector_iterator(call->msgs);

        if (msg && call == msg_get_call(msg))
            vector_iterator_set_current(&msgs, msg->index);

        if (group->sdp_only)
            vector_iterator_set_filter(&msgs, msg_has_sdp);

        cand = NULL;
        while ((cand = vector_iterator_next(&msgs))) {
            // candidate must be between msg and next
            if (msg_is_older(cand, msg) && (!next || !msg_is_older(cand, next))) {
                next = cand;
                break;
            }
        }
    }

    return sip_parse_msg(next);
}
예제 #2
0
파일: capture.c 프로젝트: cruzccl/sngrep
void
capture_close()
{
    capture_info_t *capinfo;

    // Nothing to close
    if (vector_count(capture_cfg.sources) == 0)
        return;

    // Stop all captures
    vector_iter_t it = vector_iterator(capture_cfg.sources);
    while ((capinfo = vector_iterator_next(&it))) {
        //Close PCAP file
        if (capinfo->handle) {
            pcap_breakloop(capinfo->handle);
            pthread_join(capinfo->capture_t, NULL);
            pcap_close(capinfo->handle);
        }
    }

    // Close dump file
    if (capture_cfg.pd) {
        dump_close(capture_cfg.pd);
    }
}
예제 #3
0
파일: group.c 프로젝트: romkazor/sngrep
rtp_stream_t *
call_group_get_next_stream(sip_call_group_t *group, rtp_stream_t *stream)
{
    rtp_stream_t *next = NULL;
    rtp_stream_t *cand;
    sip_call_t *call;
    vector_iter_t streams;
    int i;

    for (i = 0; i < vector_count(group->calls); i++) {
        call = vector_item(group->calls, i);
        streams = vector_iterator(call->streams);
        while ( (cand = vector_iterator_next(&streams))) {
            if (!stream_get_count(cand))
                continue;

            // candidate must be between msg and next
            if (stream_is_older(cand, stream) && (!next || stream_is_older(next, cand))) {
                next = cand;
            }
        }
    }

    return next;
}
예제 #4
0
int iterator_erase(Vector* vector, Iterator* iterator) {
    size_t index = iterator_index(vector, iterator);

    if (vector_erase(vector, index) == VECTOR_ERROR) {
        return VECTOR_ERROR;
    }

    *iterator = vector_iterator(vector, index);

    return VECTOR_SUCCESS;
}
예제 #5
0
파일: capture.c 프로젝트: cruzccl/sngrep
void
dump_packet(pcap_dumper_t *pd, const packet_t *packet)
{
    if (!pd || !packet)
        return;

    vector_iter_t it = vector_iterator(packet->frames);
    frame_t *frame;
    while ((frame = vector_iterator_next(&it))) {
        pcap_dump((u_char*) pd, frame->header, frame->data);
    }
    pcap_dump_flush(pd);
}
예제 #6
0
파일: media.c 프로젝트: cukupupas/sngrep
const char *
media_get_format(sdp_media_t *media, uint32_t code)
{
    sdp_media_fmt_t *format;
    vector_iter_t iter;
    iter = vector_iterator(media->formats);
    while ((format = vector_iterator_next(&iter))) {
        if (format->id == code)
            return format->format;
    }

    return "Unassigned";
}
예제 #7
0
파일: sip.c 프로젝트: digitainc/sngrep
sip_stats_t
sip_calls_stats()
{
    sip_stats_t stats;
    vector_iter_t it = vector_iterator(calls.list);

    // Total number of calls without filtering
    stats.total = vector_iterator_count(&it);
    // Total number of calls after filtering
    vector_iterator_set_filter(&it, filter_check_call);
    stats.displayed = vector_iterator_count(&it);
    return stats;
}
예제 #8
0
char *test_iterator_empty()
{
  vector_p vector = vector_create(sizeof(int));
  int iterations = 0;;
  
  iterator_p iterator = vector_iterator(vector);
  while(iterator_next(iterator))
  {
    iterations++;
  }

  mu_assert(iterations == 0, "should not have iterated");

  return NULL;
}
예제 #9
0
파일: sip.c 프로젝트: irontec/sngrep
void
sip_calls_rotate()
{
    sip_call_t *call;
    vector_iter_t it = vector_iterator(calls.list);
    while ((call = vector_iterator_next(&it))) {
        if (!call->locked) {
            // Remove from callids hash
            htable_remove(calls.callids, call->callid);
            // Remove first call from active and call lists
            vector_remove(calls.active, call);
            vector_remove(calls.list, call);
            return;
        }
    }
}
예제 #10
0
int
call_msg_is_retrans(sip_msg_t *msg)
{
    sip_msg_t *prev = NULL;
    vector_iter_t it;

    // Get previous message in call with same origin and destination
    it = vector_iterator(msg->call->msgs);
    vector_iterator_set_current(&it, vector_index(msg->call->msgs, msg));
    while ((prev = vector_iterator_prev(&it))) {
        if (!strcmp(SRC(prev), SRC(msg)) && !strcmp(DST(prev), DST(msg)))
            break;
    }

    return (prev && !strcasecmp(msg_get_payload(msg), msg_get_payload(prev)));
}
예제 #11
0
파일: group.c 프로젝트: romkazor/sngrep
int
call_group_msg_count(sip_call_group_t *group)
{
    sip_call_t *call;
    vector_iter_t msgs;
    int msgcnt = 0, i;

    for (i = 0; i < vector_count(group->calls); i++) {
        call = vector_item(group->calls, i);
        msgs = vector_iterator(call->msgs);
        if (group->sdp_only) {
            vector_iterator_set_filter(&msgs, msg_has_sdp);
        }
        msgcnt += vector_iterator_count(&msgs);
    }
    return msgcnt;
}
예제 #12
0
파일: sip_call.c 프로젝트: digitainc/sngrep
int
call_msg_is_retrans(sip_msg_t *msg)
{
    sip_msg_t *prev = NULL;
    vector_iter_t it;

    // Get previous message in call with same origin and destination
    it = vector_iterator(msg->call->msgs);
    vector_iterator_set_current(&it, vector_index(msg->call->msgs, msg));
    while ((prev = vector_iterator_prev(&it))) {
        if (addressport_equals(prev->packet->src, msg->packet->src) &&
                addressport_equals(prev->packet->dst, msg->packet->dst))
            break;
    }

    return (prev && !strcasecmp(msg_get_payload(msg), msg_get_payload(prev)));
}
예제 #13
0
파일: capture.c 프로젝트: cruzccl/sngrep
int
capture_launch_thread(capture_info_t *capinfo)
{
    //! capture thread attributes
    pthread_attr_t attr;
    pthread_attr_init(&attr);

    // Start all captures threads
    vector_iter_t it = vector_iterator(capture_cfg.sources);
    while ((capinfo = vector_iterator_next(&it))) {
        if (pthread_create(&capinfo->capture_t, &attr, (void *) capture_thread, capinfo)) {
            return 1;
        }
    }

    pthread_attr_destroy(&attr);
    return 0;
}
예제 #14
0
파일: capture.c 프로젝트: cruzccl/sngrep
int
capture_set_bpf_filter(const char *filter)
{
    vector_iter_t it = vector_iterator(capture_cfg.sources);
    capture_info_t *capinfo;

    // Apply the given filter to all sources
    while ((capinfo = vector_iterator_next(&it))) {
        //! Check if filter compiles
        if (pcap_compile(capinfo->handle, &capture_cfg.fp, filter, 0, capinfo->mask) == -1)
            return 1;

        // Set capture filter
        if (pcap_setfilter(capinfo->handle, &capture_cfg.fp) == -1)
            return 1;

    }

    return 0;
}
예제 #15
0
파일: sip.c 프로젝트: irontec/sngrep
void
sip_calls_clear_soft()
{
        // Create again the callid hash table
        htable_destroy(calls.callids);
        calls.callids = htable_create(calls.limit);

        // Repopulate list applying current filter
        calls.list = vector_copy_if(sip_calls_vector(), filter_check_call);
        calls.active = vector_copy_if(sip_active_calls_vector(), filter_check_call);

        // Repopulate callids based on filtered list
        sip_call_t *call;
        vector_iter_t it = vector_iterator(calls.list);

        while ((call = vector_iterator_next(&it)))
        {
                htable_insert(calls.callids, call->callid, call);
        }
}
예제 #16
0
char *test_iterator()
{
  vector_p vector = vector_create(sizeof(int));
  vector_add(vector, test_data(10));
  vector_add(vector, test_data(20));

  int total = 0;
  int iterations = 0;
  
  iterator_p iterator = vector_iterator(vector);
  while(iterator_next(iterator))
  {
    total += *(int*)iterator->current;
    iterations++;
  }

  mu_assert(total == 30, "should have visited each item in the vector");
  mu_assert(iterations == 2, "should have visited 2 items");

  vector_free(vector);
  return NULL;
}
예제 #17
0
파일: vector.c 프로젝트: romkazor/sngrep
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;
}
예제 #18
0
파일: capture.c 프로젝트: cruzccl/sngrep
packet_t *
capture_packet_reasm_tcp(packet_t *packet, struct tcphdr *tcp, u_char *payload, int size_payload) {

    vector_iter_t it = vector_iterator(capture_cfg.tcp_reasm);
    packet_t *pkt;
    u_char *new_payload;

    //! Assembled
    if ((int32_t) size_payload <= 0)
        return packet;

    while ((pkt = vector_iterator_next(&it))) {
        if (addressport_equals(pkt->src, packet->src) &&
                addressport_equals(pkt->dst, packet->dst)) {
            break;
        }
    }

    // If we already have this packet stored
    if (pkt) {
        frame_t *frame;
        // Append this frames to the original packet
        vector_iter_t frames = vector_iterator(packet->frames);
        while ((frame = vector_iterator_next(&frames)))
            packet_add_frame(pkt, frame->header, frame->data);
        // Destroy current packet as its frames belong to the stored packet
        packet_destroy(packet);
    } else {
        // First time this packet has been seen
        pkt = packet;
        // Add To the possible reassembly list
        vector_append(capture_cfg.tcp_reasm, packet);
    }

    // Store firt tcp sequence
    if (pkt->tcp_seq == 0) {
        pkt->tcp_seq = ntohl(tcp->th_seq);
    }

    // If the first frame of this packet
    if (vector_count(pkt->frames) == 1) {
        // Set initial payload
        packet_set_payload(pkt, payload, size_payload);
    } else {
        // Check payload length. Dont handle too big payload packets
        if (pkt->payload_len + size_payload > MAX_CAPTURE_LEN) {
            packet_destroy(pkt);
            vector_remove(capture_cfg.tcp_reasm, pkt);
            return NULL;
        }
        new_payload = sng_malloc(pkt->payload_len + size_payload);
        if (pkt->tcp_seq < ntohl(tcp->th_seq)) {
            // Append payload to the existing
            pkt->tcp_seq =  ntohl(tcp->th_seq);
            memcpy(new_payload, pkt->payload, pkt->payload_len);
            memcpy(new_payload + pkt->payload_len, payload, size_payload);
        } else {
            // Prepend payload to the existing
            memcpy(new_payload, payload, size_payload);
            memcpy(new_payload + size_payload, pkt->payload, pkt->payload_len);
        }
        packet_set_payload(pkt, new_payload, pkt->payload_len + size_payload);
        sng_free(new_payload);

    }

    // This packet is ready to be parsed
    int valid = sip_validate_packet(pkt);
    if (valid == VALIDATE_COMPLETE_SIP) {
        // Full SIP packet!
        vector_remove(capture_cfg.tcp_reasm, pkt);
        return pkt;
    } else if (valid == VALIDATE_NOT_SIP) {
        vector_remove(capture_cfg.tcp_reasm, pkt);
        return pkt;
    }

    // An incomplete SIP Packet
    return NULL;
}
예제 #19
0
파일: ui_save.c 프로젝트: cruzccl/sngrep
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;
}
예제 #20
0
파일: sip.c 프로젝트: digitainc/sngrep
vector_iter_t
sip_active_calls_iterator()
{
    return vector_iterator(calls.active);
}
예제 #21
0
파일: sip.c 프로젝트: digitainc/sngrep
vector_iter_t
sip_calls_iterator()
{
    return vector_iterator(calls.list);
}
예제 #22
0
/* Iterators */
Iterator vector_begin(Vector* vector) {
    return vector_iterator(vector, 0);
}
예제 #23
0
파일: capture.c 프로젝트: cruzccl/sngrep
packet_t *
capture_packet_reasm_ip(capture_info_t *capinfo, const struct pcap_pkthdr *header, u_char *packet, uint32_t *size, uint32_t *caplen)
{
    // IP header data
    struct ip *ip4;
#ifdef USE_IPV6
    // IPv6 header data
    struct ip6_hdr *ip6;
#endif
    // IP version
    uint32_t ip_ver;
    // IP protocol
    uint8_t ip_proto;
    // IP header size
    uint32_t ip_hl = 0;
    // Fragment offset
    uint16_t ip_off = 0;
    // IP content len
    uint16_t ip_len = 0;
    // Fragmentation flag
    uint16_t ip_frag = 0;
    // Fragmentation identifier
    uint32_t ip_id = 0;
    // Fragmentation offset
    uint16_t ip_frag_off = 0;
    //! Source Address
    address_t src = { };
    //! Destination Address
    address_t dst = { };
    //! Common interator for vectors
    vector_iter_t it;
    //! Packet containers
    packet_t *pkt;
    //! Storage for IP frame
    frame_t *frame;
    uint32_t len_data = 0;

    // Get IP header
    ip4 = (struct ip *) (packet + capinfo->link_hl);

#ifdef USE_IPV6
    // Get IPv6 header
    ip6 = (struct ip6_hdr *) (packet + capinfo->link_hl);
#endif

    // Get IP version
    ip_ver = ip4->ip_v;

    switch (ip_ver) {
        case 4:
            ip_hl = ip4->ip_hl * 4;
            ip_proto = ip4->ip_p;
            ip_off = ntohs(ip4->ip_off);
            ip_len = ntohs(ip4->ip_len);

            ip_frag = ip_off & (IP_MF | IP_OFFMASK);
            ip_frag_off = (ip_frag) ? (ip_off & IP_OFFMASK) * 8 : 0;
            ip_id = ntohs(ip4->ip_id);

            inet_ntop(AF_INET, &ip4->ip_src, src.ip, sizeof(src.ip));
            inet_ntop(AF_INET, &ip4->ip_dst, dst.ip, sizeof(dst.ip));
            break;
#ifdef USE_IPV6
        case 6:
            ip_hl = sizeof(struct ip6_hdr);
            ip_proto = ip6->ip6_nxt;
            ip_len = ntohs(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen) + ip_hl;

            if (ip_proto == IPPROTO_FRAGMENT) {
                struct ip6_frag *ip6f = (struct ip6_frag *) (ip6 + ip_hl);
                ip_frag_off = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK);
                ip_id = ntohl(ip6f->ip6f_ident);
            }

            inet_ntop(AF_INET6, &ip6->ip6_src, src.ip, sizeof(src.ip));
            inet_ntop(AF_INET6, &ip6->ip6_dst, dst.ip, sizeof(dst.ip));
            break;
#endif
        default:
            return NULL;
    }

    // Fixup VSS trailer in ethernet packets
    *caplen = capinfo->link_hl + ip_len;

    // Remove IP Header length from payload
    *size = *caplen - capinfo->link_hl - ip_hl;

    // If no fragmentation
    if (ip_frag == 0) {
        // Just create a new packet with given network data
        pkt = packet_create(ip_ver, ip_proto, src, dst, ip_id);
        packet_add_frame(pkt, header, packet);
        return pkt;
    }

    // Look for another packet with same id in IP reassembly vector
    it = vector_iterator(capture_cfg.ip_reasm);
    while ((pkt = vector_iterator_next(&it))) {
        if (addressport_equals(pkt->src, src)
                && addressport_equals(pkt->dst, dst)
                && pkt->ip_id == ip_id) {
            break;
        }
    }

    // If we already have this packet stored, append this frames to existing one
    if (pkt) {
        packet_add_frame(pkt, header, packet);
    } else {
        // Add To the possible reassembly list
        pkt = packet_create(ip_ver, ip_proto, src, dst, ip_id);
        packet_add_frame(pkt, header, packet);
        vector_append(capture_cfg.ip_reasm, pkt);
        return NULL;
    }

    // If no more fragments
    if ((ip_off & IP_MF) == 0) {
        // TODO Dont check the flag, check the holes
        // Calculate assembled IP payload data
        it = vector_iterator(pkt->frames);
        while ((frame = vector_iterator_next(&it))) {
            struct ip *frame_ip = (struct ip *) (frame->data + capinfo->link_hl);
            len_data += frame->header->caplen - capinfo->link_hl - frame_ip->ip_hl * 4;
        }

        // Check packet content length
        if (len_data > MAX_CAPTURE_LEN)
            return NULL;

        // Initialize memory for the assembly packet
        memset(packet, 0, capinfo->link_hl + ip_hl + len_data);

        it = vector_iterator(pkt->frames);
        while ((frame = vector_iterator_next(&it))) {
            // Get IP header
            struct ip *frame_ip = (struct ip *) (frame->data + capinfo->link_hl);
            memcpy(packet + capinfo->link_hl + ip_hl + (ntohs(frame_ip->ip_off) & IP_OFFMASK) * 8,
                   frame->data + capinfo->link_hl + frame_ip->ip_hl * 4,
                   frame->header->caplen - capinfo->link_hl - frame_ip->ip_hl * 4);
        }

        *caplen = capinfo->link_hl + ip_hl + len_data;
        *size = len_data;

        // Return the assembled IP packet
        vector_remove(capture_cfg.ip_reasm, pkt);
        return pkt;
    }

    return NULL;
}
예제 #24
0
Iterator vector_end(Vector* vector) {
    return vector_iterator(vector, vector->size);
}