📄 cardif_linux_rtnetlink.c
字号:
return; } remain = recvfrom(rtnl_sock, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr *)&rtnl_data, &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. (New or deleted link?) switch (nlhead->nlmsg_type) { case RTM_NEWLINK: debug_printf(DEBUG_INT, "Got an RTM_NEWLINK!\n"); cardif_linux_rtnetlink_do_link(intdata, nlhead, nlhead->nlmsg_len, INT_NEW); break; case RTM_DELLINK: debug_printf(DEBUG_INT, "Got an RTM_DELLINK!\n"); cardif_linux_rtnetlink_do_link(intdata, nlhead, nlhead->nlmsg_len, INT_DEL); 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"); } }#ifdef EXPERIMENTAL // Do flags specific interface checks. while (idata != NULL) { if (idata->flags & SCANNING) { // 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. cardif_linux_rtnetlink_check_nets(idata); } idata = idata->next; } cardif_linux_rtnetlink_dump_ints(*intdata);#endif}/************************************************************ * * 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 ifinfomsg *ifinfo; int nlmsg_len, rtalen, rtlen; struct rtattr *rtattr; 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_IFNAME: // This is a non-wireless event. cardif_linux_rtnetlink_ifla_ifname(intdata, ifinfo->ifi_index, type); 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); break; } rtlen = msg->nlmsg_len - nlmsg_len; // Get the next attribute rtattr = RTA_NEXT(rtattr, rtlen); }}void cardif_linux_rtnetlink_dump_ints(struct interface_data *intdata){ struct interface_data *cur; cur = intdata; while (cur != NULL) { cur = cur->next; }}/*********************************************************** * * Check to see if the interface that was removed is one we are working * with. If it is, then take it out of the list. * ***********************************************************/void cardif_linux_rtnetlink_del_int(struct interface_data **intdata, int ifindex){ struct interface_data *cur, *prev; if (intdata == NULL) { debug_printf(DEBUG_NORMAL, "Corrupt interface structure!?\n"); return; } cur = *intdata; prev = cur; if (cur == NULL) { debug_printf(DEBUG_INT, "Interface list is empty!\n"); return; // We don't have any interfaces, so just return. } if (cur->intIndex == ifindex) { debug_printf(DEBUG_INT, "Interface : %s -- Index : %d\n", cur->intName, cur->intIndex); // Clean up the interface. cardif_deinit(cur); cur = destroy_interface_struct(cur); *intdata = cur; return; } if (cur->next == NULL) { debug_printf(DEBUG_INT, "Interface not found! Bailing out!\n"); return; } cur = cur->next; while (cur->next != NULL) { if (cur->intIndex == ifindex) { debug_printf(DEBUG_INT, "Found a match : %d == %d\n", cur->intIndex, ifindex); break; } cur = cur->next; prev = prev->next; } if (cur->intIndex != ifindex) { debug_printf(DEBUG_INT, "Last attempt at matching : %d == %d\n", cur->intIndex, ifindex); return; // Nothing to do. } debug_printf(DEBUG_INT, "Interface : %s -- Index : %d\n", cur->intName, cur->intIndex); // Clean up the interface. cardif_deinit(cur); cur = destroy_interface_struct(cur); prev->next = cur;}/*********************************************************** * * Check if the interface already exists. If it does, do nothing. If * it doesn't, then it is a new interface. Verify that it is an allowed * interface, and add it. * ***********************************************************/void cardif_linux_rtnetlink_add_int(struct interface_data **intdata, int ifindex){ struct interface_data *cur; char intname[16]; struct config_string_list *denyints = NULL; if (intdata == NULL) { debug_printf(DEBUG_NORMAL, "Corrupt interface structure!?\n"); return; } cur = *intdata; if (cur == NULL) { debug_printf(DEBUG_INT, "There are not interfaces currently in the list!\n"); if_indextoname(ifindex, (char *)&intname); debug_printf(DEBUG_INT, "Checking interface : %s\n", intname); denyints = config_denied_interfaces(); if (denyints != NULL) { if (config_int_in_list(intname, denyints) == TRUE) { debug_printf(DEBUG_INT, "Interface is not allowed! Ignoring!\n"); return; } else { debug_printf(DEBUG_INT, "Attempting to add interface!\n"); } } if (cardif_validate(intname) == TRUE) { // This interface is a real interface. cur = (struct interface_data *)malloc(sizeof(struct interface_data)); if (cur == NULL) { debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for new interface! (Interface : %s)\n", intname); return; } // Zero out the new interface structure. bzero(cur, sizeof(struct interface_data)); if (init_interface_struct(cur, (char *)&intname) != XENONE) { debug_printf(DEBUG_NORMAL, "Couldn't initialize the interface struct!\n"); // Free up the memory we allocated. free(cur); return; } cardif_init(cur); cur->flags = (cur->flags & (~IS_WIRELESS)); cur->userdata = config_build(cur->cur_essid); config_set_globals(cur); cur->next = NULL; *intdata = cur; } else { debug_printf(DEBUG_INT, "Not a valid interface. Ignoring.\n"); } } else { // Loop through all of the interfaces, to verify that we don't have // the interface. do { // If the interface already exists, then don't do anything. if (cur->intIndex == ifindex) { debug_printf(DEBUG_INT, "Found interface %s, with index of %d! (Ignored)\n", cur->intName, ifindex); return; } if (cur->next != NULL) cur = cur->next; } while (cur->next != NULL); if (cur->intIndex == ifindex) { debug_printf(DEBUG_INT, "This interface already exists!\n"); return; // We have this interface. } if_indextoname(ifindex, (char *)&intname); debug_printf(DEBUG_INT, "Checking interface : %s\n", intname); denyints = config_denied_interfaces(); if (denyints != NULL) { if (config_int_in_list(intname, denyints) == TRUE) { debug_printf(DEBUG_INT, "Interface is not allowed! Ignoring!\n"); return; } else { debug_printf(DEBUG_INT, "Attempting to add interface!\n"); } } if (cardif_validate(intname) == TRUE) { // This interface is a real interface. cur->next = (struct interface_data *)malloc(sizeof(struct interface_data)); if (cur == NULL) { debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for new interface! (Interface : %s)\n", intname); return; } cur = cur->next; // Zero out the new interface structure. bzero(cur, sizeof(struct interface_data)); if (init_interface_struct(cur, (char *)&intname) != XENONE) { debug_printf(DEBUG_NORMAL, "Couldn't initialize the interface struct!\n"); // Free up the memory we allocated. free(cur); return; } cardif_init(cur); cur->flags = (cur->flags & (~IS_WIRELESS)); cur->userdata = config_build(cur->cur_essid); config_set_globals(cur); cur->next = NULL; *intdata = cur; } else { debug_printf(DEBUG_INT, "Not a valid interface. Ignoring.\n"); } } cardif_linux_rtnetlink_dump_ints(*intdata);}/*********************************************************** * * Process an event that isn't wireless. (It may be a wired card, or * it may be something like a card insertion/removal.) * ***********************************************************/void cardif_linux_rtnetlink_ifla_ifname(struct interface_data **intdata, int ifindex, int isdelete){ debug_printf(DEBUG_INT, "Working with an interface with index of %d.\n", ifindex); switch (isdelete) { case INT_NEW: debug_printf(DEBUG_INT, " -- Got a new interface request.\n"); cardif_linux_rtnetlink_add_int(intdata, ifindex); break; case INT_DEL: debug_printf(DEBUG_INT, " -- Got a deleted interface request.\n"); cardif_linux_rtnetlink_del_int(intdata, ifindex); break; }}/*********************************************************** * * Process wireless events. * ***********************************************************/void cardif_linux_rtnetlink_ifla_wireless(struct interface_data **intdata, int ifindex, char *data, int len){ struct iw_event *iwe; struct interface_data *idata; char *pos, *end; idata = (struct interface_data *)*intdata; pos = data; end = data+len; while (pos + IW_EV_LCP_LEN <= end) { iwe = (struct iw_event *) pos; debug_printf(DEBUG_INT, "Wireless event: cmd=0x%x len=%d\n", iwe->cmd, iwe->len); if (iwe->len <= IW_EV_LCP_LEN) { debug_printf(DEBUG_NORMAL, "Not enough data in wireless event!\n"); return; } switch (iwe->cmd) { case SIOCGIWAP: // We don't do anything with this event yet. debug_printf(DEBUG_INT, "New AP found!\n"); break; case SIOCGIWSCAN: // We have been told that the scan is complete. debug_printf(DEBUG_INT, "Wireless scan complete!\n"); cardif_linux_rtnetlink_check_nets(idata); break; } pos += iwe->len; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -