1. 程式人生 > >使用libpcap抓取所有的http包

使用libpcap抓取所有的http包

/* 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*/