compat.c
来自「和我之前上载的intel 802.11协议源码是配套的」· C语言 代码 · 共 599 行 · 第 1/2 页
C
599 行
/* * Header file to maintain compatibility among different kernel versions. * * Copyright (c) 2004-2006 Zhu Yi <yi.zhu@intel.com>, Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. */#if WIRELESS_EXT < 18/* Support for wpa_supplicant before WE-18, deprecated. *//* following definitions must match definitions in driver_ipw.c */#define IPW_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30#define IPW_CMD_SET_WPA_PARAM 1#define IPW_CMD_SET_WPA_IE 2#define IPW_CMD_SET_ENCRYPTION 3#define IPW_CMD_MLME 4#define IPW_PARAM_WPA_ENABLED 1#define IPW_PARAM_TKIP_COUNTERMEASURES 2#define IPW_PARAM_DROP_UNENCRYPTED 3#define IPW_PARAM_PRIVACY_INVOKED 4#define IPW_PARAM_AUTH_ALGS 5#define IPW_PARAM_IEEE_802_1X 6#define IPW_MLME_STA_DEAUTH 1#define IPW_MLME_STA_DISASSOC 2#define IPW_CRYPT_ERR_UNKNOWN_ALG 2#define IPW_CRYPT_ERR_UNKNOWN_ADDR 3#define IPW_CRYPT_ERR_CRYPT_INIT_FAILED 4#define IPW_CRYPT_ERR_KEY_SET_FAILED 5#define IPW_CRYPT_ERR_TX_KEY_SET_FAILED 6#define IPW_CRYPT_ERR_CARD_CONF_FAILED 7#define IPW_CRYPT_ALG_NAME_LEN 16struct ipw_param { u32 cmd; u8 sta_addr[ETH_ALEN]; union { struct { u8 name; u32 value; } wpa_param; struct { u32 len; u8 reserved[32]; u8 data[0]; } wpa_ie; struct { u32 command; u32 reason_code; } mlme; struct { u8 alg[IPW_CRYPT_ALG_NAME_LEN]; u8 set_tx; u32 err; u8 idx; u8 seq[8]; /* sequence counter (set: RX, get: TX) */ u16 key_len; u8 key[0]; } crypt; } u;};/* end of driver_ipw.c code */struct ipw_priv;static int ipw_wpa_enable(struct ipw_priv *priv, int value);static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value);static int ipw_disassociate(void *data);static void ipw_set_hw_decrypt_unicast(struct ipw_priv *priv, int level);static void ipw_set_hw_decrypt_multicast(struct ipw_priv *priv, int level);static void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len);static int ipw_wpa_set_param(struct net_device *dev, u8 name, u32 value){ struct ipw_priv *priv = ieee80211_priv(dev); struct ieee80211_crypt_data *crypt; unsigned long flags; int ret = 0; switch (name) { case IPW_PARAM_WPA_ENABLED: ret = ipw_wpa_enable(priv, value); break; case IPW_PARAM_TKIP_COUNTERMEASURES: crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) { IPW_WARNING("Can't set TKIP countermeasures: " "crypt not set!\n"); break; } flags = crypt->ops->get_flags(crypt->priv); if (value) flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES; else flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES; crypt->ops->set_flags(flags, crypt->priv); break; case IPW_PARAM_DROP_UNENCRYPTED:{ /* HACK: * * wpa_supplicant calls set_wpa_enabled when the driver * is loaded and unloaded, regardless of if WPA is being * used. No other calls are made which can be used to * determine if encryption will be used or not prior to * association being expected. If encryption is not being * used, drop_unencrypted is set to false, else true -- we * can use this to determine if the CAP_PRIVACY_ON bit should * be set. */ struct ieee80211_security sec = { .flags = SEC_ENABLED, .enabled = value, }; priv->ieee->drop_unencrypted = value; /* We only change SEC_LEVEL for open mode. Others * are set by ipw_wpa_set_encryption. */ if (!value) { sec.flags |= SEC_LEVEL; sec.level = SEC_LEVEL_0; } else { sec.flags |= SEC_LEVEL; sec.level = SEC_LEVEL_1; } if (priv->ieee->set_security) priv->ieee->set_security(priv->ieee->dev, &sec); break; } case IPW_PARAM_PRIVACY_INVOKED: priv->ieee->privacy_invoked = value; break; case IPW_PARAM_AUTH_ALGS: ret = ipw_wpa_set_auth_algs(priv, value); break; case IPW_PARAM_IEEE_802_1X: priv->ieee->ieee802_1x = value; break; default: IPW_ERROR("%s: Unknown WPA param: %d\n", dev->name, name); ret = -EOPNOTSUPP; } return ret;}static int ipw_wpa_mlme(struct net_device *dev, int command, int reason){ struct ipw_priv *priv = ieee80211_priv(dev); int ret = 0; switch (command) { case IPW_MLME_STA_DEAUTH: // silently ignore break; case IPW_MLME_STA_DISASSOC: ipw_disassociate(priv); break; default: IPW_ERROR("%s: Unknown MLME request: %d\n", dev->name, command); ret = -EOPNOTSUPP; } return ret;}static int ipw_wpa_ie_cipher2level(u8 cipher){ switch (cipher) { case 4: /* CCMP */ return SEC_LEVEL_3; case 2: /* TKIP */ return SEC_LEVEL_2; case 5: /* WEP104 */ case 1: /* WEP40 */ return SEC_LEVEL_1; case 0: /* NONE */ return SEC_LEVEL_0; default: return -1; }}static int ipw_wpa_set_wpa_ie(struct net_device *dev, struct ipw_param *param, int plen){ struct ipw_priv *priv = ieee80211_priv(dev); struct ieee80211_device *ieee = priv->ieee; u8 *buf; u8 *ptk, *gtk; int level; if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL)) return -EINVAL; if (param->u.wpa_ie.len) { buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); if (buf == NULL) return -ENOMEM; memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len); kfree(ieee->wpa_ie); ieee->wpa_ie = buf; ieee->wpa_ie_len = param->u.wpa_ie.len; } else { kfree(ieee->wpa_ie); ieee->wpa_ie = NULL; ieee->wpa_ie_len = 0; goto done; } if (priv->ieee->host_encrypt) goto done; /* HACK: Parse wpa_ie here to get pairwise suite, otherwise * we need to change driver_ipw.c from wpa_supplicant. This * is OK since -Dipw is deprecated. The -Dwext driver has a * clean way to handle this. */ gtk = ptk = (u8 *) ieee->wpa_ie; if (ieee->wpa_ie[0] == 0x30) { /* RSN IE */ gtk += 4 + 3; ptk += 4 + 4 + 2 + 3; } else { /* WPA IE */ gtk += 8 + 3; ptk += 8 + 4 + 2 + 3; } if (ptk - (u8 *) ieee->wpa_ie > ieee->wpa_ie_len) return -EINVAL; level = ipw_wpa_ie_cipher2level(*gtk); ipw_set_hw_decrypt_multicast(priv, level); level = ipw_wpa_ie_cipher2level(*ptk); ipw_set_hw_decrypt_unicast(priv, level); done: ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len); return 0;}/* implementation borrowed from hostap driver */static int ipw_wpa_set_encryption(struct net_device *dev, struct ipw_param *param, int param_len){ int ret = 0; int group_key = 0; struct ipw_priv *priv = ieee80211_priv(dev); struct ieee80211_device *ieee = priv->ieee; struct ieee80211_crypto_ops *ops; struct ieee80211_crypt_data **crypt; struct ieee80211_security sec = { .flags = 0, }; param->u.crypt.err = 0; param->u.crypt.alg[IPW_CRYPT_ALG_NAME_LEN - 1] = '\0'; if (param_len != (int)((char *)param->u.crypt.key - (char *)param) + param->u.crypt.key_len) { IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len, param->u.crypt.key_len); return -EINVAL; } if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { if (param->u.crypt.idx >= WEP_KEYS) return -EINVAL; crypt = &ieee->crypt[param->u.crypt.idx]; } else { return -EINVAL; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?