[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[Libevent-users] how the difference of libevent version 1.4 and 2.0 influence libpcap events?



I'm using libpcap and libevent in a program.


the related source codes are:
--------------------------------------------------------------------------------------------------------------------------------------------
const u_int16_t RELAY_PORT = 8000;

pcap_t *create_pcap(const void *dev, pcap_style_t style)
{
    pcap_t *handle;         /* Session handle */
ÂÂ Âstruct bpf_program fp; Â Â Â Â Â/* The compiled filter */
    bpf_u_int32 mask;        /* The netmask */
    bpf_u_int32 net;        Â/* The IP subnet*/
    const struct pcap_pkthdr* pcap_header;  /* A pointer to pcap_pkthdr structure */
    const u_char *pcap_packet;      /* The captured packet */Â

char interface[20];
    strcpy(interface, dev);

/* Find the properties for the network interface */
if (pcap_lookupnet(interface, &net, &mask, errbuf) == -1) {
fprintf(stderr, "Pcap counldn't get netmask for device %s: %s\n", interface, errbuf);
net = 0;
mask = 0;
}


    handle = pcap_open_live(interface, BUFSIZ, 0, 0, errbuf);
    if (handle == NULL) {
fprintf(stderr, "Pcap open live capture failure: %s\n", errbuf);
        exit(1);Â
    }

sprintf(filter_exp, "tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack) && src port %d || dst port %d", RELAY_PORT, RELAY_PORT);

    /* Compile and apply the filter */
    if (pcap_compile(handle, &fp, filter_exp, 0, mask) == -1) {
fprintf(stderr, "Pcap parse filter failure: %s\n", pcap_geterr(handle));
   Â exit(1);
}

    if (pcap_setfilter(handle, &fp) == -1) {
fprintf(stderr, "Pcap couldn't install filter: %s\n", pcap_geterr(handle));
   Â exit(1);
}
if(style == NONBLOCKING){
if(pcap_setnonblock(handle, 1, errbuf) == -1){
   Â fprintf(stderr, "Pcap set non-blocking fails: %s\n", errbuf);
       Â exit(1);
}
}
return handle;
}

//////////////////////////////////////////////////

void on_capture(int pcapfd, short op, void *arg)
{
  int res;
#ifdef DEBUG
printf("on capture \n");
#endif
pcap_t *handle;
handle = (pcap_t *)arg;
fqueue_t* pkt_queue;

/* put all packets in the buffer into the packet FIFO queue
Â* and then process these packetsÂ
Â* */
pkt_queue = init_fqueue();
res = pcap_dispatch(handle, -1, collect_pkt, (u_char *)pkt_queue);
#ifdef DEBUG
printf("pcap_dispatch() returns %d\n", res);
#endif
if(!res) return;
process_packet(pkt_queue);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int pcapfd;
pcap_t *pcap_handle;
struct event Âpcap_ev;

pcap_handle = create_pcap("eth0", NONBLOCKING); Â
pcapfd = pcap_get_selectable_fd(pcap_handle);
if(pcapfd<0){
perror("pcap_get_selectable_fd() failed!\n");
exit(1);
}

if (setnonblock(pcapfd) == -1) return -1;

base = event_init();

event_set(&pcap_ev, pcapfd, EV_READ|EV_PERSIST, on_capture, pcap_handle);
event_base_set(base, &pcap_ev);
if(event_add(&pcap_ev, NULL) == -1){
ÂÂ Âperror("event_add() failed for pcap_ev!\n");
ÂÂ Âexit(-1);
}
event_base_dispatch(base);
--------------------------------------------------------------------------------------

I also register an TCP listening event on event_base( two events: on_accept and on_recv.)

then I run the program on host A and send packets from host B, meanwhile I use a tcpdump to capture packets on A Â(tcpdump -i eth0 Âport 8000 )
Â
For comparison, I have two laptops which acts as A, I tried the program (compile and then run) on these two laptops, one with Fedora (fedora release 18) and one with Ubuntu (Ubuntu 14.04.2 LTS)

on ubuntu events are invoked in the following orderÂ

on captureÂ
pcap_dispatch() returns 0
on captureÂ
pcap_dispatch() returns 0
on acceptÂ
on recvÂ

it is strange that theÂpcap_dispatch returns 0 twice. My expectation is that the when on_capture event is triggered,Âpcap_dispatch will catch TCP SYN packets before on_accept event is triggered. But I don't know why the on_capture events are invoked twice andÂpcap_dispatch()ÂÂreturns 0.

on Fedora, the program works as expected, theÂpcap_dispatch() can capture packets the first time it is invoked before on_accept event

I use ldd to check the libraries of this program on each laptop.

Fedora:
  Â$ldd relayÂ
linux-vdso.so.1 => Â(0x00007fff1d1ad000)
libevent-1.4.so.2 => /lib/libevent-1.4.so.2 (0x00007faca467d000)
libpcap.so.1 => /lib64/libpcap.so.1 (0x00000035b4a00000)
libc.so.6 => /lib64/libc.so.6 (0x00000035b0a00000)
libnsl.so.1 => /lib64/libnsl.so.1 (0x00000035cea00000)
librt.so.1 => /lib64/librt.so.1 (0x00000035b1a00000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x00000035b2e00000)
/lib64/ld-linux-x86-64.so.2 (0x00000035b0200000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00000035b1600000)


ubuntu:

   $ ldd relayÂ
linux-vdso.so.1 => Â(0x00007ffd08bc5000)
libevent-2.0.so.5 => /usr/lib/x86_64-linux-gnu/libevent-2.0.so.5 (0x00007eff35f81000)
libpcap.so.0.8 => /usr/lib/x86_64-linux-gnu/libpcap.so.0.8 (0x00007eff35d43000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007eff3597e000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007eff35760000)
/lib64/ld-linux-x86-64.so.2 (0x00007eff361c5000)


indeed, both libpcap and libevent versions are different.
what are potential problems for my program when it runs on ubuntu? how can fix the unexpected problems on ubuntu?
thank you!