tcpdump mailing list archives

pcap segment violation


From: "Daniel H. Bahr" <dhbahr () gmail com>
Date: Wed, 12 Feb 2014 14:42:56 -0500

Hello everyone, I really hope this is the right place to post this
since I did not find a pcap-specific mailing list, if not: could
someone point me in the right direction?

So this is the thing:
I'm working on a fairly simple network passive monitor with simple
algorithms dependant mostly on packet capture time and such. I didn't
wan't to use the existing java bindings since I only needed a fairly
small set of the jnetpcap features and thought myself capable of
recreating those I required.
So I used the jni to add a library (code after message) for capturing
packets and notifying the java application of them.

Now it has been displaying an erratic behaviour in which after a
number of packets captured it would crash with a SIGSEGV.

For instance 1999 packets a first time, 5178 packets a second time and
so on (random quantities of packets before the SIGSEGV raised)... all
of this different "crash times" happened in the exact same
environment: two virtualbox boxes, one with a dummy service with an
open socketserver and the other with a dummy app connecting to that
socket and flushing short strings up and down, and the monitor along
with the dummy app monitoring only packets arriving from the dummy
service.

Does this make sense to any one... I am posting the relevant parts of
the C code in the hopes that I am doing something really stupid and
anyone can get a glimpse at it.

Best regards an thanks in advance for taking the time to read this.

================================================================

/*
 * net_provinfor_middleware_facility_NetworkInfo_LibPKTInfo_NetworkMonitor.c
 *
 *  Created on: Oct 23, 2013
 *      Author: D.H. Bahr
 */

#include "LibPKTInfo_PKTMonitor.h"
#include "definition.h"

pcap_t* pd;
int linkhdrlen;
JNIEnv *jni;
jobject this;

int bailed = 0;

JNIEXPORT void JNICALL Java_LibPKTInfo_PKTMonitor_startSniffing
        (JNIEnv *env, jobject thisObject, jstring iface, jstring filter) {
        jni = env;
        this = thisObject;

        int packets = -1;

        const char *device = (*env)->GetStringUTFChars(env, iface, NULL);
        const char *bpfstr = (*env)->GetStringUTFChars(env, filter, NULL);

    // Starting pcap socket opening
        char errbuf[PCAP_ERRBUF_SIZE];
    uint32_t  srcip, netmask;
    struct bpf_program  bpf;

    // If no network interface (device) is specfied, get the first one.
    if (!*device && !(device = pcap_lookupdev(errbuf)))
    {
        printf("pcap_lookupdev(): %s\n", errbuf);
        return;
    }

    // Get network device source IP address and netmask.
    if (pcap_lookupnet(device, &srcip, &netmask, errbuf) < 0)
    {
        printf("pcap_lookupnet: %s\n", errbuf);
        return;
    }

    // Open the device for live capture, as opposed to reading a packet
    // capture file.
    if ((pd = pcap_open_live(device, BUFSIZ, 1, 0, errbuf)) == NULL)
    {
        printf("pcap_open_live(): %s\n", errbuf);
        return;
    }

    // Convert the packet filter expression into a packet
    // filter binary.
    if (pcap_compile(pd, &bpf, (char*)bpfstr, 0, netmask))
    {
        printf("pcap_compile(): %s\n", pcap_geterr(pd));
        return;
    }

    // Assign the packet filter to the given libpcap socket.
    if (pcap_setfilter(pd, &bpf) < 0)
    {
        printf("pcap_setfilter(): %s\n", pcap_geterr(pd));
        return;
    }

        signal (SIGTERM, bailout);
        signal (SIGQUIT, bailout);
        signal (SIGSEGV, bailout);

        capture_loop (pd, packets, (pcap_handler)parse_packet);
        bailout (0);

}

JNIEXPORT void JNICALL Java_LibPKTInfo_PKTMonitor_stopSniffing
  (JNIEnv *env, jobject thisObject) {
        bailout(0);
}

void capture_loop(pcap_t* pd, int packets, pcap_handler func) {
    int linktype;

    // Determine the datalink layer type.
    if ((linktype = pcap_datalink(pd)) < 0) {
        printf("pcap_datalink(): %s\n", pcap_geterr(pd));
        return;
    }

    // Set the datalink layer header size.
    switch (linktype) {
                case DLT_NULL:
                        linkhdrlen = 4;
                        break;

                case DLT_EN10MB:
                        linkhdrlen = 14;
                        break;

                case DLT_SLIP:
                case DLT_PPP:
                        linkhdrlen = 24;
                        break;

                default:
                        return;
    }

    // Start capturing packets.
    if (pcap_loop(pd, packets, func, 0) < 0)
        printf("pcap_loop failed: %s\n", pcap_geterr(pd));
}

void bailout(int signo) {
        printf ("[libpktinfo.so] bailout caught with signal: %d\n", signo);
        printf ("[libpktinfo.so] signal legend:\n");
        printf ("[libpktinfo.so] \tINT:%d\n", SIGINT);
        printf ("[libpktinfo.so] \tTERM:%d\n", SIGTERM);
        printf ("[libpktinfo.so] \tQUIT:%d\n", SIGQUIT);
        printf ("[libpktinfo.so] \tSEGV:%d\n", SIGSEGV);
        if (bailed == 0) {
                bailed = 1;
                printf ("[libpktinfo.so] bailing out...");
                pcap_close(pd);
                printf ("done!\n");
        } else {
                printf ("[libpktinfo.so] already bailed, skipping...\n");
        }
}

void parse_packet(u_char *user, struct pcap_pkthdr *packethdr,
                  u_char *packetptr) {
        struct ip* iphdr;
    char iphdrInfo[256], srcip[256], dstip[256];
    unsigned short id, seq;

    jclass klass = (*jni)->GetObjectClass(jni, this);
    jmethodID midCallBack = (*jni)->GetMethodID(jni, klass, "newPacketArrived",
                                                                                        "(<signature here>)V");
    if (NULL == midCallBack) {
        return;
    }

    // Skip the datalink layer header and get the IP header fields.
    packetptr += linkhdrlen;
    iphdr = (struct ip*)packetptr;

    packetptr += 4*iphdr->ip_hl;
    int ID = ntohs(iphdr->ip_id);

    ...

    (*jni)->CallVoidMethod(jni, this, midCallBack, ID, <params here>);
}
_______________________________________________
tcpdump-workers mailing list
tcpdump-workers () lists tcpdump org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers


Current thread: