Showing posts with label CLR. Show all posts
Showing posts with label CLR. Show all posts

Wednesday, April 10, 2013

PCAP-NG reader for .NET.

Introduction & Scope

The PCAP-NG file format is used to store network captured data used by great programs like Wireshark. There are several API's available for both Linux and Windows but none that are ported to .NET. I decided to make one for my own use in building a network traffic replay agent.

This code demonstrates an approach to reading in PCAP-NG files. Most of the time I was concerned with the enhanced packet block type since it stored the TCP payloads I wanted to replay.

Design Considerations

All block types derive from a common abstract class (BlockBase). This is useful when you need a collection of blocks with different subtypes, as in the second code segments below. Internally, all classes populate themselves from the underlying binary reader.

The reader class can be used to iterate over a single block type.

var reader = new PcapngFile.Reader("test.pcapng");   
foreach (var packet in reader.EnhancedPackets)
{
   byte[] payload = packet.Data;
}

... or all of them, cast into their parent type.

var blocks = new List<PcapngFile.BlockBase>();
while (reader.PeekStoreType() != PcapngFile.BlockType.None)
{
   blocks.Add(reader.ReadBlock());
}

The Code and NuGet Package

Get access to the complete project here on my GitHub account. If you have any suggestions or comments, feel free to leave a comment. I also have the assembly available via NuGet here.

More Reading & Resources

Friday, July 29, 2011

Reentrant lock acquires in CLR.

I always like when a post gets to the point (especially after searching in Google). In short, if you perform an operation that waits to acquire a lock, the thread doesn't actually stop.

In concrete terms of .NET coding, if you call the WaitOne method on a thread, it may still process events that the CLR deems "high priority". This can be a big problem if the event handlers go into the critical region you are trying to protect.

int criticalRegion = 0;

private void criticalRegionWait() 
{
   AutoResetEvent are = new AutoResetEvent(false);
   Thread thread = new Thread(() => 
      { 
         criticalRegion = -1
         Debug.WriteLine(criticalRegion);
         are.Set();
      });
   thread.SetApartmentState(ApartmentState.STA);
   thread.IsBackground = true;
   thread.Start();
}

private void criticalRegionUpdateEvent(object sender, EventArgs e) 
{
   criticalRegion = 1;
}
In the above example, if there is a high priority event that has criticalRegionUpdateEvent in its call path a race condition is possible. While criticalRegionWait waits for the thread to finish, the criticalRegionUpdateEvent has a chance of setting criticalRegion = 1 so that WriteLine ends up printing 1 instead of -1.