前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >pcap文件格式及文件解析[通俗易懂]

pcap文件格式及文件解析[通俗易懂]

作者头像
全栈程序员站长
发布于 2022-09-20 02:28:24
发布于 2022-09-20 02:28:24
9.7K0
举报

大家好,又见面了,我是你们的朋友全栈君。

第一部分:PCAP包文件格式

一 基本格式:

文件头 数据包头数据报数据包头数据报……

二、文件头:

文件头结构体 sturct pcap_file_header { DWORD magic; DWORD version_major; DWORD version_minor; DWORD thiszone; DWORD sigfigs; DWORD snaplen; DWORD linktype; } 说明: 1、标识位:32位的,这个标识位的值是16进制的 0xa1b2c3d4。 a 32-bit magic number ,The magic number has the value hex a1b2c3d4. 2、主版本号:16位, 默认值为0x2。 a 16-bit major version number,The major version number should have the value 2. 3、副版本号:16位,默认值为0x04。 a 16-bit minor version number,The minor version number should have the value 4. 4、区域时间:32位,实际上该值并未使用,因此可以将该位设置为0。 a 32-bit time zone offset field that actually not used, so you can (and probably should) just make it 0; 5、精确时间戳:32位,实际上该值并未使用,因此可以将该值设置为0。 a 32-bit time stamp accuracy field tha not actually used,so you can (and probably should) just make it 0; 6、数据包最大长度:32位,该值设置所抓获的数据包的最大长度,如果所有数据包都要抓获,将该值设置为65535;例如:想获取数据包的前64字节,可将该值设置为64。 a 32-bit snapshot length” field;The snapshot length field should be the maximum number of bytes perpacket that will be captured. If the entire packet is captured, make it 65535; if you only capture, for example, the first 64 bytes of the packet, make it 64. 7、链路层类型:32位, 数据包的链路层包头决定了链路层的类型。 a 32-bit link layer type field.The link-layer type depends on the type of link-layer header that the packets in the capture file have: 以下是数据值与链路层类型的对应表 0 BSD loopback devices, except for later OpenBSD 1 Ethernet, and Linux loopback devices 以太网类型,大多数的数据包为这种类型。 6 802.5 Token Ring 7 ARCnet 8 SLIP 9 PPP 10 FDDI 100 LLC/SNAP-encapsulated ATM 101 raw IP, with no link 102 BSD/OS SLIP 103 BSD/OS PPP 104 Cisco HDLC 105 802.11 108 later OpenBSD loopback devices (with the AF_value in network byte order) 113 special Linux cooked capture 114 LocalTalk

三 packet数据包头:

struct pcap_pkthdr { struct tim ts; DWORD caplen; DWORD len; } struct tim { DWORD GMTtime; DWORD microTime } 说明: 1、时间戳,包括: 秒计时:32位,一个UNIX格式的精确到秒时间值,用来记录数据包抓获的时间,记录方式是记录从格林尼治时间的1970年1月1日 00:00:00 到抓包时经过的秒数; 微秒计时:32位, 抓取数据包时的微秒值。 a time stamp, consisting of: a UNIX-format time-in-seconds when the packet was captured, i.e. the number of seconds since January 1,1970, 00:00:00 GMT (that GMT, *NOT* local time!); the number of microseconds since that second when the packet was captured; 2、数据包长度:32位 ,标识所抓获的数据包保存在pcap文件中的实际长度,以字节为单位。 a 32-bit value giving the number of bytes of packet data that were captured; 3、数据包实际长度: 所抓获的数据包的真实长度,如果文件中保存不是完整的数据包,那么这个值可能要比前面的数据包长度的值大。 a 32-bit value giving the actual length of the packet, in bytes (which may be greater than the previous number, if you are not saving the entire packet).

四:packet数据:

即Packet(通常就是链路层的数据帧)具体内容,长度就是Caplen,这个长度的后面,就是当前PCAP文件中存放的下一个Packet数据包,也就是说:PCAP文件里面并没有规定捕获的Packet数据包之间有什么间隔字符串,下一组数据在文件中的起始位置。我们需要靠第一个Packet包确定。最后,Packet数据部分的格式其实就是标准的网路协议格式了可以任何网络教材上找得到。

五:举例分析

图中最开始的绿色部分就是24 Bytes的Pcap Header,接下来红色的16 Bytes是第一个消息的Pcap Header。后面的红色的16 Bytes是第二个消息的Pcap Header。两块蓝色的部分分别是两个消息从链路层开始的完整内容。在网络上实际传输的数据包在数据链路层上每一个Packet开始都会有7个用于同步的字节和一个用于标识该Packet开始的字节,最后还会有四个CRC校验字节;而PCAP文件中会把前8个字节和最后4个校验自己去掉,因为这些信息对于协议分析是没有用的。

用Wireshark打开一个PCAP数据包,每条消息的所有field会被解析出来并会按照协议层次折叠起来。第一层显示的是FrameXXX,这一级别没有对应某层具体的协议,而是对本条消息的一个概括性总结,描述了一些有用的概括性信息,比如从里面我们可以看到本条消息各种协议的层次关系,展开其它协议层之后对应的是该协议的各个域,如下图所示:

第二部分:PCAP文件解析

1、 pcap解析工具 Xplico

Xplico 是一个从 pcap 文件中解析出IP流量数据的工具,可解析每个邮箱 (POP, IMAP, 和 SMTP 协议), 所有 HTTP 内容, VoIP calls (SIP) 等等

2、 C语言实现PCAP文件分析

实现步骤: 1)用Wireshark软件抓包得到test.pcap文件 2)程序:分析pcap文件头 -> 分析pcap_pkt头 -> 分析帧头 -> 分析ip头 -> 分析tcp头 -> 分析http信息

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<netinet/in.h>

#include<time.h>

#define BUFSIZE 10240

#define STRSIZE 1024

typedef long bpf_int32;

typedef unsigned long bpf_u_int32;

typedef unsigned short u_short;

typedef unsigned long u_int32;

typedef unsigned short u_int16;

typedef unsigned char u_int8;

//pacp文件头结构体

struct pcap_file_header

{

bpf_u_int32 magic; /* 0xa1b2c3d4 */

u_short version_major; /* magjor Version 2 */

u_short version_minor; /* magjor Version 4 */

bpf_int32 thiszone; /* gmt to local correction */

bpf_u_int32 sigfigs; /* accuracy of timestamps */

bpf_u_int32 snaplen; /* max length saved portion of each pkt */

bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */

};

//时间戳

struct time_val

{

long tv_sec; /* seconds 含义同 time_t 对象的值 */

long tv_usec; /* and microseconds */

};

//pcap数据包头结构体

struct pcap_pkthdr

{

struct time_val ts; /* time stamp */

bpf_u_int32 caplen; /* length of portion present */

bpf_u_int32 len; /* length this packet (off wire) */

};

//数据帧头

typedef struct FramHeader_t

{ //Pcap捕获的数据帧头

u_int8 DstMAC[6]; //目的MAC地址

u_int8 SrcMAC[6]; //源MAC地址

u_short FrameType; //帧类型

} FramHeader_t;

//IP数据报头

typedef struct IPHeader_t

{ //IP数据报头

u_int8 Ver_HLen; //版本+报头长度

u_int8 TOS; //服务类型

u_int16 TotalLen; //总长度

u_int16 ID; //标识

u_int16 Flag_Segment; //标志+片偏移

u_int8 TTL; //生存周期

u_int8 Protocol; //协议类型

u_int16 Checksum; //头部校验和

u_int32 SrcIP; //源IP地址

u_int32 DstIP; //目的IP地址

} IPHeader_t;

//TCP数据报头

typedef struct TCPHeader_t

{ //TCP数据报头

u_int16 SrcPort; //源端口

u_int16 DstPort; //目的端口

u_int32 SeqNO; //序号

u_int32 AckNO; //确认号

u_int8 HeaderLen; //数据报头的长度(4 bit) + 保留(4 bit)

u_int8 Flags; //标识TCP不同的控制消息

u_int16 Window; //窗口大小

u_int16 Checksum; //校验和

u_int16 UrgentPointer; //紧急指针

}TCPHeader_t;

//

void match_http(FILE *fp, char *head_str, char *tail_str, char *buf, int total_len); //查找 http 信息函数

//

int main()

