winpcap抓包,如何判断这个包是否是HTTP的包?

sugarforever 2006-09-03 10:56:34
如题.多谢大虾指导
...全文
1832 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Arthur_ 2006-09-06
  • 打赏
  • 举报
回复
shi
sugarforever 2006-09-05
  • 打赏
  • 举报
回复
那我是从tcp数据的第一位开始字符串匹配HTTP, CONTENT等东西吗?
Arthur_ 2006-09-05
  • 打赏
  • 举报
回复
格式是固定的,查一下就可以了,一般包括 HTTP/1.0,返回码应该是200以上,content
sugarforever 2006-09-05
  • 打赏
  • 举报
回复
没有人能给予更多的知道吗?
比如我应该如何解出HTTP头呢?
sugarforever 2006-09-04
  • 打赏
  • 举报
回复
光用端口号应该不行吧。
比如我开个qq。默认登陆的时候,是连接的某个服务器的。
那么通过抓包可以发现,qq是会不断地在80端口上发包的。
如果我用IE连接新浪等,那它也是走的80端口。我这个时候这两种包都会抓到,我如何判断哪种是http包呢?
寡人对TCP/IP没有深入的理解。望大虾们指教。
OOPhaisky 2006-09-04
  • 打赏
  • 举报
回复
在应用层是利用端口号来进行“复用/解复用”的,而不是利用协议号,这个楼主应该知道吧
OOPhaisky 2006-09-04
  • 打赏
  • 举报
回复
你既然获得完整的包了,那么就可以利用端口号判断一下是什么应用程序啊......
sugarforever 2006-09-04
  • 打赏
  • 举报
回复
继续请教,我现在已经抓下。

#include "pcap.h"
#include <string>

/* 4 bytes IP address */
typedef struct ip_address
{
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
}ip_address;

/* IPv4 header */
typedef 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
}ip_header;

/* TCP header*/
typedef struct tcp_header
{
u_short sport; // Source port
u_short dport; // Destination port
u_int seq_num; // sequence number
u_int ack_num; // acknowledgement number
u_short hdr_len_resv_code; // Datagram length
u_short window; // window
u_short crc; // Checksum
u_short urg_pointer; // urgent pointer
u_int opt_pad; // options and padding
}tcp_header;

/* prototype of the packet handler */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);

/* send packet */
void packet_sender(pcap_t* fp, u_char* packet, int len);

pcap_t* handler = NULL;

main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
u_int netmask;
char packet_filter[] = "ip and tcp";
struct bpf_program fcode;

/* Retrieve the device list */
if(pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}

/* Print the list */
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);

/* Check if the user specified a valid adapter */
if(inum < 1 || inum > i)
{
printf("\nAdapter number out of range.\n");

/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}

/* Jump to the selected adapter */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);

/* Open the adapter */
if ((adhandle= pcap_open_live(d->name, // name of the device
65536, // portion of the packet to capture.
// 65536 grants that the whole packet will be captured on all the MACs.
1, // promiscuous mode (nonzero means promiscuous)
1000, // read timeout
errbuf // error buffer
)) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
handler = adhandle;
/* Check the link layer. We support only Ethernet for simplicity. */
if(pcap_datalink(adhandle) != DLT_EN10MB)
{
fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}

if(d->addresses != NULL)
/* Retrieve the mask of the first address of the interface */
netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
else
/* If the interface is without addresses we suppose to be in a C class network */
netmask=0xffffff;


//compile the filter
if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 )
{
fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}

//set the filter
if (pcap_setfilter(adhandle, &fcode)<0)
{
fprintf(stderr,"\nError setting the filter.\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}

printf("\nlistening on %s...\n", d->description);

/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);

/* start the capture */
pcap_loop(adhandle, 0, packet_handler, NULL);

return 0;
}

void packet_sender(pcap_t* fp, const u_char* packet, int len)
{
int ret = 0;
if(fp != NULL && packet != NULL)
ret = pcap_sendpacket(fp, packet, len);
if(ret != 0)
printf("\nError sending packet: %s\n", pcap_geterr(fp));
}

/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
struct tm *ltime;
char timestr[16];
ip_header *ih;
const char* http = "http";
std::string body;
tcp_header *th;
u_int ip_len;
u_int tcp_len;
u_short sport,dport;
u_int tcpbd_len;

/* retireve the position of the ip header */
ih = (ip_header *) (pkt_data +
14); //length of ethernet header

/* retireve the position of the udp header */
ip_len = (ih->ver_ihl & 0xf) * 4;
th = (tcp_header *) ((u_char*)ih + ip_len);
tcp_len = ((th->hdr_len_resv_code & 0xf000) >> 12) * 4;
tcpbd_len = ih->tlen - ip_len - tcp_len;

char* tmp = new char[tcpbd_len + 1];
memcpy(tmp, ((u_char*)th + tcp_len), tcpbd_len);
tmp[tcpbd_len] = '\0';

body = tmp;
delete[] tmp;
std::string::size_type pos = body.find(http);

if(pos != std::string::npos)
{
/* convert the timestamp to readable format */
ltime=localtime(&header->ts.tv_sec);
strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);

/* print timestamp and length of the packet */
printf("%s.%.6d len:%d \n", timestr, header->ts.tv_usec, header->len);

/* convert from network byte order to host byte order */
sport = ntohs( th->sport );
dport = ntohs( th->dport );

/* print ip addresses and udp ports */
printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n",
ih->saddr.byte1,
ih->saddr.byte2,
ih->saddr.byte3,
ih->saddr.byte4,
sport,
ih->daddr.byte1,
ih->daddr.byte2,
ih->daddr.byte3,
ih->daddr.byte4,
dport);
//}

/* send packet again */
if(handler)
packet_sender(handler, pkt_data, header->len);
}

这是我的代码,我是先剥ethernet header,然后是ip header,然后是tcp header,然后取到tcp包的数据部分。那我如何读取body中的信息呢?我上面的find方法肯定是不行的吧.
sugarforever 2006-09-04
  • 打赏
  • 举报
回复
谢谢wanfustudio(雁南飞)的解答。
winpcap可以设置filter只抓tcp包。所以分析协议类型ip_hdr->ip_p(就这个意思)
如果是6: TCP协议 这一步可以省略了。所谓的分析端口是源端口吧?这样一定能唯一确定吗?还是有点觉得不实在。
飞哥 2006-09-04
  • 打赏
  • 举报
回复
去掉以太帧头 +14
就是IP包了
分析协议类型ip_hdr->ip_p(就这个意思)
如果是6: TCP协议
去掉IP头 + 20
就是TCP包
分析端口:80
就可以了
Duwchy 2006-09-03
  • 打赏
  • 举报
回复
查看一下抓的包的内容,HTTP包都包含HTTP头等html代码

64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