Skip to content

Commit

Permalink
-Default ring buffer in libpcap < 1.0.0 relies on /proc/sys/net/core/…
Browse files Browse the repository at this point in the history
…rmem_default which differs system to system and is low in general for accurate sniffing higher traffic (on debian etch it is 135KB). Voipmonitor now requires libpcap at least >= 1.0.0 (the latest recommended) which implements pcap_set_buffer_size and default value is 2MB. I've set it to 5MB. Thanks to AronHopkins (https://sourceforge.net/tracker/?func=detail&aid=3109439&group_id=312498&atid=1315315)

- added syslog report about lost packets by pcap or interface. If pcap is bottleneck, it should be written in syslog
  • Loading branch information
Martin Vit committed Feb 6, 2011
1 parent 226d630 commit a4b19a6
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ What is required
----------------

- C and C++ compiler (gcc,g++)
- libpcap-dev package >= 0.8 (almost in every linux distribution)
- libpcap-dev package >= 1.0.0
- MySQL++ library from http://tangentsoft.net/mysql++/
- zlib ibrary

Expand Down
15 changes: 12 additions & 3 deletions sniff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ int get_sip_peercnam(char *data, int data_len, char *tag, char *peername, int pe
if ((r2 = (unsigned long)memmem(peername_tag, peername_tag_len, "\" <", 3)) == 0){
goto fail_exit;
}
if (r2 <= r || ((r2 - r) > peername_len) ){
if (r2 <= r || ((r2 - r) > (unsigned long)peername_len) ){
goto fail_exit;
}
memcpy(peername, (void*)r, r2 - r);
Expand All @@ -131,7 +131,7 @@ int get_sip_peername(char *data, int data_len, char *tag, char *peername, int pe
if ((r2 = (unsigned long)memmem(peername_tag, peername_tag_len, "@", 1)) == 0){
goto fail_exit;
}
if (r2 <= r || ((r2 - r) > peername_len) ){
if (r2 <= r || ((r2 - r) > (unsigned long)peername_len) ){
goto fail_exit;
}
memcpy(peername, (void*)r, r2 - r);
Expand Down Expand Up @@ -256,6 +256,9 @@ void readdump(pcap_t *handle) {
int iscaller;
unsigned int offset;
Call *call;
struct pcap_stat ps;
unsigned int lostpacket = 0;
unsigned int lostpacketif = 0;

while (!terminating) {
res = pcap_next_ex(handle, &header, &packet);
Expand All @@ -282,7 +285,6 @@ void readdump(pcap_t *handle) {
continue;
}


// checking and cleaning calltable every 15 seconds (if some packet arrive)
if (header->ts.tv_sec - last_cleanup > 15){
if (last_cleanup >= 0){
Expand Down Expand Up @@ -324,6 +326,13 @@ void readdump(pcap_t *handle) {
continue;
}

/* pcap statistics */
pcap_stats(handle, &ps);
if (lostpacket < ps.ps_drop || lostpacketif < ps.ps_ifdrop) {
syslog(LOG_ERR, "error: libpcap or interface dropped some packets! rx:%i drop:%i ifdrop:%i\n", ps.ps_recv, ps.ps_drop, ps.ps_ifdrop);
lostpacket = ps.ps_drop;
lostpacketif = ps.ps_ifdrop;
}

// prepare packet pointers
header_udp = (struct udphdr *) ((char *) header_ip + sizeof(*header_ip));
Expand Down
39 changes: 38 additions & 1 deletion voipmonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,12 +355,49 @@ int main(int argc, char *argv[]) {
net = 0;
mask = 0;
}
/*
handle = pcap_open_live(ifname, 1600, opt_promisc, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open inteface '%s': %s\n", ifname, errbuf);
return(2);
}
}else{
*/

/* to set own pcap_set_buffer_size it must be this way and not useing pcap_lookupnet */

int status = 0;
if((handle = pcap_create(ifname, errbuf)) == NULL) {
fprintf(stderr, "pcap_create failed on iface '%s': %s\n", ifname, errbuf);
return(2);
}
if((status = pcap_set_snaplen(handle, 3200)) != 0) {
fprintf(stderr, "error pcap_set_snaplen\n");
return(2);
}
if((status = pcap_set_promisc(handle, opt_promisc)) != 0) {
fprintf(stderr, "error pcap_set_promisc\n");
return(2);
}
if((status = pcap_set_timeout(handle, 1000)) != 0) {
fprintf(stderr, "error pcap_set_timeout\n");
return(2);
}

/* this is not possible for libpcap older than 1.0.0 so now voipmonitor requires libpcap > 1.0.0
set ring buffer size to 5M to prevent packet drops whan CPU goes high or on very high traffic
- default is 2MB for libpcap > 1.0.0
- for libpcap < 1.0.0 it is controled by /proc/sys/net/core/rmem_default which is very low
*/
if((status = pcap_set_buffer_size(handle, 5*1024*1024)) != 0) {
fprintf(stderr, "error pcap_set_buffer_size\n");
return(2);
}

if((status = pcap_activate(handle)) != 0) {
fprintf(stderr, "error pcap_activate\n");
return(2);
}
} else {
printf("Reading file: %s\n", fname);
net = 0;
mask = 0;
Expand Down

0 comments on commit a4b19a6

Please sign in to comment.