I am not releasing source code for anything else anytime soon. I will share snippets where it makes sense, but not the whole project. Like I have said before, it is not ready. (Although I am feeling quite good about it after the last test I ran.)
This thread is for announcing the availability of the sample code to drive a packet driver in C. It should be easily ported to other C variants, or if somebody wants to do a little more work Pascal should be possible.
Besides the actual calls to the packet driver interface, the slightly tricky code to handle incoming packets asynchronously is there too. This code allocates room for twenty max-sized Ethernet packets (1514 bytes including the Ethernet frame header) and then uses a simple stack to manage the free buffers and a ring buffer to manage buffers that have been filled by the packet driver but not yet picked up and processed by the user code.
The code is very fast. The stack gives a quick way to see if a buffer is available for an incoming packet. The ring buffer keeps the incoming packets that have been accepted in order until the user processes them. The user has the option to 'hold onto' pointers to buffers for processing, and then put those buffers back into the free stack after they are done processing. This allows for the user to process an incoming packet without an expensive memory copy to copy the contents into their own buffer.
In my code at the TCP layer I do a memcopy into a user defined buffer. I've found that it is slower, but I put a higher priority on getting the incoming packet buffers back to the free list. For telnet-like traffic where there are lots of little packets this makes more sense rather than letting the end user hold the incoming buffer directly for long periods of time.
(UDP still does it the first way - the user processes the incoming packet directly.)
Also, note the complete absense of locks or mutexes. I have to disable interrupts for short periods of time when manipulating the ring buffer or free list, but that is about it. These data structures are shared between the packet driver and user code, so disabling the interrupts is required when in user space to prevent the packet driver from interrupting, trying to get a buffer, and catching something 'in between'. There might be a quicker way to do this by taking advantage of atomic operations, but this is good enough.
Anyway, that is some of the design philosophy of this code. I am sure that somebody can come up with something slightly more clever than can either improve performance or reduce memory consumption.