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檔案解析
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); //將檔案指標 回到初始偏移
}
相關推薦
pcap檔案格式及檔案解析
第一部分:PCAP包檔案格式 一 基本格式: 檔案頭 資料包頭資料報資料包頭資料報...... 二、檔案頭: 檔案頭結構體 sturct pcap_file_header { DWORD magic; DWORD
TSM檔案格式及例項解析(四)——string的排列
目錄 引: 資料 簡析 Indexes: blocks: 關聯string 小結: TSM檔案格式現已基本明瞭,某些壓縮演算法有空再去研究一下。 引: 現在想知道未壓縮的檔案格式是怎樣。 但是翻遍官方配置文件 https://docs.influx
Linux---基本命令格式及檔案處理命令
命令提示符 [[email protected] ~]# 其中: root 當前登入使用者 node1 主機名 ~ 當前所在目錄(家目錄) # 超級使用者的提示符 $ 普通使用者的提示符 命令格式 命
flv檔案格式及h264 aac流封裝成flv
FLV檔案格式 FLV是流媒體封裝格式,我們可以將其資料看為二進位制位元組流。 FLV包括檔案頭(Flv Header)和檔案體(Flv Body)兩部分,其中檔案體由一系列的Tag及Tag Size對組成。Tag又可以分成三類:audio,video,
win7系統下epub檔案格式及開啟方法
最近有win7系統使用者提到一個問題即epub是什麼格式檔案、要怎樣開啟epub格式檔案,其實ePub是一個自由的開放標準,屬於一種可以“自動重新編排”的內容,也就是文字內容可以根據閱讀裝置的特性,以最適於閱讀的方式顯示。下面小編就來說說有關epub檔案的格式以及如何開啟的方法。有興趣的使用者可以參考
caffe 實戰系列:proto檔案格式以及含義解析:如何定義網路,如何設定網路引數(以AlexNet為例) 2016.3.30
(0)前言: 初學者往往不知道如何配置網路,或者面對這些引數卻無從下手不知道是什麼含義,下面我根據分析原始碼的經驗給出AlexNet的具體解釋,希望能夠給初學者一些定義網路上面的幫助此外還能夠知道如何找網路的引數,這些引數是如何設定的。 以AlexNet為例: 首先給出配
檔案系統及檔案許可權
檔案系統及檔案許可權 命令幫助 –help和-h選項 顯示用法總結和引數列表 使用的大多數,但並非所有的 示例: date–help Usage:date[OPTION]…[+FORMAT]or: date[-u|–utc|–universal][MMDDhhmm
.Neter玩轉Linux系列之二:Linux下的檔案目錄及檔案目錄的許可權
基礎篇 實戰篇 一、Linux下的檔案目錄 簡介:linux的檔案系統是採用級層式的樹狀目錄結構,在此 結構中的最上層是根目錄“/”,然後在此目錄下再建立 其他的目錄。深刻理解linux檔案目錄是非常重要的,如下圖所示: 將來你用哪個使用者登入,你就會在那個使用
Java讀取多種檔案格式的檔案(pdf,pptx,ppt,doc,docx...)
通過開源pdfbox和poi進行處理多種檔案格式的文字讀入 1.需要的jar的maven座標: <dependency> <groupId>org.apache.pdfbox</groupId> <
Linux下獲得檔案屬性及檔案結構體的使用
第一種,通過路徑的方法 int stat(const char *path, struct stat *_stat); int lstat(const char *path,struct stat *_stat); 兩者的第一個引數都是檔案的路徑,第二
檔案物件及檔案對映物件
檔案物件和檔案對映物件 (問題來源:IPP例子simple_player vm_mmap _win32.c檔案中的vm_mmap_create函式) 1.記憶體對映檔案 記憶體對映檔案與虛擬記憶體有些類似,通過記憶體對映檔案可以保留一個地址空間的區域,同時將物
python中寫入檔案資料及檔案定位操作命令
如果我們向檔案中寫入資料的話,我們可以使用write()函式。 寫檔案: #開啟檔案 f = open("./index.cpp","w") #1. 寫入資料 contents ="hello w
Linux檔案系統及檔案相關命令
Linux中一切皆檔案 檔案系統是作業系統用於在磁碟或分割槽上的組織檔案的方法和資料結構。 檔案系統由三部分組成:與檔案管理相關的軟體,被管理檔案以及實施檔案管理所需的資料結構。 從系統的角度來看,檔案系統是對檔案儲存器空間進行組織和分
Windows Server 2008 R2應用基礎-實驗二-檔案許可權及檔案共享
實驗要求 實驗內容及步驟 掌握 NTFS 與 FAT32 檔案系統的區別,觀察各分割槽的檔案系統 比較同同一分割槽和不同 NTFS 分割槽上進行檔案複製、移動時檔案許可權的變化 設定檔案加密、壓縮 在 NTFS 分割槽建立資料夾 temp,進入屬性頁面中的“安
讓你提前認識軟體開發(12):配置檔案讀取及檔案操作
第1部分 重新認識C語言配置檔案讀取及檔案操作【文章摘要】 在通訊領域的軟體開發專案中,C語言是主流的程式語言,而檔案操作在其中又佔有很重要的地位。此外,為了體現產品的靈活性,可新增配置檔
Linux系統檔案系統及檔案基礎篇
Linux系統檔案系統及檔案基礎篇 學習L
Linux的檔案系統及檔案快取知識點整理
https://www.luozhiyun.com/archives/291 ## Linux的檔案系統 ### 檔案系統的特點 1. 檔案系統要有嚴格的組織形式,使得檔案能夠以塊為單位進行儲存。 2. 檔案系統中也要有索引區,用來方便查詢一個檔案分成的多個塊都存放在了什麼位置。 3. 如果檔案系統中有的檔
ELF格式檔案符號表全解析及readelf命令使用方法
readelf 命令引數 以 hello.c 程式為例 #include <stdio.h> #include <stdlib.h> int main() { int a=100; print
Java Class檔案格式解析及例項
JAVA無關性概述 Java語言從剛誕生開始曾提出一個非常著名的宣言:“一次編寫,到處執行(Write Once, Run Anywhere)”。Sun公司和其他虛擬機器公司釋出了許多可以執行在不同作業系統上的虛擬機器,這些虛擬機器都可以載入和執行同一種平臺無關的位元組碼,
Mp3原理及檔案格式解析
1.引言 文 件壓縮技術的日新月異使得MP3成為時下最燙手的音樂格式,優質的音樂隨著0與1的排列迅速散佈到世界各地,撼動人心。何謂MP3?MP3的全稱是 MPEG Audio Layer 3,它是一種高效的計算機音訊編碼方案,它以較大的壓縮比將音訊檔案轉換成較小的副檔名為.MP3的檔案,基本保持原檔案的音質