473,327 Members | 1,936 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,327 software developers and data experts.

Wrapping WinPCap

Hi,

I'm a bit of a novice at this but i'm running into a few problems
trying to wrap winpcap in C#. I know I can use a special socket flag
to pick up all packets across an interface but this solution needs to
work w/o an IP bound to the socket so winpcap is the only way to go
(and so I can get it working in mono). I have imported the following
functions.

[DllImport("wpcap.dll")]
public static unsafe extern IntPtr pcap_open_live(char* source, int
snaplen, int flags, int read_timeout, char* errbuf);

[DllImport("wpcap.dll")]
public static unsafe extern char* pcap_lookupdev(char* errbuff);

[DllImport("wpcap.dll")]
public static extern int pcap_next_ex(IntPtr p, ref pcap_pkthdr
pkt_header, StringBuilder pkt_data);

with the structs:

[StructLayout( LayoutKind.Sequential )]
public struct pcap_pkthdr
{
public timeval test;
public UInt32 caplen;
public UInt32 len;
}

[StructLayout( LayoutKind.Sequential )]
public struct timeval
{
public long tv_sec;
public long tv_usec;
}

The problem is twofold: first my pcap_pkthdr struct comes back all out
of whack (ie, everything is zero but tv_sec which is filled with a
huge garbage number. And the string returned seems to just be junk
(around five bytes worth). I am a floundering undergrad but this is my
first attempt at interop with unmanaged code and I was wondering if
anyone sees anything I'm doing. I sincerely appriciate any help anyone
can offer.

Respectfully,
CDT Shaun Baker
sh*********@usma.edu
Nov 16 '05 #1
8 2524
Hi,
inline

"Shaun Baker" <x4****@usma.edu> wrote in message
news:cc**************************@posting.google.c om...
Hi,

I'm a bit of a novice at this but i'm running into a few problems
trying to wrap winpcap in C#. I know I can use a special socket flag
to pick up all packets across an interface but this solution needs to
work w/o an IP bound to the socket so winpcap is the only way to go
(and so I can get it working in mono). I have imported the following
functions.

[DllImport("wpcap.dll")]
public static unsafe extern IntPtr pcap_open_live(char* source, int
snaplen, int flags, int read_timeout, char* errbuf);
[DllImport("wpcap.dll", CharSet=CharSet.Ansi)]
public static extern IntPtr pcap_open_live(string source, int snaplen, int
flags, int read_timeout, StringBuffer errbuf);

Call like this:
const int PCAP_ERRBUF_SIZE = ...; // check the header files
StringBuilder errbuf = new StringBuilder(PCAP_ERRBUF_SIZE);
IntPtr handle = pcap_open_live (...,...,...,...,errbuf);
if (handle == IntPtr.Zero) Console.WriteLine( errbuf.ToString() );

[DllImport("wpcap.dll")]
public static unsafe extern char* pcap_lookupdev(char* errbuff);
[DllImport("wpcap.dll", CharSet=CharSet.Ansi)]
public static extern IntPtr pcap_lookupdev(StringBuilder errbuf);

Call like this:
StringBuilder errbuf = new StringBuilder(PCAP_ERRBUF_SIZE);
IntPtr pDev = pcap_lookupdev(errbuf);
string dev;
if (pDev != IntPtr.Zero) dev = Marshal.PtrToStringAnsi(pDev);
else Console.WriteLine ( errbuf.ToString() );

[DllImport("wpcap.dll")]
public static extern int pcap_next_ex(IntPtr p, ref pcap_pkthdr
pkt_header, StringBuilder pkt_data);
ref pcap_pkthdr means that the function can change it, but it doesn't want
to, it wants to set a pointer to a pcap_pkthdr. To be able to do that, give
a IntPtr as ref...

[DllImport("wpcap.dll")]
public static extern int pcap_next_ex(IntPtr handle, ref IntPtr pHeader, ref
IntPtr pData );

Call like this:
IntPtr pHeader = IntPtr.Zero; // pointer to header, will be set by function
IntPtr pData = IntPtr.Zero; // pointer will be set by function

int ret = pcap_next_ex( handle, ref pHeader, ref pData );
byte [] data;
pcap_pkthdr header;
if ( ret >=0 )
{
// copy structure pointed by pHeader to managed structure
Marshal.PtrToStruct ( pHeader, header );

// copy data pointed by pData to managed byte array
data = new byte[ header.len ];
Marshal.Copy ( pData, data, 0, header.len );
}

with the structs:

[StructLayout( LayoutKind.Sequential )]
public struct pcap_pkthdr
{
public timeval test;
public uint caplen;
public uint len;
}

long in c = int in c# (32bits)
[StructLayout( LayoutKind.Sequential )]
public struct timeval
{
public long tv_sec; should be public int tv_sec;
public long tv_usec; should be public int tv_usec;
}
HTH,
greetings

The problem is twofold: first my pcap_pkthdr struct comes back all out
of whack (ie, everything is zero but tv_sec which is filled with a
huge garbage number. And the string returned seems to just be junk
(around five bytes worth). I am a floundering undergrad but this is my
first attempt at interop with unmanaged code and I was wondering if
anyone sees anything I'm doing. I sincerely appriciate any help anyone
can offer.

Respectfully,
CDT Shaun Baker
sh*********@usma.edu


Nov 16 '05 #2
BMermuys

Thank you for your help, that short amount of code really did teach me a lot of what I was doing adn what I was doing wrong. My biggest source of confusion was the pkt_hdr** passing. I thought I needed to declare the pkt_hdr and I didn't quite realize that the function did the malloc'ing for me. Other than a inspection of the code, should the fact that it wanted a pointer to a pointer tip me off that it was going to handle the allocation and instantiation of the actual datastructure? I would assume otherwise it would just request a pointer to it instead of a pointer-to-a-pointer. Thank you for your time, the long time in ada,c# and java has really rustied up my C skills

Respectfully
Shaun Baker
Nov 16 '05 #3
Hi,

"Shaun Baker" <an*******@discussions.microsoft.com> wrote in message
news:A1**********************************@microsof t.com...

Thank you for your help, that short amount of code really did teach me a lot of what I was doing adn what I was doing wrong. My biggest source of confusionwas the pkt_hdr** passing. I thought I needed to declare the pkt_hdr and I
didn't quite realize that the function did the malloc'ing for me. Other than ainspection of the code, should the fact that it wanted a pointer to a pointer tipme off that it was going to handle the allocation and instantiation of the
actual datastructure?
Yes. But the best way to know is looking at c examples that use pcap
functions. The problem with signatures like pkt_hdr** is that you still
don't know who owns the memory. In case of pcap it seems that pcap always
owns the memory hence we don't free memory ourselfs...
I would assume otherwise it would just request a pointer
to it instead of a pointer-to-a-pointer. Thank you for your time, the long timein ada,c# and java has really rustied up my C skills.
Funny you mention java, because the first prototype I gave, there is a
stringbuffer which ofcourse should be a stringbuilder :)

hth,
greetings

Respectfully,
Shaun Baker

Nov 16 '05 #4
Thank you very much for your help. I got it working perfectly now. I just wanted to post a few changes that I did to get it working just in case someone has the same problem and is reading this post later.

1. Stringbuffer = StringBuilde
2. In the usage of pcap_next_ex, to convert the pHeader IntPtr to a usable instance of a header I had to use the object = Marshal.PtrToStructure(IntPtr,Type) call or I would receiver a value type exception, by doing Pcap_PktHeader header = (Pcap_PktHeader)Marshal.PtrToStructure(pHeader,typ eof(Pcap_PktHeader)); this problem went away
3. When using pcap_lookupdev(...), when trying to use Marshal.PtrToAnsiString, I kept getting a bad dev string b/c after each letter it had a '\0' null character in the middle, very odd and I'm not sure why that happened. Insetad I just passed the returned pointer to pcap_open_live cal

Thank you agian for your help

Respectfully
Shaun Baker
Nov 16 '05 #5
I promise this is my last question but when i try and do the pcap_loop (pcap_next_ex works great) it will work a couple times and then return with an "object reference not set to an instance" exception.

I have defined the pcap_loop function as

[DllImport("wpcap.dll",CharSet=CharSet.Ansi)
public static extern void pcap_loop(IntPtr p, int cnt,pcap_callback theCallback, StringBuilder user)

where the original wa
int pcap_loop (pcap_t *p, int cnt, pcap_handler callback, u_char *user)

and my callback pcap_handler is
public delegate void pcap_callback(IntPtr user, IntPtr pkt_header, IntPtr pkt_data)

where the original wa
typedef void(* pcap_handler )(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)

I tried to use StringBuilder instead of IntPtr but the pkt_data that I got back (when I got it didn't crash, was just a null reference), so I changed the u_char* to IntPtr and the allocate a byte array of header.len size and convert that to a string. I can't seem to figure out why it would work sometimes, it almost seems as if it's randomly screwing up the callback pointer. Thank you very much for the continued help, I am learning quite a bit about how this all works

Respectfully
CDT Shaun Bake
Nov 16 '05 #6
Hi,

"Shaun Baker" <an*******@discussions.microsoft.com> wrote in message
news:88**********************************@microsof t.com...
Thank you very much for your help. I got it working perfectly now. I just wanted to post a few changes that I did to get it working just in case
someone has the same problem and is reading this post later.
1. Stringbuffer = StringBuilder yes, I think it's java that's got a stringbuffer
2. In the usage of pcap_next_ex, to convert the pHeader IntPtr to a usable instance of a header I had to use the object =
Marshal.PtrToStructure(IntPtr,Type) call or I would receiver a value type
exception, by doing Pcap_PktHeader header =
(Pcap_PktHeader)Marshal.PtrToStructure(pHeader,typ eof(Pcap_PktHeader)); this
problem went away.
3. When using pcap_lookupdev(...), when trying to use Marshal.PtrToAnsiString, I kept getting a bad dev string b/c after each
letter it had a '\0' null character in the middle, very odd and I'm not sure
why that happened. Insetad I just passed the returned pointer to
pcap_open_live call

If there is a \0 after each character then this would indicate the string is
unicode. Try using PtrToStringUni, nevertheless it might be a good idea to
pass the pointer you got from open_live to lookup_dev.

Thank you agian for your help.
Glad I could help,
greetings


Respectfully,
Shaun Baker

Nov 16 '05 #7
Hi,
inline

"Shaun Baker" <an*******@discussions.microsoft.com> wrote in message
news:ED**********************************@microsof t.com...
I promise this is my last question but when i try and
You may ask as much as you want. Offcourse we won't always be able to help.
And it's a good idea to search google newsgroup archive first.
do the pcap_loop (pcap_next_ex works great) it will work a couple times
and then return with an "object reference not set to an instance" exception.
I have defined the pcap_loop function as:

[DllImport("wpcap.dll",CharSet=CharSet.Ansi)]
public static extern void pcap_loop(IntPtr p, int cnt,pcap_callback theCallback, StringBuilder user);
where the original was
int pcap_loop (pcap_t *p, int cnt, pcap_handler callback, u_char *user)

and my callback pcap_handler is:
public delegate void pcap_callback(IntPtr user, IntPtr pkt_header, IntPtr pkt_data);
where the original was
typedef void(* pcap_handler )(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
I tried to use StringBuilder instead of IntPtr but the pkt_data that I got back(when I >got it didn't crash, was just a null reference), so I changed the
You should use an IntPtr because the framework has no idea that the size of
the data is inside header.len. It can't pin or copy by itself.
u_char* to IntPtr and the allocate a byte array of header.len size and convertthat to a string. I can't seem to figure out why it would work sometimes, it almostseems as if it's randomly screwing up the callback pointer. Thank you very muchfor the continued help, I am learning quite a bit about how this all works.
You don't tell us how you use the pcap_loop function. The only reason I
know this could happen is because you create a delegate instance inside the
function call. The managed code should keep a reference otherwise the GC
will cleanup the delegate instance...

pcap_loop (...., ..., new pcap_callback(...), ...); // bad

// pcap_callback_del would be a class variable or static variable
pcap_callback_del = new pcap_callback(...);
pcap_loop (...,..., pcap_callback_del, ..., ..);

HTH,
greetings

Respectfully,
CDT Shaun Baker

Nov 16 '05 #8
You called it, I should have realized that when I realized it when the pointer was getting seemingly 'lost'. Thank you again for everything. Have a nice night, look forward to being able to field answers to these types of questions one day.
Nov 16 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

13
by: Roy Smith | last post by:
I've got a C library with about 50 calls in it that I want to wrap in Python. I know I could use some tool like SWIG, but that will give me a too-literal translation; I want to make some...
11
by: yawnmoth | last post by:
word wrapping normally treats some spaces as line feeds, if there hasn't been a line feed for quite a while. so while a string with eighty consecutive a's might not word wrap, a space placed...
0
by: Leszek | last post by:
Hi All! I am developing WinPCap 3.1 wrapper in C# and I have a problem with capturing packets with callback function. Here is some code: Declarations: //C definition:
5
by: nimdez | last post by:
Hi, I am working on an existing code base in which a lot of data displayed to the user is formatted in tables. Most tables are printed row-by-row using printf() with "%s" print conversion...
8
by: Shaun Baker | last post by:
Hi, I'm a bit of a novice at this but i'm running into a few problems trying to wrap winpcap in C#. I know I can use a special socket flag to pick up all packets across an interface but this...
2
by: Nuno Magalhaes | last post by:
Hello all, Below I have a function that captures a packet and sends that packet to a Receive function (wether it is sent or received). I'm asking what functions should I use (what imports...
3
by: Nuno Magalhaes | last post by:
How can I use WinPcap or PacketX.dll to catch any packets that flow on my machine network adapter? Is there any sample code on how to do this? I would like something like this... and without...
8
by: Nathan | last post by:
I am trying to prevent a horizontal list from wrapping. Each list item is floated with "float: left". Currently I use an ugly hack. I set the width of the list to a large number which is...
5
by: exman | last post by:
Hi ! i have a problem related to winpcap, i'm curretly making a sniffer aplication for my studies. I want to accomplish this http://www.winpcap.org/docs/man/html/group__wpcap__tut3.html but in...
1
by: Ken Fine | last post by:
I have been investigating programmatically downloading FLV content from various sites ("video scraping"??) Many interactive GUI tools do this, such as the Orbit downloader. At the heart of them...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.