cardif_linux.c

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

C
1,995
字号
  sockData = ctx->sockData;

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

  errno = 0;
  resultsize = FRAMESIZE; /* overflows resultframe if too large, or should we increase resultframe instead? */

  FREE(ctx->recvframe);

  resultframe = Malloc(FRAMESIZE);
  if (resultframe == NULL)
    {
      debug_printf(DEBUG_INT, "Couldn't allocate memory for incoming frame!\n");
      return -1;
    }

  newsize = recvfrom(sockData->sockInt, resultframe, resultsize, 0, 0, 0);
  if (newsize <= 0)
    {
      if ((errno != EAGAIN) && (errno != ENETDOWN))
	{
	  debug_printf(DEBUG_NORMAL, "Error (%d) : %s  (%s:%d)\n", errno,
		       strerror(errno), __FUNCTION__, __LINE__);
	}
      return XENOFRAMES;
    } else {
      debug_printf(DEBUG_INT, "Got Frame (%d) : \n", newsize);
      debug_hex_dump(DEBUG_INT, resultframe, newsize);
    }

  snmp_dot1xSuppEapolFramesRx();

  // Make sure that the frame we got is for us..
  if ((memcmp(&ctx->source_mac[0], &resultframe[0], 6) == 0) ||
      ((memcmp(&resultframe[0], &dot1x_default_dest[0], 6) == 0) &&
       (memcmp(&resultframe[6], &ctx->source_mac[0], 6) != 0)))
    {
      // Since we now know this frame is for us, record the address it
      // came from.
      snmp_dot1xSuppLastEapolFrameSource((uint8_t *)&resultframe[6]);

      resultsize = newsize;

      switch (globals->destination)
	{
	case DEST_AUTO:
	  // If it is a wired interface, only change the destination if
	  // the recieved frame destination isn't the multicast address.
	  if (ctx->intType == ETH_802_11_INT)
	    {
	      if (memcmp(&resultframe[0], dot1x_default_dest, 6) == 0)
		{
		  break;
		}
	      // Otherwise, fall through.
	    }
	  else
	    {
	      break;
	    }

	case DEST_SOURCE:
	  if (memcmp(ctx->dest_mac, &resultframe[6], 6) != 0)
	    {
	      debug_printf(DEBUG_INT, "Changing destination mac to source.\n");
	    }
	  memcpy(ctx->dest_mac, &resultframe[6], 6);
	  break;

	case DEST_MULTICAST:
	  memcpy(ctx->dest_mac, dot1x_default_dest, 6);
	  break;

	case DEST_BSSID:
	  cardif_GetBSSID(ctx, ctx->dest_mac);
	  break;

	default:
	  debug_printf(DEBUG_NORMAL, "Unknown destination mode!\n");
	  break;
	}

      ctx->recv_size = newsize;

      ctx->recvframe = resultframe;
      return newsize;
    }

  // Otherwise it isn't for us. 
  debug_printf(DEBUG_INT, "Got a frame, not for us.\n");
  return XENOFRAMES;
}

/**
 * \brief Set the state needed to associate to a WPA enabled AP, and actually
 *        do a WPA authentication.
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  enable WPA state on.
 *
 * \retval XEMALLOC on memory allocation error
 * \retval XENONE on success
 **/
int cardif_enable_wpa_state(context *ctx)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  if (wireless == NULL) return XEMALLOC;

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

  debug_printf(DEBUG_INT, "WPA: Enabling WPA state on interface %s.\n",ctx->intName);

  return wireless->wpa_state(ctx, TRUE);
}

/**
 * \brief Clear the state needed to associate to a WPA enabled AP, and actually
 *        do a WPA authentication.
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  clear WPA state from.
 *
 * \retval XENONE on success
 * \retval XEMALLOC on memory allocation failure
 **/
int cardif_disable_wpa_state(context *ctx)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  if (wireless == NULL) return XEMALLOC;

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

  return wireless->wpa_state(ctx, FALSE);
}

/**
 * \brief Enable WPA (if it is supported.)
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  enable WPA on.
 *
 * \retval XENONE on success
 * \retval XEMALLOC on memory allocation failure
 **/
