📄 isl_ioctl.c
字号:
/* we are asked for the life time */ rvalue = mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r); vwrq->value = r.u * 1024; vwrq->flags = IW_RETRY_LIFETIME; } else if ((vwrq->flags & IW_RETRY_LONG)) { /* we are asked for the long retry limit */ rvalue |= mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r); vwrq->value = r.u; vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; } else { /* default. get the short retry limit */ rvalue |= mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r); vwrq->value = r.u; vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_SHORT; } return rvalue;}static intprism54_set_encode(struct net_device *ndev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); int rvalue = 0, force = 0; int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0; union oid_res_t r; /* with the new API, it's impossible to get a NULL pointer. * New version of iwconfig set the IW_ENCODE_NOKEY flag * when no key is given, but older versions don't. */ if (dwrq->length > 0) { /* we have a key to set */ int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; int current_index; struct obj_key key = { DOT11_PRIV_WEP, 0, "" }; /* get the current key index */ rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r); current_index = r.u; /* Verify that the key is not marked as invalid */ if (!(dwrq->flags & IW_ENCODE_NOKEY)) { if (dwrq->length > KEY_SIZE_TKIP) { /* User-provided key data too big */ return -EINVAL; } if (dwrq->length > KEY_SIZE_WEP104) { /* WPA-PSK TKIP */ key.type = DOT11_PRIV_TKIP; key.length = KEY_SIZE_TKIP; } else if (dwrq->length > KEY_SIZE_WEP40) { /* WEP 104/128 */ key.length = KEY_SIZE_WEP104; } else { /* WEP 40/64 */ key.length = KEY_SIZE_WEP40; } memset(key.key, 0, sizeof (key.key)); memcpy(key.key, extra, dwrq->length); if ((index < 0) || (index > 3)) /* no index provided use the current one */ index = current_index; /* now send the key to the card */ rvalue |= mgt_set_request(priv, DOT11_OID_DEFKEYX, index, &key); } /* * If a valid key is set, encryption should be enabled * (user may turn it off later). * This is also how "iwconfig ethX key on" works */ if ((index == current_index) && (key.length > 0)) force = 1; } else { int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; if ((index >= 0) && (index <= 3)) { /* we want to set the key index */ rvalue |= mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &index); } else { if (!dwrq->flags & IW_ENCODE_MODE) { /* we cannot do anything. Complain. */ return -EINVAL; } } } /* now read the flags */ if (dwrq->flags & IW_ENCODE_DISABLED) { /* Encoding disabled, * authen = DOT11_AUTH_OS; * invoke = 0; * exunencrypt = 0; */ } if (dwrq->flags & IW_ENCODE_OPEN) /* Encode but accept non-encoded packets. No auth */ invoke = 1; if ((dwrq->flags & IW_ENCODE_RESTRICTED) || force) { /* Refuse non-encoded packets. Auth */ authen = DOT11_AUTH_BOTH; invoke = 1; exunencrypt = 1; } /* do the change if requested */ if ((dwrq->flags & IW_ENCODE_MODE) || force) { rvalue |= mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen); rvalue |= mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke); rvalue |= mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt); } return rvalue;}static intprism54_get_encode(struct net_device *ndev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); struct obj_key *key; u32 devindex, index = (dwrq->flags & IW_ENCODE_INDEX) - 1; u32 authen = 0, invoke = 0, exunencrypt = 0; int rvalue; union oid_res_t r; /* first get the flags */ rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r); authen = r.u; rvalue |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r); invoke = r.u; rvalue |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r); exunencrypt = r.u; if (invoke && (authen == DOT11_AUTH_BOTH) && exunencrypt) dwrq->flags = IW_ENCODE_RESTRICTED; else if ((authen == DOT11_AUTH_OS) && !exunencrypt) { if (invoke) dwrq->flags = IW_ENCODE_OPEN; else dwrq->flags = IW_ENCODE_DISABLED; } else /* The card should not work in this state */ dwrq->flags = 0; /* get the current device key index */ rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r); devindex = r.u; /* Now get the key, return it */ if ((index < 0) || (index > 3)) /* no index provided, use the current one */ index = devindex; rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r); key = r.ptr; dwrq->length = key->length; memcpy(extra, key->key, dwrq->length); kfree(key); /* return the used key index */ dwrq->flags |= devindex + 1; return rvalue;}static intprism54_get_txpower(struct net_device *ndev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); union oid_res_t r; int rvalue; rvalue = mgt_get_request(priv, OID_INL_OUTPUTPOWER, 0, NULL, &r); /* intersil firmware operates in 0.25 dBm (1/4 dBm) */ vwrq->value = (s32) r.u / 4; vwrq->fixed = 1; /* radio is not turned of * btw: how is possible to turn off only the radio */ vwrq->disabled = 0; return rvalue;}static intprism54_set_txpower(struct net_device *ndev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); s32 u = vwrq->value; /* intersil firmware operates in 0.25 dBm (1/4) */ u *= 4; if (vwrq->disabled) { /* don't know how to disable radio */ printk(KERN_DEBUG "%s: %s() disabling radio is not yet supported.\n", priv->ndev->name, __FUNCTION__); return -ENOTSUPP; } else if (vwrq->fixed) /* currently only fixed value is supported */ return mgt_set_request(priv, OID_INL_OUTPUTPOWER, 0, &u); else { printk(KERN_DEBUG "%s: %s() auto power will be implemented later.\n", priv->ndev->name, __FUNCTION__); return -ENOTSUPP; }}static int prism54_set_genie(struct net_device *ndev, struct iw_request_info *info, struct iw_point *data, char *extra){ islpci_private *priv = netdev_priv(ndev); int alen, ret = 0; struct obj_attachment *attach; if (data->length > MAX_WPA_IE_LEN || (data->length && extra == NULL)) return -EINVAL; memcpy(priv->wpa_ie, extra, data->length); priv->wpa_ie_len = data->length; alen = sizeof(*attach) + priv->wpa_ie_len; attach = kzalloc(alen, GFP_KERNEL); if (attach == NULL) return -ENOMEM;#define WLAN_FC_TYPE_MGMT 0#define WLAN_FC_STYPE_ASSOC_REQ 0#define WLAN_FC_STYPE_REASSOC_REQ 2 /* Note: endianness is covered by mgt_set_varlen */ attach->type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ASSOC_REQ << 4); attach->id = -1; attach->size = priv->wpa_ie_len; memcpy(attach->data, extra, priv->wpa_ie_len); ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, priv->wpa_ie_len); if (ret == 0) { attach->type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_REASSOC_REQ << 4); ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, priv->wpa_ie_len); if (ret == 0) printk(KERN_DEBUG "%s: WPA IE Attachment was set\n", ndev->name); } kfree(attach); return ret;}static int prism54_get_genie(struct net_device *ndev, struct iw_request_info *info, struct iw_point *data, char *extra){ islpci_private *priv = netdev_priv(ndev); int len = priv->wpa_ie_len; if (len <= 0) { data->length = 0; return 0; } if (data->length < len) return -E2BIG; data->length = len; memcpy(extra, priv->wpa_ie, len); return 0;}static int prism54_set_auth(struct net_device *ndev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ islpci_private *priv = netdev_priv(ndev); struct iw_param *param = &wrqu->param; u32 mlmelevel = 0, authen = 0, dot1x = 0; u32 exunencrypt = 0, privinvoked = 0, wpa = 0; u32 old_wpa; int ret = 0; union oid_res_t r; if (islpci_get_state(priv) < PRV_STATE_INIT) return 0; /* first get the flags */ down_write(&priv->mib_sem); wpa = old_wpa = priv->wpa; up_write(&priv->mib_sem); ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r); authen = r.u; ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r); privinvoked = r.u; ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r); exunencrypt = r.u; ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r); dot1x = r.u; ret = mgt_get_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, NULL, &r); mlmelevel = r.u; if (ret < 0) goto out; switch (param->flags & IW_AUTH_INDEX) { case IW_AUTH_CIPHER_PAIRWISE: case IW_AUTH_CIPHER_GROUP: case IW_AUTH_KEY_MGMT: break; case IW_AUTH_WPA_ENABLED: /* Do the same thing as IW_AUTH_WPA_VERSION */ if (param->value) { wpa = 1; privinvoked = 1; /* For privacy invoked */ exunencrypt = 1; /* Filter out all unencrypted frames */ dot1x = 0x01; /* To enable eap filter */ mlmelevel = DOT11_MLME_EXTENDED; authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */ } else { wpa = 0; privinvoked = 0; exunencrypt = 0; /* Do not filter un-encrypted data */ dot1x = 0; mlmelevel = DOT11_MLME_AUTO; } break; case IW_AUTH_WPA_VERSION: if (param->value & IW_AUTH_WPA_VERSION_DISABLED) { wpa = 0; privinvoked = 0; exunencrypt = 0; /* Do not filter un-encrypted data */ dot1x = 0; mlmelevel = DOT11_MLME_AUTO; } else { if (param->value & IW_AUTH_WPA_VERSION_WPA) wpa = 1; else if (param->value & IW_AUTH_WPA_VERSION_WPA2) wpa = 2; privinvoked = 1; /* For privacy invoked */ exunencrypt = 1; /* Filter out all unencrypted frames */ dot1x = 0x01; /* To enable eap filter */ mlmelevel = DOT11_MLME_EXTENDED; authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */ } break; case IW_AUTH_RX_UNENCRYPTED_EAPOL: /* dot1x should be the opposite of RX_UNENCRYPTED_EAPOL; * turn off dot1x when allowing receipt of unencrypted EAPOL * frames, turn on dot1x when receipt should be disallowed */ dot1x = param->value ? 0 : 0x01; break; case IW_AUTH_PRIVACY_INVOKED: privinvoked = param->value ? 1 : 0; break; case IW_AUTH_DROP_UNENCRYPTED: exunencrypt = param->value ? 1 : 0; break; case IW_AUTH_80211_AUTH_ALG: if (param->value & IW_AUTH_ALG_SHARED_KEY) { /* Only WEP uses _SK and _BOTH */ if (wpa > 0) { ret = -EINVAL; goto out; } authen = DOT11_AUTH_SK; } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) { authen = DOT11_AUTH_OS; } else { ret = -EINVAL; goto out; } break; default: return -EOPNOTSUPP; } /* Set all the values */ down_write(&priv->mib_sem); priv->wpa = wpa; up_write(&priv->mib_sem); mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen); mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &privinvoked); mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt); mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x); mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlmelevel);out: return ret;}static int prism54_get_auth(struct net_device *ndev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ islpci_private *priv = netdev_priv(ndev); struct iw_param *param = &wrqu->param; u32 wpa = 0; int ret = 0; union oid_res_t r; if (islpci_get_state(priv) < PRV_STATE_INIT) return 0; /* first get the flags */ down_write(&priv->mib_sem); wpa = priv->wpa; up_write(&priv->mib_sem); switch (param->flags & IW_AUTH_INDEX) { case IW_AUTH_CIPHER_PAIRWISE: case IW_AUTH_CIPHER_GROUP: case IW_AUTH_KEY_MGMT: /* * wpa_supplicant will control these internally */ ret = -EOPNOTSUPP; break; case IW_AUTH_WPA_VERSION: switch (wpa) { case 1: param->value = IW_AUTH_WPA_VERSION_WPA; break; case 2: param->value = IW_AUTH_WPA_VERSION_WPA2; break; case 0: default: param->value = IW_AUTH_WPA_VERSION_DISABLED; break; } break; case IW_AUTH_DROP_UNENCRYPTED: ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r); if (ret >= 0) param->value = r.u > 0 ? 1 : 0; break; case IW_AUTH_80211_AUTH_ALG: ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r); if (ret >= 0) { switch (r.u) { case DOT11_AUTH_OS: param->value = IW_AUTH_ALG_OPEN_SYSTEM; break; case DOT11_AUTH_BOTH: case DOT11_AUTH_SK: param->value = IW_AUTH_ALG_SHARED_KEY; case DOT11_AUTH_NONE: default: param->value = 0; break; } } break; case IW_AUTH_WPA_ENABLED: param->value = wpa > 0 ? 1 : 0; break; case IW_AUTH_RX_UNENCRYPTED_EAPOL: ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r); if (ret >= 0) param->value = r.u > 0 ? 1 : 0; break; case IW_AUTH_PRIVACY_INVOKED: ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r); if (ret >= 0) param->value = r.u > 0 ? 1 : 0; break; default: return -EOPNOTSUPP; } return ret;}static int prism54_set_encodeext(struct net_device *ndev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ islpci_private *priv = netdev_priv(ndev); struct iw_point *encoding = &wrqu->encoding; struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int idx, alg = ext->alg, set_key = 1; union oid_res_t r; int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0; int ret = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -