📄 wl_iw.c
字号:
rts = DOT11_DEFAULT_RTS_LEN; else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_RTS_LEN) return -EINVAL; else rts = vwrq->value; if ((error = dev_wlc_intvar_set(dev, "rtsthresh", rts))) return error; return 0;}static intwl_iw_get_rts( struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ int error, rts; WL_TRACE(("%s: SIOCGIWRTS\n", dev->name)); if ((error = dev_wlc_intvar_get(dev, "rtsthresh", &rts))) return error; vwrq->value = rts; vwrq->disabled = (rts >= DOT11_DEFAULT_RTS_LEN); vwrq->fixed = 1; return 0;}static intwl_iw_set_frag( struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ int error, frag; WL_TRACE(("%s: SIOCSIWFRAG\n", dev->name)); if (vwrq->disabled) frag = DOT11_DEFAULT_FRAG_LEN; else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_FRAG_LEN) return -EINVAL; else frag = vwrq->value; if ((error = dev_wlc_intvar_set(dev, "fragthresh", frag))) return error; return 0;}static intwl_iw_get_frag( struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ int error, fragthreshold; WL_TRACE(("%s: SIOCGIWFRAG\n", dev->name)); if ((error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold))) return error; vwrq->value = fragthreshold; vwrq->disabled = (fragthreshold >= DOT11_DEFAULT_FRAG_LEN); vwrq->fixed = 1; return 0;}static intwl_iw_set_txpow( struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ int error, disable; uint16 txpwrmw; WL_TRACE(("%s: SIOCSIWTXPOW\n", dev->name)); /* Make sure radio is off or on as far as software is concerned */ disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0; disable += WL_RADIO_SW_DISABLE << 16; if ((error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable)))) return error; /* Only handle mW */ if (!(vwrq->flags & IW_TXPOW_MWATT)) return -EINVAL; /* Value < 0 means just "on" or "off" */ if (vwrq->value < 0) return 0; if (vwrq->value > 0xffff) txpwrmw = 0xffff; else txpwrmw = (uint16)vwrq->value; error = dev_wlc_intvar_set(dev, "qtxpower", (int)(bcm_mw_to_qdbm(txpwrmw))); return error;}static intwl_iw_get_txpow( struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ int error, disable, txpwrdbm; uint8 result; WL_TRACE(("%s: SIOCGIWTXPOW\n", dev->name)); if ((error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable))) || (error = dev_wlc_intvar_get(dev, "qtxpower", &txpwrdbm))) return error; result = (uint8)(txpwrdbm & ~WL_TXPWR_OVERRIDE); vwrq->value = (int32)bcm_qdbm_to_mw(result); vwrq->fixed = 0; vwrq->disabled = (disable & (WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE)) ? 1 : 0; vwrq->flags = IW_TXPOW_MWATT; return 0;}#if WIRELESS_EXT > 10static intwl_iw_set_retry( struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ int error, lrl, srl; WL_TRACE(("%s: SIOCSIWRETRY\n", dev->name)); /* Do not handle "off" or "lifetime" */ if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME)) return -EINVAL; /* Handle "[min|max] limit" */ if (vwrq->flags & IW_RETRY_LIMIT) { /* "max limit" or just "limit" */ if ((vwrq->flags & IW_RETRY_MAX) || !(vwrq->flags & IW_RETRY_MIN)) { lrl = vwrq->value; if ((error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(lrl)))) return error; } /* "min limit" or just "limit" */ if ((vwrq->flags & IW_RETRY_MIN) || !(vwrq->flags & IW_RETRY_MAX)) { srl = vwrq->value; if ((error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl, sizeof(srl)))) return error; } } return 0;}static intwl_iw_get_retry( struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ int error, lrl, srl; WL_TRACE(("%s: SIOCGIWRETRY\n", dev->name)); vwrq->disabled = 0; /* Can't be disabled */ /* Do not handle lifetime queries */ if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) return -EINVAL; /* Get retry limits */ if ((error = dev_wlc_ioctl(dev, WLC_GET_LRL, &lrl, sizeof(lrl))) || (error = dev_wlc_ioctl(dev, WLC_GET_SRL, &srl, sizeof(srl)))) return error; /* Note : by default, display the min retry number */ if (vwrq->flags & IW_RETRY_MAX) { vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; vwrq->value = lrl; } else { vwrq->flags = IW_RETRY_LIMIT; vwrq->value = srl; if (srl != lrl) vwrq->flags |= IW_RETRY_MIN; } return 0;}#endif /* WIRELESS_EXT > 10 */static intwl_iw_set_encode( struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ wl_wsec_key_t key; int error, val, wsec; WL_TRACE(("%s: SIOCSIWENCODE\n", dev->name)); memset(&key, 0, sizeof(key)); if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { /* Find the current key */ for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { val = key.index; if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) return error; if (val) break; } /* Default to 0 */ if (key.index == DOT11_MAX_DEFAULT_KEYS) key.index = 0; } else { key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; if (key.index >= DOT11_MAX_DEFAULT_KEYS) return -EINVAL; } /* Old API used to pass a NULL pointer instead of IW_ENCODE_NOKEY */ if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) { /* Just select a new current key */ val = key.index; if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val, sizeof(val)))) return error; } else { key.len = dwrq->length; if (dwrq->length > sizeof(key.data)) return -EINVAL; memcpy(key.data, extra, dwrq->length); key.flags = WL_PRIMARY_KEY; switch (key.len) { case WEP1_KEY_SIZE: key.algo = CRYPTO_ALGO_WEP1; break; case WEP128_KEY_SIZE: key.algo = CRYPTO_ALGO_WEP128; break;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) case TKIP_KEY_SIZE: key.algo = CRYPTO_ALGO_TKIP; break;#endif case AES_KEY_SIZE: key.algo = CRYPTO_ALGO_AES_CCM; break; default: return -EINVAL; } /* Set the new key/index */ if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)))) return error; } /* Interpret "off" to mean no encryption */ val = (dwrq->flags & IW_ENCODE_DISABLED) ? 0 : WEP_ENABLED; if ((error = dev_wlc_intvar_get(dev, "wsec", &wsec))) return error; wsec &= ~(WEP_ENABLED); wsec |= val; if ((error = dev_wlc_intvar_set(dev, "wsec", wsec))) return error; /* Interpret "restricted" to mean shared key authentication */ val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0; if ((error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)))) return error; return 0;}static intwl_iw_get_encode( struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ wl_wsec_key_t key; int error, val, wsec, auth; WL_TRACE(("%s: SIOCGIWENCODE\n", dev->name)); if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { /* Find the current key */ for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { val = key.index; if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) return error; if (val) break; } } else key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; if (key.index < 0 || key.index >= DOT11_MAX_DEFAULT_KEYS) key.index = 0; /* Get info */ if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY, &key, sizeof(key))) || (error = dev_wlc_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec))) || (error = dev_wlc_ioctl(dev, WLC_GET_AUTH, &auth, sizeof(auth)))) return error; /* Get key length */ dwrq->length = MIN(IW_ENCODING_TOKEN_MAX, key.len); /* Get flags */ dwrq->flags = key.index + 1; if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))) { /* Interpret "off" to mean no encryption */ dwrq->flags |= IW_ENCODE_DISABLED; } if (auth) { /* Interpret "restricted" to mean shared key authentication */ dwrq->flags |= IW_ENCODE_RESTRICTED; } /* Get key */ if (dwrq->length && extra) memcpy(extra, key.data, dwrq->length); return 0;}static intwl_iw_set_power( struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ int error, pm; WL_TRACE(("%s: SIOCSIWPOWER\n", dev->name)); pm = vwrq->disabled ? PM_OFF : PM_MAX; if ((error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)))) return error; return 0;}static intwl_iw_get_power( struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ int error, pm; WL_TRACE(("%s: SIOCGIWPOWER\n", dev->name)); if ((error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)))) return error; vwrq->disabled = pm ? 0 : 1; vwrq->flags = IW_POWER_ALL_R; return 0;}#if WIRELESS_EXT > 17static intwl_iw_set_wpaie ( struct net_device *dev, struct iw_request_info *info, struct iw_point *iwp, char *extra){ WL_TRACE(("%s: SIOCSIWGENIE\n", dev->name)); dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length); return 0;}static intwl_iw_get_wpaie ( struct net_device *dev, struct iw_request_info *info, struct iw_point *iwp, char *extra){ WL_TRACE(("%s: SIOCGIWGENIE\n", dev->name)); iwp->length = 64; dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length); return 0;}static intwl_iw_set_encodeext ( struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ wl_wsec_key_t key; int error; struct iw_encode_ext *iwe; WL_TRACE(("%s: SIOCSIWENCODEEXT\n", dev->name)); memset(&key, 0, sizeof(key)); iwe = (struct iw_encode_ext *)extra; /* disable encryption completely */ if (dwrq->flags & IW_ENCODE_DISABLED) { } /* get the key index */ key.index = 0; if (dwrq->flags & IW_ENCODE_INDEX) key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; key.len = iwe->key_len; /* addr */ bcopy((void *)&iwe->addr.sa_data, (char *)&key.ea, ETHER_ADDR_LEN); /* check for key index change */ if (key.len == 0) { if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { WL_WSEC(("Changing the the primary Key to %d\n", key.index)); /* change the key index .... */ error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &key.index, sizeof(key.index)); if (error) return error; } /* key delete */ else dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); } else { if (iwe->key_len > sizeof(key.data)) return -EINVAL; WL_WSEC(("Setting the key index %d\n", key.index)); if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { WL_WSEC(("key is a Primary Key\n")); key.flags = WL_PRIMARY_KEY; } bcopy((void *)iwe->key, key.data, iwe->key_len); /* rx iv */ if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { uchar *ivptr; ivptr = (uchar *)iwe->rx_seq; key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | (ivptr[3] << 8) | ivptr[2]; key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; key.iv_initialized = TRUE; } switch(iwe->alg) { case IW_ENCODE_ALG_NONE: key.algo = CRYPTO_ALGO_OFF; break; case IW_ENCODE_ALG_WEP: if (iwe->key_len == WEP1_KEY_SIZE) key.algo = CRYPTO_ALGO_WEP1; else key.algo = CRYPTO_ALGO_WEP128; break; case IW_ENCODE_ALG_TKIP: key.algo = CRYPTO_ALGO_TKIP; break; case IW_ENCODE_ALG_CCMP: key.algo = CRYPTO_ALGO_AES_CCM; break; default: break; } error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); if (error) return error; } return 0;}static intwl_iw_get_encodeext ( struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -