使用libpcap抓取所有的http包
阿新 • • 發佈:2018-11-05
/* 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*/