winpcap alternatives

Hi everybody,

I am developing a software to manage redundancy on a private network.
My main goal is to “manipulate” traffic in real-time, that is
adding/removing a suffix
to packets out-coming/incoming the PC. Windows Applications should not
even known of this “manipulation”.

Running a prototype software using *libpcap* and a virtual interface
(with *TUN/TAP*),
I noticed some performance limitation of libpcap (confirmed reading some
papers on this issues).
I am wondering if there were any alternatives to this library (free or
commercial).

I have already considered *pcausa/rawether* but the owner wrote me
that it is not suitable for these reasons:
“Rawether is based on a NDIS protocol driver. A NDIS protocol driver is
a peer to the host OS TCP/IP protocol driver. All incoming packets
ALWAYS are indicates to all peer NDIS protocol drivers. This is not good
for the implementation that you have in mind. In a product such as I
think you have in mind you want to be able to handle some packets
privately without the host OS seeing them. You would manipulate these
“private” packets is some way and reinject them into the network flow.
You can’t do this sort of manipulation with a NDIS protocol driver.”

On winpcap forum I read of *NetMon* and, now, I am worried that the
above “rawether” issues would apply even to NetMon.

Any help will be greatly appreciated,

thank you,

Giulio

I’m not sure I understand your requirements. You say you want to “manipulate” traffic, but libpcap & netmon are tools for packet inspection, not modification.

What OS are you targeting? When you are modifying the packets, is this at layer 2 or is it higher? (E.g., are you only modifying IP packets, or are you modifying ALL Ethernet packets?)

If you’re modifying Ethernet packets at layer-2, the best model is an NDIS LWF. The LWF will let you silently encapsulate/unencapsulate all the packets that pass through the system. The LWF will also allow you to disable any hardware offloads that are incompatible with your encapsulation. (E.g., if you are adding an extra header to the packet, you wouldn’t want the NIC to attempt to write the IP checksum field anymore, because the IP header is no longer in the usual place.)

Thank you for your accurate answer,

for the best clarity of intention we are implementing PRP, a layer 2 redundancy protocol,
and we already have a software for Linux that we are porting to Windows.

The software use libpcap for capturing RAW packets on the physical interface and a TUN/TAP to
create a virtual interface to which it forward the “manipulated” packets transparently.

To implement PRP (adding a suffix at level 2) and to mitigate libpcap+TUN/TAP performance issues, would you still suggest us to use NDIS LWF?

We prefer a solution without writing code for kernel space but only in user space, can we still use NDIS LWF?

Thanks anyway for the precious suggestion,

Giulio

I see, interesting. If you were *only* adding/removing a trailer from the packets, then a LWF would be the right way to go. However, my understanding is that for PRP, you’ll also want to get all packets cloned out onto two separate network interfaces.

When you’re talking about trying to join together two separate network interfaces, then you might want to use an NDIS MUX driver instead.

I am hesitant, because it sounds like you might prefer faster development time over maximum performance of the solution. (I’m guessing this because your other implementation round-tripped packets through usermode via libpcap.) In this case, you might be able to develop a solution faster if you build a LWF + protocol, since you can use an off-the-shelf protocol.

So here’s two alternatives:

  1. Use a MUX driver. This will have maximum performance and will integrate very cleanly into the Windows stack. However, MUX drivers are notoriously difficult to write. The final architecture will look like this:

[TCPIP]
|
[Your MUX]
/ \
[NIC0] [NIC1]

The advantage here is that TCPIP sees a single network interface, yet physically all packets go out two network ports. Your MUX can trivially append the PRP field to each packet’s payload. Your MUX also has the opportunity to eliminate duplicate frames from the receive path, so TCPIP gets a clean packet stream.

  1. Use a combination of LWF + protocol. This will probably be quicker to develop. The architecture looks like this:

[TCPIP] [Your protocol]
| |
[Your LWF] |
| |
[NIC0] [NIC1]

The behavior isn’t so clear from just the diagram, so let’s go over the behavior more carefully:
2.a. When NIC0 receives a packet, it goes through the LWF. The LWF strips the PRP footer and passes the packet along.
2.b. When NIC1 receives a packet, it is received to your protocol driver. The protocol shunts the packet to your LWF, and the LWF indicates the packet up to TCPIP again.
2.c. When TCPIP sends a packet, the LWF intercepts it and adds a PRP footer. The LWF sends the packet out to NIC0. The LWF also sends the packet over to your protocol driver, which sends the packet again on NIC1.

I would go with option #2 if you need a low-cost solution. Option #1 is the “industrial-strength” solution, and it’s also cleaner. (Even my crude ascii-art diagrams illustrate how much cleaner #1 is.)

You may be able to avoid writing kernel code, if you can find an off-the-shelf LWF that supports packet injection and interception from usermode. In that case, you can use either netmon or winpcap to capture & route traffic to your usermode app, and then use the injection LWF to re-inject the traffic onto the right stack. Any solution that goes to usermode for each packet, though, won’t scale very well, and I can’t really recommend for heavy production use.

Also note that there are several NDIS driver consultants who would be happy to sell you their expertise. This list is not to be used for commercial purposes, but you should be able to find them without spamming the list.

As Mr. Tippet has indicated, implementation of this scheme would be best
achieved in Windows as a 1:2 MUX (LBFO) style driver. This is in effect
the ‘edges’ of the services you are using in the other OS in that it:

  1. Binds as a protocol to the network segments that are the redundant pair.
  2. Exposes an upper-edge interface to the host that behaves as a single link
    (e.g. what you get from TUN).

Whether or not you want to process all the frames in UM is up to you (I
would most definitely *not* do this for this protocol but that is just me).

A 1:2 MUX that includes a Control Device via which packets can be shunted to
UM and injected when sent from UM is basically the equivalent of what you
are getting from libcap and tun for functionality.

Now you did not say if you wanted to the host to act as a DAN or act as some
sort of hybrid DAN/SAN thingy. I assume you want it to act as a DAN as that
makes the most sense.

So what you are trying build is actually not “make the host be a DAN” but
instead is more like an embedded RedBox on the system that makes the
‘virtual’ Ethernet link exposed to the host (the upper edge of the 1:2 MUX)
look like the link one would attach a SAN too on the non-redundant side of a
RedBox. This way of thinking of the problem will force you to also make
the solution work correctly for entities that might ‘bridge’ above your
virtual Ethernet link (like, say, a VM solution).

With good fortune, the list resident expert on building this sort of thing
outside of MSFT, Mr. Clawson, will point out what a challenge you have ahead
of you and offer you some council. Unless your project is for a competing
system whereby I guess you may have all the advice the list can offer.

Good Luck,
Dave Cattley

“However, MUX drivers are notoriously difficult to write.” This is an understatement for 1:2 MUX drivers, the 2:1 MUX driver is much easier as the MUX sample in the WDK shows. For the 1:N MUX, the most important part is the Notify Object (NO) that does all the bindings. Our NO is now larger in lines of code than the driver itself since we now support nodes with more than 2 NICs and the operator needs to configure the two NICs they want.

In the NT3.5 timeframe we developed our Honeywell Fault Tolorent Ethernet driver (FTE) as a 2:2 MUX which is very simple to implement. However, two ports are exposed to all applications meaning that two IP addresses are required. This configuration allows packets to be send/receive on either port with some packet manipulation.

We moved to the 1:2 MUX for Vista because some of our very large customers did not want to “waste” an IP address by the requirement on the 2:2 MUX needing two IP addresses… the 1:2 MUX only requires 1 IP address.

Larry C