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