📄 hostap.c
字号:
return HFA384X_PORTTYPE_BSS; if (local->iw_mode == IW_MODE_REPEAT) return HFA384X_PORTTYPE_WDS; if (local->iw_mode == IW_MODE_MONITOR) return HFA384X_PORTTYPE_PSEUDO_IBSS; return HFA384X_PORTTYPE_HOSTAP;}int hostap_set_encryption(local_info_t *local){ u16 val, old_val; int i, keylen, len, idx; char keybuf[WEP_KEY_LEN + 1]; enum { NONE, WEP, OTHER } encrypt_type; idx = local->tx_keyidx; if (local->crypt[idx] == NULL || local->crypt[idx]->ops == NULL) encrypt_type = NONE; else if (strcmp(local->crypt[idx]->ops->name, "WEP") == 0) encrypt_type = WEP; else encrypt_type = OTHER; if (local->func->get_rid(local->dev, HFA384X_RID_CNFWEPFLAGS, &val, 2, 1) < 0) { printk(KERN_DEBUG "Could not read current WEP flags.\n"); goto fail; } le16_to_cpus(&val); old_val = val; if (encrypt_type != NONE || local->privacy_invoked) val |= HFA384X_WEPFLAGS_PRIVACYINVOKED; else val &= ~HFA384X_WEPFLAGS_PRIVACYINVOKED; if (local->open_wep || encrypt_type == NONE || ((local->ieee_802_1x || local->wpa) && local->host_decrypt)) val &= ~HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED; else val |= HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED; if ((encrypt_type != NONE || local->privacy_invoked) && (encrypt_type == OTHER || local->host_encrypt)) val |= HFA384X_WEPFLAGS_HOSTENCRYPT; else val &= ~HFA384X_WEPFLAGS_HOSTENCRYPT; if ((encrypt_type != NONE || local->privacy_invoked) && (encrypt_type == OTHER || local->host_decrypt)) val |= HFA384X_WEPFLAGS_HOSTDECRYPT; else val &= ~HFA384X_WEPFLAGS_HOSTDECRYPT; if (val != old_val && hostap_set_word(local->dev, HFA384X_RID_CNFWEPFLAGS, val)) { printk(KERN_DEBUG "Could not write new WEP flags (0x%x)\n", val); goto fail; } if (encrypt_type != WEP) return 0; /* 104-bit support seems to require that all the keys are set to the * same keylen */ keylen = 6; /* first 5 octets */ len = local->crypt[idx]->ops->get_key(keybuf, sizeof(keybuf), NULL, local->crypt[idx]->priv); if (idx >= 0 && idx < WEP_KEYS && len > 5) keylen = WEP_KEY_LEN + 1; /* first 13 octets */ for (i = 0; i < WEP_KEYS; i++) { memset(keybuf, 0, sizeof(keybuf)); if (local->crypt[i]) { (void) local->crypt[i]->ops->get_key( keybuf, sizeof(keybuf), NULL, local->crypt[i]->priv); } if (local->func->set_rid(local->dev, HFA384X_RID_CNFDEFAULTKEY0 + i, keybuf, keylen)) { printk(KERN_DEBUG "Could not set key %d (len=%d)\n", i, keylen); goto fail; } } if (hostap_set_word(local->dev, HFA384X_RID_CNFWEPDEFAULTKEYID, idx)) { printk(KERN_DEBUG "Could not set default keyid %d\n", idx); goto fail; } return 0; fail: printk(KERN_DEBUG "%s: encryption setup failed\n", local->dev->name); return -1;}int hostap_set_antsel(local_info_t *local){ u16 val; int ret = 0; if (local->antsel_tx != HOSTAP_ANTSEL_DO_NOT_TOUCH && local->func->cmd(local->dev, HFA384X_CMDCODE_READMIF, HFA386X_CR_TX_CONFIGURE, NULL, &val) == 0) { val &= ~(BIT(2) | BIT(1)); switch (local->antsel_tx) { case HOSTAP_ANTSEL_DIVERSITY: val |= BIT(1); break; case HOSTAP_ANTSEL_LOW: break; case HOSTAP_ANTSEL_HIGH: val |= BIT(2); break; } if (local->func->cmd(local->dev, HFA384X_CMDCODE_WRITEMIF, HFA386X_CR_TX_CONFIGURE, &val, NULL)) { printk(KERN_INFO "%s: setting TX AntSel failed\n", local->dev->name); ret = -1; } } if (local->antsel_rx != HOSTAP_ANTSEL_DO_NOT_TOUCH && local->func->cmd(local->dev, HFA384X_CMDCODE_READMIF, HFA386X_CR_RX_CONFIGURE, NULL, &val) == 0) { val &= ~(BIT(1) | BIT(0)); switch (local->antsel_rx) { case HOSTAP_ANTSEL_DIVERSITY: break; case HOSTAP_ANTSEL_LOW: val |= BIT(0); break; case HOSTAP_ANTSEL_HIGH: val |= BIT(0) | BIT(1); break; } if (local->func->cmd(local->dev, HFA384X_CMDCODE_WRITEMIF, HFA386X_CR_RX_CONFIGURE, &val, NULL)) { printk(KERN_INFO "%s: setting RX AntSel failed\n", local->dev->name); ret = -1; } } return ret;}int hostap_set_roaming(local_info_t *local){ u16 val; switch (local->host_roaming) { case 1: val = HFA384X_ROAMING_HOST; break; case 2: val = HFA384X_ROAMING_DISABLED; break; case 0: default: val = HFA384X_ROAMING_FIRMWARE; break; } return hostap_set_word(local->dev, HFA384X_RID_CNFROAMINGMODE, val);}int hostap_set_auth_algs(local_info_t *local){ int val = local->auth_algs; /* At least STA f/w v0.6.2 seems to have issues with cnfAuthentication * set to include both Open and Shared Key flags. It tries to use * Shared Key authentication in that case even if WEP keys are not * configured.. STA f/w v0.7.6 is able to handle such configuration, * but it is unknown when this was fixed between 0.6.2 .. 0.7.6. */ if (local->sta_fw_ver < PRISM2_FW_VER(0,7,0) && val != PRISM2_AUTH_OPEN && val != PRISM2_AUTH_SHARED_KEY) val = PRISM2_AUTH_OPEN; if (hostap_set_word(local->dev, HFA384X_RID_CNFAUTHENTICATION, val)) { printk(KERN_INFO "%s: cnfAuthentication setting to 0x%x " "failed\n", local->dev->name, local->auth_algs); return -EINVAL; } return 0;}void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx){ u16 status, fc; status = __le16_to_cpu(rx->status); printk(KERN_DEBUG "%s: RX status=0x%04x (port=%d, type=%d, " "fcserr=%d) silence=%d signal=%d rate=%d rxflow=%d; " "jiffies=%ld\n", name, status, (status >> 8) & 0x07, status >> 13, status & 1, rx->silence, rx->signal, rx->rate, rx->rxflow, jiffies); fc = __le16_to_cpu(rx->frame_control); printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x " "data_len=%d%s%s\n", fc, WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc), __le16_to_cpu(rx->duration_id), __le16_to_cpu(rx->seq_ctrl), __le16_to_cpu(rx->data_len), fc & WLAN_FC_TODS ? " [ToDS]" : "", fc & WLAN_FC_FROMDS ? " [FromDS]" : ""); printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " A4=" MACSTR "\n", MAC2STR(rx->addr1), MAC2STR(rx->addr2), MAC2STR(rx->addr3), MAC2STR(rx->addr4)); printk(KERN_DEBUG " dst=" MACSTR " src=" MACSTR " len=%d\n", MAC2STR(rx->dst_addr), MAC2STR(rx->src_addr), __be16_to_cpu(rx->len));}void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx){ u16 fc; printk(KERN_DEBUG "%s: TX status=0x%04x retry_count=%d tx_rate=%d " "tx_control=0x%04x; jiffies=%ld\n", name, __le16_to_cpu(tx->status), tx->retry_count, tx->tx_rate, __le16_to_cpu(tx->tx_control), jiffies); fc = __le16_to_cpu(tx->frame_control); printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x " "data_len=%d%s%s\n", fc, WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc), __le16_to_cpu(tx->duration_id), __le16_to_cpu(tx->seq_ctrl), __le16_to_cpu(tx->data_len), fc & WLAN_FC_TODS ? " [ToDS]" : "", fc & WLAN_FC_FROMDS ? " [FromDS]" : ""); printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " A4=" MACSTR "\n", MAC2STR(tx->addr1), MAC2STR(tx->addr2), MAC2STR(tx->addr3), MAC2STR(tx->addr4)); printk(KERN_DEBUG " dst=" MACSTR " src=" MACSTR " len=%d\n", MAC2STR(tx->dst_addr), MAC2STR(tx->src_addr), __be16_to_cpu(tx->len));}int hostap_80211_header_parse(struct sk_buff *skb, unsigned char *haddr){ memcpy(haddr, skb->mac.raw + 10, ETH_ALEN); /* addr2 */ return ETH_ALEN;}int hostap_80211_prism_header_parse(struct sk_buff *skb, unsigned char *haddr){ if (*(u32 *)skb->mac.raw == LWNG_CAP_DID_BASE) { memcpy(haddr, skb->mac.raw + sizeof(struct linux_wlan_ng_prism_hdr) + 10, ETH_ALEN); /* addr2 */ } else { /* (*(u32 *)skb->mac.raw == htonl(LWNG_CAPHDR_VERSION)) */ memcpy(haddr, skb->mac.raw + sizeof(struct linux_wlan_ng_cap_hdr) + 10, ETH_ALEN); /* addr2 */ } return ETH_ALEN;}int hostap_80211_get_hdrlen(u16 fc){ int hdrlen = 24; switch (WLAN_FC_GET_TYPE(fc)) { case WLAN_FC_TYPE_DATA: if ((fc & WLAN_FC_FROMDS) && (fc & WLAN_FC_TODS)) hdrlen = 30; /* Addr4 */ break; case WLAN_FC_TYPE_CTRL: switch (WLAN_FC_GET_STYPE(fc)) { case WLAN_FC_STYPE_CTS: case WLAN_FC_STYPE_ACK: hdrlen = 10; break; default: hdrlen = 16; break; } break; } return hdrlen;}struct net_device_stats *hostap_get_stats(struct net_device *dev){ struct hostap_interface *iface = dev->priv; return &iface->stats;}static int prism2_close(struct net_device *dev){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; PDEBUG(DEBUG_FLOW, "%s: prism2_close\n", dev->name); if (dev == local->ddev) { prism2_sta_deauth(local, WLAN_REASON_DEAUTH_LEAVING); }#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT if (!local->hostapd && dev == local->dev && (!local->func->card_present || local->func->card_present(local)) && local->hw_ready && local->ap && local->iw_mode == IW_MODE_MASTER) hostap_deauth_all_stas(dev, local->ap, 1);#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ if (local->func->dev_close && local->func->dev_close(local)) return 0; if (dev == local->dev) { local->func->hw_shutdown(dev, HOSTAP_HW_ENABLE_CMDCOMPL); } if (netif_running(dev)) { netif_stop_queue(dev); netif_device_detach(dev); } flush_scheduled_work();#ifdef NEW_MODULE_CODE module_put(local->hw_module);#elif MODULE __MOD_DEC_USE_COUNT(local->hw_module);#endif local->num_dev_open--; if (dev != local->dev && local->dev->flags & IFF_UP && local->master_dev_auto_open && local->num_dev_open == 1) { /* Close master radio interface automatically if it was also * opened automatically and we are now closing the last * remaining non-master device. */ dev_close(local->dev); } return 0;}static int prism2_open(struct net_device *dev){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; PDEBUG(DEBUG_FLOW, "%s: prism2_open\n", dev->name); if (local->no_pri) { printk(KERN_DEBUG "%s: could not set interface UP - no PRI " "f/w\n", dev->name); return 1; } if ((local->func->card_present && !local->func->card_present(local)) || local->hw_downloading) return -ENODEV; if (local->func->dev_open && local->func->dev_open(local)) return 1;#ifdef NEW_MODULE_CODE if (!try_module_get(local->hw_module)) return -ENODEV;#elif MODULE __MOD_INC_USE_COUNT(local->hw_module);#endif local->num_dev_open++; if (!local->dev_enabled && local->func->hw_enable(dev, 1)) { printk(KERN_WARNING "%s: could not enable MAC port\n", dev->name); prism2_close(dev); return 1; } if (!local->dev_enabled) prism2_callback(local, PRISM2_CALLBACK_ENABLE); local->dev_enabled = 1; if (dev != local->dev && !(local->dev->flags & IFF_UP)) { /* Master radio interface is needed for all operation, so open * it automatically when any virtual net_device is opened. */ local->master_dev_auto_open = 1; dev_open(local->dev); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -