http://www.ferrisxu.com/WinPcap/html/index.html
http://www.winpcap.org/下载:http://www.winpcap.org/archive/4.1beta5_WpdPack.zip
这个包里面有很多例子,下面我们就可以编程实现了:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#define HAVE_REMOTE
#include <pcap.h>
#include <iomanip>
#include <string>
#include <stdio.h>
using namespace std;
#include <pcap.h>
#pragma comment(lib,"wpcap.lib")
#pragma comment(lib,"ws2_32.lib")
//https://github.com/yfnick/winpcap/blob/master/ref_http/main.cpp
//demo https://github.com/yfnick/winpcap
/*Ethernet Heder*/
struct ether_header
{
u_int8_t ether_dhost[6]; /* destination eth addr */
u_int8_t ether_shost[6]; /* source ether addr */
u_int16_t ether_type; /* packet type ID field */
};
/* 4 bytes IP address */
struct ip_address{
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
};
/* IPv4 header */
struct ip_header{
u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits)
u_char tos; // Type of service
u_short tlen; // Total length
u_short identification; // Identification
u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits)
u_char ttl; // Time to live
u_char proto; // Protocol
u_short crc; // Header checksum
ip_address saddr; // Source address
ip_address daddr; // Destination address
u_int op_pad; // Option + Padding
};
/* UDP header*/
struct udp_header{
u_short sport; // Source port
u_short dport; // Destination port
u_short len; // Datagram length
u_short crc; // Checksum
};
/*TCP Header*/
struct tcp_header
{
u_int16_t th_sport; /* source port */
u_int16_t th_dport; /* destination port */
u_int32_t th_seq; /* sequence number */
u_int32_t th_ack; /* acknowledgement number */
u_int16_t th_len_resv_code; // Datagram length and reserved code
u_int16_t th_win; /* window */
u_int16_t th_sum; /* checksum */
u_int16_t th_urp; /* urgent pointer */
};
int main()
{
//retrieve the devices list
pcap_if_t *all_devs;
char err_buff[PCAP_ERRBUF_SIZE];
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &all_devs, err_buff) == -1){
cerr << "Error in pcap_findalldevs_ex " << err_buff << endl;
return -1;
}
//get the device index,default is the first one
int dev_idx = 2;
pcap_if_t *dev = all_devs;
for (int i = 0; i < dev_idx; ++i, dev = dev->next);//jump to the device of the specified index
cout << "Listen on: " << dev->name << endl;
cout << "****************************************" << endl;
//get the netcard adapter
pcap_t *adpt_hdl = pcap_open(dev->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, err_buff);
if (adpt_hdl == NULL){
cerr << "Unable to open adapter " << dev->name << endl;
pcap_freealldevs(all_devs);
return -1;
}
/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(all_devs);
//analyze each packet
struct pcap_pkthdr *header;
const u_char *pkt_data;
int rst = 0;
char x;
FILE *fp, *fq;
fp = fopen("http.txt", "w+");
fq = fopen("ac.txt", "w+");
while ((rst = pcap_next_ex(adpt_hdl, &header, &pkt_data)) >= 0)
{
if (rst == 0){
//time out and not packet captured
continue;
}
ether_header *eh = (ether_header*)pkt_data;
if (ntohs(eh->ether_type) == 0x0800){ // ip packet only
ip_header *ih = (ip_header*)(pkt_data + 14);
if (ntohs(ih->proto) == 0x0600){ // tcp packet only
int ip_len = ntohs(ih->tlen);//ip_len = ip_body + ip_header
bool find_http = false;
string http_txt = "";
//char* http;
char* ip_pkt_data = (char*)ih;
for (int i = 0; i < ip_len; ++i){
//check the http request
if (!find_http && ( 3 < ip_len && strncmp(ip_pkt_data + i, "GET", strlen("GET")) == 0)
|| (i + 4 < ip_len && strncmp(ip_pkt_data + i, "POST", strlen("POST")) == 0)){
find_http = true;
}
//check the http response
if (!find_http && i + 8 < ip_len && strncmp(ip_pkt_data + i, "HTTP/1.1", strlen("HTTP/1.1")) == 0){
find_http = true;
}
//collect the http text
if (find_http){
http_txt += ip_pkt_data[i];
fputc(ip_pkt_data[i], fp);
if ((ip_pkt_data[i] > 'A'&&ip_pkt_data[i]<'Z') || (ip_pkt_data[i]>'a'&&ip_pkt_data[i]<'z'))
{
if ((ip_pkt_data[i]>'A'&&ip_pkt_data[i] < 'Z'))
x = ip_pkt_data[i] - 'A' + 'a';
else x = ip_pkt_data[i];
fputc(x, fq);
}
}
}
//print the http request or response
if (http_txt != ""){
cout << http_txt;
cout << endl << "***********************************************************" << endl << endl;
}
}
}
}
return 0;
}
#define HAVE_REMOTE
#define _CRT_SECURE_NO_WARNINGS 1
#include <pcap.h>
#pragma comment(lib,"wpcap.lib")
/* 回调函数原型 */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
int main(int argc, char **argv)
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i = 0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_dumper_t *dumpfile;
/* 检查程序输入参数 */
if (argc != 2)
{
printf("usage: %s filename", argv[0]);
return -1;
}
/* 获取本机设备列表 */
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/* 打印列表 */
for (d = alldevs; d; d = d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if (i == 0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return -1;
}
printf("Enter the interface number (1-%d):", i);
scanf("%d", &inum);
if (inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
/* 释放列表 */
pcap_freealldevs(alldevs);
return -1;
}
/* 跳转到选中的适配器 */
for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
/* 打开适配器 */
if ((adhandle = pcap_open(d->name, // 设备名
65536, // 要捕捉的数据包的部分
// 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式
1000, // 读取超时时间
NULL, // 远程机器验证
errbuf // 错误缓冲池
)) == NULL)
{
fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
/* 打开堆文件 */
dumpfile = pcap_dump_open(adhandle, argv[1]);
if (dumpfile == NULL)
{
fprintf(stderr, "\nError opening output file\n");
return -1;
}
printf("\nlistening on %s... Press Ctrl+C to stop...\n", d->description);
/* 释放设备列表 */
pcap_freealldevs(alldevs);
/* 开始捕获 */
pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile);
return 0;
}
/* 回调函数,用来处理数据包 */
void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
/* 保存数据包到堆文件 */
pcap_dump(dumpfile, header, pkt_data);
}