分享一个在C语言中用libpcap解析pcap文件的小程序

如题, 分享一个在C语言中用libpcap解析pcap文件的小程序. 这个小程序的运行逻辑是检查以太网帧, 如果ether_type显示以太网帧中包含了一个IP报文的话继续对齐进行处理; 接着检查IP报文的协议字段, 如果它的协议字段显示其中包含一个TCP包的话, 则打印数据包的源和目标IP地址, 源和目标端口号, TCP包头的序列号和确认号. 代码如下:

//测试.c
#include <pcap.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <翻译包.h>


void packetHandler(u_char *userData, const struct pcap_pkthdr* pkthdr, const u_char* packet);

int main() {
	pcap_t *descr;
	char errbuf[PCAP_ERRBUF_SIZE];

	// open capture file for offline processing
	char* 文件名 = "/Users/zongyi/traces/hgc/HGC.20080415001.pcap";
	descr = pcap_open_offline(文件名, errbuf);
	if (descr == NULL) {
		printf("pcap_open_offline() failed: %s\n", errbuf);
		return 1;
	}

	// start packet processing loop, just like live capture
	if (pcap_loop(descr, 10, packetHandler, NULL) < 0) {
		printf("pcap_loop() failed\n");
		return 1;
	}
	printf("capture finished\n");
	pcap_close(descr);
  return 0;
}

void packetHandler(u_char *userData, const struct pcap_pkthdr* pkthdr, const u_char* packet) {
	const struct ether_header* ethernetHeader;
	const struct ip* ipHeader;
	const struct tcphdr* tcpHeader;
	char sourceIp[INET_ADDRSTRLEN];
	char destIp[INET_ADDRSTRLEN];
	u_int sourcePort, destPort;
	u_char *data;
	int dataLength = 0;
	ethernetHeader = (struct ether_header*) packet;

	if (ntohs(ethernetHeader->ether_type) == ETHERTYPE_IP) {
		ipHeader = (struct ip*)(packet + sizeof(struct ether_header));
		inet_ntop(AF_INET, &(ipHeader->ip_src), sourceIp, INET_ADDRSTRLEN);
		inet_ntop(AF_INET, &(ipHeader->ip_dst), destIp, INET_ADDRSTRLEN);
		if (ipHeader->ip_p == IPPROTO_TCP) {
			tcpHeader = (struct tcphdr*)(packet + sizeof(struct ether_header) + sizeof(struct ip));
			_正整数_ 源地址 = ntohl(ipHeader->ip_src.s_addr);
			_正整数_ 目标地址 = ntohl(ipHeader->ip_dst.s_addr);
			sourcePort = ntohs(tcpHeader->th_sport);
			destPort = ntohs(tcpHeader->th_dport);
			_正整数_ 确认号 = ntohl(tcpHeader->th_ack);
			_正整数_ 序列号 = ntohl(tcpHeader->th_seq);
			_输出("源地址:%u\t目标地址:%u\t源端口号:%5u\t目标端口号:%5u\t序列号:%u\t确认号:%u\n", \
				源地址, 目标地址, sourcePort, destPort, 序列号, 确认号);
		}
	}
}

运行以上代码的命令如下:

gcc 测试.c -o a.out -lpcap
./a.out

猜你喜欢

转载自blog.csdn.net/nankai0912678/article/details/106076522
今日推荐