cardif_linux.c

来自「linux 下通过802.1认证的安装包」· C语言 代码 · 共 1,995 行 · 第 1/4 页

C
1,995
字号
}

/**
 * \brief Clean up an interface.
 *
 * Clean up anything that was created during the initialization and operation
 * of the interface.  This will be called before the program terminates.
 *
 * @param[in] ctx   The context that contains the interface that we want to 
 *                  clean up.
 *
 * \retval XENONE on success
 * \retval XEGENERROR on general error
 **/
int cardif_deinit(context *ctx)
{
  struct ifreq ifr;
  uint16_t int16;
  struct lin_sock_data *sockData;
  uint8_t all0s[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  FREE(ctx->sendframe);
  FREE(ctx->recvframe);
  
  sockData = ctx->sockData;

  debug_printf(DEBUG_INT | DEBUG_DEINIT, "Cleaning up interface %s...\n",ctx->intName);

  cardif_linux_rtnetlink_cleanup(ctx);

  if (ctx->intType == ETH_802_11_INT)
  {
    // Remove all of the keys that we have set.
    cardif_linux_clear_keys(ctx);

    debug_printf(DEBUG_INT, "Turning off WPA support/state.\n");

    // Clear the WPA IE.
    cardif_linux_wext_set_wpa_ie(ctx, NULL, 0);

    cardif_disable_wpa_state(ctx);

    // Reset the MAC address to all 0s.  (This tells the driver to
    // scan for new associations.
    cardif_setBSSID(ctx, all0s);
  }

  // Check if we want ALLMULTI mode, and enable it.
  if (TEST_FLAG(ctx->flags, ALLMULTI))
    {
      memset(&ifr, 0x00, sizeof(ifr));

      // Tell the ifreq struct which interface we want to use.
      Strncpy((char *)&ifr.ifr_name, sizeof(ifr.ifr_name), ctx->intName, 
	      strlen(ctx->intName)+1);

      if (strlen(ifr.ifr_name) == 0)
	{
	  debug_printf(DEBUG_NORMAL, "Invalid interface name in %s():%d\n",
		       __FUNCTION__, __LINE__);
	  return XEGENERROR;
	}

      if (ioctl(sockData->sockInt, SIOCGIFFLAGS, &ifr) < 0)
	{
	  debug_printf(DEBUG_NORMAL, "Couldn't get interface flags!\n");
	} else {
	  // Check if allmulti was disabled when we started.  If it was,
	  // then disable it again, so everything is good.
	  if (!(ctx->flags & ALLMULTI))
	    {
	      debug_printf(DEBUG_INT, "Turning off ALLMULTI mode!\n");

	      int16 = ifr.ifr_flags;

	      // ANDing the flags with 0xfdff will turn off the ALLMULTI flag.
	      ifr.ifr_flags = (int16 & 0xfdff);
	      if (ioctl(sockData->sockInt, SIOCSIFFLAGS, &ifr) < 0)
		{
		  debug_printf(DEBUG_NORMAL, "Couldn't set ALLMULTI mode on this interface!  We will continue anyway!\n");
		}
	    }
	}
    }

  close(sockData->sockInt);

  // Now clean up the memory.
  FREE(ctx->sockData);

  return XENONE;
}

/**
 * \brief Set a WEP key.  Also, based on the index, we may change the transmit
 *        key.
 *
 * @param[in] ctx   The context that contains the interface that we want to 
 *                  change the WEP key on.
 * @param[in] key   A pointer to a buffer that contains the key to be set.
 * @param[in] keylen   The amount of data in the buffer "key" that should be
 *                     used as a key.
 * @param[in] index   The key index to install the key in to.  If
 *                    (index & 0x80) then this is a transmit key, and the
 *                    transmit key index will be changed as well.
 *
 * \retval XEMALLOC on memory allocation error.
 * \retval XENONE on success
 **/
int cardif_set_wep_key(context *ctx, uint8_t *key, int keylen, int index)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  if (!xsup_assert((key != NULL), "key != NULL", FALSE))
    return XEMALLOC;

  if (wireless == NULL) return XEMALLOC;

  if (wireless->set_wep_key == NULL) return XEMALLOC;

  return wireless->set_wep_key(ctx, key, keylen, index);
}

/**
 * \brief Set a TKIP key. 
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  set the TKIP key on.
 * @param[in] addr   The BSSID of the AP that this key should be used with.
 *                   (Should be ff:ff:ff:ff:ff:ff for broadcast keys!)
 * @param[in] keyidx   Set to TRUE if this key should be used as a transmit
 *                     key.
 * @param[in] key   A pointer to a buffer that contains the key to be set.
 * @param[in] keylen   The amount of data in the buffer pointed to by "key"
 *                     that contains the key data.
 *
 * \retval XEMALLOC on memory allocation error
 * \retval XENONE on success
 **/
