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

📄 cardif_linux_rtnetlink.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 3 页
字号:
  wctx = (wireless_ctx *)ctx->intTypeData;

  memset(essid, 0x00, IW_ESSID_MAX_SIZE+1);
  
  memcpy(essid, iwe->u.essid.pointer, iwe->u.essid.length);
  essid[iwe->u.essid.length] = '\0';

#warning Check this!
  if (TEST_FLAG(wctx->flags, WIRELESS_SCANNING))
    {
      debug_printf(DEBUG_NORMAL, "Got an SSID set request from a scan!? "
		   "Notify your driver maintainer!\n");
    } else {
      debug_printf(DEBUG_INT, "ESSID set .. name : %s\n", essid);
      
      if ((essid == NULL) || (wctx->cur_essid == NULL) ||
	  (strcmp(essid, wctx->cur_essid) != 0))
	{
	  if (config_ssid_ssid_known(wctx, essid) != TRUE)
	    {
	      // We only want to set this to TRUE if we don't already know
	      // something about the SSID we connected to.
	      SET_FLAG(wctx->flags, WIRELESS_SM_SSID_CHANGE);
	    }
	  
	  if (config_build(ctx, essid) == FALSE)
	    {
	      debug_printf(DEBUG_NORMAL, "Couldn't build a valid configuration"
			   " for ESSID %s!\n", essid);

	      // If we didn't initiate the set, then clear keys.
	      if (!TEST_FLAG(wctx->flags, WIRELESS_SM_SSID_CHANGE))
		{
		  cardif_clear_keys(ctx);

		  memset(wpaie, 0x00, sizeof(wpaie));

		  // We will also need to clear the WPA IE.
		  if (cardif_linux_wext_set_wpa_ie(ctx, (unsigned char *)wpaie,
						   0) < 0)
		    {
		      debug_printf(DEBUG_NORMAL, "Couldn't clear WPA IE!  You "
				   "may not be able to associate.\n");
		    }
		}
	    }
	  
	  // We changed ssids, so record the new one.
	  if (wctx->cur_essid != NULL)
	    {
	      FREE(wctx->cur_essid);

	      wctx->cur_essid = strdup(essid);
	    }
	}
    }
  // Unset the SSID_SET flag, if we set it.
  UNSET_FLAG(wctx->flags, WIRELESS_SM_SSID_CHANGE);
}

/**********************************************************************
 *
 * Scan through whatever was returned by the IWEVGENIE event, and pull
 * out any interesting IEs.
 *
 **********************************************************************/
void cardif_linux_rtnetlink_parse_ies(context *ctx,
				      uint8_t *iedata, int ielen)
{
  int i = 0;
  wireless_ctx *wctx = NULL;

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

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

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

  if (!xsup_assert((ielen > 0), "ielen > 0", FALSE))
    return;

  if (!xsup_assert((ielen < 256), "ielen < 256", FALSE))
    return;

  wctx = (wireless_ctx *)ctx->intTypeData;

  while (i < ielen)
    {
      if (iedata[i] == WPA_EID)
	{
	  if (wpa_parse_ie((char *)&iedata[i]) > 0)
	    {
	      // We have a valid IE, save it.
	      config_ssid_update_abilities(wctx, WPA_IE);
	      config_ssid_add_wpa_ie(wctx, (uint8_t *)&iedata[i], iedata[i+1]+2);
	    }
	}

      if (iedata[i] == WPA2_EID)
	{
	  if (wpa2_parse_ie((char *)&iedata[i]) > 0)
	    {
	      // We have a valid IE, save it.
	      config_ssid_update_abilities(wctx, RSN_IE);
	      config_ssid_add_rsn_ie(wctx, (uint8_t *)&iedata[i], iedata[i+1]+2);
	    }
	}
      i += (iedata[i+1]+2);
    }
}

/**********************************************************************
 *
 * Process an IWEVGENIE event.
 *
 **********************************************************************/
void cardif_linux_rtnetlink_process_IWEVGENIE(context *ctx,
					      struct iw_event *iwe)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return;

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

  debug_printf(DEBUG_INT, "IWEVGENIE (%d)\n", iwe->u.data.length);
  debug_printf_nl(DEBUG_INT, "IE : ");
  debug_hex_printf(DEBUG_INT, iwe->u.data.pointer, iwe->u.data.length);
  cardif_linux_rtnetlink_parse_ies(ctx, iwe->u.data.pointer, 
				   iwe->u.data.length);
}

