/* * win_if_list - Display network interfaces with description (for Windows) * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. * * This small tool is for the Windows build to provide an easy way of fetching * a list of available network interfaces. */ #include "includes.h" #include <stdio.h> #ifdef CONFIG_USE_NDISUIO #include <winsock2.h> #include <ntddndis.h> #else /* CONFIG_USE_NDISUIO */ #include "pcap.h" #include <winsock.h> #endif /* CONFIG_USE_NDISUIO */ #ifdef CONFIG_USE_NDISUIO /* from nuiouser.h */ #define FSCTL_NDISUIO_BASE FILE_DEVICE_NETWORK #define _NDISUIO_CTL_CODE(_Function, _Method, _Access) \ CTL_CODE(FSCTL_NDISUIO_BASE, _Function, _Method, _Access) #define IOCTL_NDISUIO_QUERY_BINDING \ _NDISUIO_CTL_CODE(0x203, METHOD_BUFFERED, \ FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_NDISUIO_BIND_WAIT \ _NDISUIO_CTL_CODE(0x204, METHOD_BUFFERED, \ FILE_READ_ACCESS | FILE_WRITE_ACCESS) typedef struct _NDISUIO_QUERY_BINDING { ULONG BindingIndex; ULONG DeviceNameOffset; ULONG DeviceNameLength; ULONG DeviceDescrOffset; ULONG DeviceDescrLength; } NDISUIO_QUERY_BINDING, *PNDISUIO_QUERY_BINDING; static HANDLE ndisuio_open(void) { DWORD written; HANDLE h; h = CreateFile(TEXT("\\\\.\\\\Ndisuio"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE); if (h == INVALID_HANDLE_VALUE) return h; #ifndef _WIN32_WCE if (!DeviceIoControl(h, IOCTL_NDISUIO_BIND_WAIT, NULL, 0, NULL, 0, &written, NULL)) { printf("IOCTL_NDISUIO_BIND_WAIT failed: %d", (int) GetLastError()); CloseHandle(h); return INVALID_HANDLE_VALUE; } #endif /* _WIN32_WCE */ return h; } static void ndisuio_query_bindings(HANDLE ndisuio) { NDISUIO_QUERY_BINDING *b; size_t blen = sizeof(*b) + 1024; int i, error; DWORD written; char name[256], desc[256]; WCHAR *pos; size_t j, len; b = malloc(blen); if (b == NULL) return; for (i = 0; ; i++) { memset(b, 0, blen); b->BindingIndex = i; if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_QUERY_BINDING, b, sizeof(NDISUIO_QUERY_BINDING), b, (DWORD) blen, &written, NULL)) { error = (int) GetLastError(); if (error == ERROR_NO_MORE_ITEMS) break; printf("IOCTL_NDISUIO_QUERY_BINDING failed: %d", error); break; } pos = (WCHAR *) ((char *) b + b->DeviceNameOffset); len = b->DeviceNameLength; if (len >= sizeof(name)) len = sizeof(name) - 1; for (j = 0; j < len; j++) name[j] = (char) pos[j]; name[len] = '\0'; pos = (WCHAR *) ((char *) b + b->DeviceDescrOffset); len = b->DeviceDescrLength; if (len >= sizeof(desc)) len = sizeof(desc) - 1; for (j = 0; j < len; j++) desc[j] = (char) pos[j]; desc[len] = '\0'; printf("ifname: %s\ndescription: %s\n\n", name, desc); } free(b); } static void ndisuio_enum_bindings(void) { HANDLE ndisuio = ndisuio_open(); if (ndisuio == INVALID_HANDLE_VALUE) return; ndisuio_query_bindings(ndisuio); CloseHandle(ndisuio); } #else /* CONFIG_USE_NDISUIO */ static void show_dev(pcap_if_t *dev) { printf("ifname: %s\ndescription: %s\n\n", dev->name, dev->description); } static void pcap_enum_devs(void) { pcap_if_t *devs, *dev; char err[PCAP_ERRBUF_SIZE + 1]; if (pcap_findalldevs(&devs, err) < 0) { fprintf(stderr, "Error - pcap_findalldevs: %s\n", err); return; } for (dev = devs; dev; dev = dev->next) { show_dev(dev); } pcap_freealldevs(devs); } #endif /* CONFIG_USE_NDISUIO */ int main(int argc, char *argv[]) { #ifdef CONFIG_USE_NDISUIO ndisuio_enum_bindings(); #else /* CONFIG_USE_NDISUIO */ pcap_enum_devs(); #endif /* CONFIG_USE_NDISUIO */ return 0; }