抓包过滤HTTP报文

来源:互联网 发布:5s支持电信4g网络吗 编辑:程序博客网 时间:2024/06/04 19:38

#include "pcap.h"
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
 
/*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 */
typedef struct ip_address{
    u_char byte1;
    u_char byte2;
    u_char byte3;
    u_char byte4;
};
 
/* 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
};
 
/* UDP header*/
typedef 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 */
};
 
/*
 * check whether a char is readable
 */
bool is_readable(char c){   
    return isalnum(c) || ispunct(c) || isspace(c) || isprint(c);
}
 
/*
 * This demo show how to use winpcap sdk to capture the http request/respone, then print the readable content.
 * Note: in Visual Studio 2005,it should set the "project->config->c/c++->language->default unsigned char" to yes(/J) 
 *       to stop the assution.
 */
void main(int argc,char* argv[]){
     
    //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;
    }
 
    //get the device index,default is the first one
    int dev_idx = 0;
    if(argc == 2){
        dev_idx = atoi(argv[1]);
    }
    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;
    }
    /* 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;
    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) == 0x600){ // tcp packet only
                int ip_len = ntohs(ih->tlen);//ip_len = ip_body + ip_header
                bool find_http = false;
                string http_txt = "";
 
                char* ip_pkt_data = (char*)ih;
                for(int i=0;i<ip_len;++i){
                     
                    //check the http request
                    if(!find_http && (i+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 && is_readable(ip_pkt_data[i])){
                        http_txt += ip_pkt_data[i];
                    }
                }
 
                //print the http request or response
                if(http_txt != ""){
                    cout<<http_txt;
                    cout<<endl<<"***********************************************************"<<endl<<endl;
                }
            }
        }
    }
}
0 0
原创粉丝点击