18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * win_if_list - Display network interfaces with description (for Windows)
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This small tool is for the Windows build to provide an easy way of fetching
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * a list of available network interfaces.
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <stdio.h>
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <winsock2.h>
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <ntddndis.h>
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "pcap.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <winsock.h>
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* from nuiouser.h */
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define FSCTL_NDISUIO_BASE      FILE_DEVICE_NETWORK
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define _NDISUIO_CTL_CODE(_Function, _Method, _Access) \
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	CTL_CODE(FSCTL_NDISUIO_BASE, _Function, _Method, _Access)
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IOCTL_NDISUIO_QUERY_BINDING \
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	_NDISUIO_CTL_CODE(0x203, METHOD_BUFFERED, \
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  FILE_READ_ACCESS | FILE_WRITE_ACCESS)
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IOCTL_NDISUIO_BIND_WAIT \
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	_NDISUIO_CTL_CODE(0x204, METHOD_BUFFERED, \
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  FILE_READ_ACCESS | FILE_WRITE_ACCESS)
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct _NDISUIO_QUERY_BINDING
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ULONG BindingIndex;
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ULONG DeviceNameOffset;
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ULONG DeviceNameLength;
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ULONG DeviceDescrOffset;
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ULONG DeviceDescrLength;
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDISUIO_QUERY_BINDING, *PNDISUIO_QUERY_BINDING;
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic HANDLE ndisuio_open(void)
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DWORD written;
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HANDLE h;
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	h = CreateFile(TEXT("\\\\.\\\\Ndisuio"),
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       GENERIC_READ | GENERIC_WRITE, 0, NULL,
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       INVALID_HANDLE_VALUE);
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (h == INVALID_HANDLE_VALUE)
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return h;
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!DeviceIoControl(h, IOCTL_NDISUIO_BIND_WAIT, NULL, 0, NULL, 0,
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     &written, NULL)) {
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		printf("IOCTL_NDISUIO_BIND_WAIT failed: %d",
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       (int) GetLastError());
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		CloseHandle(h);
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return INVALID_HANDLE_VALUE;
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return h;
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ndisuio_query_bindings(HANDLE ndisuio)
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	NDISUIO_QUERY_BINDING *b;
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t blen = sizeof(*b) + 1024;
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i, error;
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DWORD written;
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char name[256], desc[256];
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	WCHAR *pos;
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t j, len;
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	b = malloc(blen);
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (b == NULL)
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; ; i++) {
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		memset(b, 0, blen);
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		b->BindingIndex = i;
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_QUERY_BINDING,
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     b, sizeof(NDISUIO_QUERY_BINDING), b,
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     (DWORD) blen, &written, NULL)) {
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			error = (int) GetLastError();
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (error == ERROR_NO_MORE_ITEMS)
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			printf("IOCTL_NDISUIO_QUERY_BINDING failed: %d",
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       error);
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = (WCHAR *) ((char *) b + b->DeviceNameOffset);
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = b->DeviceNameLength;
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len >= sizeof(name))
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			len = sizeof(name) - 1;
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (j = 0; j < len; j++)
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			name[j] = (char) pos[j];
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		name[len] = '\0';
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = (WCHAR *) ((char *) b + b->DeviceDescrOffset);
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = b->DeviceDescrLength;
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len >= sizeof(desc))
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			len = sizeof(desc) - 1;
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (j = 0; j < len; j++)
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			desc[j] = (char) pos[j];
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		desc[len] = '\0';
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		printf("ifname: %s\ndescription: %s\n\n", name, desc);
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	free(b);
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ndisuio_enum_bindings(void)
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HANDLE ndisuio = ndisuio_open();
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ndisuio == INVALID_HANDLE_VALUE)
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ndisuio_query_bindings(ndisuio);
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	CloseHandle(ndisuio);
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void show_dev(pcap_if_t *dev)
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("ifname: %s\ndescription: %s\n\n",
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       dev->name, dev->description);
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void pcap_enum_devs(void)
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pcap_if_t *devs, *dev;
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char err[PCAP_ERRBUF_SIZE + 1];
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pcap_findalldevs(&devs, err) < 0) {
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		fprintf(stderr, "Error - pcap_findalldevs: %s\n", err);
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (dev = devs; dev; dev = dev->next) {
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		show_dev(dev);
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pcap_freealldevs(devs);
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint main(int argc, char *argv[])
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ndisuio_enum_bindings();
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pcap_enum_devs();
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
174