winpcap抓包示例原始碼
最近測試了下winpcap抓包功能,將原始碼共享出來。
啟動程式格式:程式名 ip
程式啟動需要輸入一個引數,即期望抓包的網路卡的IP。
程式碼如下:
#include "pcap.h"
#ifndef WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#else
#include <winsock.h>
#endif
#define PKT_MAX_LEN 65535
#define PKT_TIMEOUT 1000
#define PKT_ETH_MODE false
#define PA_ICMP 1 //控制資訊協議
#define PA_TCP 6 //傳輸控制協議
#define PA_EGP 8 //外部閘道器協議
#define PA_IGP 9 //內部閘道器協議
#define PA_UDP 17 //使用者資料包協議
typedef struct ethhdr
{
u_int8_t dhost[6]; //目的Mac地址
u_int8_t shost[6]; //源Mac地址
u_int16_t type; //協議型別
}ETH_HDR;
typedef struct ip_hdr //IP頭
{
#if defined(WORDS_BIENDIAN)
u_int8_t version:4,
header_length:4;
#else
u_int8_t header_length:4,
version:4;
#endif
u_int8_t tos;
u_int16_t length;
u_int16_t id;
u_int16_t off;
u_int8_t ttl;
u_int8_t proto;
u_int16_t checksum;
struct in_addr souce_addr;
struct in_addr dest_addr;
}IP_HDR;
typedef struct udp_hdr
{
unsigned short sport;
unsigned short dport;
unsigned short length;
unsigned short checksum;
}UDP_HDR;
typedef struct tcp_hdr //TCP頭
{
unsigned short sport; //16位源埠
unsigned short dport; //16位目的埠
unsigned int seq; //32位序列號
unsigned int ack; //32位確認號
unsigned char lenres; //4位首部長度/6位保留字
unsigned char flag; //6位標誌位
unsigned short win; //16位視窗大小
unsigned short sum; //16位校驗和
unsigned short urp; //16位緊急資料偏移量
}TCP_HDR;
#define IPTOSBUFFERS 12
char *iptos(u_long in)
{
static char output[IPTOSBUFFERS][3*4+3+1];
static short which;
u_char *p;
p = (u_char *)∈
which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
return output[which];
}
/* 處理資料包的回撥函式*/
void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
IP_HDR* ip_head;
TCP_HDR * tcp_head;
UDP_HDR * udp_head;
struct tm *ltime;
time_t tCurTime;
ip_head = (IP_HDR*)(pkt_data + sizeof(ETH_HDR));
if ( ip_head->proto == PA_TCP )
{
/* 轉換時間戳為可以閱讀的格式 */
tCurTime = header->ts.tv_sec;
ltime=localtime(&tCurTime);
ip_head->header_length;
tcp_head = (TCP_HDR *) ((u_char*)ip_head + ip_head->header_length);
// printf("%s,%.6d len:%d\n", timestr, , header->len);
/*printf("TCP %u:%u:%u:%u %s:%d-->%s:%d\n",ltime->tm_hour,ltime->tm_min,ltime->tm_sec,header->ts.tv_usec/1000,
inet_ntoa(ip_head->souce_addr), ntohs(tcp_head->sport), inet_ntoa(ip_head->dest_addr), ntohs(tcp_head->dport));
*/
pcap_dump(dumpfile, header, pkt_data);
}
else if ( ip_head->proto == PA_UDP )
{
/* 轉換時間戳為可以閱讀的格式 */
tCurTime = header->ts.tv_sec;
ltime=localtime(&tCurTime);
ip_head->header_length;
udp_head = (UDP_HDR *) ((u_char*)ip_head + ip_head->header_length);
/*
printf("UDP %u:%u:%u:%u %s:%d-->%s:%d\n",ltime->tm_hour,ltime->tm_min,ltime->tm_sec,header->ts.tv_usec/1000,
inet_ntoa(ip_head->souce_addr), ntohs(udp_head->sport), inet_ntoa(ip_head->dest_addr), ntohs(udp_head->dport));
*/
pcap_dump(dumpfile, header, pkt_data);
}
}
/* Print all the available information on the given interface */
void ifprint(pcap_if_t *d)
{
pcap_addr_t *a;
/* 名稱 */
//printf("%s\n",d->name);
/* 描述 */
if (d->description)
printf("\tDescription: %s\n",d->description);
/* 迴環地址 */
//printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");
/* IP 地址 */
for(a=d->addresses;a;a=a->next)
{
//printf("\tAddress Family: #%d\n",a->addr->sa_family);
switch(a->addr->sa_family)
{
case AF_INET:
//printf("\tAddress Family Name: AF_INET\n");
if (a->addr)
/* Y- IP 地址 */
printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
if (a->netmask)
/* Y- 掩碼 */
printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
if (a->broadaddr)
/* Y- 廣播地址 */
//printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
if (a->dstaddr)
/* Y - 目標地址 */
//printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
break;
default:
/* 未知 */
// printf("\tAddress Family Name: Unknown\n");
break;
}
}
printf("\n");
}
bool check_ip(pcap_if_t *d, const char* ip)
{
bool ret = false;
char szip[32];
pcap_addr_t *a;
/* 名稱 */
// printf("%s\n",d->name);
/* 描述 */
if (d->description)
//printf("\tDescription: %s\n",d->description);
/* 迴環地址 */
// printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");
/* IP 地址 */
for(a=d->addresses;a;a=a->next)
{
// printf("\tAddress Family: #%d\n",a->addr->sa_family);
switch(a->addr->sa_family)
{
case AF_INET:
// printf("\tAddress Family Name: AF_INET\n");
if (a->addr)
/* Y- IP 地址 */
{
strcpy(szip, iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
//printf("\tAddress: %s\n", szip);
if ( strcmp(szip, ip) == 0 )
ret = true;
}
if (a->netmask)
/* Y- 掩碼 */
//printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
if (a->broadaddr)
/* Y- 廣播地址 */
//printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
if (a->dstaddr)
/* Y - 目標地址 */
//printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
break;
default:
/* 未知 */
//printf("\tAddress Family Name: Unknown\n");
break;
}
}
//printf("\n");
return ret;
}
int main(int argc, char **argv)
{
pcap_if_t *alldevs;
pcap_if_t *d;
int i=0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_dumper_t *dumpfile;
printf("\n\n\n");
if(argc != 2)
{
printf("\tStart params lost, and you need too params as local ip.\n");
printf("\tFor example:winPcap4BLJ 192.168.6.6\n");
getchar();
return 0;
}
/* 獲取裝置列表 */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/* 遍歷所有元素 */
for(d=alldevs;d;d=d->next)
{
ifprint(d);
}
/* 遍歷所有元素 */
for(d=alldevs;d;d=d->next)
{
//找到有這個ip的網路卡
if ( check_ip(d, *(argv+1)) )
break;
}
if(!d)
{
printf("\tThe device is not found(%s)!\n",*(argv+1));
getchar();
return 0;
}
/* 開啟裝置 */
if ( (adhandle= pcap_open_live(d->name, //裝置名
PKT_MAX_LEN, // 捕捉完整的資料包
PKT_ETH_MODE, // 混雜模式
PKT_TIMEOUT, // 讀入超時
errbuf // 錯誤緩衝
) ) == NULL)
{
/* Y- 開啟失敗*/
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n");
/* 釋放列表 */
pcap_freealldevs(alldevs);
return -1;
}
u_int netmask;
u_int net_ip;
char error_content[PCAP_ERRBUF_SIZE] = {0};
pcap_lookupnet(d->name,&net_ip,&netmask,error_content); //這個就是用函式獲得了網路地址和子網掩碼,其返回的資料都放在net_ip和net_mask中的了,
printf("\tnetmask: 0x%02x\n",netmask); //簡單的輸出
struct bpf_program fcode;
char packet_filter[] = "ip and tcp and not port ftp-data";
// complie the filter
if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) < 0)
{
printf("\n\tUnable to compile the packet filter\n");
// Free the devices list
pcap_freealldevs(alldevs);
return -1;
}
// set the filter
if (pcap_setfilter(adhandle, &fcode) < 0)
{
printf("\n\tError setting the filter.\n");
// Free the devices list
pcap_freealldevs(alldevs);
return -1;
}
printf("\n\tlistening on %s...\n", d->description);
char path[MAX_PATH];
GetCurrentDirectory(MAX_PATH,path); // 檔案目錄儲存在path這個字元陣列中,
sprintf(path,"%s\\test.cap",path);
printf("\n\tWrite to file %s\n\t",path);
dumpfile = pcap_dump_open(adhandle, path);
if(dumpfile==NULL)
{
printf("\n\tError opening output file\n");
getchar();
return -1;
}
/* 我們已經不需要裝置列表了, 釋放它 */
pcap_freealldevs(alldevs);
/* 開始捕捉 */
pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile);
pcap_close(adhandle);
getchar();
return 0;
}
相關文章
- charles 抓包 https 亂碼HTTP
- CXC錢包系統開發需求及原始碼示例原始碼
- HTTP抓包HTTP
- tcpdump抓包TCP
- Fiddler抓包一鍵生成程式碼
- Https抓包HTTP
- iOS Charles抓包iOS
- iOS Wireshark抓包iOS
- iOS防止抓包iOS
- BLE抓包分析
- CentOS tcpflow抓包CentOSTCP
- wireshark抓包分析
- 從【抓包分析】到【程式碼實戰】,實現下載某破站影片(附原始碼)原始碼
- tshark 抓包 mysql 協議包MySql協議
- 談談HTTPS安全認證,抓包與反抓包策略HTTP
- https 真的安全嗎,可以抓包嗎,如何防止抓包嗎HTTP
- Wireshark網路抓包
- mitmproxy grpc 抓包MITRPC
- 【Charles】Https抓包HTTP
- Charles抓包實踐
- iperf測試抓包
- wireshark抓包學習
- APP抓包神器dronyAPP
- 前端抓包神器Charles前端
- Burp Suite抓包、截包和改包UI
- 蘋果示例原始碼閱讀:Reachability蘋果原始碼
- Maven生成原始碼包Maven原始碼
- sort 包原始碼分析原始碼
- Python 爬蟲、抓包Python爬蟲
- IPSEC隧道抓包分析
- APP常用抓包技術APP
- wireshark抓包新手使用教程
- Charles 4.2.1 HTTPS抓包HTTP
- Charles抓HTTP,HTTPS包HTTP
- Charles配置https抓包HTTP
- Docker 容器抓包說明Docker
- tcpdump抓包分析詳解TCP
- tcpdump抓包命令詳解TCP