コード例 #1
0
ファイル: capture.c プロジェクト: linuxmaniac/sngrep
int
capture_online(const char *dev, const char *outfile)
{
    capture_info_t *capinfo;

    //! Error string
    char errbuf[PCAP_ERRBUF_SIZE];

    // Set capture mode
    capture_cfg.status = CAPTURE_ONLINE;

    // Create a new structure to handle this capture source
    if (!(capinfo = sng_malloc(sizeof(capture_info_t)))) {
        fprintf(stderr, "Can't allocate memory for capture data!\n");
        return 1;
    }

    // Try to find capture device information
    if (pcap_lookupnet(dev, &capinfo->net, &capinfo->mask, errbuf) == -1) {
        fprintf(stderr, "Can't get netmask for device %s\n", dev);
        capinfo->net = 0;
        capinfo->mask = 0;
        return 2;
    }

    // Open capture device
    capinfo->handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
    if (capinfo->handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        return 2;
    }

    // Store capture device
    capinfo->device = dev;

    // Get datalink to parse packets correctly
    capinfo->link = pcap_datalink(capinfo->handle);

    // Check linktypes sngrep knowns before start parsing packets
    if ((capinfo->link_hl = datalink_size(capinfo->link)) == -1) {
        fprintf(stderr, "Unable to handle linktype %d\n", capinfo->link);
        return 3;
    }

    // Add this capture information as packet source
    vector_append(capture_cfg.sources, capinfo);

    // If requested store packets in a dump file
    if (outfile && !capture_cfg.pd) {
        if ((capture_cfg.pd = dump_open(outfile)) == NULL) {
            fprintf(stderr, "Couldn't open output dump file %s: %s\n", outfile,
                    pcap_geterr(capinfo->handle));
            return 2;
        }
    }

    return 0;
}
コード例 #2
0
ファイル: capture.c プロジェクト: cruzccl/sngrep
int
capture_offline(const char *infile, const char *outfile)
{
    capture_info_t *capinfo;

    // Error text (in case of file open error)
    char errbuf[PCAP_ERRBUF_SIZE];

    // Set capture mode
    capture_cfg.status = CAPTURE_OFFLINE_LOADING;

    // Create a new structure to handle this capture source
    if (!(capinfo = sng_malloc(sizeof(capture_info_t)))) {
        fprintf(stderr, "Can't allocate memory for capture data!\n");
        return 1;
    }

    // Set capture input file
    capinfo->infile = infile;

    // Open PCAP file
    if ((capinfo->handle = pcap_open_offline(infile, errbuf)) == NULL) {
        fprintf(stderr, "Couldn't open pcap file %s: %s\n", infile, errbuf);
        return 1;
    }

    // Get datalink to parse packets correctly
    capinfo->link = pcap_datalink(capinfo->handle);

    // Check linktypes sngrep knowns before start parsing packets
    if ((capinfo->link_hl = datalink_size(capinfo->link)) == -1) {
        fprintf(stderr, "Unable to handle linktype %d\n", capinfo->link);
        return 3;
    }

    // Add this capture information as packet source
    vector_append(capture_cfg.sources, capinfo);

    // If requested store packets in a dump file
    if (outfile && !capture_cfg.pd) {
        if ((capture_cfg.pd = dump_open(outfile)) == NULL) {
            fprintf(stderr, "Couldn't open output dump file %s: %s\n", outfile,
                    pcap_geterr(capinfo->handle));
            return 2;
        }
    }

    return 0;
}
コード例 #3
0
ファイル: capture.c プロジェクト: jungle-boogie/sngrep
int
capture_online(const char *dev, const char *outfile)
{
    //! Error string
    char errbuf[PCAP_ERRBUF_SIZE];

    // Set capture mode
    capinfo.status = CAPTURE_ONLINE;

    // Try to find capture device information
    if (pcap_lookupnet(dev, &capinfo.net, &capinfo.mask, errbuf) == -1) {
        fprintf(stderr, "Can't get netmask for device %s\n", dev);
        capinfo.net = 0;
        capinfo.mask = 0;
    }

    // Open capture device
    capinfo.handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
    if (capinfo.handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        return 2;
    }

    // If requested store packets in a dump file
    if (outfile) {
        if ((capinfo.pd = dump_open(outfile)) == NULL) {
            fprintf(stderr, "Couldn't open output dump file %s: %s\n", outfile,
                    pcap_geterr(capinfo.handle));
            return 2;
        }
    }

    // Get datalink to parse packets correctly
    capinfo.link = pcap_datalink(capinfo.handle);

    // Check linktypes sngrep knowns before start parsing packets
    if ((capinfo.link_hl = datalink_size(capinfo.link)) == -1) {
        fprintf(stderr, "Unable to handle linktype %d\n", capinfo.link);
        return 3;
    }

    // Get Local devices addresses
    pcap_findalldevs(&capinfo.devices, errbuf);

    return 0;
}
コード例 #4
0
ファイル: capture.c プロジェクト: jungle-boogie/sngrep
int
capture_offline(const char *infile, const char *outfile)
{
    // Error text (in case of file open error)
    char errbuf[PCAP_ERRBUF_SIZE];

    // Set capture mode
    capinfo.status = CAPTURE_OFFLINE_LOADING;
    // Set capture input file
    capinfo.infile = infile;

    // Open PCAP file
    if ((capinfo.handle = pcap_open_offline(infile, errbuf)) == NULL) {
        fprintf(stderr, "Couldn't open pcap file %s: %s\n", infile, errbuf);
        return 1;
    }

    // If requested store packets in a dump file
    if (outfile) {
        if ((capinfo.pd = dump_open(outfile)) == NULL) {
            fprintf(stderr, "Couldn't open output dump file %s: %s\n", outfile,
                    pcap_geterr(capinfo.handle));
            return 2;
        }
    }

    // Get datalink to parse packets correctly
    capinfo.link = pcap_datalink(capinfo.handle);

    // Check linktypes sngrep knowns before start parsing packets
    if ((capinfo.link_hl = datalink_size(capinfo.link)) == -1) {
        fprintf(stderr, "Unable to handle linktype %d\n", capinfo.link);
        return 3;
    }

    return 0;
}
コード例 #5
0
ファイル: capture.c プロジェクト: muchomuchacho/sngrep
void
parse_packet(u_char *mode, const struct pcap_pkthdr *header, const u_char *packet)
{
    // Datalink Header size
    int size_link;
    // IP version
    uint32_t ip_ver;
    // IP header data
    struct ip *ip4;
#ifdef WITH_IPV6
    // IPv6 header data
    struct ip6_hdr *ip6;
#endif
    // IP protocol
    uint8_t ip_proto;
    // IP segment length
    uint32_t ip_len;
    // IP header size
    uint32_t size_ip;
    // Fragment offset
    uint16_t ip_off = 0;
    // Fragmentation flag
    uint8_t ip_frag = 0;
    // Fragmentation offset
    uint16_t ip_frag_off = 0;
    //! Source Address
    char ip_src[INET6_ADDRSTRLEN + 1];
    //! Destination Address
    char ip_dst[INET6_ADDRSTRLEN + 1];
    // UDP header data
    struct udphdr *udp;
    // UDP header size
    uint16_t udp_size;
    // TCP header data
    struct tcphdr *tcp;
    // TCP header size
    uint16_t tcp_size;
    // Packet payload data
    u_char *msg_payload = NULL;
    // Packet payload size
    uint32_t size_payload;
    // Parsed message data
    sip_msg_t *msg;
    // Total packet size
    uint32_t size_packet;
    // SIP message transport
    int transport; /* 0 UDP, 1 TCP, 2 TLS */
    // Source and Destination Ports
    u_short sport, dport;

    // Ignore packets while capture is paused
    if (capture_is_paused())
        return;

    // Check if we have reached capture limit
    if (capinfo.limit && sip_calls_count() >= capinfo.limit)
        return;

    // Get link header size from datalink type
    size_link = datalink_size(capinfo.link);

    // Get IP header
    ip4 = (struct ip*) (packet + size_link);

#ifdef WITH_IPV6
    // Get IPv6 header
    ip6 = (struct ip6_hdr*)(packet + size_link);
#endif

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

    switch(ip_ver) {
        case 4:
            size_ip = ip4->ip_hl * 4;
            ip_proto = ip4->ip_p;
            ip_len = ntohs(ip4->ip_len);
            inet_ntop(AF_INET, &ip4->ip_src, ip_src, sizeof(ip_src));
            inet_ntop(AF_INET, &ip4->ip_dst, ip_dst, sizeof(ip_dst));

            ip_off = ntohs(ip4->ip_off);
            ip_frag = ip_off & (IP_MF | IP_OFFMASK);
            ip_frag_off = (ip_frag) ? (ip_off & IP_OFFMASK) * 8 : 0;
            break;
#ifdef WITH_IPV6
        case 6:
            size_ip = sizeof(struct ip6_hdr);
            ip_proto = ip6->ip6_nxt;
            ip_len = ntohs(ip6->ip6_plen);
            inet_ntop(AF_INET6, &ip6->ip6_src, ip_src, INET6_ADDRSTRLEN);
            inet_ntop(AF_INET6, &ip6->ip6_dst, ip_dst, INET6_ADDRSTRLEN);

            if (ip_proto == IPPROTO_FRAGMENT) {
                struct ip6_frag *ip6f = (struct ip6_frag *) (ip6 + ip_len);
                ip_frag_off = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK);
            }
            break;
#endif
        default:
            return;
    }

    // Only interested in UDP packets
    if (ip_proto == IPPROTO_UDP) {
        // Set transport UDP
        transport = 0;

        // Get UDP header
        udp = (struct udphdr*) (packet + size_link + size_ip);
        udp_size = (ip_frag_off) ? 0 : sizeof(struct udphdr);

        // Set packet ports
        sport = udp->uh_sport;
        dport = udp->uh_dport;

        size_payload = htons(udp->uh_ulen) - udp_size;
        if ((int32_t)size_payload > 0 ) {
            // Get packet payload
            msg_payload = malloc(size_payload + 1);
            memset(msg_payload, 0, size_payload + 1);
            memcpy(msg_payload, (u_char *) (packet + size_link + size_ip + udp_size), size_payload);
        }

        // Total packet size
        size_packet = size_link + size_ip + udp_size + size_payload;

    } else if (ip_proto == IPPROTO_TCP) {
        // Set transport TCP
        transport = 1;

        tcp = (struct tcphdr*) (packet + size_link + size_ip);
        tcp_size = (ip_frag_off) ? 0 : (tcp->th_off * 4);

        // Set packet ports
        sport = tcp->th_sport;
        dport = tcp->th_dport;

        // We're only interested in packets with payload
        size_payload = ip_len - (size_ip + tcp_size);
        if ((int32_t)size_payload > 0) {
            // Get packet payload
            msg_payload = malloc(size_payload + 1);
            memset(msg_payload, 0, size_payload + 1);
            memcpy(msg_payload, (u_char *) (packet + size_link + size_ip + tcp_size), size_payload);
        }

        // Total packet size
        size_packet = size_link + size_ip + tcp_size + size_payload;
#ifdef WITH_OPENSSL
        if (!msg_payload || !strstr((const char*) msg_payload, "SIP/2.0")) {
            if (capture_get_keyfile()) {
                // Allocate memory for the payload
                msg_payload = malloc(size_payload + 1);
                memset(msg_payload, 0, size_payload + 1);

                // Try to decrypt the packet
                tls_process_segment(ip4, &msg_payload, &size_payload);

                // Check if we have decoded payload
                if (size_payload <= 0)
                    free(msg_payload);

                // Set Transport TLS
                transport = 2;
            }
        }
#endif
    } else {
        // Not handled protocol
        return;
    }

    // Increase capture stats
    if (ip4->ip_v == 4 && capinfo.devices) {
        if(is_local_address(ip4->ip_src.s_addr)) {
            capinfo.local_ports[htons(sport)]++;
            capinfo.remote_ports[htons(dport)]++;
        } else {
            capinfo.remote_ports[htons(sport)]++;
            capinfo.local_ports[htons(dport)]++;
        }
    }

    // We're only interested in packets with payload
    if (size_payload <= 0)
        return;

    // Parse this header and payload
    msg = sip_load_message(header, ip_src, sport, ip_dst, dport, msg_payload);
    free(msg_payload);

    // This is not a sip message, Bye!
    if (!msg)
        return;

    // Store Transport attribute
    if (transport == 0) {
        msg_set_attribute(msg, SIP_ATTR_TRANSPORT, "UDP");
    } else if (transport == 1) {
        msg_set_attribute(msg, SIP_ATTR_TRANSPORT, "TCP");
    } else if (transport == 2) {
        msg_set_attribute(msg, SIP_ATTR_TRANSPORT, "TLS");
    }

    // Set message PCAP data
    msg->pcap_packet = malloc(size_packet);
    memcpy(msg->pcap_packet, packet, size_packet);

    // Store this packets in output file
    dump_packet(capinfo.pd, header, packet);

}