Fravia's special pages |
---|
/***************************BEGIN OF FILE******************************/ /* This program picks up http headers from the machine it is running on. It only gets 50 tcp packets before it quits, but since not all tcp packets are http, and only the http ones get output to file, you wont get 50 http headers. program output is in the form of a html document, with incoming packets in red and outgoing in blue. If you make this thing format your harddisk its not my fault. Trying to implement a program that does the same thing will teach you a lot about the subject areas involved. ~Roman */ #include <pcap.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #define ETHERNET_HEADER_LENGTH 14 /* function definitions */ int ip_header_len(const unsigned char *packet); int tcp_header_len(const unsigned char *packet); void printInfo(const unsigned char *packet, FILE* fp); char timeString[256]; time_t tod; /* holds the time */ /* insert your own ip here, this allows different coloured html depending on whether the packets are incoming or outgoing */ char *sourceIP = "123.123.123.123"; char *initial = "<HTML><PRE></FONT></PRE></HTML>"; /* * this gets called every time a packet is recieved */ void callback(unsigned char *args, const struct pcap_pkthdr* pkthdr, const unsigned char *packet) { /* -packet is a pointer to the start of the packet -http is a pointer to the beginning of the http header */ const unsigned char *http; const unsigned char *ptr; int i; /* used for various counting tasks */ FILE* fp; /* file pointer to the file we are writing */ /* we already know the packet is tcp because we set the filter in the main method */ if (pkthdr->len > 66){ /* ignore packets that are too short */ /* the http header starts after the ethernet, ip and tcp headers. We have to read ip and tcp header lengths from the packet */ i = ETHERNET_HEADER_LENGTH + ip_header_len(packet) + tcp_header_len(packet); http = packet + i; /* make http point to the right spot */ /* open a file */ fp = fopen("httpheaders.html", "r+b"); if (fp == 0){ printf("error opening file\n"); exit(1); } /* start writing 21 bytes before end of file so we overwrite the old "</FONT></PRE></HTML>" at the end of the file */ i = fseek(fp, -21,SEEK_END); if (i == -1){ printf("error with fseek\n"); exit(1); } /* print header if packet starts with GET,POST or HTTP */ /*-----------------------------------------------------*/ if( (strncmp(http,"GET",3) == 0) || (strncmp(http,"POST",4) == 0) ){ printInfo(packet,fp); // print src,dst and capture time /* set i to the length of the http header */ i = pkthdr->len - (int)(http - packet); /* if it starts with GET or POST, we want to write the rest of the packet to file */ fwrite(http, i, 1, fp); /*-----------------------------------------------------*/ }else if (strncmp(http,"HTTP",4) == 0){ printInfo(packet,fp); /* print src,dst and capture time */ /* if it starts with HTTP, we only want to write the section up to "\r\n\r\n" to file */ ptr = strstr(http,"\r\n\r\n"); if (ptr == 0){ printf("cant tell where to stop\n"); return; } /* ptr should be a pointer to where to stop writing */ fwrite(http, (int)(ptr - http), 1, fp); fwrite( "\n\n", 2, 1, fp); } /*------------------------------------------------------*/ fwrite("</FONT></PRE></HTML>",21,1,fp); fclose(fp); } return; } /* this initialises the network interface so we can read packets from it */ int main(int argc,char **argv) { char *dev; char errbuf[PCAP_ERRBUF_SIZE]; pcap_t* descr; struct bpf_program cp; /* hold compiled program */ bpf_u_int32 maskp; /* subnet mask */ bpf_u_int32 netp; /* ip */ u_char* args = NULL; FILE* fd; /* grab a device to peak into... */ dev = pcap_lookupdev(errbuf); if(dev == NULL) { printf("%s\n",errbuf); exit(1); } /* ask pcap for the network address and mask of the device */ pcap_lookupnet(dev,&netp,&maskp,errbuf); /* open device for reading.*/ descr = pcap_open_live(dev,BUFSIZ,0,-1,errbuf); if(descr == NULL) { printf("pcap_open_live(): %s\n",errbuf); exit(1); } /* Lets try and compile the program.. get only tcp to/from port 80 */ if(pcap_compile(descr,&cp,"tcp port 80",0,netp) == -1) { fprintf(stderr,"Error calling pcap_compile\n"); exit(1); } /* set the compiled program as the filter */ if(pcap_setfilter(descr,&cp) == -1) { fprintf(stderr,"Error setting filter\n"); exit(1); } /* creates the file if it doesnt exist, deletes contents if it is present */ fd = fopen("httpheaders.html", "w"); /* we write initial HTML tags */ fwrite(initial,strlen(initial),1,fd); fclose(fd); /* ... and loop */ pcap_loop(descr,50,callback,args); /* get 50 packets */ return 0; } /* ip_header_len returns the length of the ip header. If something other than an ip packet gets passed to it, you'll just get gibberish. The packet must be a complete packet lifted from the wire including ethernet header etc. */ int ip_header_len(const unsigned char *packet){ return 4 * (packet[14] & 0x0f); } /* tcp_header_len returns the length of the tcp header. If something other than a tcp packet gets passed to it, you'll just get gibberish. The packet must be a complete packet lifted from the wire including ethernet header etc. */ int tcp_header_len(const unsigned char *packet){ return 4 * ((packet[46]) >> 4); } /* print the source ip, destination ip, and time of capture */ void printInfo(const unsigned char *packet, FILE* fp){ char sourceStr[20]; char destStr[20]; char line[30] = "\n------------------------\n"; char src[7] = "src: "; char dst[8] = " dest: "; char tme[12] = "\ncaptured: "; sprintf(sourceStr,"%d.%d.%d.%d",packet[26],packet[27],packet[28],packet[29]); sprintf(destStr,"%d.%d.%d.%d",packet[30],packet[31],packet[32],packet[33]); if (strcmp(sourceIP,sourceStr) == 0){ fwrite("</FONT><FONT COLOR=\"#0000ff\">",29, 1,fp); }else{ fwrite("</FONT><FONT COLOR=\"#ff0000\">",29, 1,fp); } tod = time(&tod); strftime(timeString, 256, "%c", localtime(&tod)); fwrite(line,strlen(line), 1,fp); fwrite(src,strlen(src), 1,fp); fwrite(sourceStr, strlen(sourceStr), 1,fp); fwrite(dst, strlen(dst), 1,fp); fwrite(destStr, strlen(destStr), 1,fp); fwrite(tme,strlen(tme), 1,fp); fwrite(timeString,strlen(timeString),1,fp); fwrite(line,strlen(line), 1,fp); return; } /***************************END OF FILE******************************/