WinPcap编程之HTTP协议还原

今天我们来看看一个小例子,利用前面所学到的WinPcap编程知识来实现一个简单的还原HTTP协议的程序。相信大家对于HTTP协议一定不会陌生,我这里只简单地说一下它的报文格式,即HTTP报文有两种:请求报文和响应报文。为了让大家对于这两种报文有更直观的认识,给大家看两个简单的例子:

下面是一个典型的HTTP请求报文:

GET /somedir/page.html HTTP/1.1Host: Connection: closeUser-agent: Mozilla/4.0Accept-language: fr

再看一个HTTP响应报文:

HTTP/1.1 200 OKConnection: closeDate: Thu, 03 Jul 2003 12:00:15 GMTServer: Apache/1.3.0 (Unix)Last-Modified: Sun, 6 May 2007 09:23:24 GMTContent-Length: 6821Content-Type: text/html(data data data data data …)

我们注意到HTTP请求报文中的第一行是以GET打头的,没错,它实际上是HTTP请求的一种方法,类似的还有POST、HEAD等等。一般熟知的大概就是GET和POST了,像Servlet编程中就有doGet和doPost两种提交HTTP请求的方法。而对于HTTP响应报文而言,第一行开头是协议的版本号,如HTTP/1.1,现在普及的也是HTTP/1.1。利用这些我们可以来判断TCP数据报文里是否保存的HTTP数据。

本程序的实现思路有很多种,我采用的是一种最笨拙的方式,即按照 判断是否是IP数据包->判断是否是TCP分组->判断是否是HTTP报文 的逻辑,最后将HTTP报文的内容打印出来。程序开始前我们需要先定义一些重要协议的包格式,因为WinPcap并没有为我们定义这些东西。

View Code

/** define struct of ethernet header , ip address , ip header and tcp headertypedef struct ether_header {u_char ether_shost[ETHER_ADDR_LEN]; u_char ether_dhost[ETHER_ADDR_LEN]; u_short ether_type;}ether_header;typedef struct ip_address {u_char byte1;u_char byte2;u_char byte3;u_char byte4;}ip_address;typedef struct ip_header {u_char ver_ihl;u_char tos;u_short tlen;u_short identification; u_short flags_fo;// flags and fragment offset u_char ttl;u_char proto;u_short crc;ip_address saddr;ip_address daddr;u_int op_pad;}ip_header;typedef struct tcp_header {u_short th_sport;u_short th_dport;u_int th_seq;u_int th_ack;u_short th_len_resv_code; u_short th_window;u_short th_sum;u_short th_urp;}tcp_header;

还有一些重要的识别协议的类型,我们需要自己在代码中进行定义。

#define ETHERTYPE_IP 0x0800 /* ip protocol */#define TCP_PROTOCAL 0x0600 /* tcp protocol */

接下来再看看刚才所说的程序的逻辑是如何实现的。

1. 判断是否是IP数据包。我们先回顾一下,在RFC 894中定义了以太网的封装格式,由目的地址(6字节)、源地址(6字节)、类型(2字节)、数据以及CRC(4字节)构成。我们只需要关注头部中类型这个字段,当它为0x0800时,表示数据保存的是IP数据报;当它为0x0806时,表示数据保存的是ARP请求/应答;当为0x8035时,数据保存的是RARP请求/应答。所以通过比较它的类型是否为0x0800,从而可以到达目的。

2. 判断是否是TCP分组。跟上面类似,可以通过判断IP首部中协议字段是否为0x0600即可。

3. 判断是否是HTTP报文。根据上面所讲解的HTTP报文格式,我们只需要判断开头是否为"GET"、"POST"、"HTTP/1.1"就可以做到了。具体程序是如何来判断的我们来看看代码吧!

View Code

((res = pcap_next_ex(adhandle, &pheader, &pkt_data)) >= 0) {if(res == 0)ether_header * eheader = (ether_header*)pkt_data; (eheader->ether_type == htons(ETHERTYPE_IP)) { ip_header * ih = (ip_header*)(pkt_data+(ih->proto == htons(TCP_PROTOCAL)) { ip_len = ntohs(ih->tlen); find_http = false;char* ip_pkt_data = (char*)ih;int n = 0;char buffer[BUFFER_MAX_LENGTH];int bufsize = 0;for(; n<ip_len; n++){(!find_http && ((n+,strlen()) ==0 )|| (n+,strlen()) == 0)) )find_http = true;(!find_http && i+,strlen())==0)find_http = true;(find_http){buffer[bufsize] = ip_pkt_data[n]; bufsize ++;}}(find_http) {buffer[bufsize] = ;printf(, buffer);printf();}}}}

看一下运行后的截图:

梦想从来不会选择人,它是上天赋予每个人构建未来蓝图的神奇画笔。

WinPcap编程之HTTP协议还原

相关文章:

你感兴趣的文章:

标签云: