diff -ru aircrack-2.23-orig/linux/aireplay.c aircrack-2.23/linux/aireplay.c --- aircrack-2.23-orig/linux/aireplay.c 2005-11-07 23:06:49.000000000 +0100 +++ aircrack-2.23/linux/aireplay.c 2005-11-08 11:33:10.000000000 +0100 @@ -97,6 +97,7 @@ " -c dmac : set Destination MAC address\n" " -h smac : set Source MAC address\n" " -e essid : set target SSID for attack 1\n" +" -j fromds : keep FromDS bit\n" "\n" " source options:\n" "\n" @@ -133,6 +134,7 @@ unsigned char r_dmac[6]; unsigned char r_smac[6]; char r_essid[33]; + int f_fromdsinj; char *s_face; char *s_file; @@ -1408,21 +1410,42 @@ if( filter_packet( h80211, caplen ) == 0 ) { add_arp: - /* rewrite the header to make it a ToDS packet */ switch( h80211[1] & 3 ) { - case 1: /* already ToDS */ break; - case 2: memcpy( h80211 + 4, h80211 + 10, 6 ); break; - default: continue; - } + case 1: /* ToDS frame */ + { + /* Keep packet as a ToDS packet */ + memcpy( h80211 + 4, opt.f_bssid, 6 ); + memcpy( h80211 + 10, opt.r_smac, 6 ); + memcpy( h80211 + 16, opt.f_dmac, 6 ); - h80211[0] = 0x08; /* normal data */ - h80211[1] = 0x41; /* ToDS & WEP */ + h80211[1] = 0x41; /* ToDS & WEP */ + } + case 2: /* FromDS frame */ + { + if( opt.f_fromdsinj == 1 ) + { + /* Keep packet as a FromDS packet */ + memcpy( h80211 + 4, opt.f_dmac, 6 ); + memcpy( h80211 + 10, opt.f_bssid, 6 ); + memcpy( h80211 + 16, opt.r_smac, 6 ); - memcpy( h80211 + 4, opt.f_bssid, 6 ); - memcpy( h80211 + 10, opt.r_smac, 6 ); - memset( h80211 + 16, 0xFF, 6 ); + h80211[1] = 0x42; /* FromDS & WEP */ + } + else + { + /* rewrite header to make it a ToDS packet */ + memcpy( h80211 + 4, opt.f_bssid, 6 ); + memcpy( h80211 + 10, opt.r_smac, 6 ); + memcpy( h80211 + 16, opt.f_dmac, 6 ); + + h80211[1] = 0x41; /* ToDS & WEP */ + } + } + } + + h80211[0] = 0x08; /* normal data */ /* if same IV, perhaps our own packet, skip it */ @@ -2185,17 +2208,17 @@ memset( &opt, 0, sizeof( opt ) ); - opt.f_type = -1; opt.f_subtype = -1; - opt.f_minlen = -1; opt.f_maxlen = -1; - opt.f_tods = -1; opt.f_fromds = -1; - opt.f_iswep = -1; + opt.f_type = -1; opt.f_subtype = -1; + opt.f_minlen = -1; opt.f_maxlen = -1; + opt.f_tods = -1; opt.f_fromds = -1; + opt.f_iswep = -1; opt.f_fromdsinj = -1; - opt.a_mode = -1; opt.r_fctrl = -1; + opt.a_mode = -1; opt.r_fctrl = -1; while( 1 ) { int option = getopt( argc, argv, - "b:d:s:m:n:u:v:t:f:w:x:p:a:c:h:e:i:r:0:1:234" ); + "b:d:s:m:n:u:v:t:f:w:x:p:a:c:h:e:j:i:r:0:1:234" ); if( option < 0 ) break; @@ -2351,6 +2374,16 @@ strncpy( opt.r_essid, optarg, sizeof( opt.r_essid ) - 1 ); break; + case 'j' : + + sscanf( optarg, "%d", &opt.f_fromdsinj ); + if( opt.f_fromdsinj != 0 && opt.f_fromdsinj != 1 ) + { + printf( "Invalid tods mode.\n" ); + return( 1 ); + } + break; + case 'i' : if( opt.s_face != NULL || opt.s_file )