/**********************************************************************
 *
 * Process an IWEVCUSTOM event.
 *
 **********************************************************************/
void cardif_linux_rtnetlink_process_IWEVCUSTOM(context *ctx,
					       struct iw_event *iwe)
{
  char custom[IW_CUSTOM_MAX+1];
  char temp[IW_CUSTOM_MAX+1];
  wireless_ctx *wctx = NULL;

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

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

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

  wctx = (wireless_ctx *)ctx->intTypeData;

  if (TEST_FLAG(wctx->flags, WIRELESS_SCANNING))
    {
      Strncpy(custom, IW_CUSTOM_MAX+1, iwe->u.data.pointer, 
	      iwe->u.data.length);
      
      debug_printf(DEBUG_INT, "IWEVCUSTOM : %s\n", custom);
      
      if (strncmp("wpa_ie=", custom, 7) == 0)
	{
	  config_ssid_update_abilities(wctx, WPA_IE);
	  debug_printf(DEBUG_INT, "AP appears to support WPA!\n");
	  
	  process_hex(&custom[7], (iwe->len -7), temp);
	  wpa_parse_ie(temp);
	  
	  config_ssid_add_wpa_ie(wctx, (uint8_t *)temp, 
				 ((iwe->u.data.length - 7)/2));
	}
      
      if (strncmp("rsn_ie=", custom, 7) == 0)
	{
	  config_ssid_update_abilities(wctx, RSN_IE);
	  debug_printf(DEBUG_INT, "AP appears to support WPA2/802.11i!\n");
	  
	  process_hex(&custom[7], (iwe->len -7), temp);
	  wpa2_parse_ie(temp);
	  
	  config_ssid_add_rsn_ie(wctx, (uint8_t *)temp, 
				 ((iwe->u.data.length - 7)/2));
	}
    } else {
      Strncpy(custom, IW_CUSTOM_MAX+1, iwe->u.data.pointer, 
	      iwe->u.data.length);

      memset(temp, 0x00, IW_CUSTOM_MAX+1);
      
      memcpy(temp, custom, iwe->u.data.length);
      temp[iwe->u.data.length] = '\0';
      debug_printf(DEBUG_INT, "Custom Data : \n");
      debug_hex_dump(DEBUG_INT, (uint8_t *)temp, iwe->u.data.length);
      cardif_linux_rtnetlink_check_custom(ctx, temp);
    }
}

/**********************************************************************
 *
 * Process an SIOCGIWSCAN event.
 *
 **********************************************************************/
void cardif_linux_rtnetlink_process_SIOCGIWSCAN(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 (TEST_FLAG(wctx->flags, WIRELESS_SCANNING))
    {
      debug_printf(DEBUG_NORMAL, "Got an SIOCGIWSCAN in a scan result!? "
		   "Contact your wireless card driver maintainer!\n");
    } else {
      debug_printf(DEBUG_INT, "Wireless scan complete!\n");
      cardif_linux_rtnetlink_check_nets(ctx);
    }
}

/**********************************************************************
 *
 * Process an association request IE, if one is returned.
 *
 **********************************************************************/
void cardif_linux_rtnetlink_process_IWEVASSOCREQIE(context *ctx, 
						   struct iw_event *iwe)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return;

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

  if (iwe->u.data.length <= 0)
    {
      debug_printf(DEBUG_NORMAL, "Got an IWEVASSOCREQIE, but it contains "
		   "no data?!\n");
      return;
    }

  debug_printf(DEBUG_INT, "IWEVASSOCREQIE returned : \n");
  debug_hex_printf(DEBUG_INT, iwe->u.data.pointer, iwe->u.data.length);
  cardif_linux_rtnetlink_parse_ies(ctx, iwe->u.data.pointer, 
				   iwe->u.data.length);
}

/**********************************************************************
 *
 * Process a response IE if one is returned.
 *
 **********************************************************************/
