📄 driver_ralink.c
字号:
if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0)
{
perror("ioctl[SIOCSIWSCAN]");
ret = -1;
}
/* Not all drivers generate "scan completed" wireless event, so try to
* read results after a timeout. */
eloop_register_timeout(4, 0, wpa_driver_ralink_scan_timeout, drv, drv->ctx);
scanning_done = 0;
return ret;
}
static int
wpa_driver_ralink_get_scan_results(void *priv,
struct wpa_scan_result *results,
size_t max_size)
{
struct wpa_driver_ralink_data *drv = priv;
UCHAR *buf = NULL;
//NDIS_802_11_BSSID_LIST_EX *wsr = (NDIS_802_11_BSSID_LIST_EX *) buf; //<--carella modify
NDIS_802_11_BSSID_LIST_EX *wsr = NULL; //-->carella
NDIS_WLAN_BSSID_EX *wbi;
struct iwreq iwr;
int ap_num;
u8 *pos,*end;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
buf = (UCHAR *) os_malloc(RT_MAX_802_11_BSSID_LIST_EX);
if (buf == NULL)
return -1;
memset(buf, 0, RT_MAX_802_11_BSSID_LIST_EX);
wsr = (NDIS_802_11_BSSID_LIST_EX *) buf;
wsr->NumberOfItems = 0;
strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
iwr.u.data.pointer = (caddr_t) buf;
iwr.u.data.flags = OID_802_11_BSSID_LIST;
if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0)
{
os_free(buf);
return -1;
}
memset(results, 0, max_size * sizeof(struct wpa_scan_result));
for (ap_num = 0, wbi = wsr->Bssid; ap_num < wsr->NumberOfItems; ++ap_num)
{
memcpy(results[ap_num].bssid, &wbi->MacAddress, ETH_ALEN);
memcpy(results[ap_num].ssid, wbi->Ssid.Ssid, wbi->Ssid.SsidLength);
results[ap_num].ssid_len = wbi->Ssid.SsidLength;
results[ap_num].freq = (wbi->Configuration.DSConfig / 1000);
/* get ie's */
wpa_hexdump(MSG_DEBUG, "RALINK: AP IEs",
(u8 *) wbi + sizeof(*wbi) - 1, wbi->IELength);
pos = (u8 *) wbi + sizeof(*wbi) - 1;
end = (u8 *) wbi + sizeof(*wbi) + wbi->IELength;
if (wbi->IELength < sizeof(NDIS_802_11_FIXED_IEs))
break;
pos += sizeof(NDIS_802_11_FIXED_IEs) - 2;
memcpy(&results[ap_num].caps, pos, 2);
pos += 2;
while (pos + 1 < end && pos + 2 + pos[1] <= end)
{
u8 ielen = 2 + pos[1];
if (ielen > SSID_MAX_WPA_IE_LEN)
{
pos += ielen;
continue;
}
if (pos[0] == GENERIC_INFO_ELEM && pos[1] >= 4 &&
memcmp(pos + 2, "\x00\x50\xf2\x01", 4) == 0)
{
memcpy(results[ap_num].wpa_ie, pos, ielen);
results[ap_num].wpa_ie_len = ielen;
}
else if (pos[0] == RSN_INFO_ELEM)
{
memcpy(results[ap_num].rsn_ie, pos, ielen);
results[ap_num].rsn_ie_len = ielen;
}
pos += ielen;
}
wbi = (NDIS_WLAN_BSSID_EX *) ((u8 *) wbi + wbi->Length);
}
os_free(buf);
return ap_num;
}
static int ralink_set_auth_mode(struct wpa_driver_ralink_data *drv, NDIS_802_11_AUTHENTICATION_MODE mode)
{
NDIS_802_11_AUTHENTICATION_MODE auth_mode = mode;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
if (ralink_set_oid(drv, OID_802_11_AUTHENTICATION_MODE,
(char *) &auth_mode, sizeof(auth_mode)) < 0)
{
wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
"OID_802_11_AUTHENTICATION_MODE (%d)",
(int) auth_mode);
return -1;
}
return 0;
}
static int wpa_driver_ralink_remove_key(struct wpa_driver_ralink_data *drv,
int key_idx, const u8 *addr,
const u8 *bssid, int pairwise)
{
NDIS_802_11_REMOVE_KEY rkey;
NDIS_802_11_KEY_INDEX index;
int res, res2;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
memset(&rkey, 0, sizeof(rkey));
rkey.Length = sizeof(rkey);
rkey.KeyIndex = key_idx;
if (pairwise)
rkey.KeyIndex |= 1 << 30;
memcpy(rkey.BSSID, bssid, ETH_ALEN);
res = ralink_set_oid(drv, OID_802_11_REMOVE_KEY, (char *) &rkey,
sizeof(rkey));
//AlbertY@20060210 removed it
if(0)//if (!pairwise)
{
res2 = ralink_set_oid(drv, OID_802_11_REMOVE_WEP,
(char *) &index, sizeof(index));
}
else
res2 = 0;
if (res < 0 && res2 < 0)
return res;
return 0;
}
static int wpa_driver_ralink_add_wep(struct wpa_driver_ralink_data *drv,
int pairwise, int key_idx, int set_tx,
const u8 *key, size_t key_len)
{
NDIS_802_11_WEP *wep;
size_t len;
int res;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
len = 12 + key_len;
wep = os_malloc(len);
if (wep == NULL)
return -1;
memset(wep, 0, len);
wep->Length = len;
wep->KeyIndex = key_idx;
if (set_tx)
wep->KeyIndex |= 1 << 31;
#if 0 /* Setting bit30 does not seem to work with some NDIS drivers */
if (pairwise)
wep->KeyIndex |= 1 << 30;
#endif
wep->KeyLength = key_len;
memcpy(wep->KeyMaterial, key, key_len);
wpa_hexdump_key(MSG_MSGDUMP, "RALINK: OID_802_11_ADD_WEP",
(const u8 *) wep, len);
res = ralink_set_oid(drv, OID_802_11_ADD_WEP, (char *) wep, len);
os_free(wep);
return res;
}
static int wpa_driver_ralink_set_key(void *priv, wpa_alg alg, const u8 *addr,
int key_idx, int set_tx,
const u8 *seq, size_t seq_len,
const u8 *key, size_t key_len)
{
struct wpa_driver_ralink_data *drv = priv;
size_t len;
NDIS_802_11_KEY *nkey;
int i, res, pairwise;
u8 bssid[ETH_ALEN];
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
if (addr == NULL || memcmp(addr, "\xff\xff\xff\xff\xff\xff",
ETH_ALEN) == 0)
{
/* Group Key */
pairwise = 0;
wpa_driver_ralink_get_bssid(drv, bssid);
}
else
{
/* Pairwise Key */
pairwise = 1;
memcpy(bssid, addr, ETH_ALEN);
}
if (alg == WPA_ALG_NONE || key_len == 0)
{
return wpa_driver_ralink_remove_key(drv, key_idx, addr, bssid,
pairwise);
}
if (alg == WPA_ALG_WEP)
{
return wpa_driver_ralink_add_wep(drv, pairwise, key_idx, set_tx,
key, key_len);
}
len = 12 + 6 + 6 + 8 + key_len;
nkey = os_malloc(len);
if (nkey == NULL)
return -1;
memset(nkey, 0, len);
nkey->Length = len;
nkey->KeyIndex = key_idx;
if (set_tx)
nkey->KeyIndex |= 1 << 31;
if (pairwise)
nkey->KeyIndex |= 1 << 30;
if (seq && seq_len)
nkey->KeyIndex |= 1 << 29;
nkey->KeyLength = key_len;
memcpy(nkey->BSSID, bssid, ETH_ALEN);
if (seq && seq_len)
{
for (i = 0; i < seq_len; i++)
nkey->KeyRSC |= seq[i] << (i * 8);
}
if (alg == WPA_ALG_TKIP && key_len == 32)
{
memcpy(nkey->KeyMaterial, key, 16);
memcpy(nkey->KeyMaterial + 16, key + 24, 8);
memcpy(nkey->KeyMaterial + 24, key + 16, 8);
}
else
{
memcpy(nkey->KeyMaterial, key, key_len);
}
wpa_hexdump_key(MSG_MSGDUMP, "RALINK: OID_802_11_ADD_KEY",
(const u8 *) nkey, len);
res = ralink_set_oid(drv, OID_802_11_ADD_KEY, (char *) nkey, len);
os_free(nkey);
return res;
}
static int wpa_driver_ralink_disassociate(void *priv, const u8 *addr,
int reason_code)
{
struct wpa_driver_ralink_data *drv = priv;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
if (ralink_set_oid(drv, OID_802_11_DISASSOCIATE,
" ", 4) < 0)
{
wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
"OID_802_11_DISASSOCIATE");
}
return 0;
}
static int wpa_driver_ralink_deauthenticate(void *priv, const u8 *addr,
int reason_code)
{
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
return wpa_driver_ralink_disassociate(priv, addr, reason_code);
}
static int
wpa_driver_ralink_associate(void *priv,
struct wpa_driver_associate_params *params)
{
struct wpa_driver_ralink_data *drv = priv;
NDIS_802_11_NETWORK_INFRASTRUCTURE mode;
NDIS_802_11_AUTHENTICATION_MODE auth_mode;
NDIS_802_11_WEP_STATUS encr, group;
BOOLEAN ieee8021xMode;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
if (params->mode == IEEE80211_MODE_IBSS)
mode = Ndis802_11IBSS;
else
mode = Ndis802_11Infrastructure;
if (ralink_set_oid(drv, OID_802_11_INFRASTRUCTURE_MODE,
(char *) &mode, sizeof(mode)) < 0)
{
wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
"OID_802_11_INFRASTRUCTURE_MODE (%d)",
(int) mode);
/* Try to continue anyway */
}
if (params->wpa_ie == NULL || params->wpa_ie_len == 0)
{
if (params->auth_alg & AUTH_ALG_SHARED_KEY)
{
if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM)
auth_mode = Ndis802_11AuthModeAutoSwitch;
else
auth_mode = Ndis802_11AuthModeShared;
}
else
auth_mode = Ndis802_11AuthModeOpen;
}
else if (params->wpa_ie[0] == RSN_INFO_ELEM)
{
if (params->key_mgmt_suite == KEY_MGMT_PSK)
auth_mode = Ndis802_11AuthModeWPA2PSK;
else
auth_mode = Ndis802_11AuthModeWPA2;
}
else
{
if (params->key_mgmt_suite == KEY_MGMT_WPA_NONE)
auth_mode = Ndis802_11AuthModeWPANone;
else if (params->key_mgmt_suite == KEY_MGMT_PSK)
auth_mode = Ndis802_11AuthModeWPAPSK;
else
auth_mode = Ndis802_11AuthModeWPA;
}
switch (params->pairwise_suite)
{
case CIPHER_CCMP:
encr = Ndis802_11Encryption3Enabled;
break;
case CIPHER_TKIP:
encr = Ndis802_11Encryption2Enabled;
break;
case CIPHER_WEP40:
case CIPHER_WEP104:
encr = Ndis802_11Encryption1Enabled;
break;
case CIPHER_NONE:
if (params->group_suite == CIPHER_CCMP)
encr = Ndis802_11Encryption3Enabled;
else if (params->group_suite == CIPHER_TKIP)
encr = Ndis802_11Encryption2Enabled;
else
encr = Ndis802_11EncryptionDisabled;
break;
default:
encr = Ndis802_11EncryptionDisabled;
};
ralink_set_auth_mode(drv, auth_mode);
// notify driver that IEEE8021x mode is enabled
if(params->key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA)
ieee8021xMode = TRUE;
else
ieee8021xMode = FALSE;
if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X, (char *) &ieee8021xMode, sizeof(BOOLEAN)) < 0)
{
wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
"OID_802_11_SET_IEEE8021X(%d)",
(int) ieee8021xMode);
}
if (ralink_set_oid(drv, OID_802_11_WEP_STATUS,
(char *) &encr, sizeof(encr)) < 0) {
wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
"OID_802_11_WEP_STATUS(%d)",
(int) encr);
}
return wpa_driver_ralink_set_ssid(drv, params->ssid, params->ssid_len);
}
static int wpa_driver_ralink_get_associnfo(struct wpa_driver_ralink_data *drv)
{
NDIS_802_11_ASSOCIATION_INFORMATION *buf;
int ret = 0;
struct iwreq iwr;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
buf = (NDIS_802_11_ASSOCIATION_INFORMATION *)os_malloc(sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
if (buf == NULL)
return -1;
memset(buf, 0, sizeof(buf));
memset(&iwr, 0, sizeof(iwr));
strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
iwr.u.data.flags = OID_802_11_STATE;
iwr.u.data.flags |= OID_GET_SET_TOGGLE;
iwr.u.data.pointer = (caddr_t) buf;
iwr.u.data.length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0)
{
perror("ioctl[RT_PRIV_IOCTL] -- OID_802_11_SSID");
ret = -1;
}
if(((NDIS_802_11_ASSOCIATION_INFORMATION *)iwr.u.data.pointer)->AssociateResponseToMe)
{
printf("wpa_driver_ralink_get_associnfo: association success\n");
ret = 1;
}
else
printf("wpa_driver_ralink_get_associnfo: association fail\n");
os_free(buf);
return ret;
}
static int wpa_driver_ralink_poll_timeout(void *eloop_ctx, void *ctx)
{
struct wpa_driver_ralink_data *drv = eloop_ctx;
struct wpa_supplicant *wpa_s = ctx;
u8 bssid[ETH_ALEN];
if (wpa_driver_ralink_get_bssid(drv, bssid)) {
/* Disconnected */
wpa_printf(MSG_DEBUG, "%s: Disconnected!!", __FUNCTION__);
} else {
/* Connected */
if(wpa_driver_ralink_get_associnfo(drv) == 1)
{
wpa_printf(MSG_DEBUG, "%s: Connected!!", __FUNCTION__);
wpa_drv_get_bssid(wpa_s, wpa_s->bssid);
wpa_s->associate_state = 1;
wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
}
else
wpa_s->associate_state = 0;
}
}
static void wpa_driver_ralink_poll(void *priv, void *ctx)
{
struct wpa_driver_ralink_data *drv = priv;
struct wpa_supplicant *wpa_s = ctx;
if(wpa_s->wpa_state < WPA_ASSOCIATED)
wpa_driver_ralink_poll_timeout(drv, ctx);
}
const struct wpa_driver_ops wpa_driver_ralink_ops = {
.name = "ralink",
.desc = "Ralink rt73 driver",
.get_bssid = wpa_driver_ralink_get_bssid,
.get_ssid = wpa_driver_ralink_get_ssid,
.set_key = wpa_driver_ralink_set_key,
.init = wpa_driver_ralink_init,
.deinit = wpa_driver_ralink_deinit,
.scan = wpa_driver_ralink_scan,
.get_scan_results = wpa_driver_ralink_get_scan_results,
.deauthenticate = wpa_driver_ralink_deauthenticate,
.disassociate = wpa_driver_ralink_disassociate,
.associate = wpa_driver_ralink_associate,
.add_pmkid = wpa_driver_ralink_add_pmkid,
.remove_pmkid = wpa_driver_ralink_remove_pmkid,
.flush_pmkid = wpa_driver_ralink_flush_pmkid,
.poll_ralink = wpa_driver_ralink_poll,
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -