WinPcap编程之HTTP协议还原
2012-03-22 14:52
357 查看
今天我们来看看一个小例子,利用前面所学到的WinPcap编程知识来实现一个简单的还原HTTP协议的程序。相信大家对于HTTP协议一定不会陌生,我这里只简单地说一下它的报文格式,即HTTP报文有两种:请求报文和响应报文。为了让大家对于这两种报文有更直观的认识,给大家看两个简单的例子:
下面是一个典型的HTTP请求报文:
再看一个HTTP响应报文:
我们注意到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
main.c文件
下面是一个典型的HTTP请求报文:
GET /somedir/page.html HTTP/1.1 Host: www.someschool.edu Connection: close User-agent: Mozilla/4.0 Accept-language: fr
再看一个HTTP响应报文:
HTTP/1.1 200 OK Connection: close Date: Thu, 03 Jul 2003 12:00:15 GMT Server: Apache/1.3.0 (Unix) Last-Modified: Sun, 6 May 2007 09:23:24 GMT Content-Length: 6821 Content-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
#ifndef PHEADER_H_INCLUDED #define PHEADER_H_INCLUDED /* * */ #define ETHER_ADDR_LEN 6 /* ethernet address */ #define ETHERTYPE_IP 0x0800 /* ip protocol */ #define TCP_PROTOCAL 0x0600 /* tcp protocol */ #define BUFFER_MAX_LENGTH 65536 /* buffer max length */ #define true 1 /* define true */ #define false 0 /* define false */ /* * define struct of ethernet header , ip address , ip header and tcp header */ /* ethernet header */ typedef struct ether_header { u_char ether_shost[ETHER_ADDR_LEN]; /* source ethernet address, 8 bytes */ u_char ether_dhost[ETHER_ADDR_LEN]; /* destination ethernet addresss, 8 bytes */ u_short ether_type; /* ethernet type, 16 bytes */ }ether_header; /* four 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 and ip header length */ u_char tos; /* type of service */ u_short tlen; /* total length */ u_short identification; /* identification */ u_short flags_fo; // flags and fragment offset 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 and padding */ }ip_header; /* tcp header */ typedef struct tcp_header { u_short th_sport; /* source port */ u_short th_dport; /* destination port */ u_int th_seq; /* sequence number */ u_int th_ack; /* acknowledgement number */ u_short th_len_resv_code; /* datagram length and reserved code */ u_short th_window; /* window */ u_short th_sum; /* checksum */ u_short th_urp; /* urgent pointer */ }tcp_header; #endif // PHEADER_H_INCLUDED
main.c文件
#include <stdio.h> #include <stdlib.h> #define HAVE_REMOTE #include <pcap.h> #include "pheader.h" /* * function: a simple program to analyze http * author: blacksword * date: Wed March 21 2012 */ int main() { pcap_if_t* alldevs; // list of all devices pcap_if_t* d; // device you chose pcap_t* adhandle; char errbuf[PCAP_ERRBUF_SIZE]; //error buffer int i=0; int inum; struct pcap_pkthdr *pheader; /* packet header */ const u_char * pkt_data; /* packet data */ int res; /* pcap_findalldevs_ex got something wrong */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL /* auth is not needed*/, &alldevs, errbuf) == -1) { fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf); exit(1); } /* print the list of all devices */ for(d = alldevs; d != NULL; d = d->next) { printf("%d. %s", ++i, d->name); // print device name , which starts with "rpcap://" if(d->description) printf(" (%s)\n", d->description); // print device description else printf(" (No description available)\n"); } /* no interface found */ if (i == 0) { printf("\nNo interface 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++); /* jump to the selected interface */ /* open the selected interface*/ if((adhandle = pcap_open(d->name, /* the interface name */ 65536, /* length of packet that has to be retained */ PCAP_OPENFLAG_PROMISCUOUS, /* promiscuous mode */ 1000, /* read time out */ NULL, /* auth */ errbuf /* error buffer */ )) == NULL) { fprintf(stderr, "\nUnable to open the adapter. %s is not supported by Winpcap\n", d->description); return -1; } printf("\nListening on %s...\n", d->description); pcap_freealldevs(alldevs); // release device list /* capture packet */ while((res = pcap_next_ex(adhandle, &pheader, &pkt_data)) >= 0) { if(res == 0) continue; /* read time out*/ ether_header * eheader = (ether_header*)pkt_data; /* transform packet data to ethernet header */ if(eheader->ether_type == htons(ETHERTYPE_IP)) { /* ip packet only */ ip_header * ih = (ip_header*)(pkt_data+14); /* get ip header */ if(ih->proto == htons(TCP_PROTOCAL)) { /* tcp packet only */ int ip_len = ntohs(ih->tlen); /* get ip length, it contains header and body */ int 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++) { /* http get or post request */ if(!find_http && ((n+3<ip_len && strncmp(ip_pkt_data+n,"GET",strlen("GET")) ==0 ) || (n+4<ip_len && strncmp(ip_pkt_data+n,"POST",strlen("POST")) == 0)) ) find_http = true; /* http response */ if(!find_http && n+8<ip_len && strncmp(ip_pkt_data+n,"HTTP/1.1",strlen("HTTP/1.1"))==0) find_http = true; /* if http is found */ if(find_http) { buffer[bufsize] = ip_pkt_data ; /* copy http data to buffer */ bufsize ++; } } /* print http content */ if(find_http) { buffer[bufsize] = '\0'; printf("%s\n", buffer); printf("\n**********************************************\n\n"); } } } } return 0; }
相关文章推荐
- WinPcap编程之HTTP协议还原
- WinPcap编程之HTTP协议还原
- WinPcap编程之HTTP协议还原
- WinPcap编程之HTTP协议还原
- \t\t(转载)HTTP协议的C语言编程实现实例
- HTTP协议的C语言编程实现实例
- HTTP协议演示_基于 HTTP 的 Web Forms 编程2-5
- HTTP协议分析系列(五)------php+socket编程发送http请求
- HTTP协议的C语言编程实现实例[摘抄]
- Java系列-Socket网络编程,TCP/IP和Http等网络协议理解
- http 协议的编程
- Android网络编程之socket和http协议的区别
- HTTP协议的C语言编程实现实例
- IOS学习之 网络编程(1)--HTTP协议
- HTTP协议演示_基于 HTTP 的 Web Forms 编程4-5-HTTP 协议
- HTTP协议的C语言编程实现实例
- android之Http协议编程01
- javaweb基础(Http协议、Servlet编程、会话管理)
- HTTP协议的C语言编程实现实例
- java网络编程(3):HTTP协议调用SOAP