/* * prismexplode - interprets uncooked 802.11 data from stdin * * "prismexplode -?" for brief help * * updates: http://www.sublimation.org/802.11 * * 9044167b5e257189695e4c55ba41a740 * * may 19th, 2001 * */ #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_BUFFER_SIZE 4000 /* Size of receive buffer */ #define WTAP_PKTHDR_SIZE (sizeof(struct wtap_pkthdr)-4) #define ROWWIDTH 32 #define SSID_SIZE 32 __u8 dummybuf[32]; __u8 dummybuf2[32]; __u8 llc[7] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08 }; struct wtap_pkthdr { struct timeval ts; __u32 caplen; __u32 len; int pkt_encap; }; typedef struct { __u16 frame_control __attribute__ ((packed)); __u16 duration_id __attribute__ ((packed)); __u8 mac1[6] __attribute__ ((packed)); __u8 mac2[6] __attribute__ ((packed)); __u8 mac3[6] __attribute__ ((packed)); __u16 sequence __attribute__ ((packed)); __u8 mac4[6] __attribute__ ((packed)); } wlan_hdr_t; typedef struct { unsigned char version:2; unsigned char type:2; unsigned char subtype:4; unsigned char toDS:1; unsigned char fromDS:1; unsigned char morefrag:1; unsigned char retry:1; unsigned char pwr:1; unsigned char moredata:1; unsigned char wep:1; unsigned char rsvd:1; } frame_control_t; /* * for dumping the frame in ascii */ char * asciidump (__u8 * x, int y) { int i = -1; while (++i < y) if isprint (x[i]) sprintf (&dummybuf2[i], "%c", x[i]); else sprintf (&dummybuf2[i], "."); return (dummybuf2); } /* * for dumping the frame in hex */ char * hexdump (__u8 * x, int y) { int i = -1; while (++i < y) sprintf (&dummybuf[(i * 2)], "%02x", x[i]); return (dummybuf); } /* * attempts to determine if this data buffer is wep encrypted * by analyzing the distribution of each byte. encrypted data * looks like noise and unencrypted data does not. this is * however, an approximation algorithm, and therefore not 100% * reliable. */ int detect_wep (__u8 *buf, int len) { __u8 distcount[0xff], c, max=0; float dist; bzero(distcount,0xff); /* * count incident of each byte */ for (c=0;c 1) { if (strncmp (argv[counter], "-r", 2) == 0) showraw = 1; if (strncmp (argv[counter], "-s", 2) == 0) summary=1; if (strncmp (argv[counter], "-a", 2) == 0) showascii = 1; if (strncmp (argv[counter], "-m", 2) == 0) filtman = 1; if (strncmp (argv[counter], "-?", 2) == 0) { printf ("\n%s usage:\n\t%s (options) < rawlogfile\n",argv[0],argv[0]); printf ("\n\t\tor\n\n"); printf ("\tprismdump | %s (options)\n",argv[0]); printf ("\noptions:\n"); printf ("\t-r\tshow raw frame contents\n"); printf ("\t-s\tjust a line of summary per frame\n"); printf ("\t-a\tshow ascii for frame contents\n"); printf ("\t-m\tfilter all management frames\n"); printf ("\t-?\tthis help\n\n"); exit(0); } } /* * read in and discard wtap file header info */ if (1!=fread(msgbuf,24,1,stdin)) { printf ("could not read the file header\n"); perror("fread"); return(-1); } while (1) { memset (msgbuf, 0, MAX_BUFFER_SIZE); memset (ssid, 0, SSID_SIZE); n++; /* * read wtap packet header */ if (1 != fread(&packet_hdr_info,WTAP_PKTHDR_SIZE,1,stdin)) { fprintf(stderr,"could not read wiretap frame header. aborting...\n"); perror("fread"); status=-1; break; } /* * quick check for bogus headers */ if (packet_hdr_info.len != packet_hdr_info.caplen) { fprintf(stderr,"prismdump wiretap header impossibility: caplen!=len (%10u!=%u)\n", packet_hdr_info.caplen,packet_hdr_info.len); status=-1; break; } /* * read the 802.11 frame */ caplen=packet_hdr_info.caplen; if (1 != fread(msgbuf,caplen,1,stdin)) { fprintf(stderr,"couldn't read 802.11 frame header! aborting...\n"); perror("read"); status=-1; break; } /* * cast the frame into the 802.11 structs */ packet_hdr = (wlan_hdr_t *) msgbuf; fc=(frame_control_t *)&packet_hdr->frame_control; /* * sometimes we dont want to see management frames */ if ((filtman) && (fc->type == 0)) // management packets { continue; } /* * exract SSID from beacon frames */ if ((fc->type == 0) && ( fc->subtype == 8)) // beacon packets { temp=(msgbuf[37] & 0xff)+1; snprintf(ssid,temp,"%s",&msgbuf[38]); } /* * dump packet to stdout in human readable format */ if (summary) { printf ("%02u %02u %08u ",fc->type,fc->subtype,packet_hdr_info.ts.tv_sec); printf ("%s ",hexdump((unsigned char *)&packet_hdr->mac1,6)); printf ("%s ",hexdump((unsigned char *)&packet_hdr->mac2,6)); printf ("%s %s\n",hexdump((unsigned char *)&packet_hdr->mac3,6),ssid); continue; } printf ("packet number :\t%u\n",n); printf ("packet length :\t%u\n",caplen); printf ("packet time :\t%u:%u\n",packet_hdr_info.ts.tv_sec,packet_hdr_info.ts.tv_usec); printf ("frame control :\ttype:%s(%u)\n",typestring[fc->type],fc->type); switch (fc->type) { case 0: printf ("\t\t\tsubtype: %s (%u)\n",mgmtsubtypestring[fc->subtype],fc->subtype); break; case 1: printf ("\t\t\tsubtype: %s (%u)\n",ctrlsubtypestring[fc->subtype],fc->subtype); break; case 2: printf ("\t\t\tsubtype: %s (%u)\n",datasubtypestring[fc->subtype],fc->subtype); break; case 3: printf ("\t\t\tsubtype: Reserved (%u)\n",fc->subtype); break; } /* * since the smc driver clears the wep bit (I assume so that * sniffed packet will be passed up), we cant use it to recognize * WEP frames. instead, i try to recognize an unencrypted link * layer control header in the expected location. a failure * means the packet is (probably) WEP. */ if ((fc->type==2) && (detect_wep(&msgbuf[24],(caplen-24)))) fc->wep=1; if ((packet_hdr->frame_control & 0xff00) >> 8) printf ("\t\t\tflags: %s%s%s%s%s%s%s%s\n", ( fc->toDS ? "toDS " : ""), ( fc->fromDS ? "fromDS " : ""), ( fc->morefrag ? "morefrag " : ""), ( fc->retry ? "retry " : ""), ( fc->pwr ? "pwr_mngmnt " : ""), ( fc->moredata ? "moredata " : ""), ( fc->wep ? "WEP " : ""), ( fc->rsvd ? "reserved " : "") ); printf ("duration id :\t%u (0x%s)\n",packet_hdr->duration_id, hexdump((unsigned char *)&packet_hdr->duration_id,2)); printf ("mac address 1 :\t0x%s\n", hexdump((unsigned char *)&packet_hdr->mac1,6)); printf ("mac address 2 :\t0x%s\n", hexdump((unsigned char *)&packet_hdr->mac2,6)); printf ("mac address 3 :\t0x%s\n", hexdump((unsigned char *)&packet_hdr->mac3,6)); printf ("sequence :\t%u (0x%s)\n",packet_hdr->sequence, hexdump((unsigned char *)&packet_hdr->sequence,2)); printf ("mac address 4 :\t0x%s\n", hexdump((unsigned char *)&packet_hdr->mac4,6)); if ((fc->type == 0) && ( fc->subtype == 8)) // beacon packets printf ("SSID :\t%s\n",ssid); if (fc->wep) printf ("IV :\t%s\n", hexdump((unsigned char *)&msgbuf[24],3)); if (showraw) { printf ("\n"); for (counter=0;counter (counter+16) ? ROWWIDTH : caplen % ROWWIDTH ); printf ("\t%s\n", hexdump((unsigned char *)&msgbuf[counter],temp)); } } if (showascii) { printf ("\n"); for (counter=0;counter (counter+16) ? ROWWIDTH : caplen % ROWWIDTH ); printf ("\t%s\n", asciidump((unsigned char *)&msgbuf[counter],temp)); } } printf ("\n"); } fprintf (stderr,"%d packets analyzed\n",n); fflush(stdout); fflush(stderr); return(status); }