📄 cardif_linux_rtnetlink.c
字号:
strncpy(custom, iwe->u.data.pointer, iwe->u.data.length); bzero(temp, 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(struct interface_data *ctx, struct wireless_state *state){ if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return; if (!state) { 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(struct interface_data *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(struct interface_data *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(struct interface_data *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(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(COUNTERMEASURE_TIMER, MIC_COUNTERMEASURE_TIMEOUT); } else { debug_printf(DEBUG_NORMAL, "Enabling MIC countermeasures!\n"); timer_add_timer(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(struct interface_data *ctx, struct iw_event *iwe, struct wireless_state *state){ if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return; if (!xsup_assert((iwe != NULL), "iwe != NULL", FALSE)) return; // *state is allowed to be NULL, so don't check it. switch (iwe->cmd) { case SIOCGIWAP: cardif_linux_rtnetlink_process_SIOCGIWAP(ctx, iwe, state); break; case SIOCGIWFREQ: // Don't care. break; case SIOCGIWMODE: // Don't care. break; case SIOCGIWESSID: cardif_linux_rtnetlink_process_SIOCGIWESSID(ctx, iwe, state); break; case SIOCSIWESSID: cardif_linux_rtnetlink_process_SIOCSIWESSID(ctx, iwe, state); break; case SIOCGIWNAME: // Don't care. break; case SIOCGIWSCAN: cardif_linux_rtnetlink_process_SIOCGIWSCAN(ctx, state); 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: if (!state) { 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 (!state) { if (!(iwe->u.data.flags & IW_ENCODE_DISABLED)) { config_ssid_update_abilities(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(iwe->u.qual.qual, (iwe->u.qual.level - 0x100), (iwe->u.qual.noise - 0x100)); break; case IWEVCUSTOM: cardif_linux_rtnetlink_process_IWEVCUSTOM(ctx, iwe, state); 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(struct interface_data *idata, int sock){ int rtnl_data_size, remain, length; char buf[8192]; struct nlmsghdr *nlhead; struct wireless_state *ws = NULL; if (!xsup_assert((idata != NULL), "idata != NULL", FALSE)) return XEMALLOC; ws = get_wireless_sm(); if (!xsup_assert((ws != NULL), "ws != 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; // There may be more than one message in the packet. So, loop through! while (remain >= sizeof(struct nlmsghdr)) { // Make sure we have enough data for a real message. if ((nlhead->nlmsg_len > remain) || ((nlhead->nlmsg_len - sizeof(struct nlmsghdr)) < 0)) { debug_printf(DEBUG_NORMAL, "Invalid netlink message!\n"); break; } // See what kind of message it is. switch (nlhead->nlmsg_type) { case RTM_NEWLINK: debug_printf(DEBUG_INT, "Got an RTM_NEWLINK!\n"); cardif_linux_rtnetlink_do_link(idata, nlhead, nlhead->nlmsg_len, INT_NEW, ws); break; case RTM_DELLINK: debug_printf(DEBUG_INT, "Got an RTM_DELLINK!\n"); cardif_linux_rtnetlink_do_link(idata, nlhead, nlhead->nlmsg_len, INT_DEL, ws); break; } // Find the aligned length of the message, so we can skip // to the next message. length = NLMSG_ALIGN(nlhead->nlmsg_len); remain -= length; nlhead = (struct nlmsghdr *) ((char *)nlhead + length); } // If we have anything left, then there may be a problem. So, report // the we may have a problem. if (remain > 0) { debug_printf(DEBUG_NORMAL, "Extra bytes at the end of the netlink message.\n"); } } // There may be situations where the wireless card driver can scan, // but doesn't provide an event when the scan has completed. So, // we need to check if we have data, even if we don't have an event. return cardif_linux_rtnetlink_check_nets(idata);}/************************************************************ * * We got an RTM_NEWLINK or RTM_DELLINK message, so process it, and * decide how to proceed. * ************************************************************/void cardif_linux_rtnetlink_do_link(struct interface_data *intdata, struct nlmsghdr *msg, int len, int type, struct wireless_state *ws){ struct ifinfomsg *ifinfo; int nlmsg_len, rtalen, rtlen; struct rtattr *rtattr; if (!xsup_assert((intdata != NULL), "intdata != NULL", FALSE)) return; if (!xsup_assert((msg != NULL), "msg != NULL", FALSE)) return; if (!xsup_assert((ws != NULL), "ws != NULL", FALSE)) return; if (len < sizeof(struct ifinfomsg)) { debug_printf(DEBUG_NORMAL, "Netlink message too short!\n"); return; } // Get the actual message from the block. ifinfo = NLMSG_DATA(msg); // Find out how big the message is. nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); if ((msg->nlmsg_len - nlmsg_len) < 0) { debug_printf(DEBUG_NORMAL, "Message inside newlink isn't valid!\n"); return; } rtattr = (struct rtattr *)(((char *)ifinfo) + nlmsg_len); rtalen = RTA_ALIGN(sizeof(struct rtattr)); // Validate the attribute we have, and determine if it is for wireless, // or wired. while (RTA_OK(rtattr, (msg->nlmsg_len - nlmsg_len))) { switch (rtattr->rta_type) { case IFLA_UNSPEC: debug_printf(DEBUG_INT, "IFLA_UNSPEC event.\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -