Example #1
0
File: win.c Project: hermixy/qtun
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;
}
Example #2
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);
}