tcpdump mailing list archives
Re: libpcap on Mac Os X 10.6 Snow Leopard
From: Marco De Angelis <thorar () yahoo com>
Date: Fri, 12 Feb 2010 19:02:04 +0000 (UTC)
Guy Harris <guy <at> alum.mit.edu> writes:
Can you cut your application down to the smallest code snippet that shows the problem, and send that to me?
I managed to extrapolate the core. It's a little messy because of the many tests I made recently and the 80-chars line limitation, but it show the original problem. If you uncomment the call to ioctl with BIOCIMMEDIATE setting, packets get delivered immediately. I tested it with "libpcaptest en1 icmp" and while running "ping google.com". #include <iostream> #include <stdio.h> #include <string> #include <vector> #include <errno.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/time.h> #include <net/bpf.h> #include <pcap.h> pcap_t* create(const std::string& name, const std::string& pcapFilter, uint32_t snapLen, bool promisc); bool capture(pcap_t * pcapSession); void close(pcap_t* pcapSession); int main(int argc, char** argv) { if (argc != 3) { std::cerr << "Usage: libpcaptest <interface> <filter>" << std::endl; return 1; } std::string name(argv[1]), filter(argv[2]); std::cout << "Capturing from '" << name << " with filter " << filter << std::endl; pcap_t * pcapSession = create(name, filter, 128, true); capture(pcapSession); close(pcapSession); return 0; } /** This is the callback **/ void test_pcap_handler(u_char* user, const struct pcap_pkthdr* header, const u_char* pkt_data) { std::cout << "Packet captured" << std::endl; } /** Temporary used since on Windows they forgot to sign as 'const char*' the filter string provided to pcap_compile... **/ void duplicateFilterString(const std::string& pcapFilter, std::vector<char>& dupFilter) { dupFilter.clear(); dupFilter.resize(pcapFilter.size()+1, 0); for (uint32_t i=0; i<pcapFilter.size(); ++i) dupFilter[i] = pcapFilter[i]; } void close(pcap_t* pcapSession) { if (pcapSession) { pcap_close(pcapSession); } } pcap_t* create(const std::string& name, const std::string& pcapFilter, uint32_t snapLen, bool promisc) { char errbuf[PCAP_ERRBUF_SIZE]; pcap_t* pcapSession; struct BPF_TIMEVAL t; if ((pcapSession = pcap_open_live(name.c_str(), snapLen, promisc ? 1 : 0, 1000, errbuf)) == NULL) { std::cerr << "Failed pcap_open_live because <" <<errbuf<<">" << std::endl; return NULL; } if (ioctl(pcap_fileno(pcapSession), BIOCGRTIMEOUT, &t) == -1) { fprintf(stderr, "bpftest: BIOCGRTIMEOUT failed: %s\n", strerror(errno)); std::cerr << "Failed ioctl with BIOCGRTIMEOUT because <" <<errbuf<<">" << std::endl; return NULL; } printf("BIOCGRTIMEOUT = %#08lx, t.tv_sec = %d, t.tv_usec = %d\n", (unsigned long)BIOCGRTIMEOUT, t.tv_sec, t.tv_usec); // compile the filter if it's been supplied or snapLen is provided if (pcapFilter.empty()==false || snapLen<65535) { // get netmask bpf_u_int32 pcapNetaddr, pcapMask; pcap_lookupnet(name.c_str(), &pcapNetaddr, &pcapMask, errbuf); struct bpf_program pcapFilterProgram; std::vector<char> filterDup; duplicateFilterString(pcapFilter, filterDup); if (pcap_compile(pcapSession, &pcapFilterProgram, &filterDup[0], 1, pcapMask) == -1) { std::string error = pcap_geterr(pcapSession); pcap_close(pcapSession); std::cerr << "Failed pcap_compile because <" <<errbuf<<">" << std::endl; return NULL; } if (pcap_setfilter(pcapSession, &pcapFilterProgram) == -1) { std::string error = pcap_geterr(pcapSession); pcap_freecode(&pcapFilterProgram); pcap_close(pcapSession); std::cerr << "Failed pcap_setfilter because <" <<errbuf<<">" << std::endl; return NULL; } pcap_freecode(&pcapFilterProgram); } // set session in non blocking mode if (pcap_setnonblock(pcapSession, 1, errbuf)!=0) { pcap_close(pcapSession); std::cerr << "Failed pcap_setnonblock because <" <<errbuf<<">" << std::endl; return NULL; } /* Enable this for immediate delivery of packets through callback. uint32_t v = 1; if (ioctl(pcap_fileno(pcapSession), BIOCIMMEDIATE, &v) < 0) { pcap_close(pcapSession); std::cerr << "Failed ioctl BIOCIMMEDIATE" << std::endl; return NULL; } */ int dlt; const char *dlt_name; dlt = pcap_datalink(pcapSession); dlt_name = pcap_datalink_val_to_name(dlt); if (dlt_name == NULL) { (void)fprintf(stderr, "listening on %s, link-type %u, capture size %u bytes\n", name.c_str(), dlt, snapLen); } else { (void)fprintf(stderr, "listening on %s, link-type %s (%s), capture size %u bytes\n", name.c_str(), dlt_name, pcap_datalink_val_to_description(dlt), snapLen); } return pcapSession; } bool capture(pcap_t * pcapSession) { struct pcap_stat pcapStats; while (true) { int32_t ret = pcap_dispatch(pcapSession, 100, test_pcap_handler, (u_char*)NULL); std::cout << "Read " << ret << " packets" << std::endl; if (pcap_stats(pcapSession, &pcapStats) != 0) { std::string error = pcap_geterr(pcapSession); std::cerr << "Failed pcap_setnonblock because <" <<error<<">" << std::endl; return false; } std::cout << "ReceivedPackets " << pcapStats.ps_recv << " DroppedPackets " << pcapStats.ps_drop << " I/F DroppedPackets " << pcapStats.ps_ifdrop << std::endl; if (ret==-1) { std::string error = pcap_geterr(pcapSession); std::cerr << "Failed pcap_dispatch because <"<<error<<">" << std::endl; return NULL; } sleep(5); } return true; } - This is the tcpdump-workers list. Visit https://cod.sandelman.ca/ to unsubscribe.
Current thread:
- Re: libpcap on Mac Os X 10.6 Snow Leopard, (continued)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Marco De Angelis (Feb 03)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Guy Harris (Feb 03)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Marco De Angelis (Feb 03)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Marco De Angelis (Feb 09)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Carter Bullard (Feb 09)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Guy Harris (Feb 09)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Marco De Angelis (Feb 10)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Guy Harris (Feb 10)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Marco De Angelis (Feb 10)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Guy Harris (Feb 11)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Marco De Angelis (Feb 12)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Guy Harris (Feb 12)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Guy Harris (Feb 13)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Marco De Angelis (Feb 19)
- Re: libpcap on Mac Os X 10.6 Snow Leopard Guy Harris (Feb 19)