int cardif_enable_wpa(context *ctx)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  if (wireless == NULL) return XEMALLOC;

  debug_printf(DEBUG_INT, "WPA: Enabling WPA on interface %s.\n",ctx->intName);

  return wireless->wpa(ctx, TRUE);
}

/**
 * \brief Call this when we roam to a different AP, or disassociate from an AP.
 *
 * @param[in] ctx   The context that contains the interface that we want to 
 *                  associate with using WEP.
 * @param[in] zeros   TRUE if we should set all of the WEP keys to 0s, FALSE
 *                    if all of the WEP keys should just be cleared.
 * 
 * \retval XENONE on success, or not needed
 * \retval XEMALLOC on memory allocation failure
 **/
int cardif_wep_associate(context *ctx, int zeros)
{
  wireless_ctx *wctx;

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

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

  if (wireless == NULL) return XEMALLOC;

  wctx = (wireless_ctx *)ctx->intTypeData;

  if (!config_ssid_using_wep(wctx))
    {
      debug_printf(DEBUG_INT, "Doing WPA/WPA2 mode! Not "
		   "setting/unsetting keys.\n");
      return XENONE;
    }

  return wireless->wep_associate(ctx, zeros); 
}

/**
 * \brief Validate an interface, based on if it has a MAC address.
 *
 * @param[in] interface   The interface name to check.
 *
 * \retval FALSE if it isn't a valid interface
 * \retval TRUE if it is a valid interface
 **/
int cardif_validate(char *interface)
{
  int sd, res;
  struct ifreq ifr;

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

  memset(&ifr, 0x00, sizeof(ifr));
  Strncpy(ifr.ifr_name, sizeof(ifr.ifr_name), interface, strlen(interface)+1);

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

  sd = socket(PF_PACKET, SOCK_RAW, 0);
  if (sd < 0)
    return FALSE;

  res = ioctl(sd, SIOCGIFHWADDR, &ifr);
  close(sd);

  if (res < 0)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't get information for interface %s!\n",interface);
    } else {
      switch (ifr.ifr_hwaddr.sa_family)
	{
	case ARPHRD_ETHER:
	case ARPHRD_IEEE80211:
	  return TRUE;
	}
    }

  return FALSE;
}

/**
 * \brief (en)/(dis)able countermeasures on this interface.
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  enable countermeasures on.
 *
 * @param[in] endis  TRUE if we should enable countermeasures, FALSE if we
 *                   should disable countermeasures.
 *
 * \retval XENONE on success
 * \retval XEMALLOC on memory allocation failure
 **/
int cardif_countermeasures(context *ctx, char endis)
{
  if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
    return XEMALLOC;

  if (wireless == NULL) return XEMALLOC;

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

  return wireless->countermeasures(ctx, endis);
}

/**
 * \brief (en)/(dis)able receiving of unencrypted frames on this interface.
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  enable "drop unencrypted frames" on.
 *
 * @param[in] endis TRUE if we should enable "drop unencrypted frames" FALSE
 *                  if we should disable it.
 *
 * \retval XEMALLOC on memory allocation error.
 * \retval XENONE on success
 **/
int cardif_drop_unencrypted(context *ctx, char endis)
{
  wireless_ctx *wctx = NULL;

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

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

  wctx = (wireless_ctx *)ctx->intTypeData;

  if (wireless == NULL) return XEMALLOC;

  if (config_ssid_using_wep(wctx)) return XENONE;
  
  return wireless->drop_unencrypted(ctx, endis);
}

/**
 * \brief Attempt to determine if an interface is wireless.
 *
 * Check to see if an interface is wireless.  On linux, we look in
 * /proc/net/wireless to see if the interface is registered with the
 * wireless extensions.
 *
 * @param[in] ctx   The context that contains the interface that we want to
 *                  check to see if it is wireless.
 *
 * \retval -1 on error
 * \retval XENONE on success
 * \retval XEMALLOC on memory allocation error
 **/
#define PROC_WIRELESS_FILE  "/proc/net/wireless"

