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

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Uriel88
    New Member
    • Dec 2008
    • 2

    #1

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

    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:

    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Protocols.TestTools.Netmon.API;
    using System.Windows.Forms;
    using System.Threading;
    using System.Runtime.InteropServices;
    using System.IO;
    
    
    namespace Network_Monitor_Demo
    {
        public struct Constants
        {
            public static UInt32 ADAPTER_INDEX = 0;
        }
    
        public class Netmon
        {
    
            public Netmon()
            {
    
               uint ret;
    
    
                //Open a capture file for saving frames.
               string path = @"C:\\Capture\\10sec.cap";
                
                IntPtr myCapFile;
                uint CapSize;
                ret = NetmonAPI.NmCreateCaptureFile(path, 20000000, NmCaptureFileFlag.WrapAround, out myCapFile, out CapSize);
                if (ret != 0)
                {
                    MessageBox.Show("Error Opening Capture File" + "10sec.cap");
                    return;
                }
    
                //Open the capture engine
                IntPtr myCaptureEngine;
                ret = NetmonAPI.NmOpenCaptureEngine(out myCaptureEngine);
    
                if (ret != 0)
                {
                    MessageBox.Show("Error opening capture engine.");
                    NetmonAPI.NmCloseHandle(myCapFile);
                    return;
    
                }
    
                ret = NetmonAPI.NmConfigAdapter(myCaptureEngine, Constants.ADAPTER_INDEX, new CaptureCallbackDelegate(FrameIndicationCallback), myCapFile, NmCaptureCallbackExitMode.ReturnRemainFrames);
    
                if (ret != 0)
                {
                    MessageBox.Show("Error configuration adapter.");
                    NetmonAPI.NmCloseHandle(myCaptureEngine);
                    NetmonAPI.NmCloseHandle(myCapFile);
    
                    return;
                }
    
                MessageBox.Show("Capturing for 10 seconds.");
                NetmonAPI.NmStartCapture(myCaptureEngine, Constants.ADAPTER_INDEX, NmCaptureMode.Promiscuous);
    
    
    
                Thread.Sleep(10000);
    
    
                MessageBox.Show("Stopping Capture.");
                NetmonAPI.NmStopCapture(myCaptureEngine, Constants.ADAPTER_INDEX);
                NetmonAPI.NmCloseHandle(myCaptureEngine);
                NetmonAPI.NmCloseHandle(myCapFile);
    
                return;
    
            }
    
    
            public void FrameIndicationCallback(IntPtr hCapEng, UInt32 ulAdatIdx, IntPtr pContext, IntPtr hRawFrame)
            {
                IntPtr capFile = pContext;
                NetmonAPI.NmAddFrame(capFile, hRawFrame);
            }
    
        }
    }

    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.


    Code:
    #include "windows.h"
    #include "stdio.h"
    #include "stdlib.h"
    #include "objbase.h"
    #include "ntddndis.h"
    #include "NMApi.h"
    
    #define ADAPTER_INDEX    0
    
    void __stdcall 
    MyFrameIndication(HANDLE hCapEng, ULONG ulAdaptIdx, PVOID pContext, HANDLE hRawFrame)
    {
        HANDLE capFile = (HANDLE)pContext;
        NmAddFrame(capFile, hRawFrame);
    }
    
    int __cdecl wmain(int argc, WCHAR* argv[])
    {
        ULONG ret;
    
        // Open a capture file for saving frames.
        HANDLE myCapFile;
        ULONG CapSize;
        ret = NmCreateCaptureFile(L"20sec.cap", 20000000, NmCaptureFileWrapAround, &myCapFile, &CapSize);
        if(ret != ERROR_SUCCESS)
        {
            wprintf(L"Error opening capture file, 0x%X\n", ret);
            return ret;
        }
    
        // Open the capture engine.
        HANDLE myCaptureEngine;
        ret = NmOpenCaptureEngine(&myCaptureEngine);
        if(ret != ERROR_SUCCESS)
        {
            wprintf(L"Error opening capture engine, 0x%X\n", ret);
            NmCloseHandle(myCapFile);
            return ret;
        }
    
        ret = NmConfigAdapter(myCaptureEngine, ADAPTER_INDEX, MyFrameIndication, myCapFile);
        if(ret != ERROR_SUCCESS)
        {
            wprintf(L"Error configuration adapter, 0x%X\n", ret);
            NmCloseHandle(myCaptureEngine);
            NmCloseHandle(myCapFile);
            return ret;
        }
    
        wprintf(L"Capturing for 20 seconds\n");
        NmStartCapture(myCaptureEngine, ADAPTER_INDEX, NmLocalOnly);
    
        Sleep(20000);
    
        wprintf(L"Stopping capture\n");
        NmStopCapture(myCaptureEngine, ADAPTER_INDEX);
        NmCloseHandle(myCaptureEngine);
        NmCloseHandle(myCapFile);
    
        return 0;
    }
  • Plater
    Recognized Expert Expert
    • Apr 2007
    • 7872

    #2
    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?

    Comment

    • nukefusion
      Recognized Expert New Member
      • Mar 2008
      • 221

      #3
      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:

      Code:
      NetmonAPI.NmStartCapture(myCaptureEngine, Constants.ADAPTER_INDEX, NmCaptureMode.Promiscuous);
      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.

      Comment

      • Plater
        Recognized Expert Expert
        • Apr 2007
        • 7872

        #4
        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.

        Comment

        • Uriel88
          New Member
          • Dec 2008
          • 2

          #5
          Fixed

          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!

          Comment

          Working...