Yahoo Packet Analyzer
Today, we'll take a look at writing a Yahoo Packet Analyser. Yahoo changes its YMSG protocol (used on Yahoo Messenger) very often. Developers of alternative Yahoo Messengers have to scrabble around everytime this happens. This tool will show you the raw YMSG packets going in and coming out of your machine. Developers and non-developers can use this to understand the YMSG protocol better.
This code has been tested on ubuntu linux with gcc. It should work on all flavors of *nix. You'll need libpcap and libpcap-dev. You will have to run Yahoo Messenger or its alternatives available to view YMSG packets.
The idea is to capture all packets on an interface (ex. ethernet card) and pick the YMSG packets and dump them on the screen in hex.
The source code is given below. It is under GPL. It's fairly commented and you shouldn't have trouble understanding what's going on. Copy-paste the code to ypkt.c. To compile and run (as root):
$ gcc ypkt.c -lpcap -o ypkt && ./ypkt
ypkt.c1 /* Yahoo Packet Analyser 2 * by Pravin Paratey (January 12, 2005) 3 * pravinp [at] gmail [dot] com 4 **/ 5 6 #include <stdio.h> 7 #include <pcap.h> 8 #include <sys/socket.h> 9 10 char *InitCapture(); 11 void DoCapture(char *dev); 12 void ParsePkts(pcap_t *fp); 13 14 int main(int argc, char **argv) 15 { 16 char *dev; 17 fprintf(stdout,"\t\t===============================\n"); 18 fprintf(stdout,"\t\t Yahoo Packet Analyser v0.1\n"); 19 fprintf(stdout,"\t\t by Pravin Paratey\n"); 20 fprintf(stdout,"\t\t (pravinp[at]gmail[dot]com)\n"); 21 fprintf(stdout,"\t\t http://insanitybegins.com/\n"); 22 fprintf(stdout,"\t\t===============================\n"); 23 24 dev = InitCapture(); 25 if(dev) 26 DoCapture(dev); 27 28 return 0; 29 } 30 31 char *InitCapture() 32 { 33 pcap_if_t *alldevs, *d; 34 pcap_t *fp; 35 char errbuf[PCAP_ERRBUF_SIZE]; 36 u_int inum, i=0; 37 38 // Find all interfaces 39 if(pcap_findalldevs(&alldevs, errbuf) == -1) { 40 fprintf(stderr,"*** Error in pcap_findalldevs: %s\n", errbuf); 41 return 0; 42 } 43 44 // Print the list of interfaces found 45 for (d=alldevs; d; d=d->next) { 46 printf("%d. %s",++i,d->name); 47 if (d->description) 48 printf(" (%s)\n", d->description); 49 else 50 printf(" (No description available)\n"); 51 } 52 53 if(i==0) { 54 fprintf(stderr,"*** No interfaces found! Exiting ...\n"); 55 return 0; 56 } 57 58 if (i > 1) { 59 printf("Enter the interface number (1-%d):",i); 60 scanf("%d", &inum); 61 if(inum < 1 || inum > i) { 62 printf("\nInterface number out of range.\n"); 63 // Free the device list 64 pcap_freealldevs(alldevs); 65 return 0; 66 } 67 } 68 else { 69 inum = 1; 70 } 71 72 // Jump to the selected adapter 73 for(d=alldevs, i=0; i<inum-1; d=d->next, i++) 74 ; 75 return d->name; 76 } 77 78 void DoCapture(char *dev) 79 { 80 pcap_t *fp; 81 struct bpf_program fcode; 82 char errbuf[PCAP_ERRBUF_SIZE]; 83 84 // Open the device 85 if ((fp = pcap_open_live(dev, // device to open 86 65536, // grants the whole packet will be captured 87 0, // view packets of this machine 88 1000, // read timeout 89 errbuf)) == NULL) { 90 fprintf(stderr,"*** pcap_open_live(): %s\n", errbuf); 91 return; 92 } 93 94 // Set filter to capture TCP packets only 95 if (pcap_compile(fp, &fcode, "tcp", 1, 0xffffff) < 0) { 96 fprintf(stderr,"*** Unable to compile packet filter\n"); 97 return; 98 } 99 100 if (pcap_setfilter(fp,&fcode) < 0) { 101 fprintf(stderr,"*** Unable to set packet filter\n"); 102 return; 103 } 104 105 // Successful, now we sit back and listen 106 fprintf(stdout, "\n### Listening on adaptor\n### To quit, press Ctrl+C\n\n"); 107 108 ParsePkts(fp); 109 } 110 111 112 void ParsePkts(pcap_t *fp) 113 { 114 int res; 115 const u_char *pkt_data; 116 struct pcap_pkthdr *header; 117 u_int i, j; u_char c; 118 119 // While packets are present in the interface, capture them 120 while((res = pcap_next_ex(fp, &header, &pkt_data)) >= 0) { 121 // If this is a Yahoo YMSG packet 122 if(pkt_data[66] == 'Y' && pkt_data[67] == 'M' && 123 pkt_data[68] == 'S' && pkt_data[69] == 'G') { 124 // Dump contents to screen 125 for(i=66; i < header->caplen; i=i+16) { 126 for (j=0;j<16 && (i+j < header->caplen);j++) { 127 fprintf(stdout, "%2.2x ",pkt_data[i+j]); 128 if(j == 7) printf(" "); 129 } 130 131 fprintf(stdout, "\t"); 132 133 for (j=0;j<15 && (i+j < header->caplen);j++) { 134 c = pkt_data[i+j]; 135 fprintf(stdout, "%c", (c > 32 && c < 127) ? c : '.'); 136 } 137 138 fprintf(stdout, "\n"); 139 } 140 fprintf(stdout,"\n"); 141 } 142 } 143 }
The next version will have color coding to denote diffents parts of the packet.