{

struct pcap_file_header *file_header;

struct pcap_pkthdr *ptk_header;

IPHeader_t *ip_header;

TCPHeader_t *tcp_header;

FILE *fp, *output;

int pkt_offset, i=0;

int ip_len, http_len, ip_proto;

int src_port, dst_port, tcp_flags;

char buf[BUFSIZE], my_time[STRSIZE];

char src_ip[STRSIZE], dst_ip[STRSIZE];

char host[STRSIZE], uri[BUFSIZE];

//初始化

file_header = (struct pcap_file_header *)malloc(sizeof(struct pcap_file_header));

ptk_header = (struct pcap_pkthdr *)malloc(sizeof(struct pcap_pkthdr));

ip_header = (IPHeader_t *)malloc(sizeof(IPHeader_t));

tcp_header = (TCPHeader_t *)malloc(sizeof(TCPHeader_t));

memset(buf, 0, sizeof(buf));

//

if((fp = fopen(“test.pcap”,”r”)) == NULL)

{

printf(“error: can not open pcap file\n”);

exit(0);

}

if((output = fopen(“output.txt”,”w+”)) == NULL)

{

printf(“error: can not open output file\n”);

exit(0);

}

//开始读数据包

pkt_offset = 24; //pcap文件头结构 24个字节

while(fseek(fp, pkt_offset, SEEK_SET) == 0) //遍历数据包

{

i++;

//pcap_pkt_header 16 byte

if(fread(ptk_header, 16, 1, fp) != 1) //读pcap数据包头结构

{

printf(“\nread end of pcap file\n”);

break;

}

pkt_offset += 16 + ptk_header->caplen; //下一个数据包的偏移值

strftime(my_time, sizeof(my_time), “%Y-%m-%d %T”, localtime(&(ptk_header->ts.tv_sec))); //获取时间

// printf(“%d: %s\n”, i, my_time);

//数据帧头 14字节

fseek(fp, 14, SEEK_CUR); //忽略数据帧头

//IP数据报头 20字节

if(fread(ip_header, sizeof(IPHeader_t), 1, fp) != 1)

{

printf(“%d: can not read ip_header\n”, i);

break;

}

inet_ntop(AF_INET, (void *)&(ip_header->SrcIP), src_ip, 16);

inet_ntop(AF_INET, (void *)&(ip_header->DstIP), dst_ip, 16);

ip_proto = ip_header->Protocol;

ip_len = ip_header->TotalLen; //IP数据报总长度

// printf(“%d: src=%s\n”, i, src_ip);

if(ip_proto != 0×06) //判断是否是 TCP 协议

{

continue;

}

//TCP头 20字节

if(fread(tcp_header, sizeof(TCPHeader_t), 1, fp) != 1)

{

printf(“%d: can not read ip_header\n”, i);

break;

}

src_port = ntohs(tcp_header->SrcPort);

dst_port = ntohs(tcp_header->DstPort);

tcp_flags = tcp_header->Flags;

// printf(“%d: src=%x\n”, i, tcp_flags);

if(tcp_flags == 0×18) // (PSH, ACK) 3路握手成功后

{

if(dst_port == 80) // HTTP GET请求

{

http_len = ip_len – 40; //http 报文长度

match_http(fp, “Host: “, “\r\n”, host, http_len); //查找 host 值

match_http(fp, “GET “, “HTTP”, uri, http_len); //查找 uri 值

sprintf(buf, “%d: %s src=%s:%d dst=%s:%d %s%s\r\n”, i, my_time, src_ip, src_port, dst_ip, dst_port, host, uri);

//printf(“%s”, buf);

if(fwrite(buf, strlen(buf), 1, output) != 1)

{

printf(“output file can not write”);

break;

}

}

}

} // end while

fclose(fp);

fclose(output);

return 0;

}

//查找 HTTP 信息

void match_http(FILE *fp, char *head_str, char *tail_str, char *buf, int total_len)

