pcapif_helper.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /**
  2. * pcapif_helper.c - This file is part of lwIP pcapif and provides helper functions
  3. * for managing the link state.
  4. */
  5. #include "pcapif_helper.h"
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include "lwip/arch.h"
  9. #ifdef WIN32
  10. #define WIN32_LEAN_AND_MEAN
  11. #ifdef _MSC_VER
  12. #pragma warning( push, 3 )
  13. #endif
  14. #include <windows.h>
  15. #include <packet32.h>
  16. #include <ntddndis.h>
  17. #ifdef _MSC_VER
  18. #pragma warning ( pop )
  19. #endif
  20. struct pcapifh_linkstate {
  21. LPADAPTER lpAdapter;
  22. PPACKET_OID_DATA ppacket_oid_data;
  23. };
  24. struct pcapifh_linkstate* pcapifh_linkstate_init(char *adapter_name)
  25. {
  26. struct pcapifh_linkstate* state = (struct pcapifh_linkstate*)malloc(sizeof(struct pcapifh_linkstate));
  27. if (state != NULL) {
  28. memset(state, 0, sizeof(struct pcapifh_linkstate));
  29. state->ppacket_oid_data = (PPACKET_OID_DATA)malloc(sizeof(PACKET_OID_DATA) + sizeof(NDIS_MEDIA_STATE));
  30. if (state->ppacket_oid_data == NULL) {
  31. free(state);
  32. state = NULL;
  33. } else {
  34. state->lpAdapter = PacketOpenAdapter((char*)adapter_name);
  35. if ((state->lpAdapter == NULL) || (state->lpAdapter->hFile == INVALID_HANDLE_VALUE)) {
  36. /* failed to open adapter */
  37. free(state);
  38. state = NULL;
  39. }
  40. }
  41. }
  42. return state;
  43. }
  44. enum pcapifh_link_event pcapifh_linkstate_get(struct pcapifh_linkstate* state)
  45. {
  46. enum pcapifh_link_event ret = PCAPIF_LINKEVENT_UNKNOWN;
  47. if (state != NULL) {
  48. state->ppacket_oid_data->Oid = OID_GEN_MEDIA_CONNECT_STATUS;
  49. state->ppacket_oid_data->Length = sizeof(NDIS_MEDIA_STATE);
  50. if (PacketRequest(state->lpAdapter, FALSE, state->ppacket_oid_data)) {
  51. NDIS_MEDIA_STATE fNdisMediaState;
  52. fNdisMediaState = (*((PNDIS_MEDIA_STATE)(state->ppacket_oid_data->Data)));
  53. ret = ((fNdisMediaState == NdisMediaStateConnected) ? PCAPIF_LINKEVENT_UP : PCAPIF_LINKEVENT_DOWN);
  54. }
  55. }
  56. return ret;
  57. }
  58. void pcapifh_linkstate_close(struct pcapifh_linkstate* state)
  59. {
  60. if (state != NULL) {
  61. if (state->lpAdapter != NULL) {
  62. PacketCloseAdapter(state->lpAdapter);
  63. }
  64. if (state->ppacket_oid_data != NULL) {
  65. free(state->ppacket_oid_data);
  66. }
  67. free(state);
  68. }
  69. }
  70. /** Helper function for PCAPIF_RX_READONLY for windows: copy the date to a new
  71. * page which is set to READONLY after copying.
  72. * This is a helper to simulate hardware that receives to memory that cannot be
  73. * written by the CPU.
  74. */
  75. void *
  76. pcapifh_alloc_readonly_copy(void *data, size_t len)
  77. {
  78. DWORD oldProtect;
  79. void *ret;
  80. if (len > 4096) {
  81. lwip_win32_platform_diag("pcapifh_alloc_readonly_copy: invalid len: %d\n", len);
  82. while(1);
  83. }
  84. ret = VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_READWRITE);
  85. if (ret == NULL) {
  86. lwip_win32_platform_diag("VirtualAlloc failed: %d\n", GetLastError());
  87. while(1);
  88. }
  89. memcpy(ret, data, len);
  90. if (!VirtualProtect(ret, len, PAGE_READONLY, &oldProtect)) {
  91. lwip_win32_platform_diag("VirtualProtect failed: %d\n", GetLastError());
  92. while(1);
  93. }
  94. return ret;
  95. }
  96. void
  97. pcapifh_free_readonly_mem(void *data)
  98. {
  99. if (!VirtualFree(data, 0, MEM_RELEASE)) {
  100. lwip_win32_platform_diag("VirtualFree(0x%08x) failed: %d\n", data, GetLastError());
  101. while(1);
  102. }
  103. }
  104. /**
  105. * Npcap keeps its DLLs in a different directory for compatibility with winpcap.
  106. * Make sure they get found by adding that directory to the DLL search path.
  107. */
  108. void pcapifh_init_npcap(void)
  109. {
  110. char npcap_dir[512];
  111. unsigned int len;
  112. static char npcap_initialized = 0;
  113. if (!npcap_initialized)
  114. {
  115. npcap_initialized = 1;
  116. len = GetSystemDirectory(npcap_dir, 480);
  117. if (!len) {
  118. lwip_win32_platform_diag("Error in GetSystemDirectory: %x", GetLastError());
  119. return;
  120. }
  121. strcat_s(npcap_dir, 512, "\\Npcap");
  122. if (SetDllDirectory(npcap_dir) == 0) {
  123. lwip_win32_platform_diag("Error in SetDllDirectory: %x", GetLastError());
  124. return;
  125. }
  126. }
  127. }
  128. #else /* WIN32 */
  129. /* @todo: add linux/unix implementation? */
  130. struct pcapifh_linkstate {
  131. u8_t empty;
  132. };
  133. struct pcapifh_linkstate* pcapifh_linkstate_init(char *adapter_name)
  134. {
  135. LWIP_UNUSED_ARG(adapter_name);
  136. return NULL;
  137. }
  138. enum pcapifh_link_event pcapifh_linkstate_get(struct pcapifh_linkstate* state)
  139. {
  140. LWIP_UNUSED_ARG(state);
  141. return PCAPIF_LINKEVENT_UP;
  142. }
  143. void pcapifh_linkstate_close(struct pcapifh_linkstate* state)
  144. {
  145. LWIP_UNUSED_ARG(state);
  146. }
  147. void pcapifh_init_npcap(void)
  148. {
  149. }
  150. #endif /* WIN32 */