By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
431,852 Members | 2,152 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 431,852 IT Pros & Developers. It's quick & easy.

IntPtr, Unmanaged DLL, and File IO???? Need Network Understanding

P: 2
Hello, I am working with developing an application that uses the Netmon 3.2 API. Currently they have a PInvoke wrapper to access unmanaged C++ DLL functions.

Basically what I am attempting to do is rewrite an example application (written in C++ and provided in their documentation) in C#. Everything compiles fine and executes, but I have no .cap file at the end of the run. Some things that may be wrong: the ADAPTER_INDEX is not correct OR the IntPtr associated with the capture file is not getting passed correctly. Interesting note: when I set a breakpoint in the callback function the program never enters this block (which it should leading me to suspect the ADAPTER_INDEX)

Here is my code:

Expand|Select|Wrap|Line Numbers
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using Microsoft.Protocols.TestTools.Netmon.API;
  7. using System.Windows.Forms;
  8. using System.Threading;
  9. using System.Runtime.InteropServices;
  10. using System.IO;
  11.  
  12.  
  13. namespace Network_Monitor_Demo
  14. {
  15.     public struct Constants
  16.     {
  17.         public static UInt32 ADAPTER_INDEX = 0;
  18.     }
  19.  
  20.     public class Netmon
  21.     {
  22.  
  23.         public Netmon()
  24.         {
  25.  
  26.            uint ret;
  27.  
  28.  
  29.             //Open a capture file for saving frames.
  30.            string path = @"C:\\Capture\\10sec.cap";
  31.  
  32.             IntPtr myCapFile;
  33.             uint CapSize;
  34.             ret = NetmonAPI.NmCreateCaptureFile(path, 20000000, NmCaptureFileFlag.WrapAround, out myCapFile, out CapSize);
  35.             if (ret != 0)
  36.             {
  37.                 MessageBox.Show("Error Opening Capture File" + "10sec.cap");
  38.                 return;
  39.             }
  40.  
  41.             //Open the capture engine
  42.             IntPtr myCaptureEngine;
  43.             ret = NetmonAPI.NmOpenCaptureEngine(out myCaptureEngine);
  44.  
  45.             if (ret != 0)
  46.             {
  47.                 MessageBox.Show("Error opening capture engine.");
  48.                 NetmonAPI.NmCloseHandle(myCapFile);
  49.                 return;
  50.  
  51.             }
  52.  
  53.             ret = NetmonAPI.NmConfigAdapter(myCaptureEngine, Constants.ADAPTER_INDEX, new CaptureCallbackDelegate(FrameIndicationCallback), myCapFile, NmCaptureCallbackExitMode.ReturnRemainFrames);
  54.  
  55.             if (ret != 0)
  56.             {
  57.                 MessageBox.Show("Error configuration adapter.");
  58.                 NetmonAPI.NmCloseHandle(myCaptureEngine);
  59.                 NetmonAPI.NmCloseHandle(myCapFile);
  60.  
  61.                 return;
  62.             }
  63.  
  64.             MessageBox.Show("Capturing for 10 seconds.");
  65.             NetmonAPI.NmStartCapture(myCaptureEngine, Constants.ADAPTER_INDEX, NmCaptureMode.Promiscuous);
  66.  
  67.  
  68.  
  69.             Thread.Sleep(10000);
  70.  
  71.  
  72.             MessageBox.Show("Stopping Capture.");
  73.             NetmonAPI.NmStopCapture(myCaptureEngine, Constants.ADAPTER_INDEX);
  74.             NetmonAPI.NmCloseHandle(myCaptureEngine);
  75.             NetmonAPI.NmCloseHandle(myCapFile);
  76.  
  77.             return;
  78.  
  79.         }
  80.  
  81.  
  82.         public void FrameIndicationCallback(IntPtr hCapEng, UInt32 ulAdatIdx, IntPtr pContext, IntPtr hRawFrame)
  83.         {
  84.             IntPtr capFile = pContext;
  85.             NetmonAPI.NmAddFrame(capFile, hRawFrame);
  86.         }
  87.  
  88.     }
  89. }
  90.  
  91.  

And here is the code provided in the Network Monitor API documentation, doing the same thing in C++. Network Monitor 3.2 is a free download from Microsoft Downloads.


Expand|Select|Wrap|Line Numbers
  1. #include "windows.h"
  2. #include "stdio.h"
  3. #include "stdlib.h"
  4. #include "objbase.h"
  5. #include "ntddndis.h"
  6. #include "NMApi.h"
  7.  
  8. #define ADAPTER_INDEX    0
  9.  
  10. void __stdcall 
  11. MyFrameIndication(HANDLE hCapEng, ULONG ulAdaptIdx, PVOID pContext, HANDLE hRawFrame)
  12. {
  13.     HANDLE capFile = (HANDLE)pContext;
  14.     NmAddFrame(capFile, hRawFrame);
  15. }
  16.  
  17. int __cdecl wmain(int argc, WCHAR* argv[])
  18. {
  19.     ULONG ret;
  20.  
  21.     // Open a capture file for saving frames.
  22.     HANDLE myCapFile;
  23.     ULONG CapSize;
  24.     ret = NmCreateCaptureFile(L"20sec.cap", 20000000, NmCaptureFileWrapAround, &myCapFile, &CapSize);
  25.     if(ret != ERROR_SUCCESS)
  26.     {
  27.         wprintf(L"Error opening capture file, 0x%X\n", ret);
  28.         return ret;
  29.     }
  30.  
  31.     // Open the capture engine.
  32.     HANDLE myCaptureEngine;
  33.     ret = NmOpenCaptureEngine(&myCaptureEngine);
  34.     if(ret != ERROR_SUCCESS)
  35.     {
  36.         wprintf(L"Error opening capture engine, 0x%X\n", ret);
  37.         NmCloseHandle(myCapFile);
  38.         return ret;
  39.     }
  40.  
  41.     ret = NmConfigAdapter(myCaptureEngine, ADAPTER_INDEX, MyFrameIndication, myCapFile);
  42.     if(ret != ERROR_SUCCESS)
  43.     {
  44.         wprintf(L"Error configuration adapter, 0x%X\n", ret);
  45.         NmCloseHandle(myCaptureEngine);
  46.         NmCloseHandle(myCapFile);
  47.         return ret;
  48.     }
  49.  
  50.     wprintf(L"Capturing for 20 seconds\n");
  51.     NmStartCapture(myCaptureEngine, ADAPTER_INDEX, NmLocalOnly);
  52.  
  53.     Sleep(20000);
  54.  
  55.     wprintf(L"Stopping capture\n");
  56.     NmStopCapture(myCaptureEngine, ADAPTER_INDEX);
  57.     NmCloseHandle(myCaptureEngine);
  58.     NmCloseHandle(myCapFile);
  59.  
  60.     return 0;
  61. }
  62.  
  63.  
  64.  
Dec 21 '08 #1
Share this Question
Share on Google+
4 Replies


Plater
Expert 5K+
P: 7,872
I can't say for sure if it matters or not, but have you considered moving the code out of the constructor and into a function?
It might behave a little nicer.

Also, your adapter index is always 0, are you sure that is not the loopback adapter?
Dec 22 '08 #2

nukefusion
Expert 100+
P: 221
Additionally, have you installed WDK? According to the NetMon documentation this is a prerequisite to successfully use the code sample you've posted.

I'd also double check the following line from your code that differs from the NetMon sample:

Expand|Select|Wrap|Line Numbers
  1. NetmonAPI.NmStartCapture(myCaptureEngine, Constants.ADAPTER_INDEX, NmCaptureMode.Promiscuous);
  2.  
I imagine you'd need to make sure your network card supports promiscuous mode (many do not) and, if it does, put it into promiscuous mode somehow before starting the capture.
Dec 22 '08 #3

Plater
Expert 5K+
P: 7,872
promiscuous mode really only matters if you have an older network structure.
A newer-switch will not route traffic down your port if it shouldn't go to you, so promiscuous mode doesn't buy you much.
Hubs will. And I *believe* older switches might.

I had a wireless card that supported promiscuous mode (they corrected it later) so I could watch every other wireless card's traffic. It was especially fun when I disconnected from an endpoint and was able to pick up multiple endpoint's traffic.
Dec 22 '08 #4

P: 2
Thanks guys for your help. It was the Adapter Index, my wireless card was adapter 3. So I had to implement a method for enumerating and finding the active internet connections adapter and using that index.

The sad thing was I only tested adapters 0 1 and 2 before I posted.... hahhah.

Well thanks again!
Dec 22 '08 #5

Post your reply

Sign in to post your reply or Sign up for a free account.