int cardif_int_is_wireless(context *ctx)
{
  FILE *fp;
  char line[1000], *lineptr=NULL;
  int done;

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

  done = FALSE;

  fp = fopen(PROC_WIRELESS_FILE, "r");
  if (fp == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't access /proc/net/wireless!  (You probably don't have wireless extensions enabled!)\n");
      return -1;
    }

  memset(line, 0x00, 1000);

  while ((!done) && (fgets(line, 999, fp) != NULL))
    { 
      lineptr = strchr(line, ':');
      
      if (lineptr != NULL)
	{
	  
	  *lineptr = '\0';
	  lineptr = &line[0];
	  
	  while (*lineptr == ' ') lineptr++;  // Strip out blanks.
	  if (lineptr != NULL)
	    {
	      if (strcmp(lineptr, ctx->intName) == 0) done=TRUE;
	    }
	}
    }
  fclose(fp);
  
  if ((lineptr != NULL) && (strcmp(lineptr, ctx->intName) == 0))
    {
      debug_printf(DEBUG_INT, "Interface %s is wireless!\n", ctx->intName);
      return TRUE;
    } else {
      debug_printf(DEBUG_INT, "Interface %s is NOT wireless!\n", ctx->intName);
      return FALSE;
    }

  return XENONE;   // No errors.
}

int is_wireless(char *intname)
{
  FILE *fp;
  char line[1000], *lineptr=NULL;
  int done;

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

  done = FALSE;

  fp = fopen(PROC_WIRELESS_FILE, "r");
  if (fp == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't access /proc/net/wireless!  (You probably don't have wireless extensions enabled!)\n");
      return -1;
    }

  memset(line, 0x00, 1000);

  while ((!done) && (fgets(line, 999, fp) != NULL))
    {
      lineptr = strchr(line, ':');

      if (lineptr != NULL)
        {

          *lineptr = '\0';
          lineptr = &line[0];

          while (*lineptr == ' ') lineptr++;  // Strip out blanks.
          if (lineptr != NULL)
            {
              if (strcmp(lineptr, intname) == 0) done=TRUE;
            }
        }
    }
  fclose(fp);

  if ((lineptr != NULL) && (strcmp(lineptr, intname) == 0))
    {
      debug_printf(DEBUG_INT, "Interface %s is wireless!\n", intname);
      return TRUE;
    } else {
      debug_printf(DEBUG_INT, "Interface %s is NOT wireless!\n", intname);
      return FALSE;
    }

  return XENONE;   // No errors.
}

/***********************************************
 * Get the MAC address of an interface
 ***********************************************/
static int _getmac(char *dest, char *ifname) 
{
  struct ifreq ifr;
  int sock = -1;
  int retval;

  debug_printf(DEBUG_INT, "Looking for MAC address for %s!\n", ifname);

  sock = socket(PF_PACKET, SOCK_RAW, 0);
  if (sock < 0)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't establish socket needed to query "
		   "interface %s for it's MAC address.\n", ifname);
      return FALSE;
    }

  memset(&ifr, 0x00, sizeof(ifr));

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

  ifr.ifr_ifindex = if_nametoindex(ifname);

  // Tell the ifreq struct which interface we want to use.
  Strncpy((char *)&ifr.ifr_name, sizeof(ifr.ifr_name), ifname,
          strlen(ifname)+1);
  printf("Interface : %s\n", ifr.ifr_name);

  // Get our MAC address.  (Needed for sending frames out correctly.)
  retval = ioctl(sock, SIOCGIFHWADDR, &ifr);
  if (retval < 0)
    {
      debug_printf(DEBUG_NORMAL, "Error getting hardware (MAC) address for interface %s!\n", ifname);
      debug_printf(DEBUG_NORMAL, "Error was (%d) : %s\n", errno, strerror(errno));

      close(sock);
      return FALSE;
    }

  // Store a copy of our source MAC for later use.
  memcpy(dest, (char *)&ifr.ifr_hwaddr.sa_data[0], 6);

  close(sock);
  return TRUE;
}


/**
 * \todo Finish the documentation here!
 **/
int cardif_get_wpa_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 (!xsup_assert((wireless != NULL), "wireless != NULL", FALSE))
    return XEMALLOC;

  if (wireless->get_wpa_ie == NULL)
    {
      debug_printf(DEBUG_NORMAL, "No function defined for wireless->get_wpa_ie()!\n");
      return XEMALLOC;
    }

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

⌨️ 快捷键说明

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