📄 cardif_linux_wext.c
字号:
/**
* Linux wireless extensions interface.
*
* Licensed under a dual GPL/BSD license. (See LICENSE file for more info.)
*
* \file cardif_linux_wext.c
*
* \authors Chris.Hessing@utah.edu
*
* \par CVS Status Information:
* \code
* $Id: cardif_linux_wext.c,v 1.84.2.23 2007/07/09 04:53:35 chessing Exp $
* $Date: 2007/07/09 04:53:35 $
*
*/
#ifdef LINUX_FRAMER
// Use kernel headers.
#define HEADERS_KERNEL
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/compiler.h>
#include "wireless_copy.h"
#include <iwlib.h>
#include <linux/if_packet.h>
#include <linux/netlink.h>
#include "xsupconfig.h"
#include "context.h"
#include "config_ssid.h"
#include "xsup_common.h"
#include "xsup_debug.h"
#include "xsup_err.h"
#include "wpa.h"
#include "wpa2.h"
#include "wpa_common.h"
#include "cardif/cardif.h"
#include "cardif/linux/cardif_linux.h"
#include "cardif/linux/cardif_linux_wext.h"
#include "wireless_sm.h"
#include "cardif/linux/cardif_linux_rtnetlink.h"
#include "timer.h"
#include "wpa.h"
#include "wpa2.h"
#ifdef USE_EFENCE
#include <efence.h>
#endif
// Old versions of wireless.h may not have this defined.
#ifndef IW_ENCODE_TEMP
#define IW_ENCODE_TEMP 0x0400
#endif
/**
* Cancel our scan timer, if we get here before something else cancels
* it for us. ;)
**/
void cardif_linux_wext_cancel_scantimer(context *ctx)
{
timer_cancel(ctx, SCANCHECK_TIMER);
}
/**
* Tell the wireless card to start scanning for wireless networks.
**/
int cardif_linux_wext_scan(context *thisint, char passive)
{
struct lin_sock_data *sockData;
struct iwreq iwr;
#if WIRELESS_EXT > 17
struct iw_scan_req iwsr;
#endif
struct config_globals *globals;
wireless_ctx *wctx = NULL;
if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))
return XEGENERROR;
if (!xsup_assert((thisint->intTypeData != NULL), "thisint->intTypeData != NULL",
FALSE))
return XEMALLOC;
wctx = (wireless_ctx *)thisint->intTypeData;
if (thisint->intType != ETH_802_11_INT)
{
debug_printf(DEBUG_INT, "%s is not a wireless interface!\n",
thisint->intName);
return XENOWIRELESS;
}
memset(&iwr, 0x00, sizeof(iwr));
sockData = thisint->sockData;
xsup_assert((sockData != NULL), "sockData != NULL", TRUE);
if (sockData->sockInt <= 0)
{
debug_printf(DEBUG_INT, "No socket available to start scan!\n");
return XENOSOCK;
}
cardif_linux_wext_wpa_state(thisint, 1);
debug_printf(DEBUG_INT, "Issuing %s scan request for interface %s!\n",
passive ? "passive":"active", thisint->intName);
#if WIRELESS_EXT > 17
// Build our extended scan structure.
memset(&iwsr, 0x00, sizeof(iwsr));
if (passive)
{
iwsr.scan_type = IW_SCAN_TYPE_PASSIVE;
iwsr.scan_type = IW_SCAN_TYPE_ACTIVE;
// If we are doing a passive scan, then we only care about other APs
// that are on this SSID. Otherwise, we might end up picking an SSID
// later that isn't in the same layer2/3 space.
// iwr.u.data.flags = IW_SCAN_THIS_ESSID | IW_SCAN_ALL_FREQ |
// IW_SCAN_THIS_MODE | IW_SCAN_ALL_RATE;
// iwr.u.data.flags = IW_SCAN_DEFAULT;
iwr.u.data.flags = IW_SCAN_THIS_ESSID;
}
else
{
// Some cards won't do a full scan if they are associated.
// cardif_linux_wext_set_bssid(thisint, all4s);
iwsr.scan_type = IW_SCAN_TYPE_ACTIVE;
iwr.u.data.flags = IW_SCAN_DEFAULT;
}
// We aren't looking for a specific BSSID.
memset(iwsr.bssid.sa_data, 0xff, 6);
iwr.u.data.length = sizeof(iwsr);
iwr.u.data.pointer = (caddr_t) &iwsr;
#else
iwr.u.data.length = 0;
iwr.u.data.pointer = NULL;
iwr.u.data.flags = IW_SCAN_DEFAULT;
#endif
Strncpy((char *)&iwr.ifr_name, sizeof(iwr.ifr_name), thisint->intName,
strlen(thisint->intName)+1);
if (ioctl(sockData->sockInt, SIOCSIWSCAN, &iwr) < 0)
{
debug_printf(DEBUG_NORMAL, "Error with SCAN ioctl! (Perhaps your card "
"doesn't support scanning, or isn't up?)\n");
debug_printf(DEBUG_NORMAL, "Error was (%d) : %s\n", errno, strerror(errno));
return -1;
}
SET_FLAG(wctx->flags, WIRELESS_SCANNING);
globals = config_get_globals();
if (!globals)
{
debug_printf(DEBUG_NORMAL, "Couldn't get a handle to the scan timeout "
"variable! (Perhaps the configuration isn't "
"initalized?)\n");
debug_printf(DEBUG_NORMAL, "Scanning will commence, but will only be "
"successful on cards that send scan complete events.\n");
return XENONE;
}
timer_add_timer(thisint, SCANCHECK_TIMER, globals->assoc_timeout,
cardif_linux_rtnetlink_scancheck,
cardif_linux_wext_cancel_scantimer);
return XENONE;
}
/**
* Set all of the keys to 0s.
**/
void cardif_linux_wext_set_zero_keys(context *thisint)
{
char zerokey[13];
char keylen = 13;
if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))
return;
debug_printf(DEBUG_INT, "Setting keys to zeros!\n");
memset(zerokey, 0x00, 13);
// We set the key index to 0x80, to force key 0 to be set to all 0s,
// and to have key 0 be set as the default transmit key.
cardif_set_wep_key(thisint, (uint8_t *)&zerokey, keylen, 0x80);
cardif_set_wep_key(thisint, (uint8_t *)&zerokey, keylen, 0x01);
cardif_set_wep_key(thisint, (uint8_t *)&zerokey, keylen, 0x02);
cardif_set_wep_key(thisint, (uint8_t *)&zerokey, keylen, 0x03);
}
/**
* If we have detected, or forced this interface to reset keys, then
* we need to reset them. Otherwise, we will just ignore the fact that
* we changed APs, and return.
**/
void cardif_linux_wext_zero_keys(context *thisint)
{
wireless_ctx *wctx = NULL;
if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))
return;
if (!xsup_assert((thisint->intTypeData != NULL), "thisint->intTypeData != NULL",
FALSE))
return;
wctx = (wireless_ctx *)thisint->intTypeData;
if (TEST_FLAG(wctx->flags, WIRELESS_ROAMED))
{
return;
}
SET_FLAG(wctx->flags, WIRELESS_ROAMED);
cardif_linux_wext_set_zero_keys(thisint);
cardif_linux_wext_enc_open(thisint);
}
/**
* Disable encryption on the wireless card. This is used in cases
* where we roam to a different AP and the card needs to have WEP
* disabled.
**/
int cardif_linux_wext_enc_disable(context *thisint)
{
int rc = 0;
struct iwreq wrq;
struct lin_sock_data *sockData;
if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))
return XEMALLOC;
memset((struct iwreq *)&wrq, 0x00, sizeof(struct iwreq));
sockData = thisint->sockData;
xsup_assert((sockData != NULL), "sockData != NULL", TRUE);
if (sockData->sockInt <= 0)
return XENOSOCK;
Strncpy(wrq.ifr_name, sizeof(wrq.ifr_name), thisint->intName,
strlen(thisint->intName)+1);
if (strlen(wrq.ifr_name) == 0)
{
debug_printf(DEBUG_NORMAL, "Invalid interface name in %s():%d\n",
__FUNCTION__, __LINE__);
return XEGENERROR;
}
// We got some data, so see if we have encryption or not.
#ifdef IW_ENCODE_NOKEY
wrq.u.encoding.flags = (IW_ENCODE_DISABLED | IW_ENCODE_NOKEY);
#else
wrq.u.encoding.flags = IW_ENCODE_DISABLED;
#endif
wrq.u.encoding.length = 0;
wrq.u.encoding.pointer = (caddr_t)NULL;
rc = ioctl(sockData->sockInt, SIOCSIWENCODE, &wrq);
if (rc < 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't disable encryption!\n");
} else {
debug_printf(DEBUG_INT, "Encryption disabled!\n");
}
return rc;
}
/**
* Create the WPA2 Information Element.
**/
int cardif_linux_wext_get_wpa2_ie(context *thisint, char *iedata, int *ielen)
{
if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))
return XEMALLOC;
if (!xsup_assert((iedata != NULL), "iedata != NULL", FALSE))
return XEMALLOC;
if (!xsup_assert((ielen != NULL), "ielen != NULL", FALSE))
return XEMALLOC;
#if WIRELESS_EXT > 17
// Should we use capabilities here?
wpa2_gen_ie(thisint, iedata, ielen);
debug_printf(DEBUG_INT, "Setting WPA2 IE : ");
debug_hex_printf(DEBUG_INT, (uint8_t *)iedata, *ielen);
debug_printf(DEBUG_INT, "\n");
#else
debug_printf(DEBUG_NORMAL, "WPA2 isn't implemented in this version of the "
"wireless extensions! Please upgrade to the latest version "
"of wireless extensions, or specify the driver to use with the"
" -D option!\n");
iedata = NULL;
*ielen = 0;
#endif
return XENONE;
}
/**
* Generate the WPA1 Information Element
**/
int cardif_linux_wext_get_wpa_ie(context *thisint,
char *iedata, int *ielen)
{
if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))
return XEMALLOC;
if (!xsup_assert((iedata != NULL), "iedata != NULL", FALSE))
return XEMALLOC;
if (!xsup_assert((ielen != NULL), "ielen != NULL", FALSE))
return XEMALLOC;
#if WIRELESS_EXT > 17
wpa_gen_ie(thisint, iedata);
*ielen = 24;
debug_printf(DEBUG_INT, "Setting WPA IE : ");
debug_hex_printf(DEBUG_INT, (uint8_t *)iedata, *ielen);
debug_printf(DEBUG_INT, "\n");
#else
debug_printf(DEBUG_NORMAL, "WPA isn't implemented in this version of the "
"wireless extensions! Please upgrade to the latest version "
"of wireless extensions, or specify the driver to use with the"
" -D option!\n");
iedata = NULL;
*ielen = 0;
#endif
return XENONE;
}
/**
* Set encryption to open on the wireless card.
**/
int cardif_linux_wext_enc_open(context *thisint)
{
int rc = 0;
struct iwreq wrq;
struct lin_sock_data *sockData;
if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))
return XEMALLOC;
memset((struct iwreq *)&wrq, 0x00, sizeof(struct iwreq));
sockData = thisint->sockData;
xsup_assert((sockData != NULL), "sockData != NULL", TRUE);
if (sockData->sockInt <= 0)
return XENOSOCK;
Strncpy(wrq.ifr_name, sizeof(wrq.ifr_name), thisint->intName,
strlen(thisint->intName)+1);
if (strlen(wrq.ifr_name) == 0)
{
debug_printf(DEBUG_NORMAL, "Invalid interface name in %s():%d\n",
__FUNCTION__, __LINE__);
return XEGENERROR;
}
// We got some data, so see if we have encryption or not.
wrq.u.encoding.flags = IW_ENCODE_OPEN;
wrq.u.encoding.length = 0;
wrq.u.encoding.pointer = (caddr_t)NULL;
rc = ioctl(sockData->sockInt, SIOCSIWENCODE, &wrq);
if (rc < 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't disable encryption!\n");
} else {
debug_printf(DEBUG_INT, "Encryption set to Open!\n");
}
return rc;
}
/**
* Set a WEP key. Also, based on the index, we may change the transmit
* key.
**/
int cardif_linux_wext_set_WEP_key(context *thisint, uint8_t *key,
int keylen, int index)
{
int rc = 0;
int settx = 0;
struct iwreq wrq;
struct lin_sock_data *sockData;
wireless_ctx *wctx = NULL;
char seq[6] = {0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))
return XEMALLOC;
if (!xsup_assert((thisint->intTypeData != NULL), "thisint->intTypeData != NULL",
FALSE))
return XEMALLOC;
wctx = (wireless_ctx *)thisint->intTypeData;
if (index & 0x80) settx = 1;
#if WIRELESS_EXT > 17
rc = cardif_linux_wext_set_key_ext(thisint, IW_ENCODE_ALG_WEP, addr,
(index & 0x7f), settx, seq, 6, (char *)key,
keylen);
if (rc == XENONE) return rc;
#endif
debug_printf(DEBUG_INT, "Couldn't use extended key calls to set keys. \n");
debug_printf(DEBUG_INT, "Trying old method.\n");
memset(&wrq, 0x00, sizeof(wrq));
if (thisint->intType != ETH_802_11_INT)
{
debug_printf(DEBUG_NORMAL, "Interface isn't wireless, but an attempt"
" to set a key was made!\n");
return XENOWIRELESS;
}
sockData = thisint->sockData;
xsup_assert((sockData != NULL), "sockData != NULL", TRUE);
if (sockData->sockInt <= 0)
return XENOSOCK;
Strncpy(wrq.ifr_name, sizeof(wrq.ifr_name), thisint->intName,
strlen(thisint->intName)+1);
if (strlen(wrq.ifr_name) == 0)
{
debug_printf(DEBUG_NORMAL, "Invalid interface name in %s():%d\n",
__FUNCTION__, __LINE__);
return XEGENERROR;
}
wrq.u.data.flags = ((index & 0x7f)+1);
if (TEST_FLAG(wctx->flags, WIRELESS_DONT_USE_TEMP))
wrq.u.data.flags |= IW_ENCODE_OPEN;
else
wrq.u.data.flags |= IW_ENCODE_OPEN | IW_ENCODE_TEMP;
wrq.u.data.length = keylen;
wrq.u.data.pointer = (caddr_t)key;
if ((rc = ioctl(sockData->sockInt, SIOCSIWENCODE, &wrq)) < 0)
{
debug_printf(DEBUG_NORMAL, "Failed to set WEP key [%d], error %d : %s\n",
(index & 0x7f) + 1, errno, strerror(errno));
rc = XENOKEYSUPPORT;
} else {
debug_printf(DEBUG_INT, "Successfully set WEP key [%d]\n",
(index & 0x7f)+1);
if (index & 0x80)
{
// This is a unicast key, use it for transmissions.
Strncpy(wrq.ifr_name, sizeof(wrq.ifr_name), thisint->intName,
strlen(thisint->intName)+1);
if (strlen(wrq.ifr_name) == 0)
{
debug_printf(DEBUG_NORMAL, "Invalid interface name in %s():%d\n",
__FUNCTION__, __LINE__);
return XEGENERROR;
}
wrq.u.data.flags = (((index & 0x7f) + 1) & IW_ENCODE_INDEX) | IW_ENCODE_NOKEY;
if (TEST_FLAG(wctx->flags, WIRELESS_DONT_USE_TEMP))
wrq.u.data.flags |= IW_ENCODE_OPEN;
else
wrq.u.data.flags |= IW_ENCODE_OPEN | IW_ENCODE_TEMP;
wrq.u.data.length = 0;
wrq.u.data.pointer = (caddr_t)NULL;
if (ioctl(sockData->sockInt, SIOCSIWENCODE, &wrq) < 0)
{
debug_printf(DEBUG_NORMAL, "Failed to set the WEP transmit key ID [%d]\n", (index & 0x7f)+1);
rc = XENOKEYSUPPORT;
} else {
debug_printf(DEBUG_INT, "Successfully set the WEP transmit key [%d]\n", (index & 0x7f)+1);
}
}
}
return rc;
}
/**
* Set the SSID of the wireless card.
**/
int cardif_linux_wext_set_ssid(context *thisint, char *ssid_name)
{
struct iwreq iwr;
struct lin_sock_data *sockData;
char newssid[100];
wireless_ctx *wctx = NULL;
if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))
return XEGENERROR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -