cardif_linux.c

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

C
1,995
字号
/**
 * \todo Write this!
 **/
int cardif_get_wpa2_ie(context *ctx, char *iedata, int *ielen)
{
  if (!xsup_assert((ctx != NULL), "ctx != 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)
    {
      debug_printf(DEBUG_NORMAL, "Invalid wireless function pointers.\n");
      return XEMALLOC;
    }

  if (iedata == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Invalid memory for IE data! (%s:%d)\n",
		   __FUNCTION__, __LINE__);
      return XEMALLOC;
    }

  if (!wireless->get_wpa2_ie)
    {
      debug_printf(DEBUG_NORMAL, "No valid function to get WPA2 IE!\n");
      return XEMALLOC;
    }

  return wireless->get_wpa2_ie(ctx, iedata, ielen);
}

/**
 * \brief Clear any keys that are in use on the interface.
 *
 * This function should clear out all keys that have been applied to the card.
 * It should be indepentant of the type (WEP/TKIP/CCMP) of key that was
 * applied.
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  clear the keys for.
 *
 * \retval XENONE on success
 * \retval XEMALLOC on error
 **/
int cardif_clear_keys(context *ctx)
{
  int retVal = 0, i;

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

  // Clear the TX key.
  retVal = cardif_delete_key(ctx, 0, 1);
  if (retVal != XENONE) 
    {
      debug_printf(DEBUG_NORMAL, "Error clearing default TX key!\n");
      return retVal;
    }

  // Now, clear out the broadcast/multicast/group key(s).
  for (i=0;i<4;i++)
    {
      retVal = cardif_delete_key(ctx, i, 0);
      if (retVal != XENONE)
	{
	  debug_printf(DEBUG_NORMAL, "Error clearing key %d!\n", i);
	  return retVal;
	}
    }

  return XENONE;
}

/**
 * \brief Attempt to reassociate to the network we were previously connected 
 *        to.
 *
 * @param[in] ctx   The context that contains the interface that we want
 *                  to reassociate on.
 * @param[in] reason   The reason code for a disassociation  as specified by 
 *                     the IEEE 802.11  standards documents.
 **/
void cardif_reassociate(context *ctx, uint8_t reason)
{
  wireless_ctx *wctx;

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

  if (!xsup_assert((ctx->intTypeData != NULL), "ctx->intTypeData != NULL", FALSE))
    return;

  wctx = (wireless_ctx *)ctx->intTypeData;

  if (!config_ssid_using_wep(wctx))
    {
      debug_printf(DEBUG_NORMAL, "SSID '%s' is WPA/WPA2 capable. WPA/WPA2 is "
		   "enabled on this connection.\n", wctx->cur_essid);
      
      // Since we are doing WPA/WPA2, we need to disassociate from 
      // the network, and reassociate with WPA/WPA2 set up.
      cardif_enable_wpa(ctx);
      cardif_enable_wpa_state(ctx);

      cardif_clear_keys(ctx);
    }

  cardif_associate(ctx);  
}

/**
 * \brief Disable encryption on the card.  (Set the interface to open mode.)
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  disable encryption on.
 *
 * \retval XENONE on success
 * \retval !XENONE on error
 **/
int cardif_enc_disable(context *ctx)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  return wireless->enc_disable(ctx);
}

/**
 * \brief Determine what abilities this card has.  (WPA, WPA2, TKIP, CCMP, 
 *        WEP40, etc.)
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  get the abilities for.
 **/
void cardif_get_abilities(context *ctx)
{
  wireless_ctx *wctx = NULL;

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

  if (!xsup_assert((ctx->intTypeData != NULL), "ctx->intTypeData != NULL",
		   FALSE))
    return;

  wctx = (wireless_ctx *)ctx->intTypeData;

  if (!wireless->enc_capabilities)
    {
      wctx->enc_capa = 0;
      return;
    }

  wireless->enc_capabilities(ctx);
}

/**
 * \brief Change the BSSID that we are currently connected to.
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  get the BSSID for.
 * @param[in,out] new_bssid   A pointer to a buffer of at least 6 bytes that
 *                            will return the BSSID of the AP.
 **/
void cardif_setBSSID(context *ctx, uint8_t *new_bssid)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return;

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

  if (!wireless->setbssid)
    {
      return;
    }

  wireless->setbssid(ctx, new_bssid);
}

