This is an old revision of the document!
/* This code is intended to address some issues in pcap2ivs that affect (at least) aircrack-2.41 and aircrack-ng 0.2.1: * Restriction in IVs file format design * A check to detect broadcast frames was missing in pcap2ivs * Bug in pcap2ivs, that saved dst-mac instead of bssid As a result it was getting frequent broadcast mac, which did not filter, and messed up file format. Usage: fixivs [FromMac1 ToMac1] [FromMac2 ToMac2]... < broken.ivs > fixed.ivs (do NOT use same filename for input and output!). It will replace occurences of FromMac for ToMac, because bssid got replaced with dst-mac of packets. Author: LatinSuD */ #include <stdio.h> #define IVSONLY_MAGIC "\xBF\xCA\x84\xD4" #define M 1 #define IVD 2 /* States (s): * IVD, if next is FF:FF:FF:FF:FF:FF -> Read it as a mac. s=MAC * else if next is FF -> Read IV and Data. s=IVD * else next is a mac -> Read it. s=MAC * MAC, read IV and Data. s=IVD */ #define BCAST "\xff\xff\xff\xff\xff\xff" void usage() { fprintf(stderr, "Fixes IVs files generated by broken pcap2ivs, replacing mac's as desired\n"); fprintf(stderr, "\n"); fprintf(stderr, "Usage:\n"); fprintf(stderr, "\tfixivs [FromMac1 ToMac1] [FromMac2 ToMac2]... < broken.ivs > fixed.ivs\n"); fprintf(stderr, "\t (do NOT use same file for input and output!)\n"); } int atoh(char c) { if (c>= '0' && c<='9') return c-'0'; if (c>='a' && c<='f') return c-'a'+0xa; if (c>='A' && c<='F') return c-'A'+0xa; usage(); fprintf(stderr, "ERROR: Invalid character in mac address '%c'\n", c); exit(1); } void strtomac(unsigned char *mac, char * str) { int i,c; i=0; while (*str) { if (i>=12) { usage(); fprintf(stderr, "ERROR: Mac address too long\n"); exit(1); } if ((i%2)==0) { mac[i/2]=atoh(*str)<<4; } else { mac[i/2]+=atoh(*str); } i++; do { // skip junk str++; } while (*str==':' || *str=='-') ; } if (i!=12) { usage(); fprintf(stderr, "ERROR: Mac address too short\n"); exit(1); } } main (int argc, char **argv) { int s=IVD; unsigned char buf[6]; char *frommac,*tomac; int i,ntr; if (argc%2 != 1) { usage(); exit(1); } else { ntr=(argc-1)/2; } // initialize user custom mac replacement frommac=(char*)malloc(6*ntr); tomac=(char*)malloc(6*ntr); for (i=0; i<ntr; i++) { strtomac(&frommac[i*6],argv[i*2+1]); strtomac(&tomac[i*6],argv[i*2+2]); } // read, check and write magic if (fread(buf,4,1,stdin)!=1) { fprintf(stderr, "Error reading input"); exit(1); } if( memcmp( buf, IVSONLY_MAGIC, 4 ) != 0 ) { fprintf(stderr, "Error: Input is not an .ivs file\n" ); exit(1); } fwrite(buf,4,1,stdout); while (1) { // s = state representing what we read just before switch(s) { case IVD: // read 6 bytes, either: mac address or ff+iv+data if(fread(buf,6,1,stdin)!=1) // detect eof exit(0); // Fix buggy bcast for 7F:FF:FF:FF:FF:FF if (memcmp(buf,BCAST,6)==0) { buf[0]=0x7F; } // User custom replaces for (i=0; i<ntr; i++) { if (memcmp(buf, &frommac[i*6], 6)==0) { memcpy(buf, &tomac[i*6], 6); } } // Detect next if (buf[0] != (unsigned char)'\xff') { // next will be a mac s=M; } else { // next will be an iv and data s=IVD; } // Write the 6 bytes, either FF+IV+data or mac fwrite(buf,6,1,stdout); break; case M: if(fread(buf,5,1,stdin)!=1) // detect eof exit(0); s=IVD; // write the 5 bytes of the iv+data fwrite(buf,5,1,stdout); break; } } return 0; }