抓包过滤HTTP报文


#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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值