Yahoo Messenger Packet Analyser
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
<?prettify linenums=true?>
/* 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. A Microsoft Windows implementation with a GUI can be viewed on Github