⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cardif_linux_wext.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 3 页
字号:
/**
 * 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 + -