📄 cardif_linux_rtnetlink.c
字号:
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 + -