[tcpdump-workers] pcap segment violation

2014-02-12 Thread Daniel H. Bahr
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;
pr

Re: [tcpdump-workers] pcap segment violation

2014-02-12 Thread Guy Harris

On Feb 12, 2014, at 11:42 AM, Daniel H. Bahr  wrote:

> Hello everyone, I really hope this is the right place to post this
> since I did not find a pcap-specific mailing list,

There aren't separate tcpdump or libpcap mailing lists.  This list is for all 
tcpdump-related and libpcap-related mail, regardless of whether they're about 
using tcpdump/libpcap (you're in the "using libpcap" group) or developing 
tcpdump/libpcap.

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

On what OS is this?  (I ask because not all OSes use SIGSEGV and SIGBUS for the 
same purposes, and because, with some versions of some OSes and libpcap, the 
packet data handed to your callback will, I think, be write-protected - see 
below.)

What type of processor is this running on?  (I ask because there might be 
alignment issues on some processors, although I'd expect a SIGBUS, rather than 
a SIGSEGV, for alignment issues.)

Can you get a stack trace to see where the SIGSEGV is happening?

>   capture_loop (pd, packets, (pcap_handler)parse_packet);

The cast to (pcap_handler) shouldn't be necessary...

> void parse_packet(u_char *user, struct pcap_pkthdr *packethdr,
>  u_char *packetptr) {

...and *won't* be necessary if you change that to

void parse_packet(u_char *user, const struct pcap_pkthdr *packethdr,
 const u_char *packetptr) {

If your code fails to compile after you make that change, your code may be 
incorrect; libpcap does not guarantee that you will be able to modify either 
the struct pcap_pkthdr handed to you or the raw packet data handed to you, and, 
if you try to do so, Bad Things could happen (including a crash, if that data 
is in a region of your address space not writable by you).
___
tcpdump-workers mailing list
tcpdump-workers@lists.tcpdump.org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers


Re: [tcpdump-workers] pcap segment violation

2014-02-12 Thread Guy Harris
Note also that there is *NO* guarantee that the struct pcap_pkthdr or packet 
data pointers handed to your callback remain valid after it returns, so those 
pointers must not be saved by your callback or anything it calls.
___
tcpdump-workers mailing list
tcpdump-workers@lists.tcpdump.org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers