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