Purely out of boredom (even though I have plenty of homework to do) I decided to hack out a managed wrapper around libpcap. Though it’s only a few hours later, the implementation is complete enough to read packets off the wire. Here is a quick example of how it could be used:
using System; using PcapSharp; public class MainClass { public static void Main(string[] args) { Console.WriteLine("Using {0}", Pcap.LibraryVersion); PcapHandle handle = Pcap.OpenLive("eth2", short.MaxValue, true, 5000); handle.Loop(-1, delegate(Packet p) { Console.WriteLine("At {0}, recieved a {1}-byte packet.", p.Time, p.RealLength); Console.Write(" The first five bytes are:"); for (int i = 0; i < 5; i++) Console.Write(" {0}", p[i]); Console.WriteLine(); }); } }
Which does something like this:
# ./pcaptest.exe Using libpcap version 0.9.5 At 2/27/2007 9:26:49 AM, recieved a 60-byte packet. The first five bytes are: 255 255 255 255 255 At 2/27/2007 9:26:49 AM, recieved a 60-byte packet. The first five bytes are: 255 255 255 255 255 At 2/27/2007 9:26:49 AM, recieved a 60-byte packet. The first five bytes are: 255 255 255 255 255 At 2/27/2007 9:26:49 AM, recieved a 60-byte packet. The first five bytes are: 255 255 255 255 255 At 2/27/2007 9:26:49 AM, recieved a 60-byte packet. The first five bytes are: 255 255 255 255 255 At 2/27/2007 9:26:50 AM, recieved a 243-byte packet. The first five bytes are: 255 255 255 255 255 At 2/27/2007 9:26:50 AM, recieved a 60-byte packet. The first five bytes are: 255 255 255 255 255 At 2/27/2007 9:26:50 AM, recieved a 60-byte packet. The first five bytes are: 255 255 255 255 255 At 2/27/2007 9:26:50 AM, recieved a 62-byte packet. The first five bytes are: 0 20 94 34 48 At 2/27/2007 9:26:50 AM, recieved a 60-byte packet. The first five bytes are: 255 255 255 255 255 At 2/27/2007 9:26:50 AM, recieved a 161-byte packet. The first five bytes are: 255 255 255 255 255 At 2/27/2007 9:26:50 AM, recieved a 60-byte packet. The first five bytes are: 255 255 255 255 255 At 2/27/2007 9:26:50 AM, recieved a 60-byte packet. The first five bytes are: 255 255 255 255 255 At 2/27/2007 9:26:51 AM, recieved a 60-byte packet. The first five bytes are: 255 255 255 255 255 At 2/27/2007 9:26:51 AM, recieved a 60-byte packet. The first five bytes are: 255 255 255 255 255 ...
The library is in my public Subversion repository (svn co https://layla.chrishowie.com/svn/pcap-sharp
) and is available under the terms of the MIT license.
hi, it is pretty good code and it seem to work. I have 2 questions:
1. Do you know how to get the device name? instead of writing “eth2”, I would like to get the device name as a pick from the list.
2. I also would like to use a while loop insted handle.loop routine. Do you know what is the best routine to use from your class structure? and also how do i use it in the main code?
If you can, please respond, I appreciate your code. I use multithread technique with my VC#program and your code is working properly. Thanx again for posting it!
To get a list of devices, call Pcap.FindAllDevices(). This returns an IList containing InterfaceDefinition objects that correspond to all available network interfaces.
You can use a while loop. PcapHandle.Dispatch() takes the same arguments as PcapHandle.Loop() but returns generally after one packet has been read. You can also use PcapHandle.ReadNext() to read exactly one packet and return it.
Note that both Dispatch and ReadNext (which uses Dispatch) if called many times seem to leak memory. I’m not sure where this is coming from, so keep your eyes on memory usage if you go this route.
Thanx for the quick response!!!, I am also trying to use pcap_next_ex function call instead of Read, ReadNext, and Dispatch, because of this memory leak. I have a sample code provided by WinPcap 4.0 development downlad in VC++ 6.0 and pcap_next_ex function seems to work pretty well. But in VC# after implementation of pcap_next_ex function, I don’t recieve any data, even though I don’t get the error that it would tell me that I defined the function wrong. Here is my function call that I am using:
int res = PcapCall.pcap_next_ex(this.ptr, ref header, pkt_data);
and the definition is:
[DllImport(PcapDll)]
internal static extern int pcap_next_ex(IntPtr p, ref PocketHeader header, string buf);
I am not sure, maybe I am defining it wrong, but the program will not give the error. Also I am using VC# in Visual Studio 2005.
If you get bored sometimes, could you look into that function? I am getting eager to resolve this problem. Basically I am trying to interrupt the data collection from ethernet with a click of a button from my application interface. Right now the “ethernet” routine runs in a different thread then the application itself, so I can easly click other buttons or what not while I am collecting the ethernet data, just the interruption of collecting that data gives me a problem. If you want I can send you the “.sln” file with other “.cs” files.
Thanx again for the previous response!
Yes, I understand that you can’t break the loop from another thread. pcap_breakloop for some reason breaks the loop after the next packet is received. Which makes it useless unless you’re on a pretty busy network.
The declaration you gave is insufficient unfortunately. This call is not quite as simple. For reference, the C declaration is:
int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, const u_char **pkt_data);
The closest we can get is:
[DllImport(PcapDll)]
internal static extern int pcap_next_ex(IntPtr p, out IntPtr header, out IntPtr buf);
Then we’d have to make a few calls to some Marshal methods to extract the data. Sit tight, I may have something in svn by the end of the day.
I’ve implemented this and committed it (r43). There is a sharp drop in CPU usage and the memory consumption is no longer growing out of control, but seems to be cleaning up after itself with no problems.
I had planned to do this eventually, but thanks for the motivation. I simply changed the implementation of PcapHandle.ReadNext() so you should be able to use that method just as you were using it.
I see your efforts but this is something that already exists,
SharpPcap
– http://www.tamirgal.com/home/dev.aspx?Item=SharpPcap
– http://www.codeproject.com/cs/internet/sharppcap.asp
Lucky_JL