使用libpcap抓取所有的http包

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/stSahana/article/details/79487144
/* Simple Raw Sniffer                                                    */ 
/* Author: Luis Martin Garcia. luis.martingarcia [.at.] gmail [d0t] com  */
/* To compile: gcc httpsniffer.c -o httpsniffer -lpcap               */ 
/* Run as root!                                                          */ 
/*                                                                       */
/* This code is distributed under the GPL License. For more info check:  */
/* http://www.gnu.org/copyleft/gpl.html                                  */

#include <pcap.h> 
#include <string.h> 
#include <stdlib.h> 
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <net/ethernet.h>

#define MAXBYTES2CAPTURE 2048 


/* processPacket(): Callback function called by pcap_loop() everytime a packet */
/* arrives to the network card. This function prints the captured raw data in  */
/* hexadecimal.                                                                */
void processPacket(u_char *arg, const struct pcap_pkthdr* pkthdr, const u_char * packet){ 
struct ether_header *ethernet;
struct iphdr *ip;
struct tcphdr *tcp;
u_char *payload;
 int i=0, *counter = (int *)arg; 
/*
printf("size_ethernet:%d\n",ETHER_HDR_LEN);
printf("size_ip:%d\n",sizeof(struct iphdr));
printf("size_tcp:%d\n",sizeof(struct tcphdr));
 printf("Packet Count: %d\n", ++(*counter)); 
 printf("Received Packet Size: %d\n", pkthdr->len); 
*/
ethernet = (struct ether_header*)(packet);
ip = (struct iphdr*)(packet + ETHER_HDR_LEN);
tcp = (struct tcphdr*)(packet + ETHER_HDR_LEN+ sizeof(struct iphdr));
payload = (u_char *)(packet + ETHER_HDR_LEN + sizeof(struct iphdr) + sizeof(struct tcphdr));    
if(strstr(payload,"HTTP")!=NULL){
printf("%d\tPayload:\n", ++(*counter)); 
printf("%s\n",payload);
}

 return; 
} 



/* main(): Main function. Opens network interface and calls pcap_loop() */
int main(int argc, char *argv[] ){ 

 int i=0, count=0; 
 pcap_t *descr = NULL; 
 char errbuf[PCAP_ERRBUF_SIZE], *device=NULL; 
 memset(errbuf,0,PCAP_ERRBUF_SIZE); 

 if( argc > 1){  /* If user supplied interface name, use it. */
    device = argv[1];
 }
 else{  /* Get the name of the first device suitable for capture */ 

    if ( (device = pcap_lookupdev(errbuf)) == NULL){
        fprintf(stderr, "ERROR: %s\n", errbuf);
        exit(1);
    }
 }

 printf("Opening device %s\n", device); 

 /* Open device in promiscuous mode */ 
 if ( (descr = pcap_open_live(device, MAXBYTES2CAPTURE, 1,  512, errbuf)) == NULL){
    fprintf(stderr, "ERROR: %s\n", errbuf);
    exit(1);
 }

 /* Loop forever & call processPacket() for every received packet*/ 
 if ( pcap_loop(descr, -1, processPacket, (u_char *)&count) == -1){
    fprintf(stderr, "ERROR: %s\n", pcap_geterr(descr) );
    exit(1);
 }

return 0; 

} 

/* EOF*/

运行效果如图:
这里写图片描述

对程序的修改,添加了过滤器(只处理tcp数据),并把捕捉到的包保存到pcap文件

/*capture tcp packet and save as pcap file*/
/* print http payload*/
/*author : StSahana */
#include <pcap.h> 
#include <string.h> 
#include <stdlib.h> 
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <net/ethernet.h>

#define MAXBYTES2CAPTURE 65535
static pcap_dumper_t* dump_handle = NULL; //output trace dump() handle

void processPacket(u_char *arg, const struct pcap_pkthdr* pkthdr, const u_char * packet) {
    pcap_dump(((u_char*)dump_handle), pkthdr, packet);
    struct ether_header *ethernet;
    struct iphdr *ip;
    struct tcphdr *tcp;
    u_char *payload;
    int *counter = (int *)arg;

    ethernet = (struct ether_header*)(packet);
    ip = (struct iphdr*)(packet + ETHER_HDR_LEN);
    tcp = (struct tcphdr*)(packet + ETHER_HDR_LEN + sizeof(struct iphdr));
    payload = (u_char *)(packet + ETHER_HDR_LEN + sizeof(struct iphdr) + sizeof(struct tcphdr));
    if (strstr(payload, "HTTP") != NULL) {
        printf("%d\tPayload:\n", ++(*counter));
        printf("%s\n", payload);
    }

    return;
}



/* main(): Main function. Opens network interface and calls pcap_loop() */
int main(int argc, char *argv[]) {
    char *filtro = "tcp and port 80";
    struct bpf_program fp;
    int i = 0, count = 0;
    pcap_t *descr = NULL;
    char errbuf[PCAP_ERRBUF_SIZE], *device = NULL;
    static FILE* dump_file = NULL;  //
    bpf_u_int32 mask;       /* Our netmask */
    bpf_u_int32 net;        /* Our IP */
int num_packets=100;/*number of packets to capture,when  -1 will not stop*/


    memset(errbuf, 0, PCAP_ERRBUF_SIZE);

    if (argc > 1) {  /* If user supplied interface name, use it. */
        device = argv[1];
    }
    else {  /* Get the name of the first device suitable for capture */

        if ((device = pcap_lookupdev(errbuf)) == NULL) {
            fprintf(stderr, "ERROR: %s\n", errbuf);
            exit(1);
        }
    }

    printf("Opening device %s\n", device);

    /* Open device in promiscuous mode */
    if ((descr = pcap_open_live(device, MAXBYTES2CAPTURE, 1, 512, errbuf)) == NULL) {
        fprintf(stderr, "ERROR: %s\n", errbuf);
        exit(1);
    }
    /*compile program*/
    if (pcap_compile(descr, &fp, filtro, 0, net) == -1)
    {
        exit(1);
    }
    /*set filter*/
    if (pcap_setfilter(descr, &fp) == -1)
    {
        fprintf(stderr, "Error set Filter\n");
        exit(1);
    }
    dump_file = fopen("test.pcap", "w+");
    if ((dump_handle = pcap_dump_fopen(descr, dump_file)) == NULL) {
        fprintf(stderr, "Error dump fopen\n");
        exit(1);
    };

    /* Loop forever & call processPacket() for every received packet*/
    if (pcap_loop(descr, num_packets, processPacket, (u_char *)&count) == -1) {
        fprintf(stderr, "ERROR: %s\n", pcap_geterr(descr));
        exit(1);
    }
    if(NULL!=dump_handle)
{
   pcap_dump_flush(dump_handle);
   pcap_dump_close(dump_handle);
   dump_handle = NULL;
   dump_file = NULL;
}
    pcap_close(descr);
    return 0;

}

/* EOF*/

猜你喜欢

转载自blog.csdn.net/stSahana/article/details/79487144
今日推荐