void cardif_linux_rtnetlink_process_IWEVASSOCRESPIE(context *ctx,
						    struct iw_event *iwe)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return;

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

  if (iwe->u.data.length <= 0)
    {
      debug_printf(DEBUG_NORMAL, "Got an IWEVASSOCRESPIE, but it contains "
		   "no data?!\n");
      return;
    }
  debug_printf(DEBUG_INT, "IWEVASSOCRESPIE returned : \n");
  debug_hex_printf(DEBUG_INT, iwe->u.data.pointer, iwe->u.data.length);
  cardif_linux_rtnetlink_parse_ies(ctx, iwe->u.data.pointer,
				   iwe->u.data.length);
}

/***************************************************************************
 *
 * Handle a Michael MIC failure.
 *
 ***************************************************************************/
void cardif_linux_rtnetlink_process_IWEVMICHAELMICFAILURE(context *ctx,
							  struct iw_event *iwe)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return;

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

#ifdef IW_MICFAILURE_KEY_ID
  struct iw_michaelmicfailure *mic;

  // TODO : Double check this implementation.

  if (iwe->u.data.length <= 0)
    {
      debug_printf(DEBUG_NORMAL, "Got a MIC failure, but it contained no "
		   "data!  Ignoring! (This may be dangerous.)\n");
      return;
    }

  mic = iwe->u.data.pointer;

  debug_printf(DEBUG_INT, "MIC failure :\n");
  debug_printf(DEBUG_INT, "  Key ID   : %d\n", mic->flags & IW_MICFAILURE_KEY_ID);
  
  if (mic->flags & IW_MICFAILURE_GROUP)
    {
      debug_printf(DEBUG_INT, "  Key Type : Group\n");
      debug_printf(DEBUG_NORMAL, "MIC failure on group key!\n");
      eapol_key_type254_request_new_key(ctx, 0);
      ctx->send_size = 0;
    } 

  if (mic->flags & IW_MICFAILURE_PAIRWISE)
    {
      debug_printf(DEBUG_INT, "  Key Type : Pairwise\n");
      debug_printf(DEBUG_NORMAL, "MIC failure on pairwise key!\n");
      eapol_key_type254_request_new_key(ctx, 1);
      ctx->send_size = 0;
    }

  if (mic->flags & IW_MICFAILURE_STAKEY)
    {
      debug_printf(DEBUG_INT, "  STAKEY\n");
    }

  // Some wireless cards may also return a count.  But we maintain our own
  // internal counter, so it isn't relevant.
  
  ctx->statemachine->MICfailures++;
  debug_printf(DEBUG_NORMAL, "MIC failure #%d!\n",
	       ctx->statemachine->MICfailures);
      
  if (ctx->statemachine->MICfailures >= 2)
    {
      // The WPA/802.11i standard requires we assert countermeasures 
      // for 60 seconds.
      if (timer_check_existing(ctx, COUNTERMEASURE_TIMER))
	{
	  debug_printf(DEBUG_NORMAL, "For some reason, we already have "
		       "a countermeasure timer in the queue!  Resetting "
		       "the timer!\n");
	  timer_reset_timer_count(ctx, COUNTERMEASURE_TIMER, 
				  MIC_COUNTERMEASURE_TIMEOUT);
	} else {
	  debug_printf(DEBUG_NORMAL, "Enabling MIC countermeasures!\n");
	  timer_add_timer(ctx, COUNTERMEASURE_TIMER, 
			  MIC_COUNTERMEASURE_TIMEOUT,
			  NULL, &mic_disable_countermeasures);
	}
      cardif_countermeasures(ctx, TRUE);
    }
#else
  debug_printf(DEBUG_NORMAL, "MIC failure support is not enabled in the "
	       "version of wireless extensions on your platform.  You should"
	       " consider upgrading to a more current version!\n");
#endif
}

/**********************************************************************
 *
 * Given a wireless event, process it.  If *state is NULL, then the event
 * is the result of a requested scan, so it needs to be added to the
 * SSID list.  If *state is not NULL, then this is an event generated by
 * the wireless interface.
 *
 **********************************************************************/
void cardif_linux_rtnetlink_process_token(context *ctx,
					  struct iw_event *iwe)
{
  wireless_ctx *wctx = NULL;

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

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

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

  wctx = (wireless_ctx *)ctx->intTypeData;

  switch (iwe->cmd)
    {
    case SIOCGIWAP:
      cardif_linux_rtnetlink_process_SIOCGIWAP(ctx, iwe);
      break;
      
    case SIOCGIWFREQ:
      // Don't care.
      break;
      
    case SIOCGIWMODE:
      // Don't care.
      break;
      
    case SIOCGIWESSID:
      cardif_linux_rtnetlink_process_SIOCGIWESSID(ctx, iwe);
      break;

    case SIOCSIWESSID:
      cardif_linux_rtnetlink_process_SIOCSIWESSID(ctx, iwe);
      break;
      
    case SIOCGIWNAME:
      // Don't care.
      break;

    case SIOCGIWSCAN:
      cardif_linux_rtnetlink_process_SIOCGIWSCAN(ctx);
      break;

#ifdef IWEVTXDROP
      // This is mostly for the gee-whiz factor.
    case IWEVTXDROP:
      debug_printf(DEBUG_INT, "Wireless TX Drop\n");
      break;
#endif
      
#if WIRELESS_EXT > 17
    case IWEVASSOCREQIE:
      debug_printf(DEBUG_INT, "IWEVASSOCREQIE\n");
      debug_hex_printf(DEBUG_INT, iwe->u.data.pointer, iwe->u.data.length);
      cardif_linux_rtnetlink_process_IWEVASSOCREQIE(ctx, iwe);
      break;
      
    case IWEVASSOCRESPIE:
      debug_printf(DEBUG_INT, "IWEVASSOCRESPIE\n");
      cardif_linux_rtnetlink_process_IWEVASSOCRESPIE(ctx, iwe);
      break;
      
    case IWEVGENIE:
#warning Check this!
      if (TEST_FLAG(wctx->flags, WIRELESS_SCANNING))
	{
	  cardif_linux_rtnetlink_process_IWEVGENIE(ctx, iwe);
	}
      break;

    case IWEVMICHAELMICFAILURE:
      debug_printf(DEBUG_INT, "MIC Failure!\n");
      cardif_linux_rtnetlink_process_IWEVMICHAELMICFAILURE(ctx, iwe);
      break;
      
    case IWEVPMKIDCAND:
      debug_printf(DEBUG_INT, "IWEVPMKIDCAND\n");
      break;
#endif
    case SIOCGIWENCODE:
      if (TEST_FLAG(wctx->flags, WIRELESS_SCANNING))
	{
	  if (!(iwe->u.data.flags & IW_ENCODE_DISABLED))
	    {
	      config_ssid_update_abilities(wctx, ENC);
	    }
	}
      break;
      
    case SIOCGIWRATE:
      // Don't care.
      break;
      
    case IWEVQUAL:
      debug_printf(DEBUG_INT, "Quality : %d  Signal : %d   Noise : %d\n",
		   iwe->u.qual.qual, (iwe->u.qual.level - 0x100), 
		   (iwe->u.qual.noise - 0x100));
      config_ssid_add_qual(wctx, iwe->u.qual.qual, (iwe->u.qual.level - 0x100), 
			   (iwe->u.qual.noise - 0x100));
      break;
      
    case IWEVCUSTOM:
      cardif_linux_rtnetlink_process_IWEVCUSTOM(ctx, iwe);
      break;

    case SIOCSIWENCODE:
      debug_printf(DEBUG_INT, "Encryption key set\n");
      break;

    default:
      debug_printf(DEBUG_INT, "Unknown event (%04X)  (Unknown in wireless "
		   "extensions %d?)\n", iwe->cmd, WIRELESS_EXT);
    }
}

/*******************************************************
 *
 * Check to see if we have any events, and act on them if we do.
 *
 *******************************************************/
int cardif_linux_rtnetlink_check_event(context *idata, int sock)
{
  int rtnl_data_size, remain, length;
  char buf[8192];
  struct nlmsghdr *nlhead = NULL;

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

  // Grab the next message off the rtnetlink socket.
  rtnl_data_size = sizeof(rtnl_data);
  if (rtnl_sock < 0)
    {
      debug_printf(DEBUG_NORMAL, "RTnetlink socket not available!\n");
      return XENOSOCK;
    }

  remain = recvfrom(rtnl_sock, buf, sizeof(buf), MSG_DONTWAIT,
		    (struct sockaddr *)&rtnl_data, 
		    (u_int *) &rtnl_data_size);
  if (remain >= 0)
    {
      // We need a pointer to the buffer to work with.
      nlhead = (struct nlmsghdr *)buf;

⌨️ 快捷键说明

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