{

int i;

int http_offset;

int head_len, tail_len, val_len;

char head_tmp[STRSIZE], tail_tmp[STRSIZE];

//初始化

memset(head_tmp, 0, sizeof(head_tmp));

memset(tail_tmp, 0, sizeof(tail_tmp));

head_len = strlen(head_str);

tail_len = strlen(tail_str);

//查找 head_str

http_offset = ftell(fp); //记录下HTTP报文初始文件偏移

while((head_tmp[0] = fgetc(fp)) != EOF) //逐个字节遍历

{

if((ftell(fp) – http_offset) > total_len) //遍历完成

{

sprintf(buf, “can not find %s \r\n”, head_str);

exit(0);

}

if(head_tmp[0] == *head_str) //匹配到第一个字符

{

for(i=1; i<head_len; i++) //匹配 head_str 的其他字符

{

head_tmp[i]=fgetc(fp);

if(head_tmp[i] != *(head_str+i))

break;

}

if(i == head_len) //匹配 head_str 成功,停止遍历

break;

}

}

// printf(“head_tmp=%s \n”, head_tmp);

//查找 tail_str

val_len = 0;

while((tail_tmp[0] = fgetc(fp)) != EOF) //遍历

{

if((ftell(fp) – http_offset) > total_len) //遍历完成

{

sprintf(buf, “can not find %s \r\n”, tail_str);

exit(0);

}

buf[val_len++] = tail_tmp[0]; //用buf 存储 value 直到查找到 tail_str

if(tail_tmp[0] == *tail_str) //匹配到第一个字符

{

for(i=1; i<tail_len; i++) //匹配 head_str 的其他字符

{

tail_tmp[i]=fgetc(fp);

if(tail_tmp[i] != *(tail_str+i))

break;

}

if(i == tail_len) //匹配 head_str 成功,停止遍历

{

buf[val_len-1] = 0; //清除多余的一个字符

break;

}

}

}

// printf(“val=%s\n”, buf);

fseek(fp, http_offset, SEEK_SET); //将文件指针 回到初始偏移

}

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/168390.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
pythonpcap原生python读取
本文代码都由python编写,无需安装第三方拓展库,代码更新:https://github.com/mengdj/python
py3study
2020/01/03
1.5K0
pythonpcap原生python读取
Libpcap 落地包转发及性能调优
近期接到一个需求,需要使用 libpcap 从某网卡抓包发送到另一张网卡,关于 libpcap 的使用方法在这里不再赘述,网上有很多教程,本文最后会给出一个示例程序。这里记录一个转发效率性能调优的方法。
宋天伦
2023/10/18
6850
Libpcap 落地包转发及性能调优
使用 BPF 统计网络流量
本文介绍使用 BPF 统计网络流量。网络流量是云产品的重要计费指标,服务器每秒可以处理上百万的数据包,这也要求有高效的方法来统计流量,而 BPF 最初作为网络包处理的技术,被设计和构造成可以支持这个速率的流量处理。
ritchiechen
2021/03/21
3.9K0
运用Npcap库实现SYN半开放扫描
Npcap 是一款高性能的网络捕获和数据包分析库,作为 Nmap 项目的一部分,Npcap 可用于捕获、发送和分析网络数据包。本章将介绍如何使用 Npcap 库来实现半开放扫描功能。TCP SYN 半开放扫描是一种常见且广泛使用的端口扫描技术,用于探测目标主机端口的开放状态。由于这种方法并不完成完整的 TCP 三次握手过程,因此具有更高的隐蔽性和扫描效率。
王瑞MVP
2024/08/10
1920
运用Npcap库实现SYN半开放扫描
利用 Python 解析pcap文件
当面对处理网络数据包分析时,pcap文件作为一个常见的文件格式存储了网络数据包的详细记录,它常常被用来进行网络故障排查或安全分析。为了充分利用这些数据,我们需要对其进行解析并提取出有价值的信息,例如数据包类型 (如 TCP 或 UDP)、数据包的起始和结束时间等。本文旨在探讨如何使用 Python 解析pcap文件,并提供实用的解决方案和代码示例。
用户11021319
2024/07/08
9050
利用 Python 解析pcap文件
使用Libpcap捕获局域网中的数据包
void handler(u_char *, const struct pcap_pkthdr *, const u_char *);是一个回调函数,用于处理数据包。它接受三个参数:
Andromeda
2023/11/23
7070
Winpcap基础代码
Winpcap基础代码     使用Winpcap进行网络数据的截获和发送都需要的一段代码: #include<PCAP.H> #pragma comment(lib, "wpcap.lib") //#pragma comment(lib, "ws2_32.lib") #include<iostream> using namespace std; //回调函数 void packet_handler(u_char*param,const struct pcap_pkthdr*header,const u
Florian
2018/02/05
9020
代码实现TCP三次握手:程序实现
本节我们通过代码来实现TCP协议连接时的三次握手过程。首先我们需要再次重温一下TCP数据包的相关结构:
望月从良
2019/08/20
1K0
代码实现TCP三次握手:程序实现
基于Go Packet实现网络数据包的捕获与分析
Packet capture is a computer networking term for intercepting a data packet that is crossing or moving over a specific computer network.Once a packet is captured, it is stored temporarily so that it can be analyzed. The packet is inspected to help diagnose and solve network problems and determine whether network security policies are being followed.
RiboseYim
2018/01/20
6.5K0
数据包发送与嗅探
实验过程中采用过libnet与libpcap,最后全部转为Raw Socket发送与嗅探。
公众号guangcity
2019/09/20
2.6K0
数据包发送与嗅探
Python 运用Dpkt库解析数据包
dpkt项目是一个python模块,用于快速、简单的数据包解析,并定义了基本TCP/IP协议,使用该库可以快速解析通过各类抓包工具抓到的数据包,从而提取分析包内的参数。
王瑞MVP
2022/12/28
1.9K0
恶意加密流量- pcap包解析
e5da c850 就是时间戳的高位 fbdc 0800 就是时间戳的低位 2a00 0000 就是数据包的大小,十六进制,转换成十进制,就是42 Byte 2a00 0000 就是抓到的包的大小 ffff ffff ffff 0000 0000 0000 0800 4500 001c 0001 0000 4032 7cad 7f00 0001 7f00 0001 0102 0304 0000 0001 就是数据包,长度一共是 42 Byte
AI拉呱
2022/10/05
2.3K0
恶意加密流量- pcap包解析
18.3 NPCAP自定义数据包过滤
NPCAP 库是一种用于在Windows平台上进行网络数据包捕获和分析的库。它是WinPcap库的一个分支,由Nmap开发团队开发,并在Nmap软件中使用。与WinPcap一样,NPCAP库提供了一些API,使开发人员可以轻松地在其应用程序中捕获和处理网络数据包。NPCAP库可以通过WinPcap API进行编程,因此现有的WinPcap应用程序可以轻松地迁移到NPCAP库上。
王瑞MVP
2023/10/26
5620
18.3 NPCAP自定义数据包过滤
DPDK 网卡收包流程
NIC 在接收到数据包之后,首先需要将数据同步到内核中,这中间的桥梁是 rx ring buffer。它是由 NIC 和驱动程序共享的一片区域,事实上,rx ring buffer 存储的并不是实际的 packet 数据,而是一个描述符,这个描述符指向了它真正的存储地址,具体流程如下:
dpdk-vpp源码解读
2023/03/07
3.5K0
DPDK 网卡收包流程
C/C++ Npcap包实现数据嗅探
npcap 是Nmap自带的一个数据包处理工具,Nmap底层就是使用这个包进行收发包的,该库,是可以进行二次开发的,不过使用C语言开发费劲,在进行渗透任务时,还是使用Python构建数据包高效,这东西没啥意义.
王瑞MVP
2022/12/28
1K0
Python-对Pcap文件进行处理,获
        通过对TCP/IP协议的学习,本人写了一个可以实现对PCAP文件中的IPV4下的TCP流提取,以及提取指定的TCP流,鉴于为了学习,没有采用第三方包解析pcap,而是对bytes流进行解析,其核心思想为:若想要提取TCP Content,需在下层的IPV4协议中判断Protocol是否为TCP,然后判断下层的以太网协议的Type是否为IPV4协议(此处的IPV4判断,只针对本人所写项目);对于指定流需要获取Client以及Server的[IP,PORT]。
py3study
2020/01/19
4K0
Python-对Pcap文件进行处理,获
SeedLab——Packet Sniffing and Spoofing Lab
在这个实验中,攻击者需要能够嗅探数据包,但在容器内运行嗅探程序会有问题,因为容器实际上连接到一个虚拟交换机,所以它只能看到自己的流量,无法看到其他容器之间的数据包。为了解决这个问题,我们在攻击者容器中使用主机模式(host mode)。
Andromeda
2023/11/22
1K0
SeedLab——Packet Sniffing and Spoofing Lab
libpcap试玩
libpcap驱动了tcpdump,和wireshark这类抓包工具.提供了高度灵活的包过滤语言. 据wikipedia,高性能的包过滤最早是在bsd上作为一个问题被解决,被称为bpf,在内核实现了一个解释器,进行包匹配,用户态提供一个字符设备, linux作为后来者,支持与bsd基本相同的packet filter,称为lpf,不同的是,linux是通过在一个raw socket来支持包过滤的,通过setsockopt来SO_ATTACH_FILTER,挂载过滤器. strace 可知,libpcap实际上进行了如下syscall:
byronhe
2021/06/25
7200
MIT 6.S081 Lab 11 -- NetWork - 下
上一节我们总体介绍了一下手册中有关数据接收和传输的章节,本节借助上节的基础来完成lab的具体代码实现。
大忽悠爱学习
2023/10/11
3240
MIT 6.S081 Lab 11 -- NetWork - 下
腾讯云上 Winpcap 网络编程四之主机通信
根据文章内容总结,该文讨论了技术社区在应对大规模突发事件时,如何利用其丰富的技术工具、资源、人脉、知识和经验,快速响应和解决实际问题,以保障国家和社会的安全、稳定和发展。
崔庆才
2017/03/26
4.8K0
相关推荐
pythonpcap原生python读取
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文