2008
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | /* Yahoo Packet Analyser * by Pravin Paratey (January 12, 2005) * pravinp [at] gmail [dot] com **/ #include <stdio.h> #include <pcap.h> #include <sys/socket.h> char *InitCapture(); void DoCapture(char *dev); void ParsePkts(pcap_t *fp); int main(int argc, char **argv) { char *dev; fprintf(stdout,"\t\t===============================\n"); fprintf(stdout,"\t\t Yahoo Packet Analyser v0.1\n"); fprintf(stdout,"\t\t by Pravin Paratey\n"); fprintf(stdout,"\t\t (pravinp[at]gmail[dot]com)\n"); fprintf(stdout,"\t\t http://insanitybegins.com/\n"); fprintf(stdout,"\t\t===============================\n"); dev = InitCapture(); if(dev) DoCapture(dev); return 0; } char *InitCapture() { pcap_if_t *alldevs, *d; pcap_t *fp; char errbuf[PCAP_ERRBUF_SIZE]; u_int inum, i=0; // Find all interfaces if(pcap_findalldevs(&alldevs, errbuf) == -1) { fprintf(stderr,"*** Error in pcap_findalldevs: %s\n", errbuf); return 0; } // Print the list of interfaces found for (d=alldevs; d; d=d->next) { printf("%d. %s",++i,d->name); if (d->description) printf(" (%s)\n", d->description); else printf(" (No description available)\n"); } if(i==0) { fprintf(stderr,"*** No interfaces found! Exiting ...\n"); return 0; } if (i > 1) { printf("Enter the interface number (1-%d):",i); scanf("%d", &inum); if(inum < 1 || inum > i) { printf("\nInterface number out of range.\n"); // Free the device list pcap_freealldevs(alldevs); return 0; } } else inum = 1; // Jump to the selected adapter for(d=alldevs, i=0; i<inum-1; d=d->next, i++) ; return d->name; } void DoCapture(char *dev) { pcap_t *fp; struct bpf_program fcode; char errbuf[PCAP_ERRBUF_SIZE]; // Open the device if ((fp = pcap_open_live(dev, // device to open 65536, // grants the whole packet will be captured 0, // view packets of this machine 1000, // read timeout errbuf)) == NULL) { fprintf(stderr,"*** pcap_open_live(): %s\n", errbuf); return; } // Set filter to capture TCP packets only if (pcap_compile(fp, &fcode, "tcp", 1, 0xffffff) < 0) { fprintf(stderr,"*** Unable to compile packet filter\n"); return; } if (pcap_setfilter(fp,&fcode) < 0) { fprintf(stderr,"*** Unable to set packet filter\n"); return; } // Successful, now we sit back and listen fprintf(stdout, "\n### Listening on adaptor\n### To quit, press Ctrl+C\n\n"); ParsePkts(fp); } void ParsePkts(pcap_t *fp) { int res; const u_char *pkt_data; struct pcap_pkthdr *header; u_int i, j; u_char c; // While packets are present in the interface, capture them while((res = pcap_next_ex(fp, &header, &pkt_data)) >= 0) { // If this is a Yahoo YMSG packet if(pkt_data[66] == \'Y\' && pkt_data[67] == \'M\' && pkt_data[68] == \'S\' && pkt_data[69] == \'G\') { // Dump contents to screen for(i=66; i < header->caplen; i=i+16) { for (j=0;j<16 && (i+j < header->caplen);j++) { fprintf(stdout, "%2.2x ",pkt_data[i+j]); if(j == 7) printf(" "); } fprintf(stdout, "\t"); for (j=0;j<15 && (i+j < header->caplen);j++) { c = pkt_data[i+j]; fprintf(stdout, "%c", (c > 32 && c < 127) ? c : '.'); } fprintf(stdout, "\n"); } fprintf(stdout,"\n"); } } } |
The next version will have color coding to denote diffents parts of the packet.


