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 + -
显示快捷键?