Pax be upon packets
System and network programming can be a magical mystery tour de force across several APIs and tools. Pax aspires to be your peaceful gesture at complexity, and seeks to facilitate prototype development.
Pax provides a library and runtime support that wrap underlying wrappers so you can quickly test prototypes of packet-processors written in high-level languages. More information can be found in our API documentation.
Various example implementations are included in this repo. Additional examples involving Pax show how to replay a pcap file on the network (recap) and an implementation of TCP (TCPuny).
Follow the instructions in BUILD.md. We've tested Pax on OSX and different versions of Ubuntu Linux, but it shouldn't be hard to get it running wherever .NET runs.
Packet processers using Pax can be written in any .NET language. They use Pax's API and define one or more functions that handle incoming packets. Semantic versioning is used for Pax, to facilitate checking whether a given version of a packet processor should run on a given version of Pax. The examples included with Pax could help get you going. The workflow is as follows:
- Write your packet processors and use a .NET compiler to produce a DLL. Your DLL may contain multiple packet processors -- it is the configuration file that specifies which processor you wish you bind with which network interface.
- Write a configuration file (or scheme) for your packet processor. This specifies all parameters to your packet processor, including which specific network interfaces that are bound to logical ports. Configuration in Pax is JSON-encoded.
- Run Pax, indicating your configuration and DLL.
The configuration file "wires up" the network interfaces with packet processors in your assembly. Not all packet processors in your assembly need be connected, and different network interfaces may be connected to the same handler. The drawing example shows an assembly with four packet processors, only two of which is used. The blue processor handles packets coming on network port 0. The configuration file determines which processors handle traffic coming on which network interface.
Simply run Pax.exe --config=CONFIGURATION_FILENAME --code=ASSEMBLY_FILENAME
.
For more on command-line switches, run Pax.exe --help
.
Probably you'd have to run this command with root/administrator-level access
because of the privileged access to hardware that's used while Pax is running.
For the example code I run:
sudo ./Bin/Pax.exe --config=examples/wiring.json --code=examples/Bin/Examples.dll
This runs the Printer element, which simply prints an integer whenever a particular kind of packet arrives on an interface. For another element we use for debugging, try:
sudo ./Bin/Pax.exe --config=examples/tallyer_wiring.json --code=examples/Bin/Examples.dll
Pax then starts up and checks the configuration file and assembly, listing some of their contents. It connects the network interfaces with the handlers in the assembly, as specified in the configuration. Then Pax activates the handlers, and your code takes it from there.
Pax is licensed under Apache 2.0. Mono.Options is licensed as described in its header.
- Project NaaS and its funder (EPSRC).
- Colleagues at NetOS.
- Contributors to PacketDotNet, SharpPcap, Newtonsoft.JSON, libpcap and winpcap, Mono.Options.
Try using Pax to implement prototypes of the following:
- Protocol conversion (e.g., IPv4 <-> IPv6)
- DPI
- Load balancer (see these descriptions from the HAProxy and NGINX sites for ideas)
- Datagram-based servers, e.g., DNS.
- Firewall
- Router
If you're interested in what Pax does, you might be interested in these other systems: