Exemple #1
0
static void
printies(const u_int8_t *vp, int ielen, int maxcols)
{
	while (ielen > 0) {
		switch (vp[0]) {
		case IEEE80211_ELEMID_VENDOR:
			if (iswpaoui(vp))
				printie(" WPA", vp, 2 + vp[1], maxcols);
			else if (iswmeoui(vp))
				printie(" WME", vp, 2 + vp[1], maxcols);
			else if (isatherosoui(vp))
				printie(" ATH", vp, 2 + vp[1], maxcols);
			else
				printie(" VEN", vp, 2 + vp[1], maxcols);
			break;
		case IEEE80211_ELEMID_RSN:
			printie(" RSN", vp, 2 + vp[1], maxcols);
			break;
		default:
			printie(" ???", vp, 2 + vp[1], maxcols);
			break;
		}
		ielen -= 2 + vp[1];
		vp += 2 + vp[1];
	}
}
Exemple #2
0
static void
getIEs(const u_int8_t *vp, int ielen, int maxcols, u_int8_t *str_out)
{
    char *ptr = (char *)str_out;
    int iTemp = 0;
    
	while (ielen > 0 && iTemp < maxcols) {
     
		switch (vp[0]) {
		case IEEE80211_ELEMID_VENDOR:
			if (iswpaoui(vp))				
                sprintf(ptr, " WPA");
			else if (iswmeoui(vp))
                sprintf(ptr, " WME");				
			else if (isatherosoui(vp))
                sprintf(ptr, " ATH");				
			else
                sprintf(ptr, " VEN");

            ptr += 4 ;
            iTemp++;
			break;
        case IEEE80211_ELEMID_RSN:
            sprintf(ptr, " RSN");
            ptr += 4;
            iTemp++;
            break;
		default:
            //sprintf(str_out, " ???");
			break;
		}
		ielen -= 2+vp[1];
		vp += 2+vp[1];
	}

    *ptr = '\0';
}
Exemple #3
0
A_STATUS
wlan_parse_beacon(A_UINT8 *buf, int framelen, struct ieee80211_common_ie *cie, A_UINT8 phy_mode)	/* Bug 82893 */
{
    A_UINT8 *frm, *efrm;
    A_UINT8 elemid_ssid = FALSE;

    frm = buf;
    efrm = (A_UINT8 *) (frm + framelen);

    /*
     * beacon/probe response frame format
     *  [8] time stamp
     *  [2] beacon interval
     *  [2] capability information
     *  [tlv] ssid
     *  [tlv] supported rates
     *  [tlv] country information
     *  [tlv] parameter set (FH/DS)
     *  [tlv] erp information
     *  [tlv] extended supported rates
     *  [tlv] WMM
     *  [tlv] WPA or RSN
     *  [tlv] Atheros Advanced Capabilities
     */
    IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
    A_MEMZERO(cie, sizeof(*cie));

    cie->ie_tstamp = frm; frm += 8;
    cie->ie_beaconInt = A_LE2CPU16(*(A_UINT16 *)frm);  frm += 2;
    cie->ie_capInfo = A_LE2CPU16(*(A_UINT16 *)frm);  frm += 2;
    cie->ie_chan = 0;

    while (frm < efrm) {
        switch (*frm) {
        case IEEE80211_ELEMID_SSID:
            if (!elemid_ssid) {
                cie->ie_ssid = frm;
                elemid_ssid = TRUE;
            }
            break;
        case IEEE80211_ELEMID_RATES:
            cie->ie_rates = frm;
	    if (A_OK != check_phy_rates(cie->ie_rates, phy_mode))	 /* Fix Bug 82893 */
		return A_EINVAL;
            break;
        case IEEE80211_ELEMID_COUNTRY:
            cie->ie_country = frm;
            break;
        case IEEE80211_ELEMID_FHPARMS:
            break;
        case IEEE80211_ELEMID_DSPARMS:
            cie->ie_chan = frm[2];
            break;
        case IEEE80211_ELEMID_TIM:
            cie->ie_tim = frm;
            break;
        case IEEE80211_ELEMID_IBSSPARMS:
            break;
        case IEEE80211_ELEMID_XRATES:
            cie->ie_xrates = frm;
	    if (A_OK != check_phy_rates(cie->ie_xrates, phy_mode))	/* Fix Bug 82893 */
		return A_EINVAL;
            break;
        case IEEE80211_ELEMID_ERP:
            if (frm[1] != 1) {
                //A_PRINTF("Discarding ERP Element - Bad Len\n");
                return A_EINVAL;
            }
            cie->ie_erp = frm[2];
            break;
        case IEEE80211_ELEMID_RSN:
            cie->ie_rsn = frm;
            break;
#ifdef WAPI_ENABLE
        case IEEE80211_ELEMID_WAPI:
            cie->ie_wapi = frm;
            break;
#endif /* WAPI_ENABLE */
        case IEEE80211_ELEMID_VENDOR:
            if (iswpaoui(frm)) {
                cie->ie_wpa = frm;
            } else if (iswmmoui(frm)) {
                cie->ie_wmm = frm;
            } else if (isatherosoui(frm)) {
                cie->ie_ath = frm;
            } else if(iswscoui(frm)) {
                cie->ie_wsc = frm;
            }
            break;
        default:
            break;
        }
        frm += frm[1] + 2;
    }
    IEEE80211_VERIFY_ELEMENT(cie->ie_rates, IEEE80211_RATE_MAXSIZE);
    IEEE80211_VERIFY_ELEMENT(cie->ie_ssid, IEEE80211_NWID_LEN);

    return A_OK;
}
void ath6kl_tgt_sony_get_scaninfo_event(struct ath6kl_vif *vif, u8 *datap, u32 len)
{
	struct wmi_bss_info_hdr2 *bih;
	u8 *buf;
	struct ieee80211_channel *channel;
	struct ieee80211_mgmt *mgmt;
	//struct cfg80211_bss *bss;

	if (len <= sizeof(struct wmi_bss_info_hdr2))
		return;

	bih = (struct wmi_bss_info_hdr2 *) datap;
	buf = datap + sizeof(struct wmi_bss_info_hdr2);
	len -= sizeof(struct wmi_bss_info_hdr2);

	printk(
		   "bss info evt - ch %u, snr %d, rssi %d, bssid \"%pM\" "
		   "frame_type=%d\n",
		   bih->ch, bih->snr, bih->snr - 95, bih->bssid,
		   bih->frame_type);

	if (bih->frame_type != BEACON_FTYPE &&
	    bih->frame_type != PROBERESP_FTYPE)
		return; /* Only update BSS table for now */

	channel = ieee80211_get_channel(vif->wdev->wiphy, le16_to_cpu(bih->ch));
	if (channel == NULL)
		return;

	if (len < 8 + 2 + 2)
		return;
	/*
	 * In theory, use of cfg80211_inform_bss_ath6kl() would be more natural here
	 * since we do not have the full frame. However, at least for now,
	 * cfg80211 can only distinguish Beacon and Probe Response frames from
	 * each other when using cfg80211_inform_bss_frame_ath6kl(), so let's build a
	 * fake IEEE 802.11 header to be able to take benefit of this.
	 */
	mgmt = kmalloc(24 + len, GFP_ATOMIC);
	if (mgmt == NULL)
		return;

	if (bih->frame_type == BEACON_FTYPE) {
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_BEACON);
		memset(mgmt->da, 0xff, ETH_ALEN);
	} else {
		struct net_device *dev = vif->net_dev;

		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_PROBE_RESP);
		memcpy(mgmt->da, dev->dev_addr, ETH_ALEN);
	}
	mgmt->duration = cpu_to_le16(0);
	memcpy(mgmt->sa, bih->bssid, ETH_ALEN);
	memcpy(mgmt->bssid, bih->bssid, ETH_ALEN);
	mgmt->seq_ctrl = cpu_to_le16(0);

	memcpy(&mgmt->u.beacon, buf, len);
    
    
    {//save to scan information database
        athcfg_wcmd_scan_result_t   scan_entry;
        
        
        memset(&scan_entry,0x00,sizeof(athcfg_wcmd_scan_result_t));
        scan_entry.isr_freq = bih->ch;
        scan_entry.isr_ieee = (unsigned char)ieee80211_frequency_to_channel_ath6kl(bih->ch);
        scan_entry.isr_rssi = (bih->snr < 0) ? 0 : bih->snr;
        memcpy(&scan_entry.isr_bssid[0],&bih->bssid[0],ATHCFG_WCMD_ADDR_LEN);
        scan_entry.isr_capinfo = le16_to_cpu(mgmt->u.beacon.capab_info);
        //parse ie information
        {
            struct ieee80211_ie_header *ie_element;
            unsigned char *temp_ptr;
            int remained_len;
            ie_element = (struct ieee80211_ie_header *)&(mgmt->u.beacon.variable);
            remained_len = len - 5*sizeof(u8);
            while(remained_len >= 0) {   
                remained_len = remained_len - sizeof(struct ieee80211_ie_header)- ie_element->length;
                if (ie_element->length == 0) {
                    ie_element += 1;    /* next IE */
                    continue;
                }                
                if (remained_len < ie_element->length) {
                    /* Incomplete/bad info element */
                    //printk("EOF\n");
                    break;
                }                
                temp_ptr = (unsigned char *)ie_element;
                temp_ptr = temp_ptr+sizeof(struct ieee80211_ie_header);//point to data area
                
                switch (ie_element->element_id) {
                    case IEEE80211_ELEMID_SSID:
                        memcpy(&scan_entry.isr_ssid,temp_ptr,ie_element->length);
                        //printk("info_element->length=%d\n",ie_element->length); 
                        //printk("SSID=%s\n",scan_entry.isr_ssid);
                        break;
                    case IEEE80211_ELEMID_RATES:
                        memcpy(&scan_entry.isr_rates[0],temp_ptr,ie_element->length);
                        scan_entry.isr_nrates = ie_element->length;
                        break;
                    case IEEE80211_ELEMID_XRATES:        
                        memcpy(&scan_entry.isr_rates[scan_entry.isr_nrates],temp_ptr,ie_element->length);
                        scan_entry.isr_nrates += ie_element->length;
                        break;
                    case IEEE80211_ELEMID_ERP:
                        memcpy(&scan_entry.isr_erp,temp_ptr,ie_element->length);                      
                        break;
                    case IEEE80211_ELEMID_RSN:
                        scan_entry.isr_rsn_ie.len = ie_element->length;
                        memcpy(&scan_entry.isr_rsn_ie.data,temp_ptr,ie_element->length);    
                        break;    
                    case IEEE80211_ELEMID_HTCAP_ANA:
                        if (scan_entry.isr_htcap_ie.len == 0) {
                            scan_entry.isr_htcap_ie.len = ie_element->length;
                            memcpy(&scan_entry.isr_htcap_ie.data[0],temp_ptr,ie_element->length);
                        }
                        break;
                    case IEEE80211_ELEMID_HTINFO_ANA:
                        /* we only care if there isn't already an HT IE (ANA) */
                        if (scan_entry.isr_htinfo_ie.len == 0) {
                            scan_entry.isr_htinfo_ie.len = ie_element->length;
                            memcpy(&scan_entry.isr_htinfo_ie.data[0],temp_ptr,ie_element->length);
                        }
                        break;                     
                    case IEEE80211_ELEMID_HTCAP:
                        /* we only care if there isn't already an HT IE (ANA) */
                        if (scan_entry.isr_htcap_ie.len == 0) {
                            scan_entry.isr_htcap_ie.len = ie_element->length;
                            memcpy(&scan_entry.isr_htcap_ie.data[0],temp_ptr,ie_element->length);
                        }
                        break;     
                    case IEEE80211_ELEMID_HTINFO:
                        /* we only care if there isn't already an HT IE (ANA) */
                        if (scan_entry.isr_htinfo_ie.len == 0) {
                            scan_entry.isr_htinfo_ie.len = ie_element->length;
                            memcpy(&scan_entry.isr_htinfo_ie.data[0],temp_ptr,ie_element->length);
                        }
                        break;                        
                    case IEEE80211_ELEMID_VENDOR:   
                        if (iswpaoui((u_int8_t *) ie_element)) {
                            scan_entry.isr_wpa_ie.len = ie_element->length;
                            memcpy(&scan_entry.isr_wpa_ie.data[0],temp_ptr,ie_element->length);
                        } else if (iswpsoui((u_int8_t *) ie_element)) {
                            scan_entry.isr_wps_ie.len = ie_element->length;
                            memcpy(&scan_entry.isr_wps_ie.data[0],temp_ptr,ie_element->length);
                        } else if (iswmeparam((u_int8_t *) ie_element)) {
                            scan_entry.isr_wme_ie.len = ie_element->length;
                            memcpy(&scan_entry.isr_wme_ie.data[0],temp_ptr,ie_element->length);                        
                        } else if (isatherosoui((u_int8_t *) ie_element)) {
                            scan_entry.isr_ath_ie.len = ie_element->length;
                            memcpy(&scan_entry.isr_ath_ie.data[0],temp_ptr,ie_element->length);                      
                        } else if (ishtcap((u_int8_t *) ie_element)) {
                            if (scan_entry.isr_htcap_ie.len == 0) {
                                scan_entry.isr_htcap_ie.len = ie_element->length;
                                memcpy(&scan_entry.isr_htcap_ie.data[0],temp_ptr,ie_element->length);               
                            }
                        }
                        else if (ishtinfo((u_int8_t *) ie_element)) {
                            if (scan_entry.isr_htinfo_ie.len == 0) {
                                scan_entry.isr_htinfo_ie.len = ie_element->length;
                                memcpy(&scan_entry.isr_htinfo_ie.data[0],temp_ptr,ie_element->length);
                            }
                        } else {
                            //printk("Unknow know !!info_element->length=%d\n",ie_element->length); 
                        }
                        break;
                    default:
                        //printk("Unknow know info_element->length=%d\n",ie_element->length); 
                        break;
                }
                ie_element = (struct ieee80211_ie_header *)(temp_ptr + ie_element->length);
            }
        }
        
        
        //find the exist entry or add new one
        {
            int i,entry_match_item;
            bool entry_match = 0;
            
            if(total_bss_info >= 100) {
                printk("Excess max entry 100\n");        
                kfree(mgmt);
                return;
            }
            
            for(i=0;i<total_bss_info;i++) {
                if(scaninfor_db[i].isr_freq == scan_entry.isr_freq) {
                    if(memcmp(scaninfor_db[i].isr_bssid ,scan_entry.isr_bssid,ATHCFG_WCMD_ADDR_LEN) == 0) {
                        //find it                     
                        if(strcmp(scaninfor_db[i].isr_ssid ,scan_entry.isr_ssid) == 0) {
                            //update it
                            entry_match = 1;
                            entry_match_item = i;
                            //printk("fully match!! i=%d,update it,total_bss_info=%d\n",i,total_bss_info);
                            memcpy(&scaninfor_db[i],&scan_entry,sizeof(athcfg_wcmd_scan_result_t));
                            break;
                        }
                    }
                }
            }
            
            if(entry_match == 0) {
                memcpy(&scaninfor_db[total_bss_info],&scan_entry,sizeof(athcfg_wcmd_scan_result_t));
                #if 0
                printk("[%d]Freq=%d\n",total_bss_info,scaninfor_db[total_bss_info].isr_freq);        
                printk("[%d]CH=%d\n",total_bss_info,scaninfor_db[total_bss_info].isr_ieee);        
                printk("[%d]RSSI=%d\n",total_bss_info,scaninfor_db[total_bss_info].isr_rssi);  
                printk("[%d]BSSID=%pM\n",total_bss_info,scaninfor_db[total_bss_info].isr_bssid);
                printk("[%d]SSID=%s\n",total_bss_info,scaninfor_db[total_bss_info].isr_ssid);
                printk("[%d]isr_htinfo_ie.len=%d\n",total_bss_info,scaninfor_db[total_bss_info].isr_htinfo_ie.len);  
                #endif                
                total_bss_info++;
                //printk("               next entry=%d\n",total_bss_info);
            } else {
                #if 0
                printk("[%d]Freq=%d\n",entry_match_item,scaninfor_db[entry_match_item].isr_freq);        
                printk("[%d]CH=%d\n",entry_match_item,scaninfor_db[entry_match_item].isr_ieee);        
                printk("[%d]RSSI=%d\n",entry_match_item,scaninfor_db[entry_match_item].isr_rssi);  
                printk("[%d]BSSID=%pM\n",entry_match_item,scaninfor_db[entry_match_item].isr_bssid);
                printk("[%d]SSID=%s\n",entry_match_item,scaninfor_db[entry_match_item].isr_ssid);
                printk("[%d]isr_htinfo_ie.len=%d\n",entry_match_item,scaninfor_db[entry_match_item].isr_htinfo_ie.len);  
                #endif                 
            }
        }               
    }
    
    kfree(mgmt);
    ///total_bss_info++;
    return;
}