FixIvs

  /* 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 occurrences 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;
  }