/**
 * \brief Change the operstate of the interface.
 *
 * @param[in] ctx   The context that contains the interface that we want
 *                  to update the operstate for.
 * @param[in] newstate   The new operstate for the interface pointed to by
 *                       "ctx".
 **/
void cardif_operstate(context *ctx, uint8_t newstate)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return;

  if (!wireless->set_operstate)
    {
      debug_printf(DEBUG_INT, "No function defined to set operstate. (This "
		   "is probably nothing to worry about.\n");
      return;
    }

  wireless->set_operstate(ctx, newstate);
}

/******************************************************************
 *
 * Wait for an interface to be "attached" to the system before starting to
 * attempt authentication with it.  This is a blocking call that should
 * *ONLY* return when the interface is available.  (Note : 'available'
 * does not mean that the interface is UP.  The 802.1X state machine will
 * deal with the interface if it is down.  We just need to wait for an
 * interface to exist so that we can use it.
 *
 ******************************************************************/
void cardif_wait_for_int(char *intname)
{
  int idx = -1;

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

  idx = if_nametoindex(intname);
  if (idx < 1)
    {
      debug_printf(DEBUG_NORMAL, "Waiting for interface to be inserted, or "
		   "driver to be loaded.\n");
      while (if_nametoindex(intname) < 1)
	{
	  sleep(1);
	}
    }
}

/**
 * \brief Called when the passive scan timer times out.
 *
 * The passive scan timer expried.  So, we need to issue a scan request,
 * and reset our timer to recheck the scan results periodically.
 *
 * @param[in] ctx   A pointer to the context that contains the interface
 *                  that the passive scan timer timed out on.
 **/
void cardif_passive_scan_timeout(context *ctx)
{
  struct config_globals *globals;
  uint8_t *mac;
  char *ssid;
  wireless_ctx *wctx;

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

  if (!xsup_assert((ctx->intTypeData != NULL), "ctx->intTypeData != NULL",
		   FALSE))
    return;

  wctx = (wireless_ctx *)ctx->intTypeData;

#warning FINISH!  We get scan data results, but we still need to do something with them.

  if (!TEST_FLAG(wctx->flags, WIRELESS_PASV_SCANNING))
    {
     if (!TEST_FLAG(wctx->flags, WIRELESS_SCANNING))
	{
	  timer_reset_timer_count(ctx, PASSIVE_SCAN_TIMER, 5);
	  cardif_do_wireless_scan(ctx, 1);
	  SET_FLAG(wctx->flags, WIRELESS_PASV_SCANNING);
	}
      else
	{
	  debug_printf(DEBUG_NORMAL, "Got a request to start a new passive scan "
		       "when a previous one has not completed!\n");
	}
    }
  else
    {
      // If the scanning flag is no longer set, then we need to make a decision
      // about how to associate.
      debug_printf(DEBUG_NORMAL, "Looking for the best network to connect to.\n");
      // Clear the passive scanning flag.
      UNSET_FLAG(ctx->flags, WIRELESS_PASV_SCANNING);

      // Reset the timer so that we scan again.
      
      globals = config_get_globals();
      
      if (!globals)
	{
	  debug_printf(DEBUG_NORMAL, "No global data!  Passive scanning will"
		       " be broken until the next time an authentication "
		       "completes.\n");
	}
      else
	{
	  debug_printf(DEBUG_INT, "Resetting passive scan timer.\n");
	  timer_reset_timer_count(ctx, PASSIVE_SCAN_TIMER, globals->passive_timeout);
	  
	}

      ssid = config_ssid_get_desired_ssid(ctx);

      if (ssid == NULL)
        {
          debug_printf(DEBUG_NORMAL, "No valid SSID was returned.  Either "
                       "there is something wrong with your configuration, or"
                       " the passive scan didn't find a network that is "
                       "currently configured.\n");
          return;
        }

      if (strcmp(ssid, wctx->cur_essid) != 0)
	{
	  debug_printf(DEBUG_NORMAL, "The best AP to connect to appears to be"
		       " in a different ESSID!  It is likely that your card"
		       " doesn't support the needed passive scanning flags."
		       "\n");
	  // Don't do anything with the result.
	} 
      else
	{
	  // We got a valid result.  So, see if it is a different AP.  If it
	  // is, then jump to it.
	  mac = config_ssid_get_mac(wctx);

          if (mac == NULL)
            {
              debug_printf(DEBUG_NORMAL, "Couldn't determine the MAC "
                           "address for the desired SSID found in a passive "
                           "scan.  You may not be associated to the best AP, "
                           "but your network should continue to work.\n");
              return;
            }

	  if (memcmp(ctx->dest_mac, mac, 6) != 0)
	    {
	      debug_printf(DEBUG_INT, "Jumpping to a BSSID with a better "
			   "signal.  (BSSID : ");
	      debug_hex_printf(DEBUG_INT, mac, 6);
	      debug_printf_nl(DEBUG_INT, ")\n");

	      // Then change our BSSIDs.
	      cardif_setBSSID(ctx, mac);
	    }
	  else
	    {
	      debug_printf(DEBUG_INT, "We are connected to the best "
			   "BSSID already.\n");
	    }
	}
    }
}


int cardif_get_signal_strength_percent(context *ctx)
{
#warning FINISH!
  return 0;
}

char *cardif_get_ip(context *ctx)
{
#warning FINISH!
  return NULL;
}

char *cardif_get_netmask(context *ctx)
{
#warning FINISH!
  return NULL;
}

char *cardif_get_gw(context *ctx)
{
#warning FINISH!
  return NULL;
}

char *cardif_get_dns1(context *ctx)
{
#warning FINISH!
  return NULL;
}

char *cardif_get_dns2(context *ctx)
{
#warning FINISH!
  return NULL;
}

char *cardif_get_dns3(context *ctx)
{
#warning FINISH!
  return NULL;
}

/**
 * \brief Enumerate all of the interfaces that are on the machine, and put
 *        them in the interface cache.
 **/
void cardif_enum_ints()
{
  struct if_nameindex *ifnames;
  int i = 0;
  char mac[6];

  ifnames = if_nameindex();
  if (ifnames == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Got an error with if_nameindex() call!\n");
      debug_printf(DEBUG_NORMAL, "Are there no interfaces on this machine?\n");
      return;
    }

  while ((ifnames[i].if_index != 0) && (ifnames[i].if_name != NULL))
    {
      debug_printf(DEBUG_INT, "Interface %d named %s.\n", ifnames[i].if_index, ifnames[i].if_name);

      // Make sure we aren't looking at any loopback interfaces.
      if (strcasestr(ifnames[i].if_name, "lo") == NULL)
        {
          if (_getmac((char *)&mac, ifnames[i].if_name) == TRUE)
            {
              // Add it to our interface cache!
              interfaces_add(ifnames[i].if_name, ifnames[i].if_name, mac,
                             is_wireless(ifnames[i].if_name));
            }
        }

      i++;
    }

  if_freenameindex(ifnames);
}

/**
 * \brief Determine the device description based on the OS specific interface
 *        name.  For Linux, the OS specific interface name, and the 
 *        device description will be the same.
 *
 * @param[in] intname   The OS specific interface name to search for.
 *
 * \retval NULL on error, or interface not found.
 * \retval ptr to the interface description
 **/
char *cardif_find_description(char *intname)
{
  return strdup(intname);
}

/**
 * \brief Get a string representation of an interface's MAC address based on the
 *        OS specific interface name.
 *
 * @param[in] intname   The OS specific interface name for the interface we want to
 *                      get information on.
 *
 * \retval NULL on error
 * \retval ptr to MAC address string on success
 **/
char *cardif_get_mac_str(char *intname)
{
  uint8_t mac[6];
  char *resmac = NULL;

  if (get_mac_by_name(intname, (char *)&mac) != 0) return NULL;

  resmac = Malloc(25);
  if (resmac == NULL) return NULL;

  sprintf(resmac, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2]\
	  , mac[3],
	  mac[4], mac[5]);

  return resmac;
}

/**
 * \brief Determine in an interface is wireless based on it's OS specific
 *        interface name.
 *
 * @param[in] intname   The OS specific interface name that we want to check
 *                      to see if it is wireless.
 *
 * \retval TRUE if the interface is wireless
 * \retval FALSE if the interface is *NOT* wireless
 **/
int cardif_is_wireless_by_name(char *intname)
{
  return is_wireless(intname);
}


#endif

⌨️ 快捷键说明

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