linux下libpcap支持从多网卡抓包,设置为any即可
在IOS或者mac上就无法通过次方法抓取所有网卡报文
1.通过设置libevent事件回调,每个网卡注册读事件, fd通过
pd = pcap_open_live(device, snaplen, dopromisc, timeout, ebuf);
获得。
#ifdef IOS static int add_event(pcap_t *p) { if(!p) return -1; //event_init(); if(!base) base = event_base_new(); struct event *ev = NULL; int fd = pcap_fileno(p); printf("---------fd:%d ", fd); //event_set(&evListen, fd, EV_READ, user_pcap_run, p ); ev = event_new(base,fd, EV_READ | EV_PERSIST, user_pcap_run,p); struct timeval timeout; timeout.tv_sec = 1; timeout.tv_usec = 0; //event_base_set(base,&evListen); event_add(ev, NULL); return 0; } #endif
2.开线程 调用事件循环
void *mt_vqmon_thread(void *param) { #ifdef ANDROID mmap_cap_run(); #elif defined IOS event_base_dispatch(base); printf("exit monitor thread "); #else pcap_t *p = (pcap_t *)param; user_pcap_loop(p); #endif return NULL; }
3.其他读取报文,处理和pcap之前类似
#ifdef IOS void user_pcap_run(evutil_socket_t s, short t, void *arg) { if(!arg) return; pcap_t *p = (pcap_t *)arg; const uint8_t *packet; struct pcap_pkthdr *pcap_header; int32_t retval; static uint64_t recv_bytes = 0; static unsigned long start_time = 0; unsigned long end_time, diff_time; int link_type; link_type = pcap_datalink(p); while(1) { retval = pcap_next_ex(p, &pcap_header, &packet); if(retval >= 1 && packet) { //handle_dissector(link_type,packet,pcap_header->caplen,&pcap_header->ts); recv_bytes += pcap_header->caplen; } else if(retval == 0) //time out { printf("call user_pcap_run failed : No packets arrived before the timeout expired,try again!!! "); break; } else if(retval == -2 ) // error { printf("No more packets to read from the file ! "); return ; } else { printf("call pcap_next_ex failed : %s ",pcap_geterr(p)); return ; } static uint32_t last_drop_num = 0; struct pcap_stat stat; pcap_stats(p,&stat); if(stat.ps_drop && stat.ps_drop != last_drop_num) { printf("========>total packet = %u drop packet = %u ",stat.ps_recv,stat.ps_drop); last_drop_num = stat.ps_drop; } // Print debug info. end_time = time(0); if(start_time == 0) { start_time = end_time; } diff_time = end_time - start_time; if(diff_time >= 30) { float mbps; mbps = recv_bytes * 1.0 / (128 * 1024 * diff_time); start_time = end_time; recv_bytes = 0; printf("==================================================> captured speed = %.2f Mbps !!! ",mbps); } /* * Check for savagely closed TCP connections. */ tcp_check_timeouts(&pcap_header->ts); } return ; } #endif