📄 cardif_linux_rtnetlink.c
字号:
break; case IFLA_ADDRESS: debug_printf(DEBUG_INT, "IFLA_ADDRESS event.\n"); break; case IFLA_BROADCAST: debug_printf(DEBUG_INT, "IFLA_BROADCAST event.\n"); break; case IFLA_IFNAME: // This is a non-wireless event. (Ignore it.) debug_printf(DEBUG_INT, "IFLA_IFNAME event.\n"); break; case IFLA_MTU: debug_printf(DEBUG_INT, "IFLA_MTU event.\n"); break; case IFLA_LINK: debug_printf(DEBUG_INT, "IFLA_LINK event.\n"); break; case IFLA_WIRELESS: // This is a wireless event. cardif_linux_rtnetlink_ifla_wireless(intdata, ifinfo->ifi_index, ((char *) rtattr)+rtalen, rtattr->rta_len - rtalen, ws); break; case IFLA_OPERSTATE: cardif_linux_rtnetlink_ifla_operstate(intdata, ifinfo->ifi_index, ((char *) rtattr)+rtalen, rtattr->rta_len - rtalen, ws); break; default: debug_printf(DEBUG_INT, "RTNetlink Event type %d\n", rtattr->rta_type); break; } rtlen = msg->nlmsg_len - nlmsg_len; // Get the next attribute rtattr = RTA_NEXT(rtattr, rtlen); }}/*********************************************************** * * Check the string that identifies the custom event that we got. And * act on it. * ***********************************************************/void cardif_linux_rtnetlink_check_custom(struct interface_data *intdata, char *str){ if (!xsup_assert((intdata != NULL), "intdata != NULL", FALSE)) return; if (!xsup_assert((str != NULL), "str != NULL", FALSE)) return; if (strncmp(str, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { intdata->statemachine->MICfailures++; debug_printf(DEBUG_NORMAL, "MIC failure #%d!\n", intdata->statemachine->MICfailures); if (strstr(str, " unicast ") != NULL) { // The attempted attack was probably against the unicast key. debug_printf(DEBUG_NORMAL, "MIC failure on unicast key!\n"); eapol_key_type254_request_new_key(intdata, 1); intdata->send_size = 0; } else { // The attempted attack was probably against the group key. debug_printf(DEBUG_NORMAL, "MIC failure on group key!\n"); eapol_key_type254_request_new_key(intdata, 0); intdata->send_size = 0; } if (intdata->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(intdata, TRUE); } }}/*********************************************************** * * Check to see if we have become disassociated before the rekey_prob_timer * (found in profile.h) reaches 0. If we have, it may indicate that we * have a card driver that resets the card on a key set. This should only be * a problem with WEP and older card drivers. * ***********************************************************/void cardif_linux_rtnetlink_check_key_prob(struct interface_data *idata){ struct config_globals *globals; if (!xsup_assert((idata != NULL), "idata != NULL", FALSE)) return; globals = config_get_globals(); if (!xsup_assert((globals != NULL), "globals != NULL", FALSE)) return; if (timer_check_existing(REKEY_PROB_TIMER)) { if (!TEST_FLAG(globals->flags, CONFIG_GLOBALS_NO_FRIENDLY_WARNINGS)) { debug_printf(DEBUG_NORMAL, "** WARNING! ** You were disassocated " "within a short time of setting a key!\nThis usually " "means there is a problem with the card driver.\n" "Please e-mail the developers for more information on " "what this means. Be sure to include the type of card, " "driver in use, and driver version number.\n"); } }}/*********************************************************** * * Process operstate events. * ***********************************************************/void cardif_linux_rtnetlink_ifla_operstate(struct interface_data *idata, int ifindex, char *data, int len, struct wireless_state *ws){ if (!xsup_assert((idata != NULL), "idata != NULL", FALSE)) return; if (!xsup_assert((data != NULL), "data != NULL", FALSE)) return; if (!xsup_assert((ws != NULL), "ws != NULL", FALSE)) return; debug_printf(DEBUG_INT, "Got a netlink OPERSTATE event!\n"); debug_printf(DEBUG_INT, "OPERSTATE event on interface %d\n", ifindex); debug_printf(DEBUG_INT, "Event dump (%d) : \n", len); debug_hex_dump(DEBUG_INT, data, len); switch(data[0]) { case IF_OPER_UNKNOWN: debug_printf(DEBUG_INT, "Interface is in unknown state.\n"); break; case IF_OPER_NOTPRESENT: debug_printf(DEBUG_INT, "Interface is not present.\n"); break; case IF_OPER_DOWN: debug_printf(DEBUG_INT, "Interface is down.\n"); break; case IF_OPER_LOWERLAYERDOWN: debug_printf(DEBUG_INT, "Interface lower layer is down.\n"); break; case IF_OPER_DORMANT: debug_printf(DEBUG_INT, "Interface is dormant.\n"); break; case IF_OPER_UP: debug_printf(DEBUG_INT, "Interface is up.\n"); break; default: debug_printf(DEBUG_INT, "Unknown interface state %d.\n", data[0]); break; }}/*********************************************************** * * Process wireless events. * ***********************************************************/void cardif_linux_rtnetlink_ifla_wireless(struct interface_data *idata, int ifindex, char *data, int len, struct wireless_state *ws){ struct iw_event iwe; struct config_network *network_data; struct config_globals *globals; struct stream_descr stream; int ret = 0; if (!xsup_assert((idata != NULL), "idata != NULL", FALSE)) return; if (!xsup_assert((data != NULL), "data != NULL", FALSE)) return; if (!xsup_assert((ws != NULL), "ws != NULL", FALSE)) return; network_data = config_get_network_config(); if (network_data == NULL) { // If we are in manual mode, and we just switched from an nonexistant // SSID to something else, we will get this "error". It should // generally be considered a warning. debug_printf(DEBUG_CONFIG, "<warning> Invalid network configuration " "structure! (%s:%d)\n", __FUNCTION__, __LINE__); } if ((data == NULL) || (len == 0)) { debug_printf(DEBUG_NORMAL, "No data available in event!\n"); return; } globals = config_get_globals(); if (!xsup_assert((globals != NULL), "globals != NULL", FALSE)) return; iw_init_event_stream(&stream, data, len); do {#ifdef NEW_IWLIB ret = iw_extract_event_stream(&stream, &iwe, cardif_linux_rtnetlink_get_we_ver(idata));#else ret = iw_extract_event_stream(&stream, &iwe);#endif if (ret <= 0) return; if ((ifindex != idata->intIndex) && (!(idata->flags & ONEDOWN))) { debug_printf(DEBUG_INT, "Got a wireless event! Interface index is %d, " "we are using index %d!\n", ifindex, idata->intIndex); debug_printf(DEBUG_INT, "Ignoring!\n"); return; } if (idata->flags & ONEDOWN) { if ((ifindex < (idata->intIndex - 1)) || (ifindex > (idata->intIndex))) { debug_printf(DEBUG_INT, "Got a wireless event! Interface index is " "%d, we are using indexes %d & %d!\n", ifindex, idata->intIndex-1, idata->intIndex); return; } } // Process the event. cardif_linux_rtnetlink_process_token(idata, &iwe, ws); } while (ret > 0);}/************************************************************************* * * Manually check and see if we have scan data to return. This is needed * for devices that don't return scan complete events. * *************************************************************************/uint8_t cardif_linux_rtnetlink_scancheck(struct interface_data *ctx){ if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE)) return 0; if (TEST_FLAG(ctx->flags, IS_WIRELESS)) { if (TEST_FLAG(ctx->flags, SCANNING)) { // It is okay to set a socket of -1 to rtnetlink_check_event. It // uses an internal variable to keep track of it's socket anyway. if (cardif_linux_rtnetlink_check_event(ctx, -1) != XDATA) { debug_printf(DEBUG_INT, "Waiting for SSID information...\n"); } else { // We got data, and canceled our timer, so let the caller know. return -1; } } } return 0;}/************************************************************************* * * Add an attribute to our packet that we are going to send to the kernel. * *************************************************************************/int cardif_linux_rtnetlink_add_attr(int type, struct nlmsghdr *nldr, int bufsize, uint8_t *data, int attrlen){ struct rtattr *rtattr; int len = 0; // Determine the total length of the message. len = RTA_LENGTH(attrlen); if (NLMSG_ALIGN(nldr->nlmsg_len)+len > bufsize) { debug_printf(DEBUG_NORMAL, "Not enough buffer space to create netlink " "request. Buffer size is %d, but required buffer size " "is %d.\n", bufsize, NLMSG_ALIGN(nldr->nlmsg_len)); return -1; } rtattr = (struct rtattr *)(((char *)nldr) + NLMSG_ALIGN(nldr->nlmsg_len)); rtattr->rta_type = type; rtattr->rta_len = len; memcpy(RTA_DATA(rtattr), data, attrlen); // Update our length to account for everything. nldr->nlmsg_len = NLMSG_ALIGN(nldr->nlmsg_len) + len; return 0;}/************************************************************************* * * On init, we need to tell the OS to put interfaces that are "UP" in to * dormant mode. See http://www.flamewarmaster.de/software/operstates.txt * for information on how this should all work. * *************************************************************************/void cardif_linux_rtnetlink_set_linkmode(struct interface_data *ctx, uint8_t newstate){ struct { struct nlmsghdr nlmsg; struct ifinfomsg ifi; uint8_t data[sizeof(struct rtattr)+1]; } state; static int seq; debug_printf(DEBUG_INT, "Setting Linkmode to %d.\n", newstate); memset(&state, 0x00, sizeof(state)); state.nlmsg.nlmsg_type = RTM_SETLINK; state.nlmsg.nlmsg_seq = ++seq; state.nlmsg.nlmsg_flags = NLM_F_REQUEST; state.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); state.ifi.ifi_family = AF_UNSPEC; state.ifi.ifi_index = ctx->intIndex; if (cardif_linux_rtnetlink_add_attr(IFLA_LINKMODE, &state.nlmsg, sizeof(state), &newstate, 1) != 0) { // Couldn't do anything. return; } // Otherwise, send the packet. send(rtnl_sock, (void *)&state, sizeof(state), 0);}/************************************************************************* * * Send an RTNETLINK message that indicates that the interface is now * fully up. This will allow things such as DHCP to happen. * * See http://www.flamewarmaster.de/software/operstates.txt for information * on how this should all work. * *************************************************************************/void cardif_linux_rtnetlink_set_operstate(struct interface_data *ctx, uint8_t newstate){ struct operstaterequest { struct nlmsghdr nlmsg; struct ifinfomsg ifi; uint8_t data[sizeof(struct rtattr)+1]; }; static uint32_t seq; struct operstaterequest opstate; memset(&opstate, 0x00, sizeof(opstate)); opstate.nlmsg.nlmsg_type = RTM_SETLINK; opstate.nlmsg.nlmsg_seq = ++seq; opstate.nlmsg.nlmsg_flags = NLM_F_REQUEST; opstate.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); opstate.ifi.ifi_family = AF_UNSPEC; opstate.ifi.ifi_index = ctx->intIndex; if (cardif_linux_rtnetlink_add_attr(IFLA_OPERSTATE, &opstate.nlmsg, sizeof(opstate), &newstate, 1) != 0) { // Couldn't do anything. return; } // Otherwise, send the packet. send(rtnl_sock, (void *)&opstate, sizeof(opstate), 0);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -