#include "rping.h" void init_capture(void) { uint32_t localnet, netmask; char pcap_error[PCAP_ERRBUF_SIZE]; struct bpf_program pcapfilter; char *filter = "icmp"; if (device == NULL) { if ((device = pcap_lookupdev(pcap_error)) == NULL) { fprintf(stderr, "pcap_lookupdev: %s\n", pcap_error); exit(EXIT_FAILURE); } } if ((pcapd = pcap_open_live(device, 200, 0, 10, pcap_error)) == NULL) { fprintf(stderr, "pcap_open_live: %s\n", pcap_error); exit(EXIT_FAILURE); } if (pcap_lookupnet(device, &localnet, &netmask, pcap_error) < 0) { fprintf(stderr, "pcap_lookupnet: %s\n", pcap_error); exit(EXIT_FAILURE); } if (pcap_compile(pcapd, &pcapfilter, filter, 0, netmask)) { fprintf(stderr, "pcap_comile: %s\n", pcap_error); exit(EXIT_FAILURE); } if (pcap_setfilter(pcapd, &pcapfilter) < 0) { fprintf(stderr, "pcap_setfilter: %s\n", pcap_error); exit(EXIT_FAILURE); } switch (pcap_datalink(pcapd)) { case DLT_EN10MB: link_offset = 14; break; case DLT_SLIP: link_offset = 16; break; case DLT_SLIP_BSDOS: link_offset = 24; break; case DLT_NULL: link_offset = 4; break; case DLT_PPP: link_offset = 4; break; case DLT_PPP_BSDOS: link_offset = 25; break; case DLT_IEEE802: link_offset = 22; break; case DLT_ATM_RFC1483: link_offset = 8; break; case DLT_RAW: link_offset = 0; break; default: fprintf(stderr, "init_capture: unsupported interface type\n"); exit(EXIT_FAILURE); } } char *next_pcap(void) { char *pkt; struct pcap_pkthdr head; pkt = (char *)pcap_next(pcapd, &head); return pkt ? pkt + link_offset : NULL; } void cleanup(int signo) { struct pcap_stat stat; fflush(stdout); putc('\n', stdout); if (pcap_stats(pcapd, &stat) < 0) { fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pcapd)); exit(EXIT_FAILURE); } printf("%d packets received by filter\n", stat.ps_recv); printf("%d packets dropped by kernel\n", stat.ps_drop); exit(0); }