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 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 
     44 typedef 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 
     54 static 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 
     80 static 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 
    131 static 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 
    143 static void show_dev(pcap_if_t *dev)
    144 {
    145 	printf("ifname: %s\ndescription: %s\n\n",
    146 	       dev->name, dev->description);
    147 }
    148 
    149 
    150 static 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 
    170 int 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