qfedu-network-advanced-level/day7/pcap2.c

84 lines
2.6 KiB
C

// pcap_next 接收下一条数据
#include <pcap.h> // libpcap头文件
#include <stdio.h>
#include <netinet/in.h>
#include <netinet/ether.h>
#include <netinet/ip.h>
#include <arpa/inet.h> // 网络地址转换函数,如inet_ntoa()->将网络地址转换成“.”点隔的字符串格式
#include <string.h>
#include <unistd.h>
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;
}