PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/winpcap/Packet9x/DLL/Packet32.c

#
C | 1234 lines | 880 code | 205 blank | 149 comment | 149 complexity | 63960e69ae3250ad9107b72dd3802fdf MD5 | raw file
  1. /*
  2. * Copyright (c) 1999 - 2003
  3. * NetGroup, Politecnico di Torino (Italy)
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the Politecnico di Torino nor the names of its
  16. * contributors may be used to endorse or promote products derived from
  17. * this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. *
  31. */
  32. #include <packet32.h>
  33. #include <windows.h>
  34. #include <windowsx.h>
  35. #include <ntddndis.h>
  36. #include <sys/timeb.h>
  37. #ifdef __MINGW32__
  38. #ifdef DBG
  39. #include <assert.h>
  40. #define _ASSERTE assert
  41. #else
  42. #define _ASSERTE
  43. #endif /* DBG */
  44. #else
  45. #include <crtdbg.h>
  46. #endif /* __MINGW32__ */
  47. #include "../../version.h"
  48. #ifdef __cplusplus
  49. extern "C"
  50. {
  51. #endif
  52. TCHAR szWindowTitle[] = TEXT ("PACKET.DLL");
  53. LPADAPTER lpTheAdapter = NULL;
  54. #if _DBG
  55. #define ODS(_x) OutputDebugString(TEXT(_x))
  56. #define ODSEx(_x, _y)
  57. #else
  58. #ifdef _DEBUG_TO_FILE
  59. #include <stdio.h>
  60. // Macro to print a debug string. The behavior differs depending on the debug level
  61. #define ODS(_x) { \
  62. FILE *f; \
  63. f = fopen("winpcap_debug.txt", "a"); \
  64. fprintf(f, "%s", _x); \
  65. fclose(f); \
  66. }
  67. // Macro to print debug data with the printf convention. The behavior differs depending on */
  68. #define ODSEx(_x, _y) { \
  69. FILE *f; \
  70. f = fopen("winpcap_debug.txt", "a"); \
  71. fprintf(f, _x, _y); \
  72. fclose(f); \
  73. }
  74. #else
  75. #define ODS(_x)
  76. #define ODSEx(_x, _y)
  77. #endif
  78. #endif
  79. typedef DWORD(CALLBACK* OPENVXDHANDLE)(HANDLE);
  80. BOOLEAN StartPacketDriver (LPTSTR ServiceName);
  81. BOOLEAN StopPacketDriver (void);
  82. BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject);
  83. char PacketLibraryVersion[] = WINPCAP_PACKET9x_STRING_VERSION;
  84. //---------------------------------------------------------------------------
  85. PCHAR PacketGetVersion()
  86. {
  87. return PacketLibraryVersion;
  88. }
  89. //---------------------------------------------------------------------------
  90. PCHAR PacketGetDriverVersion()
  91. {
  92. return PacketLibraryVersion;
  93. }
  94. //---------------------------------------------------------------------------
  95. BOOL APIENTRY DllMain (HANDLE hModule,
  96. DWORD dwReason,
  97. LPVOID lpReserved)
  98. {
  99. BOOL Status;
  100. ODS ("Packet32: DllEntry\n");
  101. switch (dwReason)
  102. {
  103. case DLL_PROCESS_ATTACH:
  104. Status = StartPacketDriver (TEXT ("PACKET"));
  105. break;
  106. case DLL_PROCESS_DETACH:
  107. Status = StopPacketDriver ();
  108. break;
  109. default:
  110. Status = TRUE;
  111. break;
  112. }
  113. return Status;
  114. }
  115. //---------------------------------------------------------------------------
  116. BOOL PacketDeviceIoControl (LPADAPTER lpAdapterObject,
  117. LPPACKET lpPacket,
  118. ULONG ulIoctl,
  119. BOOLEAN bSync)
  120. {
  121. BOOLEAN Result;
  122. DWORD Error;
  123. ODS ("Packet32: PacketDeviceIoControl\n");
  124. _ASSERTE (lpAdapterObject != NULL);
  125. _ASSERTE (lpPacket != NULL);
  126. lpPacket->OverLapped.Offset = 0;
  127. lpPacket->OverLapped.OffsetHigh = 0;
  128. lpPacket->ulBytesReceived = 0;
  129. if (!ResetEvent (lpPacket->OverLapped.hEvent))
  130. {
  131. lpPacket->bIoComplete = FALSE;
  132. return FALSE;
  133. }
  134. Result = DeviceIoControl (lpAdapterObject->hFile,
  135. ulIoctl,
  136. lpPacket->Buffer,
  137. lpPacket->Length,
  138. lpPacket->Buffer,
  139. lpPacket->Length,
  140. &(lpPacket->ulBytesReceived),
  141. &(lpPacket->OverLapped));
  142. Error=GetLastError () ;
  143. if (!Result && bSync)
  144. {
  145. if (Error == ERROR_IO_PENDING)
  146. {
  147. Result = GetOverlappedResult (lpAdapterObject->hFile,
  148. &(lpPacket->OverLapped),
  149. &(lpPacket->ulBytesReceived),
  150. TRUE);
  151. }
  152. else
  153. ODS ("Packet32: unsupported API call return error!\n");
  154. }
  155. lpPacket->bIoComplete = Result;
  156. return Result;
  157. }
  158. //---------------------------------------------------------------------------
  159. LPADAPTER PacketOpenAdapter (LPTSTR AdapterName)
  160. {
  161. LPPACKET lpSupport;
  162. LPADAPTER nAdapter;
  163. DWORD error;
  164. BOOL res;
  165. OPENVXDHANDLE OpenVxDHandle;
  166. DWORD KernEvent;
  167. UINT BytesReturned;
  168. struct _timeb time;
  169. ODSEx ("Packet32: PacketOpenAdapter, opening %s\n", AdapterName);
  170. nAdapter = (LPADAPTER) GlobalAllocPtr (GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof (ADAPTER));
  171. if (nAdapter == NULL)
  172. {
  173. error=GetLastError();
  174. ODS ("Packet32: PacketOpenAdapter GlobalAlloc Failed\n");
  175. ODSEx("Error=%d\n",error);
  176. //set the error to the one on which we failed
  177. SetLastError(error);
  178. return NULL;
  179. }
  180. wsprintf (nAdapter->SymbolicLink,
  181. TEXT ("\\\\.\\%s"),
  182. TEXT ("NPF.VXD"));
  183. nAdapter->hFile = CreateFile (nAdapter->SymbolicLink,
  184. GENERIC_WRITE | GENERIC_READ,
  185. 0,
  186. NULL,
  187. OPEN_EXISTING,
  188. FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE,
  189. 0);
  190. if (nAdapter->hFile == INVALID_HANDLE_VALUE)
  191. {
  192. error=GetLastError();
  193. ODS ("Packet32: PacketOpenAdapter Could not open adapter, 1\n");
  194. ODSEx("Error=%d\n",error);
  195. GlobalFreePtr (nAdapter);
  196. //set the error to the one on which we failed
  197. SetLastError(error);
  198. return NULL;
  199. }
  200. lpSupport=PacketAllocatePacket();
  201. PacketInitPacket(lpSupport,AdapterName,strlen(AdapterName));
  202. if (nAdapter && (nAdapter->hFile != INVALID_HANDLE_VALUE))
  203. {
  204. res=PacketDeviceIoControl(nAdapter,
  205. lpSupport,
  206. (ULONG) IOCTL_OPEN,
  207. TRUE);
  208. if (res==FALSE || ((char*)lpSupport->Buffer)[0]=='\0'){
  209. SetLastError(ERROR_FILE_NOT_FOUND);
  210. goto err;
  211. }
  212. PacketFreePacket(lpSupport);
  213. // Set the time zone
  214. _ftime(&time);
  215. if(DeviceIoControl(nAdapter->hFile,pBIOCSTIMEZONE,&time.timezone,2,NULL,0,&BytesReturned,NULL)==FALSE){
  216. error=GetLastError();
  217. ODS ("Packet32: PacketOpenAdapter Could not open adapter, 2\n");
  218. ODSEx("Error=%d\n",error);
  219. GlobalFreePtr (nAdapter);
  220. //set the error to the one on which we failed
  221. SetLastError(error);
  222. return NULL;
  223. }
  224. // create the read event
  225. nAdapter->ReadEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
  226. // obtain the pointer of OpenVxDHandle in KERNEL32.DLL.
  227. // It is not possible to reference statically this function, because it is present only in Win9x
  228. OpenVxDHandle = (OPENVXDHANDLE) GetProcAddress(GetModuleHandle("KERNEL32"),"OpenVxDHandle");
  229. // map the event to kernel mode
  230. KernEvent=(DWORD)(OpenVxDHandle)(nAdapter->ReadEvent);
  231. // pass the event to the driver
  232. if(DeviceIoControl(nAdapter->hFile,pBIOCEVNAME,&KernEvent,4,NULL,0,&BytesReturned,NULL)==FALSE){
  233. error=GetLastError();
  234. ODS("Packet32: PacketOpenAdapter Could not open adapter, 3\n");
  235. ODSEx("Error=%d\n",error);
  236. GlobalFreePtr (nAdapter);
  237. //set the error to the one on which we failed
  238. SetLastError(error);
  239. return NULL;
  240. }
  241. //set the maximum lookhahead size allowable with this NIC driver
  242. PacketSetMaxLookaheadsize(nAdapter);
  243. //set the number of times a single write will be repeated
  244. PacketSetNumWrites(nAdapter,1);
  245. return nAdapter;
  246. }
  247. err:
  248. error=GetLastError();
  249. ODS ("Packet32: PacketOpenAdapter Could not open adapter, 4\n");
  250. ODSEx("Error=%d\n",error);
  251. //set the error to the one on which we failed
  252. SetLastError(error);
  253. return NULL;
  254. }
  255. //---------------------------------------------------------------------------
  256. /* Function to set the working mode of the driver
  257. mode working mode
  258. */
  259. BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode)
  260. {
  261. int BytesReturned;
  262. return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL);
  263. }
  264. //---------------------------------------------------------------------------
  265. /* Function to get the the read event*/
  266. HANDLE PacketGetReadEvent(LPADAPTER AdapterObject)
  267. {
  268. return AdapterObject->ReadEvent;
  269. }
  270. //---------------------------------------------------------------------------
  271. /* Function to set the the number of times a write will be repeated*/
  272. BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)
  273. {
  274. AdapterObject->NumWrites=nwrites;
  275. return TRUE;
  276. }
  277. //---------------------------------------------------------------------------
  278. /* This function is used to set the read timeout
  279. timeout value of timeout(milliseconds). 0 means infinite.
  280. */
  281. BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)
  282. {
  283. int BytesReturned;
  284. return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&timeout,4,NULL,0,&BytesReturned,NULL);
  285. }
  286. //---------------------------------------------------------------------------
  287. /* This function allows to set the dimension of the packet buffer in the driver
  288. parameters:
  289. dim dimension of the buffer (kilobytes)
  290. */
  291. BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)
  292. {
  293. int BytesReturned;
  294. return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL);
  295. }
  296. //---------------------------------------------------------------------------
  297. /* Function to set the minimum amount of bytes that will be copied by the driver*/
  298. BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes)
  299. {
  300. // not yet implemented in Windows 9x
  301. return TRUE;
  302. }
  303. //---------------------------------------------------------------------------
  304. /* Function to set a bpf filter in the driver
  305. parameters:
  306. fp the pointer to the beginning of the filtering program
  307. */
  308. BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp)
  309. {
  310. int BytesReturned;
  311. return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL);
  312. }
  313. //---------------------------------------------------------------------------
  314. BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)
  315. {
  316. int BytesReturned;
  317. return DeviceIoControl(AdapterObject->hFile,pBIOCGSTATS,NULL,0,s,sizeof(struct bpf_stat),&BytesReturned,NULL);
  318. }
  319. //---------------------------------------------------------------------------
  320. BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s)
  321. {
  322. int BytesReturned;
  323. return DeviceIoControl(AdapterObject->hFile,pBIOCGSTATS,NULL,0,s,sizeof(struct bpf_stat),&BytesReturned,NULL);
  324. }
  325. //---------------------------------------------------------------------------
  326. VOID PacketCloseAdapter (LPADAPTER lpAdapter)
  327. {
  328. ODS ("Packet32: PacketCloseAdapter\n");
  329. // close the capture handle
  330. CloseHandle (lpAdapter->hFile);
  331. // close the read event
  332. CloseHandle (lpAdapter->ReadEvent);
  333. GlobalFreePtr (lpAdapter);
  334. lpAdapter = NULL;
  335. }
  336. //---------------------------------------------------------------------------
  337. LPPACKET PacketAllocatePacket (void)
  338. {
  339. LPPACKET lpPacket;
  340. lpPacket = (LPPACKET) GlobalAllocPtr (
  341. GMEM_MOVEABLE | GMEM_ZEROINIT,
  342. sizeof (PACKET));
  343. if (lpPacket == NULL)
  344. {
  345. ODS ("Packet32: PacketAllocatePacket: GlobalAlloc Failed\n");
  346. return NULL;
  347. }
  348. lpPacket->OverLapped.hEvent = CreateEvent (NULL,
  349. FALSE,
  350. FALSE,
  351. NULL);
  352. if (lpPacket->OverLapped.hEvent == NULL)
  353. {
  354. ODS ("Packet32: PacketAllocatePacket: CreateEvent Failed\n");
  355. GlobalFreePtr (lpPacket);
  356. return NULL;
  357. }
  358. lpPacket->Buffer=NULL;
  359. lpPacket->Length=0;
  360. lpPacket->ulBytesReceived = 0;
  361. lpPacket->bIoComplete = FALSE;
  362. return lpPacket;
  363. }
  364. //---------------------------------------------------------------------------
  365. VOID PacketFreePacket (LPPACKET lpPacket)
  366. {
  367. CloseHandle (lpPacket->OverLapped.hEvent);
  368. GlobalFreePtr (lpPacket);
  369. }
  370. //---------------------------------------------------------------------------
  371. VOID PacketInitPacket (LPPACKET lpPacket,
  372. PVOID Buffer,
  373. UINT Length)
  374. {
  375. lpPacket->Buffer = Buffer;
  376. lpPacket->Length = Length;
  377. }
  378. //---------------------------------------------------------------------------
  379. BOOLEAN PacketSendPacket (LPADAPTER AdapterObject,
  380. LPPACKET lpPacket,
  381. BOOLEAN Sync)
  382. {
  383. int i;
  384. for(i=0;i<AdapterObject->NumWrites;i++){
  385. if(PacketDeviceIoControl (AdapterObject,lpPacket,(ULONG) IOCTL_PROTOCOL_WRITE,Sync)==FALSE)
  386. return FALSE;
  387. }
  388. return TRUE;
  389. }
  390. //---------------------------------------------------------------------------
  391. // Emulated at user-level under Win9x
  392. INT PacketSendPackets(LPADAPTER AdapterObject,
  393. PVOID PacketBuff,
  394. ULONG Size,
  395. BOOLEAN Sync)
  396. {
  397. struct dump_bpf_hdr *winpcap_hdr;
  398. PCHAR EndOfUserBuff = (PCHAR)PacketBuff + Size;
  399. LPPACKET PacketToSend;
  400. BOOLEAN res;
  401. // Start from the first packet
  402. winpcap_hdr = (struct dump_bpf_hdr*)PacketBuff;
  403. if( (PCHAR)winpcap_hdr + winpcap_hdr->caplen + sizeof(struct dump_bpf_hdr) > EndOfUserBuff )
  404. {
  405. // Malformed buffer
  406. return 0;
  407. }
  408. while( TRUE ){
  409. if(winpcap_hdr->caplen ==0 || winpcap_hdr->caplen > 65536)
  410. {
  411. // Malformed header
  412. return 0;
  413. }
  414. // Set up the LPPACKET structure
  415. PacketToSend=PacketAllocatePacket();
  416. PacketInitPacket(PacketToSend,
  417. (PCHAR)winpcap_hdr + sizeof(struct dump_bpf_hdr),
  418. winpcap_hdr->caplen);
  419. // Send the packet
  420. res = PacketSendPacket (AdapterObject, PacketToSend, TRUE);
  421. // Free the just used LPPACKET structure
  422. PacketFreePacket(PacketToSend);
  423. if(res == FALSE){
  424. // Error sending the packet
  425. return (PCHAR)winpcap_hdr - (PCHAR)PacketBuff;
  426. }
  427. // Step to the next packet in the buffer
  428. (PCHAR)winpcap_hdr += winpcap_hdr->caplen + sizeof(struct dump_bpf_hdr);
  429. // Check if the end of the user buffer has been reached
  430. if( (PCHAR)winpcap_hdr >= EndOfUserBuff )
  431. {
  432. return (PCHAR)winpcap_hdr - (PCHAR)PacketBuff;
  433. }
  434. }
  435. }
  436. //---------------------------------------------------------------------------
  437. BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,
  438. LPPACKET lpPacket,
  439. BOOLEAN Sync)
  440. {
  441. return PacketDeviceIoControl(AdapterObject,
  442. lpPacket,
  443. (ULONG) IOCTL_PROTOCOL_READ,
  444. Sync);
  445. }
  446. //---------------------------------------------------------------------------
  447. BOOLEAN PacketWaitPacket (LPADAPTER AdapterObject,
  448. LPPACKET lpPacket)
  449. {
  450. lpPacket->bIoComplete = GetOverlappedResult( AdapterObject->hFile,
  451. &lpPacket->OverLapped,
  452. &lpPacket->ulBytesReceived,
  453. TRUE );
  454. return lpPacket->bIoComplete;
  455. }
  456. //---------------------------------------------------------------------------
  457. BOOLEAN PacketResetAdapter (LPADAPTER AdapterObject)
  458. {
  459. UINT BytesReturned;
  460. DeviceIoControl (
  461. AdapterObject->hFile,
  462. (DWORD) IOCTL_PROTOCOL_RESET,
  463. NULL,
  464. 0,
  465. NULL,
  466. 0,
  467. &BytesReturned,
  468. NULL);
  469. return TRUE;
  470. }
  471. //---------------------------------------------------------------------------
  472. BOOLEAN PacketRequest (LPADAPTER AdapterObject,
  473. BOOLEAN Set,
  474. PPACKET_OID_DATA OidData)
  475. {
  476. UINT BytesReturned;
  477. BOOLEAN Result;
  478. OVERLAPPED Overlap;
  479. ODS ("Packet32: PacketRequest\n");
  480. _ASSERTE (AdapterObject != NULL);
  481. _ASSERTE (OidData != NULL);
  482. _ASSERTE (OidData->Data != NULL);
  483. Overlap.Offset = 0;
  484. Overlap.OffsetHigh = 0;
  485. Overlap.hEvent = CreateEvent (NULL,
  486. FALSE,
  487. FALSE,
  488. NULL);
  489. if (Overlap.hEvent == NULL)
  490. {
  491. ODS ("Packet32: PacketRequestPacket: CreateEvent Failed\n");
  492. return FALSE;
  493. }
  494. if (!ResetEvent(Overlap.hEvent))
  495. {
  496. ODS ("Packet32: PacketRequestPacket: ResetEvent Failed\n");
  497. CloseHandle(Overlap.hEvent);
  498. return FALSE;
  499. }
  500. Result = DeviceIoControl (
  501. AdapterObject->hFile,
  502. (DWORD) Set ? pBIOCSETOID : pBIOCQUERYOID,
  503. OidData,
  504. sizeof (PACKET_OID_DATA) - 1 + OidData->Length,
  505. OidData,
  506. sizeof (PACKET_OID_DATA) - 1 + OidData->Length,
  507. &BytesReturned,
  508. &Overlap);
  509. if (!Result)
  510. {
  511. if (GetLastError() == ERROR_IO_PENDING)
  512. {
  513. Result = GetOverlappedResult(AdapterObject->hFile,
  514. &Overlap,
  515. &BytesReturned,
  516. TRUE);
  517. }
  518. else
  519. {
  520. ODS("Packet32: Unssupported API call return error!\n");
  521. }
  522. }
  523. if (BytesReturned == 0)
  524. {
  525. // There was an ndis error
  526. ODS ("Packet32: Ndis returned error to OID\n");
  527. Result = FALSE;
  528. }
  529. CloseHandle(Overlap.hEvent);
  530. return Result;
  531. }
  532. //---------------------------------------------------------------------------
  533. BOOLEAN PacketSetHwFilter (LPADAPTER AdapterObject,
  534. ULONG Filter)
  535. {
  536. BOOLEAN Status;
  537. ULONG IoCtlBufferLength = (sizeof (PACKET_OID_DATA) + sizeof (ULONG) - 1);
  538. PPACKET_OID_DATA OidData;
  539. ODS ("Packet32: PacketSetFilter\n");
  540. _ASSERTE (AdapterObject != NULL);
  541. OidData = GlobalAllocPtr (
  542. GMEM_MOVEABLE | GMEM_ZEROINIT,
  543. IoCtlBufferLength
  544. );
  545. if (OidData == NULL)
  546. {
  547. return FALSE;
  548. }
  549. OidData->Oid = OID_GEN_CURRENT_PACKET_FILTER;
  550. OidData->Length = sizeof (ULONG);
  551. *((PULONG) OidData->Data) = Filter;
  552. Status = PacketRequest (
  553. AdapterObject,
  554. TRUE,
  555. OidData
  556. );
  557. GlobalFreePtr (OidData);
  558. return Status;
  559. }
  560. //---------------------------------------------------------------------------
  561. BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type)
  562. {
  563. BOOLEAN Status;
  564. ULONG IoCtlBufferLength = (sizeof (PACKET_OID_DATA) + sizeof (ULONG) - 1);
  565. PPACKET_OID_DATA OidData;
  566. ODS ("Packet32: PacketSetFilter\n");
  567. _ASSERTE (AdapterObject != NULL);
  568. OidData = GlobalAllocPtr (
  569. GMEM_MOVEABLE | GMEM_ZEROINIT,
  570. IoCtlBufferLength
  571. );
  572. if (OidData == NULL)
  573. {
  574. return FALSE;
  575. }
  576. //get the link-layer type
  577. OidData->Oid = OID_GEN_MEDIA_IN_USE;
  578. OidData->Length = sizeof (ULONG);
  579. Status = PacketRequest(AdapterObject,FALSE,OidData);
  580. if(Status==FALSE)return FALSE;
  581. type->LinkType=*((UINT*)OidData->Data);
  582. //get the link-layer speed
  583. OidData->Oid = OID_GEN_LINK_SPEED;
  584. OidData->Length = sizeof (ULONG);
  585. Status = PacketRequest(AdapterObject,FALSE,OidData);
  586. type->LinkSpeed=*((UINT*)OidData->Data)*100;
  587. GlobalFreePtr (OidData);
  588. return Status;
  589. }
  590. //---------------------------------------------------------------------------
  591. BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject)
  592. {
  593. BOOLEAN Status;
  594. ULONG IoCtlBufferLength = (sizeof (PACKET_OID_DATA) + sizeof (ULONG) - 1);
  595. PPACKET_OID_DATA OidData;
  596. ODS ("Packet32: PacketSetFilter\n");
  597. _ASSERTE (AdapterObject != NULL);
  598. OidData = GlobalAllocPtr (
  599. GMEM_MOVEABLE | GMEM_ZEROINIT,
  600. IoCtlBufferLength
  601. );
  602. if (OidData == NULL)
  603. {
  604. return FALSE;
  605. }
  606. //set the size of the lookahead buffer to the maximum available by the the NIC driver
  607. OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD;
  608. OidData->Length=sizeof(ULONG);
  609. Status=PacketRequest(AdapterObject,FALSE,OidData);
  610. OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD;
  611. Status=PacketRequest(AdapterObject,TRUE,OidData);
  612. GlobalFreePtr(OidData);
  613. return Status;
  614. }
  615. //---------------------------------------------------------------------------
  616. BOOLEAN StartPacketDriver (LPTSTR lpstrServiceName)
  617. {
  618. ODS ("Packet32: StartPacketDriver\n");
  619. return TRUE;
  620. }
  621. //---------------------------------------------------------------------------
  622. BOOLEAN StopPacketDriver(void)
  623. {
  624. ODS ("Packet32: StopPacketDriver\n");
  625. return TRUE;
  626. }
  627. //---------------------------------------------------------------------------
  628. INT PacketSetSnapLen(LPADAPTER AdapterObject, int snaplen)
  629. {
  630. ODS ("Packet32: PacketSetSnapLen\n");
  631. return 0;
  632. }
  633. //---------------------------------------------------------------------------
  634. BOOLEAN PacketGetAdapterNames (PTSTR pStr,
  635. PULONG BufferSize)
  636. {
  637. ULONG Result,i;
  638. LONG Status;
  639. char* pStrInternal;
  640. ULONG RemainingBytes;
  641. LPADAPTER adapter;
  642. PPACKET_OID_DATA OidData;
  643. HKEY Key;
  644. char NdisName[80];
  645. ULONG NeededBytes;
  646. ULONG NeededBytesForString;
  647. char TempBuffer[1024];
  648. BOOLEAN retVal;
  649. OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,256);
  650. if (OidData == NULL)
  651. {
  652. return FALSE;
  653. }
  654. Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\class\\net",0,KEY_READ,&Key);
  655. if (Status != ERROR_SUCCESS)
  656. {
  657. GlobalFree(OidData);
  658. return FALSE;
  659. }
  660. NeededBytes = 0;
  661. //first we calculate the needed bytes
  662. i=0;
  663. while((Result=RegEnumKey(Key,i,NdisName,sizeof(NdisName) - sizeof("\\NDIS") - 1))==ERROR_SUCCESS)
  664. {
  665. HKEY hKeyNdisName;
  666. strcat(NdisName,"\\NDIS");
  667. Status=RegOpenKeyEx(Key,NdisName,0,KEY_READ,&hKeyNdisName);
  668. if (Status != ERROR_SUCCESS)
  669. {
  670. i++;
  671. continue;
  672. }
  673. //we need to tell RegOpenKeyEx the length of the buffer passed as argument
  674. NeededBytesForString = sizeof(TempBuffer);
  675. Status=RegQueryValueEx(hKeyNdisName,"LOGDRIVERNAME",NULL,NULL,(LPBYTE)TempBuffer,&NeededBytesForString);
  676. if (Status != ERROR_SUCCESS)
  677. {
  678. RegCloseKey(hKeyNdisName);
  679. i++;
  680. continue;
  681. }
  682. NeededBytes += NeededBytesForString;
  683. //we try to open the adapter and retrieve its name
  684. adapter=PacketOpenAdapter(TempBuffer);
  685. if(adapter==NULL)
  686. {
  687. NeededBytes += sizeof("Unknown") + 1;
  688. }
  689. else
  690. {
  691. //we retrieve its name by performing a PacketRequest,
  692. //the buffer that will contain the name is at the end of the OidData structure
  693. OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
  694. OidData->Length = 256 - sizeof(PACKET_OID_DATA);
  695. Status = PacketRequest(adapter,FALSE,OidData);
  696. if(Status==0)
  697. {
  698. NeededBytes += sizeof("Unknown") + 1;
  699. }
  700. else
  701. {
  702. NeededBytes += strlen((char*) OidData->Data) + 1;
  703. }
  704. PacketCloseAdapter(adapter);
  705. }
  706. i++;
  707. RegCloseKey(hKeyNdisName);
  708. }
  709. NeededBytes += 1 + 1; //the two nulls at the end of each block of strings
  710. if (NeededBytes > *BufferSize || pStr == NULL || Result != ERROR_NO_MORE_ITEMS)
  711. {
  712. *BufferSize = NeededBytes;
  713. GlobalFree(OidData);
  714. RegCloseKey(Key);
  715. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  716. return FALSE;
  717. }
  718. //now we copy the strings
  719. retVal = TRUE;
  720. NeededBytes = 0;
  721. i = 0;
  722. pStrInternal = pStr;
  723. RemainingBytes = *BufferSize;
  724. while((Result=RegEnumKey(Key,i,NdisName,sizeof(NdisName) - sizeof("\\NDIS") - 1))==ERROR_SUCCESS)
  725. {
  726. HKEY hKeyNdisName;
  727. strcat(NdisName,"\\NDIS");
  728. NeededBytesForString = sizeof(TempBuffer);
  729. Status=RegOpenKeyEx(Key,NdisName,0,KEY_READ,&hKeyNdisName);
  730. if (Status != ERROR_SUCCESS)
  731. {
  732. i++;
  733. continue;
  734. }
  735. Status=RegQueryValueEx(hKeyNdisName,"LOGDRIVERNAME",NULL,NULL,(LPBYTE)TempBuffer,&NeededBytesForString);
  736. if (Status == ERROR_SUCCESS && NeededBytesForString <= RemainingBytes)
  737. {
  738. //this copy is safe, since we have checked that the available space will fit the string
  739. strcpy(pStrInternal, TempBuffer);
  740. pStrInternal += NeededBytesForString;
  741. RemainingBytes -= NeededBytesForString;
  742. }
  743. NeededBytes += NeededBytesForString; //just in case the second scan returns a larger number of adapters!!
  744. i++;
  745. RegCloseKey(hKeyNdisName);
  746. }
  747. RegCloseKey(Key);
  748. //we need to properly terminate the list of adapter names with another \0
  749. if (RemainingBytes > 0)
  750. {
  751. pStrInternal[0] = 0;
  752. pStrInternal++;
  753. RemainingBytes--;
  754. }
  755. NeededBytes++;
  756. while (*pStr != 0) //now we scan again the list of adapters in pStr to retrieve their names
  757. {
  758. adapter=PacketOpenAdapter(pStr);
  759. if(adapter==NULL)
  760. {
  761. if ( RemainingBytes < sizeof("Unknown") + 1 )
  762. retVal = FALSE; //we do not copy anything, we simply skip this adapter, and return failure
  763. else
  764. { //this copy is safe as we have checked that the remaining bytes will fit the source string
  765. strcpy(pStrInternal, "Unknown");
  766. //we move the pointer of the list of adapter names
  767. pStrInternal += sizeof("Unknown") + 1;
  768. RemainingBytes -= sizeof("Unknown") + 1;
  769. }
  770. //we continue to keep track of available bytes. This is used if we fail in this phase
  771. NeededBytes += sizeof("Unknown") + 1;
  772. }
  773. else
  774. {
  775. OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
  776. OidData->Length = 256 - sizeof(PACKET_OID_DATA);
  777. Status = PacketRequest(adapter,FALSE,OidData);
  778. if(Status==0)
  779. {
  780. if ( RemainingBytes < sizeof("Unknown") + 1 )
  781. retVal = FALSE; //we do not copy anything, we simply skip this adapter, and return failure
  782. else
  783. { //this copy is safe as we have checked that the remaining bytes will fit the source string
  784. strcpy(pStrInternal, "Unknown");
  785. //we move the pointer of the list of adapter names
  786. pStrInternal += sizeof("Unknown") + 1;
  787. RemainingBytes -= sizeof("Unknown") + 1;
  788. }
  789. //we continue to keep track of available bytes. This is used if we fail in this phase
  790. NeededBytes += sizeof("Unknown") + 1;
  791. }
  792. else
  793. {
  794. if ( RemainingBytes < strlen((char*) OidData->Data) + 1 )
  795. retVal = FALSE; //we do not copy anything, we simply skip this adapter, and return failure
  796. else
  797. {
  798. //this copy is safe as we have checked that the remaining bytes will fit the source string
  799. strcpy(pStrInternal, (char*)OidData->Data);
  800. //we move the pointer of the list of adapter names
  801. pStrInternal += strlen((char*) OidData->Data) + 1;
  802. RemainingBytes -= strlen((char*) OidData->Data) + 1;
  803. }
  804. //we continue to keep track of available bytes. This is used if we fail in this phase
  805. NeededBytes += strlen((char*) OidData->Data) + 1;
  806. }
  807. PacketCloseAdapter(adapter);
  808. }
  809. //we move to the next adapter in the list. We end when we reach the double \0
  810. pStr += strlen(pStr) + 1;
  811. }
  812. //we need to properly terminate the list of adapter descriptions with another \0
  813. if (RemainingBytes > 0)
  814. {
  815. pStrInternal[0] = 0;
  816. pStrInternal++;
  817. RemainingBytes--;
  818. }
  819. else
  820. retVal = FALSE;
  821. NeededBytes++;
  822. *BufferSize = NeededBytes;
  823. GlobalFree(OidData);
  824. return retVal;
  825. }
  826. //---------------------------------------------------------------------------
  827. BOOLEAN PacketGetNetInfo(LPTSTR AdapterName, PULONG netp, PULONG maskp)
  828. {
  829. struct hostent* h;
  830. char szBuff[80];
  831. if(gethostname(szBuff, 79))
  832. {
  833. if(WSAGetLastError()==WSANOTINITIALISED){
  834. WORD wVersionRequested;
  835. WSADATA wsaData;
  836. wVersionRequested = MAKEWORD( 1, 1);
  837. if(WSAStartup( wVersionRequested, &wsaData )!=0) return FALSE;
  838. if(gethostname(szBuff, 79))
  839. {
  840. return FALSE;
  841. }
  842. h=gethostbyname(szBuff);
  843. *netp=((h->h_addr_list[0][0]<<24))+
  844. ((h->h_addr_list[0][1]<<16))+
  845. ((h->h_addr_list[0][2]<<8))+
  846. ((h->h_addr_list[0][3]));
  847. if (((*netp)&0x80000000)==0) *maskp=0xFF000000;
  848. else if (((*netp)&0xC0000000)==0x80000000) *maskp=0xFFFF0000;
  849. else if (((*netp)&0xE0000000)==0xC0000000) *maskp=0xFFFFFF00;
  850. else return FALSE;
  851. (*netp)&=*maskp;
  852. return TRUE;
  853. }
  854. else
  855. {
  856. return FALSE;
  857. }
  858. }
  859. h=gethostbyname(szBuff);
  860. *netp=((h->h_addr_list[0][0]<<24))+
  861. ((h->h_addr_list[0][1]<<16))+
  862. ((h->h_addr_list[0][2]<<8))+
  863. ((h->h_addr_list[0][3]));
  864. if (((*netp)&0x80000000)==0) *maskp=0xFF000000;
  865. else if (((*netp)&0xC0000000)==0x80000000) *maskp=0xFFFF0000;
  866. else if (((*netp)&0xE0000000)==0xC0000000) *maskp=0xFFFFFF00;
  867. else return FALSE;
  868. (*netp)&=*maskp;
  869. return TRUE;
  870. }
  871. //---------------------------------------------------------------------------
  872. /* Convert a ASCII dotted-quad to a 32-bit IP address.
  873. Doesn't check to make sure it's valid. */
  874. ULONG inet_addrU(const char *cp)
  875. {
  876. ULONG val, part;
  877. WCHAR c;
  878. int i;
  879. val = 0;
  880. for (i = 0; i < 4; i++) {
  881. part = 0;
  882. while ((c = *cp++) != '\0' && c != '.' && c != ',') {
  883. if (c < '0' || c > '9')
  884. return -1;
  885. part = part*10 + (c - '0');
  886. }
  887. if (part > 255)
  888. return -1;
  889. val = val | (part << i*8);
  890. if (i == 3) {
  891. if (c != '\0' && c != ',')
  892. return -1; // extra gunk at end of string
  893. } else {
  894. if (c == '\0' || c == ',')
  895. return -1; // string ends early
  896. }
  897. }
  898. return val;
  899. }
  900. //---------------------------------------------------------------------------
  901. BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterName, npf_if_addr* buffer, PLONG NEntries)
  902. {
  903. HKEY InterfaceKey,CycleKey,NdisKey;
  904. LONG status;
  905. TCHAR String[1024+1];
  906. DWORD RegType;
  907. ULONG BufLen;
  908. struct sockaddr_in *TmpAddr, *TmpBroad;
  909. LONG naddrs,nmasks;
  910. ULONG StringPos;
  911. char CurAdapName[256];
  912. char NdisName[256];
  913. ULONG IIndex;
  914. ULONG Result;
  915. // Reach the class\net registry key
  916. status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\class\\net",0,KEY_READ,&InterfaceKey);
  917. if (status != ERROR_SUCCESS) return FALSE;
  918. // Scan the subkeys to determine the index of the current adapter
  919. IIndex=0;
  920. while((Result=RegEnumKey(InterfaceKey,IIndex,NdisName,sizeof NdisName))==ERROR_SUCCESS)
  921. {
  922. status=RegOpenKeyEx(InterfaceKey,NdisName,0,KEY_READ,&CycleKey);
  923. status=RegOpenKeyEx(CycleKey,"NDIS",0,KEY_READ,&NdisKey);
  924. BufLen=256;
  925. status=RegQueryValueEx(NdisKey,"LOGDRIVERNAME",NULL,NULL,CurAdapName,&BufLen);
  926. RegCloseKey(CycleKey);
  927. RegCloseKey(NdisKey);
  928. if(!strcmp(AdapterName, CurAdapName))
  929. break;
  930. IIndex++;
  931. }
  932. RegCloseKey(InterfaceKey);
  933. // Reach the Enum\Network\MSTCP registry key and open the key at position IIndex
  934. status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Enum\\Network\\MSTCP",0,KEY_READ,&InterfaceKey);
  935. status=RegEnumKey(InterfaceKey,IIndex,NdisName,sizeof NdisName);
  936. status=RegOpenKeyEx(InterfaceKey,NdisName,0,KEY_READ,&CycleKey);
  937. if (status != ERROR_SUCCESS) return FALSE;
  938. BufLen=sizeof NdisName;
  939. status=RegQueryValueEx(CycleKey,"Driver",NULL,NULL,NdisName,&BufLen);
  940. RegCloseKey(InterfaceKey);
  941. RegCloseKey(CycleKey);
  942. // Now go to the just obtained NetTrans Entry
  943. status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\class",0,KEY_READ,&InterfaceKey);
  944. status=RegOpenKeyEx(InterfaceKey,NdisName,0,KEY_READ,&CycleKey);
  945. if (status != ERROR_SUCCESS) return FALSE;
  946. BufLen = sizeof String;
  947. // Open the key with the addresses
  948. status = RegQueryValueEx(CycleKey,"IPAddress",NULL,&RegType,String,&BufLen);
  949. if (status != ERROR_SUCCESS){
  950. RegCloseKey(InterfaceKey);
  951. RegCloseKey(CycleKey);
  952. return FALSE;
  953. }
  954. // scan the key to obtain the addresses
  955. StringPos = 0;
  956. for(naddrs = 0;naddrs < *NEntries;naddrs++){
  957. TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
  958. if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
  959. TmpAddr->sin_family = AF_INET;
  960. TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
  961. TmpBroad->sin_family = AF_INET;
  962. // Don't know where to find the broadcast adrr under Win9x, default to 255.255.255.255
  963. TmpBroad->sin_addr.S_un.S_addr = 0xffffffff;
  964. while(*(String + StringPos) != '\0' && *(String + StringPos) != ',')StringPos++;
  965. StringPos++;
  966. if(*(String + StringPos) == 0 || StringPos >= BufLen)
  967. break;
  968. }
  969. else break;
  970. }
  971. BufLen = sizeof String;
  972. // Open the key with the addresses
  973. status = RegQueryValueEx(CycleKey,"IPMask",NULL,&RegType,String,&BufLen);
  974. if (status != ERROR_SUCCESS){
  975. RegCloseKey(InterfaceKey);
  976. RegCloseKey(CycleKey);
  977. return FALSE;
  978. }
  979. // scan the key to obtain the masks
  980. StringPos = 0;
  981. for(nmasks = 0;nmasks <* NEntries;nmasks++){
  982. TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
  983. if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
  984. TmpAddr->sin_family = AF_INET;
  985. while(*(String + StringPos) != '\0' && *(String + StringPos) != ',')StringPos++;
  986. StringPos++;
  987. if(*(String + StringPos) == 0 || StringPos >= BufLen)
  988. break;
  989. }
  990. else break;
  991. }
  992. RegCloseKey(InterfaceKey);
  993. RegCloseKey(CycleKey);
  994. // The number of masks MUST be equal to the number of adresses
  995. if(nmasks != naddrs){
  996. return FALSE;
  997. }
  998. *NEntries = naddrs + 1;
  999. return TRUE;
  1000. }
  1001. // not supported in Win9x
  1002. BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len)
  1003. {
  1004. return FALSE;
  1005. }
  1006. // not supported in Win9x
  1007. BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks)
  1008. {
  1009. return FALSE;
  1010. }
  1011. // not supported in Win9x
  1012. BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync)
  1013. {
  1014. return FALSE;
  1015. }
  1016. // not supported in Win9x
  1017. BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior)
  1018. {
  1019. return FALSE;
  1020. }
  1021. // not supported in Win9x
  1022. PAirpcapHandle PacketGetAirPcapHandle(LPADAPTER AdapterObject)
  1023. {
  1024. return NULL;
  1025. }
  1026. //---------------------------------------------------------------------------
  1027. #ifdef __cplusplus
  1028. }
  1029. #endif