size_t enum_devices(enum_device_t devices[MAX_DEVICE_COUNT]) { ULONG len = 0; IP_ADAPTER_INFO* adapters = NULL; IP_INTERFACE_INFO* interfaces = NULL; HANDLE handle = INVALID_HANDLE_VALUE; size_t idx = 0; if (GetAdaptersInfo(NULL, &len) == ERROR_NO_DATA) goto failed; adapters = malloc(sizeof(IP_ADAPTER_INFO) * len); if (adapters == NULL) goto failed; if (GetAdaptersInfo(adapters, &len) == ERROR_SUCCESS) { IP_ADAPTER_INFO* adp = adapters; while (adp) { if (adp->Type == MIB_IF_TYPE_ETHERNET) { if (strncmp(adp->Description, "QTun", sizeof("QTun") - 1) == 0) { devices[idx].index = adp->Index; strcpy(devices[idx].dev_path, "\\\\.\\"); strcat(devices[idx].dev_path, adp->AdapterName); strcat(devices[idx].dev_path, ".tun"); ++idx; } } adp = adp->Next; } } MprConfigServerConnect(NULL, &handle); len = 0; if (GetInterfaceInfo(NULL, &len) == ERROR_NO_DATA) goto failed; interfaces = malloc(sizeof(IP_INTERFACE_INFO) * len); if (interfaces == NULL) goto failed; if (GetInterfaceInfo(interfaces, &len) == ERROR_SUCCESS) { LONG i; size_t j; for (i = 0; i < interfaces->NumAdapters; ++i) { for (j = 0; j < idx; ++j) { if (devices[j].index == interfaces->Adapter[i].Index) { WCHAR w_name[128] = { 0 }; int name_len = 0; MprConfigGetFriendlyName(handle, interfaces->Adapter[i].Name, w_name, sizeof(w_name)); name_len = WideCharToMultiByte(CP_ACP, 0, w_name, -1, NULL, 0, NULL, FALSE); WideCharToMultiByte(CP_ACP, 0, w_name, -1, devices[j].dev_name, name_len, NULL, FALSE); break; } } } } if (adapters) free(adapters); if (interfaces) free(interfaces); return idx; failed: if (adapters) free(adapters); if (interfaces) free(interfaces); return 0; }
int rtm_ifannounce(LPWSTR ifname, DWORD ifindex, int what) { WCHAR fnameW[IFNAMSIZ]; struct if_announcemsghdr *ifa; int result; int retval; TRACE3(ENTER, "Entering rtm_ifannounce %S %d %d", ifname, ifindex, what); ifa = NULL; retval = -1; if ((what != IFAN_ARRIVAL) && (what != IFAN_DEPARTURE)) { goto out; } ifa = malloc(sizeof(*ifa)); if (ifa == NULL) { goto out; } ifa->ifan_name[0] = '\0'; /* * If this is a new interface, then look up the FriendlyName from * the unicode GUID name; convert Unicode to ASCII afterwards. * If the caller didn't supply this, the error is fatal to this function. * If we can't find it, the error is non-fatal to this function. * * XXX: The very fact that we don't provide the interface name here * is a limitation to do with how the notifications work in the * Microsoft stack. It only tells us the interface index when * the interface goes away. XORP currently depends on both for * interface deletion. We could look it up from the transport, * but it's more work to deliver redundant information. */ if (what == IFAN_ARRIVAL) { if (ifname == NULL) goto out; result = MprConfigGetFriendlyName(g_ce.hMprConfig, ifname, fnameW, sizeof(fnameW)); if (result != NO_ERROR) { TRACE1(NETWORK, "can't find friendlyname for ifname %S", ifname); } else { wcstombs(ifa->ifan_name, fnameW, IFNAMSIZ); } } /* * Fill our the rest of the interface announcement and send it to * all connected clients. */ ifa->ifan_msglen = sizeof(*ifa); ifa->ifan_version = RTM_VERSION; /* XXX should set to 0 or ignore */ ifa->ifan_type = RTM_IFANNOUNCE; ifa->ifan_index = ifindex; ifa->ifan_what = what; broadcast_pipe_message(ifa, sizeof(*ifa)); retval = 0; out: if (ifa != NULL) free(ifa); TRACE0(ENTER, "Leaving rtm_ifannounce"); return (retval); }