int cardif_set_tkip_key(context *ctx, char *addr,  int keyidx, int settx, 
			char *key, int keylen)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  if (wireless == NULL) return XEMALLOC;

  if (wireless->set_tkip_key == NULL) return XEMALLOC;

  return wireless->set_tkip_key(ctx, (uint8_t *) addr, keyidx, settx, 
				key, keylen);
}

/**
 * \brief Set a CCMP (AES) key
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  set the CCMP key on.
 * @param[in] addr   The BSSID of the AP that this key should be used with.
 *                   (Should be ff:ff:ff:ff:ff:ff for broadcast keys!)
 * @param[in] keyidx   The index that this key should be installed in to.
 * @param[in] settx   Set to TRUE if this key should be used as a transmit key.
 * @param[in] key   A pointer to a buffer that contains the key to be set.
 * @param[in] keylen   The amount of data in the buffer pointed to by "key" 
 *                     that contains the key data.
 *
 * \retval XEMALLOC on memory allocation error.
 * \retval XENONE on success
 **/
int cardif_set_ccmp_key(context *ctx, char *addr, int keyidx,
			int settx, char *key, int keylen)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  if (wireless == NULL) return XEMALLOC;

  if (wireless->set_ccmp_key == NULL) return XEMALLOC;

  return wireless->set_ccmp_key(ctx, (uint8_t *) addr, keyidx, settx,
				key, keylen);
}

/**
 * \brief Delete a key
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  delete a key from.
 * @param[in] key_idx   The index for the key that we want to delete.
 * @param[in] set_tx   TRUE if the key is a transmit key, FALSE if it isn't.
 *
 * \retval XEMALLOC on memory allocation error
 * \retval XENONE on success
 **/
int cardif_delete_key(context *ctx, int key_idx, int set_tx)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  if (wireless == NULL) return XEMALLOC;

  if (wireless->delete_key == NULL) return XEMALLOC;

  return wireless->delete_key(ctx, key_idx, set_tx);
}

/**
 * \brief Attempt to associate to a non-WEP network.
 *
 * Do whatever we need to do in order to associate based on the flags in
 * the ssids_list struct.
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  attempt an association on.
 **/
void cardif_associate(context *ctx)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return;

  if (wireless == NULL) 
    {
      debug_printf(DEBUG_NORMAL, "Invalid wireless structure in %s() at %d.\n",
		   __FUNCTION__, __LINE__);
      return;
    }

  if (wireless->associate == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Attempted to associate using an invalid "
		   "wireless driver struct in %s() at %d.\n", __FUNCTION__,
		   __LINE__);
      return;
    }

  wireless->associate(ctx);
}

/**
 * \brief Request the current SSID from the driver/card.
 *
 * Ask the wireless card for the ESSID that we are currently connected to.  If
 * this is not a wireless card, or the information is not available, we should
 * return an error.
 *
 * @param[in] ctx   The context that contains the interface that we are 
 *                  requesting the SSID for.
 *
 * @param[in,out] ssid_name   A pointer to a buffer that will contain the
 *                            SSID.  This should be at least 33 characters
 *                            long!
 * @param[in] ssid_buf_size   An integer that specifies the size of the 
 *                            buffer pointed to by "ssid_name".
 *
 * \retval XEMALLOC on memory allocation error
 * \retval XENONE on success
 **/
int cardif_GetSSID(context *ctx, char *ssid_name, unsigned int ssid_buf_size)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  if (!xsup_assert((ssid_name != NULL), "ssid_name != NULL", FALSE))
    return XEMALLOC;

  if (wireless == NULL) 
    {
      debug_printf(DEBUG_NORMAL, "No valid call to get SSID for this driver!"
		   "\n");
      return XEMALLOC;
    }

  if ((ctx == NULL) || (ssid_name == NULL)) 
  {
    debug_printf(DEBUG_INT, "NULL value passed to %s!\n", __FUNCTION__);
    return XEMALLOC;
  }

  return wireless->get_ssid(ctx, ssid_name, ssid_buf_size);
}

/******************************************
 *
 * Get the Broadcast SSID (MAC address) of the Access Point we are connected 
 * to.  If this is not a wireless card, or the information is not available,
 * we should return an error.
 *
 ******************************************/
int cardif_GetBSSID(context *thisint, char *bssid_dest)
{
  if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))
    return XEMALLOC;

  if (!xsup_assert((bssid_dest != NULL), "bssid_dest != NULL", FALSE))
    return XEMALLOC;

  if (wireless == NULL) return -1;

  if (thisint == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Invalid interface data structure passed to %s!\n", __FUNCTION__);
      return -1;
    }

  if (bssid_dest == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Invalid bssid_dest in %s!\n", __FUNCTION__);
      return -1;
    }

  return wireless->get_bssid(thisint, bssid_dest);
}

/**
 * \brief Determine the state of the interface.
 *
 * Set the flag in the state machine that indicates if this interface is up
 * or down.  If there isn't an interface, we should return an error.
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  determine the up/down state for.
 *
 * \retval XEMALLOC on memory allocation error
 * \retval XENONE on success
 * \retval XEGENERROR on general error
 **/
int cardif_get_if_state(context *ctx)
{
  int retVal;
  struct ifreq ifr;
  struct lin_sock_data *sockData;

  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  sockData = ctx->sockData;

  if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE))
    return XEMALLOC;

  memset(&ifr, 0x00, sizeof(ifr));
  Strncpy(ifr.ifr_name, sizeof(ifr.ifr_name), ctx->intName, 
	  strlen(ctx->intName)+1);

  if (strlen(ifr.ifr_name) == 0)
    {
      debug_printf(DEBUG_NORMAL, "Invalid interface name in %s():%d\n",
                   __FUNCTION__, __LINE__);
      return XEGENERROR;
    }

  retVal = ioctl(sockData->sockInt, SIOCGIFFLAGS, &ifr);
  if (retVal < 0)
    {
      debug_printf(DEBUG_NORMAL, "Interface %s not found!\n", ctx->intName);
      return FALSE;
    }
  
  if ((ifr.ifr_flags & IFF_UP) == IFF_UP)
    {
      return TRUE;
    } else {
      SET_FLAG(ctx->flags, WAS_DOWN);
      return FALSE;
    }
  return XENONE;
}

/**
 * \brief Send a frame out a network card interface.
 *
 * Send a frame out of the network card interface.  If there isn't an 
 * interface, we should return an error.  We should return a different error
 * if we have a problem sending the frame.
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  send a frame out.
 *
 * \retval XEMALLOC on memory allocation error
 * \retval XENONE on nothing to do
 * \retval XEGENERROR on general error
 * \retval >0 on success
 **/
int cardif_sendframe(context *ctx)
{
  char nomac[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  int retval;
  struct lin_sock_data *sockData;
  uint16_t pad;

  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  sockData = ctx->sockData;

  if (!xsup_assert((sockData != NULL), "sockData != NULL", FALSE))
    return XEMALLOC;

  if (ctx->send_size == 0) 
    {
      debug_printf(DEBUG_INT, "%s:%d -- Nothing to send!\n",
		   __FUNCTION__, __LINE__);
      return XENONE;
    }

  if (ctx->conn == NULL)
    {
      debug_printf(DEBUG_NORMAL, "No connection information available!\n");
      return XENONE;
    }

  // The frame we are handed in shouldn't have a src/dest, so put it in.
  memcpy(&ctx->sendframe[0], &ctx->dest_mac[0], 6);
  memcpy(&ctx->sendframe[6], &ctx->source_mac[0], 6);

  if (ctx->conn == NULL)
    {
      debug_printf(DEBUG_NORMAL, "No connection information available!  Can't"
		   " complete authentication!\n");
      return XEGENERROR;
    }

  if (memcmp(nomac, (char *)&ctx->conn->dest_mac[0], 6) != 0)
    {
      debug_printf(DEBUG_INT, "Static MAC address defined!  Using it!\n");
      memcpy(&ctx->sendframe[0], &ctx->conn->dest_mac[0], 6);
    }

  // Make sure the frame is large enough.
  if (ctx->send_size < 64)
    {
      pad = 64 - ctx->send_size;
      debug_printf(DEBUG_INT, "Padding frame to 64 bytes by adding %d byte"
		   "(s).\n", pad);
      memset(&ctx->sendframe[ctx->send_size+1], 0x00, pad);
      ctx->send_size += pad;
    }

  debug_printf(DEBUG_INT, "Frame to be sent (%d) : \n",
	       ctx->send_size);
  debug_hex_dump(DEBUG_INT, ctx->sendframe, ctx->send_size);

  snmp_dot1xSuppEapolFramesTx();

  retval = sendto(sockData->sockInt, ctx->sendframe, ctx->send_size, 0,
		  NULL, 0);
  if (retval <= 0)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't send frame! (%s)\n", strerror(errno));
    }

  memset(ctx->sendframe, 0x00, FRAMESIZE);
  ctx->send_size = 0;
  
  // Clear out the receive buffer so we don't accidently try to process it
  // again.
  if (ctx->recvframe != NULL)
    {
      memset(ctx->recvframe, 0x00, FRAMESIZE);
      ctx->recv_size = 0;
    }

  return retval;
}

/**
 * \brief Get a frame from a network interface.
 * 
 * Get a frame from the network.  Make sure to check the frame, to determine 
 * if it is something we care about, and act accordingly.
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  get a frame from.
 *
 * \retval XEMALLOC on memory allocation error
 * \retval XENOFRAMES if there are no frames to be had
 * \retval >0 if a frame was received
 **/
int cardif_getframe(context *ctx)
{
  int newsize=0;
  char dot1x_default_dest[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x03};
  struct lin_sock_data *sockData;
  uint8_t *resultframe;
  int resultsize;
  struct config_globals *globals;

  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  globals = config_get_globals();

  if (!xsup_assert((globals != NULL), "globals != NULL", FALSE))
    return XEMALLOC;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?