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文件是wireshark配置腳本文件。可以用Wireshark軟體打開。
下面是打開pcap文件的步驟:
1、Wireshark(前稱Ethereal)是一個網路封包分析軟體。網路封包分析軟體的功能是擷取網路封包,並盡可能顯示出最為詳細的網路封包資料。Wireshark使用WinPCAP作為介面,直接與網卡進行數據報文交換。
2、網路封包分析軟體的功能可想像成 "電工技師使用電表來量測電流、電壓、電阻" 的工作 - 只是將場景移植到網路上,並將電線替換成網路線。
3、在過去,網路封包分析軟體是非常昂貴,或是專門屬於營利用的軟體。Ethereal的出現改變了這一切。在GNUGPL通用許可證的保障范圍底下,使用者可以以免費的代價取得軟體與其源代碼,並擁有針對其源代碼修改及客制化的權利。Ethereal是目前全世界最廣泛的網路封包分析軟體之一。
備註:需要下載Wireshark軟體才能打開。
③ C#.C/C++.net抓包抓網路協議包(WinPcap),該如何編寫,求源碼,求注釋,求指教!
您好,要添加一個預處理定義,你需要打開Project菜單,選擇Settings,然後選擇C/C++選項卡,在General類下,你必須在Preprocessor
Definitions下的文本框中添加定義。
要在一個VC++6.0工程中,添加一,個新的庫,你必須打開Project菜單,選擇Settings,然後選擇Link選項卡,然後把新庫的名字添加到Object/Library
moles下的文本框中
要向VC++6.0中添加一個新的庫所在的路徑,你必須打開Tool菜單,選擇Options,然後選擇Directories選項卡,在Show
directories下拉框中選擇Library
files,並且將新的路徑添加到Directories中去
要向VC++6.0中添加一個新的包含文件所在的路徑,你必須打開Tool菜單,選擇Options,然後選擇Directories選項卡,在Show
directories下拉框中選擇Include
files,並且將新的路徑添加到Directories中去
范常式序
我們一共了一些范常式序來顯示WinPcap API的用法。這些程序的源代碼,以及編譯運行這些代碼所需的所有文件,都可以在 Developer's
Pack找到。作為教程,在這里,我們提供了瀏覽器式的代碼:這樣,在每個函數和變數之間的跳轉會比較方便。更多完整的范常式序,請參閱 WinPcap
教程.
// NOTE: remember to include WPCAP and HAVE_REMOTE among
your preprocessor
definitions.
(工程->設置->c/c++->預處理程序定義
中添加WPCAP和HAVE_REMOTE)
如果連接有問題,把lib復制到工程目錄下用下面方法:
#pragma
comment(lib,"wpcap.lib")
#pragma comment(lib,"packet.lib")
④ 求助python pcap模塊問題
這個東西可能是兩個原因。一個就是少安裝了pcap對應的驅動程序,第二個可能是操作系統版本問題。 你可以在一個xp操作系統上試驗。 另外pcap應該有新版本。支持python2.7的。如果沒有自己下源碼編譯一下。 不過,還是建議你用linux來做試驗。這樣
⑤ linux下使用libpcap進行數據捕獲,能夠將捕獲到的數據包保存為pcap文件
libpcap和winpcap最大的不同就是 內核緩沖區,用戶緩沖區等都不能設置,沒有提供這樣的函數,要編譯libpcap源碼。
另外,linux Fedora 下使用libpcap時,找不到pcap.h,查找發現安裝了libpcap的庫但是沒有頭文件。解決辦法是:
1.如何查看是否安裝libpcap? #rpm -aq libpcap
2.查找libpcap源,yum search pcap
3.安裝libpcap, yum install libpcap-devel.i386
⑥ 哪裡可以下載到支持python2.7的pcapy呢望山下載的都是支持python2.5的。跪求支持python2.7的pcapy。
1.用google搜:
Pcapy - Corelabs site
可以找到該網頁。
2.去下載裡面的zip的源碼包,比如
pcapy-0.10.8.zip
3.然後解壓,運行cmd,手動執行:
setup.py install
4。如果不會安裝,那麼參考:
【總結】Python安裝第三方的庫、package的方法
(此處不給貼地址,請自己用google搜帖子標題,即可找到帖子地址)
⑦ 如何通過源碼安裝升級libpcap
安裝libcap開發包後,再試試看 sudo apt-get install libpcap-dev sudo apt-get install libnids-dev sudo apt-get install libnet1-dev
⑧ ubuntu下沒有沒有pcap.h頭文件,怎麼辦
今天在ubuntu下進行安裝wireshark,費了很多時間,過程中出了很多錯誤,但最終安裝成功了,這里寫下自己的安裝步驟和方法,供大家參考。
安裝編譯工具:
$sudo apt-get install build-essential
為了成功編譯Wireshark,您需要安裝GTK+的開發文件和GLib庫(libraries)。
$sudo apt-get install libgtk2.0-dev libglib2.0-dev
安裝Checkinstall以便管理您系統中直接由源代碼編譯安裝的軟體。
$sudo apt-get install checkinstall
wireshark源碼 (頁面中的source code)
下載後的文件名:wireshark-1.2.2.tar.bz2
cd到文件目錄解壓:$tar -xvf wireshark-1.2.2.tar.bz2
$cd wireshark-1.2.2
編譯安裝命令如下:
$./configure
$make
$sudo make install
其中make編譯時間會比較長,這樣下來就基本安裝了。
下面是我這篇文章的關鍵,也是用ubuntu安裝的過程中極有可能遇到的問題,且都是在進行./configure編譯過程中出現,兩個問題如下:
---------------------------------------------------------------------------------------------------------
問題1:
view plain to clipboardprint?
./configure執行到最後出錯
checking for perl... /usr/bin/perl
checking for bison... no
checking for byacc... no
checking for yacc... no
configure: error: I couldn't find yacc (or bison or ...); make sure it's installed and in your path
./configure執行到最後出錯
checking for perl... /usr/bin/perl
checking for bison... no
checking for byacc... no
checking for yacc... no
configure: error: I couldn't find yacc (or bison or ...); make sure it's installed and in your path
解決辦法:
view plain to clipboardprint?
sudo apt-get install flex bison
sudo apt-get install flex bison
yacc(Yet Another Compiler Compiler),是Unix/Linux上一個用來生成編譯器的編譯器(編譯器代碼生成器)。
如想深入了解google下。
問題2:
view plain to clipboardprint?
configure: error: Header file pcap.h not found; if you installed libpcap from source, did you also do "make install-incl", and if you installed a binary package of libpcap, is there also a developer's package of libpcap,
and did you also install that package?
configure: error: Header file pcap.h not found; if you installed libpcap from source, did you also do "make install-incl", and if you installed a binary package of libpcap, is there also a developer's package of libpcap,
and did you also install that package?
問題原因是ubuntu下缺少pcap.h等文件。
解決方法:
編譯安裝libpcap.
在www.tcpmp.org頁面中可下載源碼:libpcap-1.0.0.tar.gz
cd到文件目錄:
view plain to clipboardprint?
$tar -xvf libpcap-1.0.0.tar.gz
$cd libpcap-1.0.0.tar.gz
$./configure
$make
$sudo make install
$tar -xvf libpcap-1.0.0.tar.gz
$cd libpcap-1.0.0.tar.gz
$./configure
$make
$sudo make install
----------------------------------------------------------------------------------------------------------------------------------------------------
採用上面的方法後再回到文章前面的步驟:
$cd wireshark-1.2.2編譯安裝:
$./configure
$make
$sudo make install
這樣就安裝好了。
啟動方法:進入wireshark-1.2.2,輸入命令:view plain to clipboardprint?
$sudo ./wireshark
$sudo ./wireshark
這里如果不用sudo,則wireshark找不到網路設備介面,這主要與許可權有關,啟動時注意下就行。
⑨ 請教tshark源碼整合
tshark是wireshark的指令形式,有些情況下抓取網路包但是不想調用圖形界面時,可以用tshark
1、下載libpcap源代碼
http://www.tcpmp.org/
libpcap-x.x.x.tar.gz libpcap安裝源文件
2. 解壓縮libpcap
tar zxvf libpcap-x.x.x.tar.gz
進入到解壓縮後的文件夾中 cd libpcap- x.x.x
3. 安裝flex
apt-get install flex
4. 安裝bison
apt-get install biso
5. 安裝libpcap
./configure
make
make install
6. 安裝tshark
apt-get install tshark
7、指令應用
tshark是wireshark命令行形式
1)指定要監聽的介面
-i <介面名稱>
比如-i eth2.如果不用-i指定監聽的介面,則默認為介面列表中第一個非回環介面(-D列印介面列表)
2)可監聽的介面列表
-D 列印介面列表
3)設置cap過濾條件
-f <過濾參數設置>
A. 設置監聽的協議類型:-f udp/tcp/http 註:協議類型必須為小寫
B. 設置源ip: -f「src host x.x.x.x」
C. 設置源埠: -f「src port xx」
D. 設置源ip和源埠: -f 「srchost x.x.x.x and src port xx」
E. 設置目的ip: -f「dst host x.x.x.x」
F. 設置目的埠: -f「dst port xx」
G. 設置目的ip和埠: -f 「dsthost x.x.x.x and port xx」
註:設置ip或埠時,必須用雙引號
4)設置抓包數
-c <包數量> ,比如-c 15 表示抓15個包就停止
5) 設置cap包容量
-a filesize:NUM
其中NUM為filesize的包容量,用此命令需要用-w命令指定保存的文件包。NUM單位為KB
6)保存文件
-w <文件名稱>
-w後面是要保存到的文件名字,也可以指定路徑
7) 在屏幕中顯示抓包的內容
-S
8)指定數據包的最大長度
-s <數據包長度>,單位為bytes
其他指令請參照在線幫助