Watt-32 tcp/ip  2.2 dev-rel.10
winadinf.c
Go to the documentation of this file.
1 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <assert.h>
41 
42 //#define OLE2ANSI /* Use ASCII from Ole32.dll functions */
43 
48 #if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
49 
50 #include "winadinf.h"
51 #include "wattcp.h"
52 #include "strings.h"
53 #include "pcdbug.h"
54 #include "packet32.h"
55 #include "misc.h"
56 #include "run.h"
57 #include "win_dll.h"
58 
59 #if defined(COMPILE_WINADINF_C) /* Rest of file. Only for MSVC, OpenWatcom and MinGW/MinGW-w64. */
60 
61 /* If on Windows NT 3.5 or on early Windows 95 betas, this is defined
62  */
63 #ifdef WINNT35COMPATIBLE
64 #error "Win-NT 3.5 compatible!!??"
65 #endif
66 
67 #define NA_STR "<N/A>"
68 #define NONE_STR "<None>"
69 #define NONE_STR_W L"<None>"
70 
71 typedef int (WINAPI *func_WSAStartup) (
72  __in WORD version,
73  __inout LPWSADATA data);
74 
75 typedef int (WINAPI *func_WSACleanup) (void);
76 
77 typedef int (WINAPI *func_WSAGetLastError) (void);
78 
79 typedef INT (WINAPI *func_WSAAddressToStringA) (
80  __in LPSOCKADDR lpsaAddress,
81  __in DWORD dwAddressLength,
82  __in_opt LPWSAPROTOCOL_INFO lpProtocolInfo,
83  __inout LPSTR lpszAddressString,
84  __inout DWORD *lpdwAddressStringLength);
85 
86 typedef ULONG (WINAPI *func_GetAdaptersAddresses) (
87  __in ULONG Family,
88  __in ULONG Flags,
89  __in VOID *Reserved,
90  __out IP_ADAPTER_ADDRESSES *AdapterAddresses,
91  __inout PULONG outBufLen);
92 
93 typedef DWORD (WINAPI *func_GetIfTable) (
94  __out PMIB_IFTABLE pIfTable,
95  __inout PULONG pdwSize,
96  __in BOOL bOrder);
97 
98 typedef DWORD (WINAPI *func_GetIfTable2) (
99  __out PMIB_IF_TABLE2 *table);
100 
101 typedef DWORD (WINAPI *func_GetIfTable2Ex) (
102  __in MIB_IF_TABLE_LEVEL level,
103  __out PMIB_IF_TABLE2 *table);
104 
105 typedef DWORD (WINAPI *func_GetIpNetTable) (
106  __out MIB_IPNETTABLE *table,
107  __inout ULONG *size,
108  __in BOOL sort);
109 
110 typedef DWORD (WINAPI *func_GetIfEntry) (__inout PMIB_IFROW pIfRow);
111 
112 typedef DWORD (WINAPI *func_RasEnumConnectionsA) (
113  __inout RASCONN *lprasconn,
114  __inout DWORD *lpcb,
115  __out DWORD *lpcConnections);
116 
117 typedef DWORD (WINAPI *func_RasGetConnectionStatistics) (
118  __in HRASCONN hRasConn,
119  __inout RAS_STATS *lpStatistics);
120 
121 typedef DWORD (WINAPI *func_RasGetErrorStringA) (
122  __in UINT uErrorValue,
123  __out LPSTR lpszErrorString,
124  __in DWORD cBufSize);
125 
126 typedef DWORD (WINAPI *func_RasGetProjectionInfoA) (
127  __in HRASCONN hrasconn,
128  __in RASPROJECTION rasprojection,
129  __out VOID *lpprojection,
130  __inout DWORD *lpcb);
131 
132 typedef DWORD (WINAPI *func_WlanOpenHandle) (
133  __in DWORD dwClientVersion,
134  __reserved VOID *pReserved,
135  __out DWORD *pdwNegotiatedVersion,
136  __out HANDLE *phClientHandle);
137 
138 typedef DWORD (WINAPI *func_WlanCloseHandle) (
139  __in HANDLE dwClientHandle,
140  __reserved VOID *pReserved);
141 
142 typedef DWORD (WINAPI *func_WlanEnumInterfaces) (
143  __in HANDLE hClientHandle,
144  __reserved VOID *pReserved,
145  __deref_out WLAN_INTERFACE_INFO_LIST **ppInterfaceList);
146 
147 typedef DWORD (WINAPI *func_WlanQueryInterface) (
148  __in HANDLE hClientHandle,
149  __in const GUID *pInterfaceGuid,
150  __in WLAN_INTF_OPCODE OpCode,
151  __reserved VOID *pReserved,
152  __out DWORD *pdwDataSize,
153  __out VOID **ppData,
154  __out_opt WLAN_OPCODE_VALUE_TYPE *pWlanOpcodeValueType);
155 
156 typedef DWORD (WINAPI *func_WlanGetAvailableNetworkList) (
157  __in HANDLE hClientHandle,
158  __in const GUID *pInterfaceGuid,
159  __in DWORD dwFlags,
160  __reserved VOID *pReserved,
161  __out WLAN_AVAILABLE_NETWORK_LIST **AvailableNetworks);
162 
163 typedef DWORD (WINAPI *func_WlanReasonCodeToString) (
164  __in DWORD dwReasonCode,
165  __in DWORD dwBufferSize,
166  __in WCHAR *pStringBuffer,
167  __reserved VOID *pReserved);
168 
169 typedef DWORD (WINAPI *func_WlanGetInterfaceCapability) (
170  __in HANDLE hClientHandle,
171  __in const GUID *pInterfaceGuid,
172  __reserved VOID *pReserved,
173  __out WLAN_INTERFACE_CAPABILITY **ppCapability
174 );
175 
176 typedef VOID (WINAPI *func_WlanFreeMemory) (
177  __in VOID *memory);
178 
179 typedef int (WINAPI *func_StringFromGUID2) (
180  __in REFGUID rguid,
181  __out LPOLESTR lpsz,
182  __in int cchMax);
183 
184 struct one_addr {
185  char addr [MAX_IP6_SZ];
186  int family; /* AF_INET or AF_INET6 */
187  };
188 
189 typedef char address_buf [MAX_IP6_SZ+1];
190 
191 static func_WSAStartup p_WSAStartup = NULL;
192 static func_WSACleanup p_WSACleanup = NULL;
193 static func_WSAAddressToStringA p_WSAAddressToStringA = NULL;
194 static func_WSAGetLastError p_WSAGetLastError = NULL;
195 static func_GetAdaptersAddresses p_GetAdaptersAddresses = NULL;
196 static func_GetIfTable p_GetIfTable = NULL;
197 static func_GetIfTable2 p_GetIfTable2 = NULL;
198 static func_GetIfTable2Ex p_GetIfTable2Ex = NULL;
199 static func_GetIpNetTable p_GetIpNetTable = NULL;
200 static func_RasEnumConnectionsA p_RasEnumConnectionsA = NULL;
201 static func_RasGetErrorStringA p_RasGetErrorStringA = NULL;
202 static func_RasGetConnectionStatistics p_RasGetConnectionStatistics = NULL;
203 static func_RasGetProjectionInfoA p_RasGetProjectionInfoA = NULL;
204 static func_WlanOpenHandle p_WlanOpenHandle = NULL;
205 static func_WlanCloseHandle p_WlanCloseHandle = NULL;
206 static func_WlanEnumInterfaces p_WlanEnumInterfaces = NULL;
207 static func_WlanQueryInterface p_WlanQueryInterface = NULL;
208 static func_WlanGetAvailableNetworkList p_WlanGetAvailableNetworkList = NULL;
209 static func_WlanFreeMemory p_WlanFreeMemory = NULL;
210 static func_WlanReasonCodeToString p_WlanReasonCodeToString = NULL;
211 static func_StringFromGUID2 p_StringFromGUID2 = NULL;
212 
213 #define ADD_VALUE(dll, func) { NULL, _T(dll), #func, (void**)&p_##func }
214 
215 static struct LoadTable dyn_funcs2[] = {
216  ADD_VALUE ("ws2_32.dll", WSAStartup),
217  ADD_VALUE ("ws2_32.dll", WSACleanup),
218  ADD_VALUE ("ws2_32.dll", WSAAddressToStringA),
219  ADD_VALUE ("ws2_32.dll", WSAGetLastError),
220  ADD_VALUE ("Ole32.dll", StringFromGUID2),
221  ADD_VALUE ("IPhlpApi.dll", GetAdaptersAddresses),
222  ADD_VALUE ("IPhlpApi.dll", GetIfTable),
223  ADD_VALUE ("IPhlpApi.dll", GetIfTable2),
224  ADD_VALUE ("IPhlpApi.dll", GetIfTable2Ex),
225  ADD_VALUE ("IPhlpApi.dll", GetIpNetTable),
226  ADD_VALUE ("RasApi32.dll", RasEnumConnectionsA),
227  ADD_VALUE ("RasApi32.dll", RasGetConnectionStatistics),
228  ADD_VALUE ("RasApi32.dll", RasGetErrorStringA),
229  ADD_VALUE ("RasApi32.dll", RasGetProjectionInfoA),
230  ADD_VALUE ("WlanApi.dll" , WlanOpenHandle),
231  ADD_VALUE ("WlanApi.dll" , WlanCloseHandle),
232  ADD_VALUE ("WlanApi.dll" , WlanEnumInterfaces),
233  ADD_VALUE ("WlanApi.dll" , WlanFreeMemory),
234  ADD_VALUE ("WlanApi.dll" , WlanGetAvailableNetworkList),
235  ADD_VALUE ("WlanApi.dll" , WlanQueryInterface),
236  ADD_VALUE ("WlanApi.dll" , WlanReasonCodeToString)
237  };
238 
239 static void unload_dlls (void)
240 {
241  if (p_WSACleanup)
242  (*p_WSACleanup)();
243  unload_dynamic_table (dyn_funcs2, DIM(dyn_funcs2));
244 }
245 
246 /*
247  * Main initializer for WinAdapterInfo; load DLLs, set func-ptrs and
248  * call the real WSAStartup().
249  */
250 static int load_dlls (void)
251 {
252  static int rc, done = 0;
253  WORD ver = MAKEWORD (2,2);
254  WSADATA data = { 0 };
255 
256  if (done)
257  return (rc);
258 
259  rc = load_dynamic_table (dyn_funcs2, DIM(dyn_funcs2));
260  if (rc)
261  {
262  int err = (*p_WSAStartup) (ver, &data); /* Required for WSAAddressToStringA() etc. */
263  TCP_CONSOLE_MSG (4, ("WSAStartup() -> err: %s\n"
264  " ver: %u.%u, high-ver: %u.%u, "
265  "description: \"%s\", status: \"%s\"\n",
266  err ? win_strerror ((*p_WSAGetLastError)()) : NONE_STR,
267  loBYTE(data.wVersion), hiBYTE(data.wVersion),
268  loBYTE(data.wHighVersion), hiBYTE(data.wHighVersion),
269  data.szDescription, data.szSystemStatus));
270  rc = (err == 0);
271  }
272 
273  TCP_CONSOLE_MSG (4, ("load_dlls(): %s.\n", rc ? "okay" : "failed"));
274  RUNDOWN_ADD (unload_dlls, 300);
275  done = 1;
276  return (rc);
277 }
278 
283 static const char *_list_lookup (DWORD type, const struct search_list *list, int num)
284 {
285  static char buf[15];
286 
287  while (num > 0 && list->name)
288  {
289  if (list->type == type)
290  return (list->name);
291  num--;
292  list++;
293  }
294  sprintf (buf, "?%lu", type);
295  return (buf);
296 }
297 
298 #if defined(NOT_USED)
299 static const struct search_list wsock_err_tab[] = {
300  { 10004, "Call interrupted" }, /* WSAEINTR */
301  };
302 
303 static const char *get_wsock_err (void)
304 {
305  static char buf[100];
306  DWORD err;
307 
308  if (!p_WSAGetLastError)
309  return ("WS2_32.DLL not loaded");
310  err = (*p_WSAGetLastError)();
311 
312  SNPRINTF (buf, sizeof(buf), "%s", err ?
313  _list_lookup(err, wsock_err_tab, DIM(wsock_err_tab)) : NONE_STR);
314  return (buf);
315 }
316 #endif
317 
318 /*
319  * Terminate a string 'buf' if 'ch' is found at the end.
320  */
321 static char *strip_end (char *buf, char ch)
322 {
323  char *p = buf + strlen(buf) - 1;
324  if (*p == ch)
325  *p = '\0';
326  return (buf);
327 }
328 
329 /*
330  * Replace a "," with "\n\t\t\t " and print to stdout.
331  */
332 static void check_indent_and_print (const char *buf)
333 {
334 #if 1
335  fputs (buf, stdout);
336 #else
337  const char *p = buf;
338 
339  while (p && *p)
340  {
341  if (*p == ',')
342  (*_printf) ("\n\t\t\t ");
343  else putchar (*p);
344  p++;
345  }
346 #endif
347 }
348 
349 
355 static const char *dword_string (DWORD val)
356 {
357  static char buf[8][20];
358  static int idx = 0;
359  char tmp[20];
360  char *rc = buf [idx++];
361 
362  if (val < 1000UL)
363  {
364  sprintf (rc, "%lu", val);
365  }
366  else if (val < 1000000UL) /* 1E6 */
367  {
368  sprintf (rc, "%lu.%03lu", val/1000UL, val % 1000UL);
369  }
370  else if (val < 1000000000UL) /* 1E9 */
371  {
372  sprintf (tmp, "%9lu", val);
373  sprintf (rc, "%.3s.%.3s.%.3s", tmp, tmp+3, tmp+6);
374  }
375  else /* >= 1E9 */
376  {
377  sprintf (tmp, "%12lu", val);
378  sprintf (rc, "%.3s.%.3s.%.3s.%.3s", tmp, tmp+3, tmp+6, tmp+9);
379  }
380  idx &= 7;
381  return strltrim (rc);
382 }
383 
387 static const char *speed_string (DWORD val)
388 {
389  static char buf[30];
390  char denom = '\0';
391  double fl_val = (double) (val+1);
392 
393  if (fl_val >= 1E9)
394  {
395  denom = 'G';
396  fl_val /= 1E9;
397  }
398  else if (fl_val >= 1E6)
399  {
400  denom = 'M';
401  fl_val /= 1E6;
402  }
403  else if (fl_val >= 1E3)
404  {
405  denom = 'k';
406  fl_val /= 1E3;
407  }
408  sprintf (buf, "%.0f %cB/s", fl_val, denom);
409  return (buf);
410 }
411 
412 #if defined(ON_WIN_VISTA)
413 
416 static const char *speed64_string (ULONG64 val)
417 {
418  static char buf[30];
419  char denom = '\0';
420  double fl_val = (double) (val+1);
421 
422  if (fl_val <= 1E9)
423  return speed_string ((DWORD)val);
424 
425  if (fl_val >= 1E12)
426  {
427  denom = 'T';
428  fl_val /= 1E12;
429  }
430  else if (fl_val >= 1E9)
431  {
432  denom = 'G';
433  fl_val /= 1E9;
434  }
435  sprintf (buf, "%.0f %cB/s", fl_val, denom);
436  return (buf);
437 }
438 #endif
439 
440 /*
441  * Return string "<days> HH:MM:SS.MS" for a time in milli-seconds.
442  */
443 static const char *duration_string (DWORD msec)
444 {
445  static char buf[60];
446  DWORD sec = msec / 1000;
447  WORD hours = (WORD) (sec / 3600UL);
448  WORD mins = (WORD) (sec / 60) - (60 * hours);
449  WORD days = 0;
450  char *p = buf;
451 
452  while (hours >= 24)
453  {
454  hours -= 24;
455  days++;
456  }
457  if (days > 1)
458  p += sprintf (p, "%ud ", days);
459 
460  sprintf (p, "%02u:%02u:%02u.%ld", hours, mins, (UINT)(sec % 60UL), msec % sec);
461  return (buf);
462 }
463 
464 static const struct search_list if_types[] = {
465  { IF_TYPE_OTHER, "Other type" },
466  { IF_TYPE_ETHERNET_CSMACD, "Ethernet" },
467  { IF_TYPE_ISO88025_TOKENRING, "Token-ring" },
468  { IF_TYPE_PPP, "Point-to-Point" },
469  { IF_TYPE_SOFTWARE_LOOPBACK, "Loopback" },
470  { IF_TYPE_ATM, "ATM" },
471  { IF_TYPE_IEEE80211, "IEEE 802.11 wireless" },
472  { IF_TYPE_TUNNEL, "Tunnel" },
473  { IF_TYPE_IEEE1394, "IEEE 1394 (Firewire)" }
474  };
475 
476 static const struct search_list mib_oper_status[] = {
477  { IF_OPER_STATUS_NON_OPERATIONAL, "disabled" },
478  { IF_OPER_STATUS_UNREACHABLE, "WAN not connected" },
479  { IF_OPER_STATUS_DISCONNECTED, "disconnected/no carrier" },
480  { IF_OPER_STATUS_CONNECTING, "WAN connecting" },
481  { IF_OPER_STATUS_CONNECTED, "WAN connected" },
482  { IF_OPER_STATUS_OPERATIONAL, "LAN okay" },
483  };
484 
485 static const struct search_list oper_status[] = {
486  { IfOperStatusUp, "Up" },
487  { IfOperStatusDown, "Down" },
488  { IfOperStatusTesting, "Testing" },
489  { IfOperStatusUnknown, "Unknown" },
490  { IfOperStatusDormant, "Dormant" },
491  { IfOperStatusNotPresent, "Not present" },
492  { IfOperStatusLowerLayerDown, "Lower layer down" }
493 };
494 
495 static char work_buf [10000];
496 
497 static const char *get_address_flags (DWORD flags)
498 {
499  char *p = work_buf;
500 
501  *p = '\0';
502 
503  if (flags == 0)
504  return (NONE_STR);
505 
506  if (flags & IP_ADAPTER_DDNS_ENABLED)
507  p += sprintf (p, "Dynamic DNS enabled, ");
508 
509  if (flags & IP_ADAPTER_REGISTER_ADAPTER_SUFFIX)
510  p += sprintf (p, "Register DNS suffix, ");
511 
512  if (flags & IP_ADAPTER_DHCP_ENABLED)
513  p += sprintf (p, "DHCP enabled, ");
514 
515  if (flags & IP_ADAPTER_RECEIVE_ONLY)
516  p += sprintf (p, "Rx only, ");
517 
518  if (flags & IP_ADAPTER_NO_MULTICAST)
519  p += sprintf (p, "No multicast, ");
520 
521  if (flags & IP_ADAPTER_IPV6_OTHER_STATEFUL_CONFIG)
522  p += sprintf (p, "IPv6 stateful config, ");
523 
524  if (flags & IP_ADAPTER_NETBIOS_OVER_TCPIP_ENABLED)
525  p += sprintf (p, "NetBIOS over tcp/ip, ");
526 
527  if (flags & IP_ADAPTER_IPV4_ENABLED)
528  p += sprintf (p, "IPv4 enabled, ");
529 
530  if (flags & IP_ADAPTER_IPV6_ENABLED)
531  p += sprintf (p, "IPv6 enabled, ");
532 
533  if (p > work_buf)
534  *(p -= 2) = '\0';
535  assert (p < work_buf + sizeof(work_buf));
536  return (work_buf);
537 }
538 
539 static const char *get_addr_common (int num, const address_buf *abuf)
540 {
541  char *p = work_buf;
542  int i;
543 
544  *p = '\0';
545  if (num == 0)
546  return (NONE_STR);
547 
548  for (i = 0; i < num; i++)
549  {
550  strncat (p, abuf[i], sizeof(abuf[0])-1);
551  p += strlen (p);
552  if (i < num - 1)
553  strcat (p, ", "), p += 2;
554  else break;
555  }
556  return strupr (work_buf);
557 }
558 
559 #define GET_ONE_ADDR(addr, alen, buf, buf_sz) \
560  if ((*p_WSAAddressToStringA) (addr, alen, NULL, buf, &buf_sz)) { \
561  (*_printf) (" WSAAddressToString(): %s\n", \
562  win_strerror((*p_WSAGetLastError)())); \
563  break; \
564  }
565  /* Or use 'getnameinfo (addr, alen, buf, buf_sz, NULL ,0, NI_NUMERICHOST)' ?? */
566 
567 #define GET_ADDRESSES(func, type, var) \
568  static const char *func (type *var) \
569  { \
570  address_buf abuf[10]; /* todo 'struct one_addr[10]' */ \
571  int i; \
572  for (i = 0; var && i < DIM(abuf); i++) { \
573  SOCKADDR *addr = var->Address.lpSockaddr; \
574  DWORD alen = var->Address.iSockaddrLength; \
575  DWORD asize = sizeof(abuf[i]); \
576  \
577  strcpy (abuf[i], "??"); \
578  GET_ONE_ADDR (addr, alen, abuf[i], asize); \
579  var = var->Next; \
580  } \
581  return get_addr_common (i, (const address_buf*)&abuf); \
582  }
583 
584 GET_ADDRESSES (get_unicast_addrs, const IP_ADAPTER_UNICAST_ADDRESS, uca)
585 GET_ADDRESSES (get_anycast_addrs, const IP_ADAPTER_ANYCAST_ADDRESS, aca)
586 GET_ADDRESSES (get_multicast_addrs, const IP_ADAPTER_MULTICAST_ADDRESS, mca)
587 GET_ADDRESSES (get_dns_server_addrs, const IP_ADAPTER_DNS_SERVER_ADDRESS, dns)
588 
589 #if defined(ON_WIN_VISTA)
590  GET_ADDRESSES (get_wins_addrs, const IP_ADAPTER_WINS_SERVER_ADDRESS, wins)
591  GET_ADDRESSES (get_gateway_addrs, const IP_ADAPTER_GATEWAY_SERVER_ADDRESS, gw)
592 #endif
593 
594 /*
595  * to-do: print these too:
596  * 'ValidLifeTime', 'PreferredLifetime', 'LeaseLifetime',
597  * 'PrefixOrigin', 'SuffixOrigin'
598  * '(Address.lpSockaddr)->sa_family' for 'uca' and 'aca'
599  *
600  * and:
601  * '(Address.lpSockaddr)->sa_family' for 'mca' and 'dns'
602  */
603 
604 #ifdef BUG_HUNT
605 static void dump_data (const void *data_p, UINT datalen)
606 {
607  const BYTE *data = (const BYTE*) data_p;
608  UINT ofs;
609 
610  for (ofs = 0; ofs < datalen; ofs += 16)
611  {
612  UINT j;
613 
614  if (ofs == 0)
615  printf ("%u:%s%04X: ", datalen,
616  datalen > 9999 ? " " :
617  datalen > 999 ? " " :
618  datalen > 99 ? " " :
619  datalen > 9 ? " " :
620  " ",
621  ofs);
622  else printf (" %04X: ", ofs);
623 
624  for (j = 0; j < 16 && j+ofs < datalen; j++)
625  printf ("%02X%c", (unsigned)data[j+ofs],
626  j == 7 ? '-' : ' '); /* no beeps */
627 
628  for ( ; j < 16; j++) /* pad line to 16 positions */
629  printf (" ");
630 
631  for (j = 0; j < 16 && j+ofs < datalen; j++)
632  {
633  int ch = data[j+ofs];
634 
635  if (ch < ' ') /* non-printable */
636  putchar ('.');
637  else putchar (ch);
638  }
639  putchar ('\n');
640  }
641 }
642 #endif
643 
644 /*
645  * Use GetIfTable() and dump information from MIB.
646  */
647 int W32_CALL pkt_win_print_GetIfTable (void)
648 {
649  MIB_IFTABLE *if_table = NULL;
650  ULONG out_len = 0;
651  DWORD rc = 0;
652  UINT i = 0;
653 
654  (*_printf) ("\nFrom GetIfTable():\n");
655 
656  if (!load_dlls())
657  return (0);
658 
659  rc = (*p_GetIfTable) (if_table, &out_len, TRUE);
660  if_table = alloca (out_len);
661 
662  rc = (*p_GetIfTable) (if_table, &out_len, TRUE);
663  if (rc != NO_ERROR)
664  {
665  if_table = NULL;
666  (*_printf) ("error: %s\n", win_strerror(rc));
667  }
668  else
669  {
670  (*_printf) ("\tNumber of MIB entries: %ld\n", if_table->dwNumEntries);
671  for (i = 0; i < if_table->dwNumEntries; i++)
672  {
673  const MIB_IFROW *if_row = (const MIB_IFROW*) (if_table->table + i);
674 
675  /* Note: The 'if_row->wszName' may *not* have the same GUID
676  * as returned in GetAdapteraddresses() despite it's the same
677  * interface. To verify same interface, we can compare the
678  * descriptions from the 2 API functions.
679  */
680 
681 #if defined(_MSC_VER) /* wprintf() gives nothing or rubbish. What's going on here? */
682  wprintf (L"\tInterface name:\t %.30s\n", if_row->wszName);
683 #else
684  (*_printf) ("\tInterface name:\t %s\n", wstring_utf8(if_row->wszName));
685 #endif
686 
687  (*_printf) ("\tDescription:\t %s\n", if_row->bDescr);
688 
689  (*_printf) ("\t\tMTU:\t %lu\n", if_row->dwMtu);
690  (*_printf) ("\t\tSpeed:\t %s\n", speed_string(if_row->dwSpeed));
691  (*_printf) ("\t\tStatus:\t %s\n",
692  _list_lookup(if_row->dwOperStatus, mib_oper_status, DIM(mib_oper_status)));
693 
694 #define COLUMN_FORMAT "%11.11s %11.11s %11.11s %11.11s %11.11s %11.11s\n"
695 
696  (*_printf) ("\t\t " COLUMN_FORMAT,
697  "Bytes", "Unicasts", "Non-unicasts", "Discarded", "Errors", "Unk Proto");
698 
699  (*_printf) ("\t\tIn: " COLUMN_FORMAT,
700  dword_string(if_row->dwInOctets), dword_string(if_row->dwInUcastPkts),
701  dword_string(if_row->dwInNUcastPkts), dword_string(if_row->dwInDiscards),
702  dword_string(if_row->dwInErrors), dword_string(if_row->dwInUnknownProtos));
703 
704  (*_printf) ("\t\tOut: " COLUMN_FORMAT,
705  dword_string(if_row->dwOutOctets), dword_string(if_row->dwOutUcastPkts),
706  dword_string(if_row->dwOutNUcastPkts), dword_string(if_row->dwOutDiscards),
707  dword_string(if_row->dwOutErrors), NA_STR);
708  }
709  }
710  return (1);
711 }
712 
713 /*
714  * Use GetIfTable2() and dump information from MIB.
715  */
716 int W32_CALL pkt_win_print_GetIfTable2 (void)
717 {
718 #if !(defined(ON_WIN_VISTA) && defined(HAVE_NETIOAPI_H))
719  (*_printf) ("MIB_IFTABLE2 not available with this compiler/SDK.");
720  return (0);
721 #else
722  MIB_IFTABLE2 *if_table2 = NULL;
723 
724  (*_printf) ("\nFrom GetIfTable2():\n");
725 
726  if (!load_dlls())
727  return (0);
728 
729  if (!p_GetIfTable2)
730  {
731  (*_printf) ("This function not available on this OS.");
732  return (0);
733  }
734 
735  rc = (*p_GetIfTable2) (if_table);
736  if (rc != NO_ERROR)
737  {
738  (*_printf) ("error: %s\n", win_strerror(rc));
739  return (0);
740  }
741  /* \todo */
742  return (1);
743 #endif
744 }
745 
746 /*
747  * Use GetIpNetTable() and dump ARP information from MIB.
748  */
749 int W32_CALL pkt_win_print_GetIpNetTable (void)
750 {
751  /* \todo */
752  return (0);
753 }
754 
755 /*
756  * Use GetAdapterAddresses and dump information on all IPv4 adapters.
757  * Rewritten from an MSDN example:
758  * http://msdn.microsoft.com/en-us/library/aa366058(v=vs.85).aspx
759  *
760  * Also see this:
761  * http://www.ipv6style.jp/files/ipv6/en/apps/20060320_2/GetAdaptersAddresses-EN.c
762  * http://svn.netlabs.org/repos/qt4/trunk/src/plugins/bearer/nativewifi/qnativewifiengine.cpp
763  */
764 int W32_CALL pkt_win_print_GetAdaptersAddresses (void)
765 {
766  char *p;
767  DWORD rc = 0;
768  UINT i = 0;
769  ULONG family = AF_UNSPEC;
770  ULONG out_len = 0;
771  ULONG flags = GAA_FLAG_INCLUDE_PREFIX |
772  GAA_FLAG_INCLUDE_ALL_INTERFACES |
773  GAA_FLAG_INCLUDE_WINS_INFO |
774  GAA_FLAG_INCLUDE_TUNNEL_BINDINGORDER |
775  GAA_FLAG_INCLUDE_GATEWAYS;
776 
777  IP_ADAPTER_ADDRESSES *addr = NULL;
778  IP_ADAPTER_PREFIX *prefix = NULL;
779 
780  flags |= GAA_FLAG_SKIP_FRIENDLY_NAME;
781 
782  (*_printf) ("\nFrom GetAdaptersAddresses():\n");
783 
784  if (!load_dlls())
785  return (0);
786 
787  /* Make an initial call to GetAdaptersAddresses() to get the
788  * size needed into the out_len variable.
789  */
790  rc = (*p_GetAdaptersAddresses) (family, flags, NULL, NULL, &out_len);
791  if (rc != ERROR_BUFFER_OVERFLOW)
792  {
793  (*_printf) ("error: %s\n", win_strerror(rc));
794  return (0);
795  }
796 
797  addr = alloca (out_len);
798 
799  /* Make a second call to GetAdaptersAddresses() to get the
800  * actual data we want
801  */
802  rc = (*p_GetAdaptersAddresses) (family, flags, NULL, addr, &out_len);
803  if (rc != NO_ERROR)
804  {
805  (*_printf) ("\t\tError: %s\n", win_strerror(rc));
806  return (0);
807  }
808 
809  while (addr)
810  {
811  (*_printf) ("\tAdapter name: %s\n", addr->AdapterName);
812  (*_printf) ("\t\tDescription: %" WIDESTR_FMT "\n", addr->Description);
813 
814  (*_printf) ("\t\tUnicast Addresses: %s\n", get_unicast_addrs(addr->FirstUnicastAddress));
815  (*_printf) ("\t\tAnycast Addresses: %s\n", get_anycast_addrs(addr->FirstAnycastAddress));
816  (*_printf) ("\t\tMulticast Addresses: %s\n", get_multicast_addrs(addr->FirstMulticastAddress));
817 
818  (*_printf) ("\t\tDNS Servers: ");
819  check_indent_and_print (get_dns_server_addrs(addr->FirstDnsServerAddress));
820 
821  (*_printf) ("\n\t\tDNS Suffix: %" WIDESTR_FMT "\n",
822  addr->DnsSuffix[0] ? addr->DnsSuffix : NONE_STR_W);
823 
824 #if defined(ON_WIN_VISTA_SP1)
825  (*_printf) ("\t\t1st DNS Suffix: %" WIDESTR_FMT "\n",
826  addr->FirstDnsSuffix ? addr->FirstDnsSuffix : NONE_STR_W);
827 #endif
828 
829  if ((flags & GAA_FLAG_SKIP_FRIENDLY_NAME) == 0)
830  {
831  (*_printf) ("\t\tFriendly name: %" WIDESTR_FMT "\n", addr->FriendlyName);
832  }
833 
834  if (addr->PhysicalAddressLength)
835  {
836  (*_printf) ("\t\tPhysical address: ");
837  p = work_buf;
838  for (i = 0; i < addr->PhysicalAddressLength; i++)
839  p += sprintf (p, "%.2X:", (int)addr->PhysicalAddress[i]);
840  (*_printf) ("%s\n", strip_end(work_buf,':'));
841  }
842  (*_printf) ("\t\tFlags: %s\n", get_address_flags(addr->Flags));
843  (*_printf) ("\t\tMTU: %lu\n", addr->Mtu);
844 
845 #if defined(ON_WIN_VISTA)
846  (*_printf) ("\t\tTx speed: %s\n", speed64_string(addr->TransmitLinkSpeed));
847  (*_printf) ("\t\tRx speed: %s\n", speed64_string(addr->ReceiveLinkSpeed));
848  (*_printf) ("\t\tWINS servers: %s\n", get_wins_addrs(addr->FirstWinsServerAddress));
849  (*_printf) ("\t\tGateways: %s\n", get_gateway_addrs(addr->FirstGatewayAddress));
850 #endif
851 
852  (*_printf) ("\t\tIfType: %s (%lu)\n",
853  _list_lookup(addr->IfType, if_types, DIM(if_types)),
854  addr->IfType);
855 
856  (*_printf) ("\t\tOperStatus: %s (%u)\n",
857  _list_lookup(addr->OperStatus, oper_status, DIM(oper_status)),
858  addr->OperStatus);
859 
860  (*_printf) ("\t\tIpv6IfIndex (IPv6 interface): %ld\n", addr->Ipv6IfIndex);
861 
862 #if defined(ON_WIN_VISTA_SP1)
863  (*_printf) ("\t\tConnection type: %ld\n", addr->ConnectionType);
864 #endif
865 
866  (*_printf) ("\t\tZoneIndices (hex): ");
867  for (i = 0; i < 16; i++)
868  (*_printf) ("%lX ", addr->ZoneIndices[i]);
869  (*_printf) ("\n");
870 
871  prefix = addr->FirstPrefix;
872  for (i = 0; prefix; i++)
873  prefix = prefix->Next;
874  (*_printf) ("\t\tNum IP Adapter Prefix entries: %d\n", i);
875 
876  addr = addr->Next;
877  if (addr)
878  (*_printf) ("\n");
879  }
880 
881  return (1);
882 }
883 
884 /*
885  * Return err-number+string for 'err' returned from a RAS function.
886  * Remove trailing [\r\n.]
887  */
888 static const char *ras_strerror (DWORD err)
889 {
890  static char buf[512+20];
891  char err_buf[512], *p;
892 
893  if (!p_RasGetErrorStringA ||
894  (*p_RasGetErrorStringA) (err,err_buf,sizeof(err_buf)) != ERROR_SUCCESS)
895  strcpy (err_buf, "Unknown error");
896  SNPRINTF (buf, sizeof(buf), "%lu/0x%lX %s", err, err, err_buf);
897  rip (buf);
898  p = strrchr (buf, '.');
899  if (p && p[1] == '\0')
900  *p = '\0';
901  return (buf);
902 }
903 
904 
905 static const struct search_list auth_proto[] = {
906  { 0, NONE_STR },
907  { RASLCPAP_PAP, "PAP" },
908  { RASLCPAP_SPAP, "Shiva" },
909  { RASLCPAP_CHAP, "CHAP" },
910  { RASLCPAP_EAP, "EAP" }
911  };
912 
913 static const struct search_list auth_data[] = {
914  { 0, NONE_STR },
915  { RASLCPAD_CHAP_MD5, "CHAP MD5" },
916  { RASLCPAD_CHAP_MS, "Microsoft CHAP" },
917  { RASLCPAD_CHAP_MSV2, "Microsoft CHAP v2" }
918  };
919 
920 static const struct search_list compression[] = {
921  { RASCCPCA_MPPC, "MPPC" },
922  { RASCCPCA_STAC, "STAC" }
923  };
924 /*
925  * Return description of "PPP Compression Control Protocol (CCP)" option
926  * flags. Server or client side.
927  */
928 static const char *get_ccp_flags (DWORD flags)
929 {
930  char *p = work_buf;
931 
932  *p = '\0';
933 
934  if (flags == 0)
935  return (NONE_STR);
936 
937  if (flags & RASCCPO_Compression)
938  p += sprintf (p, "Compression/No encryption, ");
939 
940  if (flags & RASCCPO_HistoryLess)
941  p += sprintf (p, "MPPE stateless, ");
942 
943  if (flags & RASCCPO_Encryption40bit)
944  p += sprintf (p, "MPPE compression (40 bit keys), ");
945 
946  if (flags & RASCCPO_Encryption56bit)
947  p += sprintf (p, "MPPE compression (56 bit keys), ");
948 
949  if (flags & RASCCPO_Encryption128bit)
950  p += sprintf (p, "MPPE compression (128 bit keys), ");
951 
952  if (p > work_buf)
953  *(p -= 2) = '\0';
954  assert (p < work_buf + sizeof(work_buf));
955  return (work_buf);
956 }
957 
958 /*
959  * Return description of "PPP Link Control Protocol (LCP)" option
960  * flags. Server or client side.
961  */
962 static const char *get_lcp_flags (DWORD flags)
963 {
964  char *p = work_buf;
965 
966  *p = '\0';
967 
968  if (flags == 0)
969  return (NONE_STR);
970 
971  if (flags & RASLCPO_PFC)
972  p += sprintf (p, "PF compr., ");
973 
974  if (flags & RASLCPO_ACFC)
975  p += sprintf (p, "ACF compr., ");
976 
977  if (flags & RASLCPO_SSHF)
978  p += sprintf (p, "Short sequence num. header format, ");
979 
980  if (flags & RASLCPO_DES_56)
981  p += sprintf (p, "DES encr., ");
982 
983  if (flags & RASLCPO_3_DES)
984  p += sprintf (p, "3DES encr., ");
985 
986  if (flags & RASLCPO_AES_128)
987  p += sprintf (p, "AES 128-bit encr., "); /* Win7+ */
988 
989  if (flags & RASLCPO_AES_256)
990  p += sprintf (p, "AES 256-bit encr., "); /* Win7+ */
991 
992  if (p > work_buf)
993  *(p -= 2) = '\0';
994  assert (p < work_buf + sizeof(work_buf));
995  return (work_buf);
996 }
997 
998 
999 int W32_CALL pkt_win_print_RasEnumConnections (void)
1000 {
1001  DWORD i, ret;
1002  DWORD len = sizeof(RASCONN);
1003  DWORD num_conn = 0;
1004  RASCONN *ras_conn = alloca (len);
1005 
1006  (*_printf) ("\nFrom RasEnumConnections():\n");
1007 
1008  if (!load_dlls())
1009  return (0);
1010 
1011  /* RasEnumConnections returns the handles of the current active RAS connections */
1012  ras_conn->dwSize = len;
1013  ret = (*p_RasEnumConnectionsA) (ras_conn, &len, &num_conn);
1014  if (!(ret == ERROR_SUCCESS || ret == ERROR_BUFFER_TOO_SMALL))
1015  {
1016  (*_printf) ("\t\terror: %s\n", ras_strerror(ret));
1017  return (0);
1018  }
1019 
1020  if (len > sizeof(RASCONN)) /* Make a biger buffer and call enum again. */
1021  {
1022  ras_conn = alloca (len);
1023  ras_conn->dwSize = sizeof(RASCONN);
1024  }
1025 
1026  ret = (*p_RasEnumConnectionsA) (ras_conn, &len, &num_conn);
1027  if (ret != ERROR_SUCCESS)
1028  {
1029  (*_printf) ("\t\terror: %s\n", ras_strerror(ret));
1030  return (0);
1031  }
1032 
1033  for (i = 0; i < num_conn; i++, ras_conn++)
1034  {
1035  RAS_STATS stats;
1036  RASPPPIPA pppIp;
1037  RASPPPCCP pppCcp;
1038  RASPPPLCP pppLcp;
1039 
1040  memset (&stats, 0, sizeof(stats));
1041  stats.dwSize = sizeof(stats);
1042 
1043  ret = (*p_RasGetConnectionStatistics) (ras_conn->hrasconn, &stats);
1044  if (ret != ERROR_SUCCESS)
1045  {
1046  (*_printf) ("\t\terror: %s\n", ras_strerror(ret));
1047  continue;
1048  }
1049  (*_printf) (" Statistics for connection \"%" TSTR2ASCII_FMT "\":\n", ras_conn->szEntryName);
1050  (*_printf) ("\tBytes Xmited\t\t\t%s\n", dword_string(stats.dwBytesXmited));
1051  (*_printf) ("\tBytes Received\t\t\t%s\n", dword_string(stats.dwBytesRcved));
1052  (*_printf) ("\tFrames Xmited\t\t\t%s\n", dword_string(stats.dwFramesXmited));
1053  (*_printf) ("\tFrames Received\t\t\t%s\n", dword_string(stats.dwFramesRcved));
1054  (*_printf) ("\tCRC Error\t\t\t%s\n", dword_string(stats.dwCrcErr));
1055  (*_printf) ("\tTimeout Error\t\t\t%s\n", dword_string(stats.dwTimeoutErr));
1056  (*_printf) ("\tAlignment Error\t\t\t%s\n", dword_string(stats.dwAlignmentErr));
1057  (*_printf) ("\tHardware Overrun Error\t\t%s\n", dword_string(stats.dwHardwareOverrunErr));
1058  (*_printf) ("\tFraming Error\t\t\t%s\n", dword_string(stats.dwFramingErr));
1059  (*_printf) ("\tBuffer Overrun Error\t\t%s\n", dword_string(stats.dwBufferOverrunErr));
1060  (*_printf) ("\tCompression Ratio [In]\t\t%lu%%\n", stats.dwCompressionRatioIn);
1061  (*_printf) ("\tCompression Ratio [Out]\t\t%lu%%\n", stats.dwCompressionRatioOut);
1062  (*_printf) ("\tSpeed\t\t\t\t%s\n", speed_string(stats.dwBps));
1063  (*_printf) ("\tConnection Duration\t\t%s\n", duration_string(stats.dwConnectDuration));
1064 
1065 #if 1
1066  (*_printf) (" From RasGetProjectionInfo() (PPP_IP):\n");
1067  memset (&pppIp, 0, sizeof(pppIp));
1068  len = pppIp.dwSize = sizeof(pppIp);
1069  ret = (*p_RasGetProjectionInfoA) (ras_conn->hrasconn, RASP_PppIp, &pppIp, &len);
1070  if (ret != ERROR_SUCCESS)
1071  (*_printf) ("\terror: %s\n", ras_strerror(ret));
1072  else
1073  {
1074  (*_printf) ("\tClient IP-address\t\t%s\n", pppIp.szIpAddress);
1075  (*_printf) ("\tServer IP-address\t\t%s\n", pppIp.szServerIpAddress);
1076  (*_printf) ("\tPPP-negotiation error\t\t%lu\n", pppIp.dwError);
1077  (*_printf) ("\tIP Client options\t\t%lu\n", pppIp.dwOptions);
1078  (*_printf) ("\tIP Server options\t\t%lu\n", pppIp.dwServerOptions);
1079  }
1080 
1081  (*_printf) (" From RasGetProjectionInfo() (PPP_CCP):\n");
1082  memset (&pppCcp, 0, sizeof(pppCcp));
1083  len = pppCcp.dwSize = sizeof(pppCcp);
1084  ret = (*p_RasGetProjectionInfoA) (ras_conn->hrasconn, RASP_PppCcp, &pppCcp, &len);
1085  if (ret != ERROR_SUCCESS)
1086  (*_printf) ("\terror: %s\n", ras_strerror(ret));
1087  else
1088  {
1089  (*_printf) ("\tClient compression\t\t%s\n", _list_lookup(pppCcp.dwCompressionAlgorithm, compression, DIM(compression)));
1090  (*_printf) ("\tServer compression\t\t%s\n", _list_lookup(pppCcp.dwServerCompressionAlgorithm, compression, DIM(compression)));
1091  (*_printf) ("\tCCP client options\t\t%s\n", get_ccp_flags(pppCcp.dwOptions));
1092  (*_printf) ("\tCCP server options\t\t%s\n", get_ccp_flags(pppCcp.dwServerOptions));
1093  }
1094 
1095  (*_printf) (" From RasGetProjectionInfo() (PPP_LCP):\n");
1096  memset (&pppLcp, 0, sizeof(pppLcp));
1097  len = pppLcp.dwSize = sizeof(pppLcp);
1098  ret = (*p_RasGetProjectionInfoA) (ras_conn->hrasconn, RASP_PppLcp, &pppLcp, &len);
1099  if (ret != ERROR_SUCCESS)
1100  (*_printf) ("\terror: %s\n", ras_strerror(ret));
1101  else
1102  {
1103  (*_printf) ("\tMultilink\t\t\t%s\n", pppLcp.dwSize && pppLcp.fBundled ? "Yes" : "No");
1104  (*_printf) ("\tNegotiation error\t\t%lu\n", pppLcp.dwError);
1105  (*_printf) ("\tClient Authentication protocol\t%s\n", _list_lookup(pppLcp.dwAuthenticationProtocol, auth_proto, DIM(auth_proto)));
1106  (*_printf) ("\tServer Authentication protocol\t%s\n", _list_lookup(pppLcp.dwServerAuthenticationProtocol, auth_proto, DIM(auth_proto)));
1107  (*_printf) ("\tClient Authentication data\t%s\n", _list_lookup(pppLcp.dwAuthenticationData, auth_data, DIM(auth_data)));
1108  (*_printf) ("\tServer Authentication data\t%s\n", _list_lookup(pppLcp.dwServerAuthenticationData, auth_data, DIM(auth_data)));
1109  (*_printf) ("\tAuthentication message\t\t%" TSTR2ASCII_FMT "\n",
1110  pppLcp.szReplyMessage[0] ? pppLcp.szReplyMessage : _T(NONE_STR));
1111 
1112  (*_printf) ("\tEAP type\t\t\t%s\n", pppLcp.dwServerAuthenticationProtocol == RASLCPAP_EAP ?
1113  itoa(pppLcp.dwServerEapTypeId,work_buf,10) : NA_STR);
1114  (*_printf) ("\tLCP client options\t\t%s\n", get_lcp_flags(pppLcp.dwOptions));
1115  (*_printf) ("\tLCP server options\t\t%s\n", get_lcp_flags(pppLcp.dwServerOptions));
1116  }
1117 #endif
1118  }
1119  return (1);
1120 }
1121 
1122 static const struct search_list wlan_intf_state[] = { /* table for 'WLAN_INTERFACE_STATE' */
1123  { wlan_interface_state_not_ready, "Not ready" },
1124  { wlan_interface_state_connected, "Connected" },
1125  { wlan_interface_state_ad_hoc_network_formed, "First node in a Ad Hoc network" },
1126  { wlan_interface_state_disconnecting, "Disconnecting" },
1127  { wlan_interface_state_disconnected, "Disconnected" },
1128  { wlan_interface_state_associating, "Attempting to associate with a network" },
1129  { wlan_interface_state_discovering, "Auto configuration is discovering settings for the network" },
1130  { wlan_interface_state_authenticating, "Authenticating in process" },
1131  };
1132 
1133 static const struct search_list wlan_conn_mode[] = { /* table for 'WLAN_CONNECTION_MODE' */
1134  { wlan_connection_mode_profile, "Profile" },
1135  { wlan_connection_mode_temporary_profile, "Temporary profile" },
1136  { wlan_connection_mode_discovery_secure, "Secure discovery" },
1137  { wlan_connection_mode_discovery_unsecure, "Unsecure discovery" },
1138  { wlan_connection_mode_auto, "Auto" },
1139  { wlan_connection_mode_invalid, "N/A" }
1140  };
1141 
1142 static int print_wlan_networklist (const WLAN_AVAILABLE_NETWORK_LIST *wlist);
1143 static int print_wlan_current_connection (const WLAN_CONNECTION_ATTRIBUTES *conn_attr);
1144 
1145 int W32_CALL pkt_win_print_WlanEnumInterfaces (void)
1146 {
1147  WLAN_INTERFACE_INFO_LIST *if_list = NULL;
1148  HANDLE client = NULL;
1149  DWORD cur_version = 0;
1150  DWORD res = 0;
1151  int i;
1152 
1153  (*_printf) ("\nFrom WlanEnumInterfaces():\n");
1154 
1155  if (!load_dlls())
1156  return (0);
1157 
1158  res = (*p_WlanOpenHandle) (2, NULL, &cur_version, &client);
1159  if (res != ERROR_SUCCESS)
1160  {
1161  (*_printf) ("WlanOpenHandle() failed with error: %s\n", win_strerror(res));
1162  (*p_WlanCloseHandle) (client, NULL);
1163  return (0);
1164  }
1165 
1166  res = (*p_WlanEnumInterfaces) (client, NULL, &if_list);
1167  if (res != ERROR_SUCCESS)
1168  {
1169  (*_printf) ("WlanEnumInterfaces( failed with error: %lu, %s\n", res, win_strerror(res));
1170  (*p_WlanCloseHandle) (client, NULL);
1171  return (0);
1172  }
1173 
1174  for (i = 0; i < (int)if_list->dwNumberOfItems; i++)
1175  {
1176  const WLAN_INTERFACE_INFO *if_info = (const WLAN_INTERFACE_INFO*) &if_list->InterfaceInfo[i];
1177  WLAN_AVAILABLE_NETWORK_LIST *network_list = NULL;
1178  WLAN_CONNECTION_ATTRIBUTES *conn_attr = NULL;
1179  WCHAR guidString[40] = { L"{??}" };
1180  BOOL auto_conf = FALSE;
1181  BOOL bkg_scan = FALSE;
1182  BOOL str_mode = FALSE;
1183  DWORD ch_number = 0, op_mode = 0, data_size = 0;
1184 
1185  (*_printf) ("\tIndex:\t\t %d\n", i);
1186  (*_printf) ("\tDescription:\t %" WIDESTR_FMT "\n", if_info->strInterfaceDescription);
1187 
1188  (*p_StringFromGUID2) (&if_info->InterfaceGuid, (LPOLESTR)&guidString, DIM(guidString)-1);
1189  (*_printf) ("\tGUID:\t\t %" WIDESTR_FMT "\n", guidString);
1190 
1191  /* opcode: 'wlan_intf_opcode_current_connection' */
1192 
1193  (*_printf) ("\tFrom WlanQueryInterface():\n");
1194  res = (*p_WlanQueryInterface) (client, &if_info->InterfaceGuid,
1195  wlan_intf_opcode_current_connection, NULL,
1196  &data_size, (void*)&conn_attr, NULL);
1197  if (res != ERROR_SUCCESS || !data_size)
1198  (*_printf) ("WlanQueryInterface() failed with error: %s\n", win_strerror(res));
1199  else print_wlan_current_connection (conn_attr);
1200 
1201  if (conn_attr)
1202  (*p_WlanFreeMemory) (conn_attr);
1203 
1204  res = (*p_WlanQueryInterface) (client, &if_info->InterfaceGuid,
1205  wlan_intf_opcode_autoconf_enabled, NULL,
1206  &data_size, (void*)&auto_conf, NULL);
1207  (*_printf) ("\t\tAutoconf: %s\n", res == ERROR_SUCCESS ?
1208  (auto_conf ? "Yes" : "No") : "<unsupp>");
1209 
1210  res = (*p_WlanQueryInterface) (client, &if_info->InterfaceGuid,
1211  wlan_intf_opcode_background_scan_enabled, NULL,
1212  &data_size, (void*)&bkg_scan, NULL);
1213  (*_printf) ("\t\tBackground scan: %s\n", res == ERROR_SUCCESS ?
1214  (bkg_scan ? "Yes" : "No") : "<unsupp>");
1215 
1216  res = (*p_WlanQueryInterface) (client, &if_info->InterfaceGuid,
1217  wlan_intf_opcode_channel_number, NULL,
1218  &data_size, (void*)&ch_number, NULL);
1219  (*_printf) ("\t\tChannel number: %s\n", res == ERROR_SUCCESS ?
1220  itoa(ch_number,work_buf,10) : "<unsupp>");
1221 
1222  res = (*p_WlanQueryInterface) (client, &if_info->InterfaceGuid,
1223  wlan_intf_opcode_media_streaming_mode, NULL,
1224  &data_size, (void*)&str_mode, NULL);
1225  (*_printf) ("\t\tStreaming mode: %s\n", res == ERROR_SUCCESS ?
1226  (str_mode ? "Yes" : "No") : "<unsupp>");
1227 
1228  res = (*p_WlanQueryInterface) (client, &if_info->InterfaceGuid,
1229  wlan_intf_opcode_current_operation_mode, NULL,
1230  &data_size, (void*)&op_mode, NULL);
1231  (*_printf) ("\t\tOperation mode: %s\n", res == ERROR_SUCCESS ?
1232  (op_mode == DOT11_OPERATION_MODE_EXTENSIBLE_STATION ? "Extensible station" :
1233  op_mode == DOT11_OPERATION_MODE_NETWORK_MONITOR ? "Network monitor" : "Unknown") :
1234  "<unsupp>");
1235 
1236  (*_printf) ("\tFrom WlanGetAvailableNetworkList():\n");
1237 
1238  res = (*p_WlanGetAvailableNetworkList) (client, &if_info->InterfaceGuid,
1239  WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES |
1240  WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES,
1241  NULL, &network_list);
1242  if (res != ERROR_SUCCESS || !network_list)
1243  (*_printf) ("WlanGetAvailableNetworkList() failed with error: %s\n", win_strerror(res));
1244  else print_wlan_networklist (network_list);
1245 
1246  if (network_list)
1247  (*p_WlanFreeMemory) (network_list);
1248  }
1249 
1250  if (if_list)
1251  (*p_WlanFreeMemory) (if_list);
1252 
1253  (*p_WlanCloseHandle) (client, NULL);
1254  return (1);
1255 }
1256 
1257 static const struct search_list dot11_auth_algo[] = {
1258  { DOT11_AUTH_ALGO_80211_OPEN, "802.11 Open" },
1259  { DOT11_AUTH_ALGO_80211_SHARED_KEY, "802.11 Shared" },
1260  { DOT11_AUTH_ALGO_WPA, "WPA" },
1261  { DOT11_AUTH_ALGO_WPA_PSK, "WPA-PSK" },
1262  { DOT11_AUTH_ALGO_WPA_NONE, "WPA-None" },
1263  { DOT11_AUTH_ALGO_RSNA, "RSNA" },
1264  { DOT11_AUTH_ALGO_RSNA_PSK, "RSNA with PSK (WEP2)" }
1265  };
1266 
1267 static const struct search_list dot11_cipher_algo[] = {
1268  { DOT11_CIPHER_ALGO_NONE, "None" },
1269  { DOT11_CIPHER_ALGO_WEP40, "WEP-40" },
1270  { DOT11_CIPHER_ALGO_TKIP, "TKIP" },
1271  { DOT11_CIPHER_ALGO_CCMP, "CCMP" },
1272  { DOT11_CIPHER_ALGO_WEP104, "WEP-104" },
1273  { DOT11_CIPHER_ALGO_WEP, "WEP" }
1274  };
1275 
1276 static const struct search_list bss_types[] = {
1277  { dot11_BSS_type_infrastructure, "Infrastructure" },
1278  { dot11_BSS_type_independent, "Ad-hoc" }
1279  };
1280 
1281 static int print_wlan_networklist (const WLAN_AVAILABLE_NETWORK_LIST *wlist)
1282 {
1283  int i;
1284 
1285  for (i = 0; i < (int)wlist->dwNumberOfItems; i++)
1286  {
1287  const WLAN_AVAILABLE_NETWORK *bss = (const WLAN_AVAILABLE_NETWORK*) wlist->Network + i;
1288  int dBm;
1289 
1290  (*_printf) ("\t\tProfile Name[%u]:\t%" WIDESTR_FMT "\n",
1291  i, bss->strProfileName[0] ? bss->strProfileName : L"<not connected>");
1292 
1293  (*_printf) ("\t\tSSID:\t\t\t%.*s\n", (int)bss->dot11Ssid.uSSIDLength, bss->dot11Ssid.ucSSID);
1294  (*_printf) ("\t\tBSS Network type:\t%s\n",
1295  _list_lookup (bss->dot11BssType, bss_types, DIM(bss_types)));
1296 
1297  (*_printf) ("\t\tNumber of BSSIDs:\t%lu\n", bss->uNumberOfBssids);
1298  (*_printf) ("\t\tConnectable:\t\t");
1299  if (bss->bNetworkConnectable)
1300  (*_printf) ("Yes\n");
1301  else (*_printf) ("No: not connectable. WLAN_REASON_CODE value:\t %lu\n", bss->wlanNotConnectableReason);
1302 
1303  (*_printf) ("\t\t# Phy types supported:\t%lu\n", bss->uNumberOfPhyTypes);
1304 
1305  if (bss->wlanSignalQuality == 0)
1306  dBm = -100;
1307  else if (bss->wlanSignalQuality == 100)
1308  dBm = -50;
1309  else dBm = -100 + (bss->wlanSignalQuality/2);
1310 
1311  (*_printf) ("\t\tSignal Quality:\t\t%lu (RSSI: %d dBm)\n", bss->wlanSignalQuality, dBm);
1312 
1313  (*_printf) ("\t\tSecurity Enabled:\t%s\n", bss->bSecurityEnabled ? "Yes" : "No");
1314 
1315  (*_printf) ("\t\tDef AuthAlgorithm:\t%s\n",
1316  _list_lookup(bss->dot11DefaultAuthAlgorithm,dot11_auth_algo,DIM(dot11_auth_algo)));
1317 
1318  (*_printf) ("\t\tDef CipherAlgorithm:\t%s\n",
1319  _list_lookup(bss->dot11DefaultCipherAlgorithm,dot11_cipher_algo,DIM(dot11_cipher_algo)));
1320 
1321  (*_printf) ("\t\tFlags:\t\t\t0x%08lX", bss->dwFlags);
1322  if (bss->dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED)
1323  (*_printf) (" - Currently connected");
1324  if (bss->dwFlags & WLAN_AVAILABLE_NETWORK_HAS_PROFILE)
1325  (*_printf) (" - Has profile");
1326 
1327  (*_printf) ("\n\n");
1328  }
1329  return (1);
1330 }
1331 
1332 static int print_wlan_current_connection (const WLAN_CONNECTION_ATTRIBUTES *attr)
1333 {
1334  (*_printf) ("\t\tInterface state: %s\n",
1335  _list_lookup(attr->isState, wlan_intf_state, DIM(wlan_intf_state)));
1336 
1337  (*_printf) ("\t\tConnection mode: %s\n",
1338  _list_lookup(attr->wlanConnectionMode, wlan_conn_mode, DIM(wlan_conn_mode)));
1339 
1340  (*_printf) ("\t\tProfile name: %" WIDESTR_FMT "\n", attr->strProfileName);
1341 
1342 #if 0
1343  (*_printf) ("\t\tAssociation attr: %s\n", get_wlan_assoc_attr(attr->wlanAssociationAttributes));
1344  (*_printf) ("\t\tSecurity attr: %s\n", get_wlan_secur_attr(attr->wlanSecurityAttributes));
1345 #endif
1346 
1347  return (1);
1348 }
1349 
1350 #else /* COMPILE_WINADINF_C */
1351 
1352 int W32_CALL pkt_win_print_GetIfTable (void)
1353 {
1354  UNIMPLEMENTED();
1355  return (0);
1356 }
1357 
1358 int W32_CALL pkt_win_print_GetAdaptersAddresses (void)
1359 {
1360  UNIMPLEMENTED();
1361  return (0);
1362 }
1363 
1364 int W32_CALL pkt_win_print_RasEnumConnections (void)
1365 {
1366  UNIMPLEMENTED();
1367  return (0);
1368 }
1369 
1370 int W32_CALL pkt_win_print_WlanEnumInterfaces (void)
1371 {
1372  UNIMPLEMENTED();
1373  return (0);
1374 }
1375 #endif /* COMPILE_WINADINF_C */
1376 #endif /* WIN32 || _WIN32 */
1377 
char * strltrim(const char *s)
Return pointer to first non-blank (space/tab) in a string.
Definition: strings.c:243
Core definitions.
static const char * speed64_string(ULONG64 val)
Return a number with suffix for a link-speed of 64-bit value.
Definition: winadinf.c:416
static const char * dword_string(DWORD val)
Return nicely formatted string "xx.xxx.xxx" with thousand separators (left adjusted).
Definition: winadinf.c:355
char *W32_CALL rip(char *s)
Removes end-of-line termination from a string.
Definition: strings.c:180
static const char * speed_string(DWORD val)
Return a number with suffix for a link-speed 32-bit value.
Definition: winadinf.c:387
static const char * _list_lookup(DWORD type, const struct search_list *list, int num)
Search 'list' for 'type' and return it's name.
Definition: winadinf.c:283