Home | History | Annotate | Download | only in wpa_supplicant
      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