// pcap_next 接收下一条数据 #include // libpcap头文件 #include #include #include #include #include // 网络地址转换函数,如inet_ntoa()->将网络地址转换成“.”点隔的字符串格式 #include #include int main(int argc, char const *argv[]) { // 1. 获取可用的网络设备名称 char *dev = pcap_lookupdev(NULL); // NULL表示获取默认网络设备 if (dev != NULL) { printf("网络设备名称: %s\n", dev); } // 2. 打开网络设备, 开始捕获数据 char err_buf[PCAP_ERRBUF_SIZE] = ""; pcap_t *cap = pcap_open_live(dev, 128, 0, 0, err_buf); if (cap == NULL) { printf("open pcap fail: %s\n", err_buf); return -1; } // 3. 开始捕获数据 while (1) { struct pcap_pkthdr cap_hdr; bzero(&cap_hdr, sizeof(cap_hdr)); const u_char *data = pcap_next(cap, &cap_hdr); if (cap_hdr.len > 0) { printf("数据包长度: %d, 实际长度: %d\n", cap_hdr.caplen, cap_hdr.len); } // 分析 mac 报文的数据 struct ether_header *mac_hdr = (struct ether_header *)data; unsigned char src_mac[18] = ""; unsigned char dst_mac[18] = ""; sprintf(dst_mac, "%02x:%02x:%02x:%02x:%02x:%02x", mac_hdr->ether_dhost[0], mac_hdr->ether_dhost[1], mac_hdr->ether_dhost[2], mac_hdr->ether_dhost[3], mac_hdr->ether_dhost[4], mac_hdr->ether_dhost[5]); sprintf(src_mac, "%02x:%02x:%02x:%02x:%02x:%02x", mac_hdr->ether_shost[0], mac_hdr->ether_shost[1], mac_hdr->ether_dhost[2], mac_hdr->ether_shost[3], mac_hdr->ether_shost[4], mac_hdr->ether_shost[5]); unsigned short mac_type = ntohs(mac_hdr->ether_type); printf("type(%#x) src mac: %s, dst mac: %s\n", mac_type, src_mac, dst_mac); if (mac_type == 0x0800) { // 分析 ip 报文的数据 struct iphdr *ip_hdr = (struct iphdr *)(data + sizeof(struct ether_header)); u_char src_ip[INET_ADDRSTRLEN] = ""; u_char dst_ip[INET_ADDRSTRLEN] = ""; inet_ntop(AF_INET, &ip_hdr->saddr, src_ip, INET_ADDRSTRLEN); inet_ntop(AF_INET, &ip_hdr->daddr, dst_ip, INET_ADDRSTRLEN); printf("ip type(%d) %s->%s\n", ip_hdr->protocol, src_ip, dst_ip); } sleep(1); } // 关闭网卡设备 pcap_close(cap); return 0; }