1 /* 2 * win_if_list - Display network interfaces with description (for Windows) 3 * Copyright (c) 2004-2006, Jouni Malinen <j (at) w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 * 8 * This small tool is for the Windows build to provide an easy way of fetching 9 * a list of available network interfaces. 10 */ 11 12 #include "includes.h" 13 #include <stdio.h> 14 #ifdef CONFIG_USE_NDISUIO 15 #include <winsock2.h> 16 #include <ntddndis.h> 17 #else /* CONFIG_USE_NDISUIO */ 18 #include "pcap.h" 19 #include <winsock.h> 20 #endif /* CONFIG_USE_NDISUIO */ 21 22 #ifdef CONFIG_USE_NDISUIO 23 24 /* from nuiouser.h */ 25 #define FSCTL_NDISUIO_BASE FILE_DEVICE_NETWORK 26 27 #define _NDISUIO_CTL_CODE(_Function, _Method, _Access) \ 28 CTL_CODE(FSCTL_NDISUIO_BASE, _Function, _Method, _Access) 29 30 #define IOCTL_NDISUIO_QUERY_BINDING \ 31 _NDISUIO_CTL_CODE(0x203, METHOD_BUFFERED, \ 32 FILE_READ_ACCESS | FILE_WRITE_ACCESS) 33 34 #define IOCTL_NDISUIO_BIND_WAIT \ 35 _NDISUIO_CTL_CODE(0x204, METHOD_BUFFERED, \ 36 FILE_READ_ACCESS | FILE_WRITE_ACCESS) 37 38 typedef struct _NDISUIO_QUERY_BINDING 39 { 40 ULONG BindingIndex; 41 ULONG DeviceNameOffset; 42 ULONG DeviceNameLength; 43 ULONG DeviceDescrOffset; 44 ULONG DeviceDescrLength; 45 } NDISUIO_QUERY_BINDING, *PNDISUIO_QUERY_BINDING; 46 47 48 static HANDLE ndisuio_open(void) 49 { 50 DWORD written; 51 HANDLE h; 52 53 h = CreateFile(TEXT("\\\\.\\\\Ndisuio"), 54 GENERIC_READ | GENERIC_WRITE, 0, NULL, 55 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 56 INVALID_HANDLE_VALUE); 57 if (h == INVALID_HANDLE_VALUE) 58 return h; 59 60 #ifndef _WIN32_WCE 61 if (!DeviceIoControl(h, IOCTL_NDISUIO_BIND_WAIT, NULL, 0, NULL, 0, 62 &written, NULL)) { 63 printf("IOCTL_NDISUIO_BIND_WAIT failed: %d", 64 (int) GetLastError()); 65 CloseHandle(h); 66 return INVALID_HANDLE_VALUE; 67 } 68 #endif /* _WIN32_WCE */ 69 70 return h; 71 } 72 73 74 static void ndisuio_query_bindings(HANDLE ndisuio) 75 { 76 NDISUIO_QUERY_BINDING *b; 77 size_t blen = sizeof(*b) + 1024; 78 int i, error; 79 DWORD written; 80 char name[256], desc[256]; 81 WCHAR *pos; 82 size_t j, len; 83 84 b = malloc(blen); 85 if (b == NULL) 86 return; 87 88 for (i = 0; ; i++) { 89 memset(b, 0, blen); 90 b->BindingIndex = i; 91 if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_QUERY_BINDING, 92 b, sizeof(NDISUIO_QUERY_BINDING), b, 93 (DWORD) blen, &written, NULL)) { 94 error = (int) GetLastError(); 95 if (error == ERROR_NO_MORE_ITEMS) 96 break; 97 printf("IOCTL_NDISUIO_QUERY_BINDING failed: %d", 98 error); 99 break; 100 } 101 102 pos = (WCHAR *) ((char *) b + b->DeviceNameOffset); 103 len = b->DeviceNameLength; 104 if (len >= sizeof(name)) 105 len = sizeof(name) - 1; 106 for (j = 0; j < len; j++) 107 name[j] = (char) pos[j]; 108 name[len] = '\0'; 109 110 pos = (WCHAR *) ((char *) b + b->DeviceDescrOffset); 111 len = b->DeviceDescrLength; 112 if (len >= sizeof(desc)) 113 len = sizeof(desc) - 1; 114 for (j = 0; j < len; j++) 115 desc[j] = (char) pos[j]; 116 desc[len] = '\0'; 117 118 printf("ifname: %s\ndescription: %s\n\n", name, desc); 119 } 120 121 free(b); 122 } 123 124 125 static void ndisuio_enum_bindings(void) 126 { 127 HANDLE ndisuio = ndisuio_open(); 128 if (ndisuio == INVALID_HANDLE_VALUE) 129 return; 130 131 ndisuio_query_bindings(ndisuio); 132 CloseHandle(ndisuio); 133 } 134 135 #else /* CONFIG_USE_NDISUIO */ 136 137 static void show_dev(pcap_if_t *dev) 138 { 139 printf("ifname: %s\ndescription: %s\n\n", 140 dev->name, dev->description); 141 } 142 143 144 static void pcap_enum_devs(void) 145 { 146 pcap_if_t *devs, *dev; 147 char err[PCAP_ERRBUF_SIZE + 1]; 148 149 if (pcap_findalldevs(&devs, err) < 0) { 150 fprintf(stderr, "Error - pcap_findalldevs: %s\n", err); 151 return; 152 } 153 154 for (dev = devs; dev; dev = dev->next) { 155 show_dev(dev); 156 } 157 158 pcap_freealldevs(devs); 159 } 160 161 #endif /* CONFIG_USE_NDISUIO */ 162 163 164 int main(int argc, char *argv[]) 165 { 166 #ifdef CONFIG_USE_NDISUIO 167 ndisuio_enum_bindings(); 168 #else /* CONFIG_USE_NDISUIO */ 169 pcap_enum_devs(); 170 #endif /* CONFIG_USE_NDISUIO */ 171 172 return 0; 173 } 174