win_if_list.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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 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. #include "includes.h"
  12. #include <stdio.h>
  13. #ifdef CONFIG_USE_NDISUIO
  14. #include <winsock2.h>
  15. #include <ntddndis.h>
  16. #else /* CONFIG_USE_NDISUIO */
  17. #include "pcap.h"
  18. #include <winsock.h>
  19. #endif /* CONFIG_USE_NDISUIO */
  20. #ifdef CONFIG_USE_NDISUIO
  21. /* from nuiouser.h */
  22. #define FSCTL_NDISUIO_BASE FILE_DEVICE_NETWORK
  23. #define _NDISUIO_CTL_CODE(_Function, _Method, _Access) \
  24. CTL_CODE(FSCTL_NDISUIO_BASE, _Function, _Method, _Access)
  25. #define IOCTL_NDISUIO_QUERY_BINDING \
  26. _NDISUIO_CTL_CODE(0x203, METHOD_BUFFERED, \
  27. FILE_READ_ACCESS | FILE_WRITE_ACCESS)
  28. #define IOCTL_NDISUIO_BIND_WAIT \
  29. _NDISUIO_CTL_CODE(0x204, METHOD_BUFFERED, \
  30. FILE_READ_ACCESS | FILE_WRITE_ACCESS)
  31. typedef struct _NDISUIO_QUERY_BINDING
  32. {
  33. ULONG BindingIndex;
  34. ULONG DeviceNameOffset;
  35. ULONG DeviceNameLength;
  36. ULONG DeviceDescrOffset;
  37. ULONG DeviceDescrLength;
  38. } NDISUIO_QUERY_BINDING, *PNDISUIO_QUERY_BINDING;
  39. static HANDLE ndisuio_open(void)
  40. {
  41. DWORD written;
  42. HANDLE h;
  43. h = CreateFile(TEXT("\\\\.\\\\Ndisuio"),
  44. GENERIC_READ | GENERIC_WRITE, 0, NULL,
  45. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  46. INVALID_HANDLE_VALUE);
  47. if (h == INVALID_HANDLE_VALUE)
  48. return h;
  49. #ifndef _WIN32_WCE
  50. if (!DeviceIoControl(h, IOCTL_NDISUIO_BIND_WAIT, NULL, 0, NULL, 0,
  51. &written, NULL)) {
  52. printf("IOCTL_NDISUIO_BIND_WAIT failed: %d",
  53. (int) GetLastError());
  54. CloseHandle(h);
  55. return INVALID_HANDLE_VALUE;
  56. }
  57. #endif /* _WIN32_WCE */
  58. return h;
  59. }
  60. static void ndisuio_query_bindings(HANDLE ndisuio)
  61. {
  62. NDISUIO_QUERY_BINDING *b;
  63. size_t blen = sizeof(*b) + 1024;
  64. int i, error;
  65. DWORD written;
  66. char name[256], desc[256];
  67. WCHAR *pos;
  68. size_t j, len;
  69. b = malloc(blen);
  70. if (b == NULL)
  71. return;
  72. for (i = 0; ; i++) {
  73. memset(b, 0, blen);
  74. b->BindingIndex = i;
  75. if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_QUERY_BINDING,
  76. b, sizeof(NDISUIO_QUERY_BINDING), b,
  77. (DWORD) blen, &written, NULL)) {
  78. error = (int) GetLastError();
  79. if (error == ERROR_NO_MORE_ITEMS)
  80. break;
  81. printf("IOCTL_NDISUIO_QUERY_BINDING failed: %d",
  82. error);
  83. break;
  84. }
  85. pos = (WCHAR *) ((char *) b + b->DeviceNameOffset);
  86. len = b->DeviceNameLength;
  87. if (len >= sizeof(name))
  88. len = sizeof(name) - 1;
  89. for (j = 0; j < len; j++)
  90. name[j] = (char) pos[j];
  91. name[len] = '\0';
  92. pos = (WCHAR *) ((char *) b + b->DeviceDescrOffset);
  93. len = b->DeviceDescrLength;
  94. if (len >= sizeof(desc))
  95. len = sizeof(desc) - 1;
  96. for (j = 0; j < len; j++)
  97. desc[j] = (char) pos[j];
  98. desc[len] = '\0';
  99. printf("ifname: %s\ndescription: %s\n\n", name, desc);
  100. }
  101. free(b);
  102. }
  103. static void ndisuio_enum_bindings(void)
  104. {
  105. HANDLE ndisuio = ndisuio_open();
  106. if (ndisuio == INVALID_HANDLE_VALUE)
  107. return;
  108. ndisuio_query_bindings(ndisuio);
  109. CloseHandle(ndisuio);
  110. }
  111. #else /* CONFIG_USE_NDISUIO */
  112. static void show_dev(pcap_if_t *dev)
  113. {
  114. printf("ifname: %s\ndescription: %s\n\n",
  115. dev->name, dev->description);
  116. }
  117. static void pcap_enum_devs(void)
  118. {
  119. pcap_if_t *devs, *dev;
  120. char err[PCAP_ERRBUF_SIZE + 1];
  121. if (pcap_findalldevs(&devs, err) < 0) {
  122. fprintf(stderr, "Error - pcap_findalldevs: %s\n", err);
  123. return;
  124. }
  125. for (dev = devs; dev; dev = dev->next) {
  126. show_dev(dev);
  127. }
  128. pcap_freealldevs(devs);
  129. }
  130. #endif /* CONFIG_USE_NDISUIO */
  131. int main(int argc, char *argv[])
  132. {
  133. #ifdef CONFIG_USE_NDISUIO
  134. ndisuio_enum_bindings();
  135. #else /* CONFIG_USE_NDISUIO */
  136. pcap_enum_devs();
  137. #endif /* CONFIG_USE_NDISUIO */
  138. return 0;
  139. }