Skip to content

Commit 20ed893

Browse files
authored
Merge pull request niksu#10 from niksu/pax_lite
Pax "lite" for targets with limited .NET support checked that tests still pass for NAT implementation by calling script by @TMVector as follows: `$ sudo ./examples/Nat/nat_topo.py --no-X test`
2 parents 77f0619 + 35599ff commit 20ed893

16 files changed

+284
-54
lines changed

ForwardingDecision.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
namespace Pax {
99

10+
// FIXME should there be a Lite version of this class? I think specifically
11+
// it would statically dimension the MultiPortForward's array, and
12+
// perhaps have it write directly to a field in Packet_Buffer.
1013
/// <summary>
1114
/// A packet processor makes some sort of forwarding decision, in addition
1215
/// to possibly analysing/modifying the packet (and generating new packets).
@@ -68,5 +71,27 @@ public MultiPortForward (int[] target_ports) {
6871
this.target_ports = target_ports;
6972
}
7073
}
74+
75+
public static int[] broadcast_raw (int in_port)
76+
{
77+
int[] out_ports = new int[PaxConfig_Lite.no_interfaces - 1];
78+
// We retrieve number of interfaces in use from PaxConfig_Lite.
79+
// Naturally, we exclude in_port from the interfaces we're forwarding to since this is a broadcast.
80+
int idx = 0;
81+
for (int ofs = 0; ofs < PaxConfig_Lite.no_interfaces; ofs++)
82+
{
83+
if (ofs != in_port)
84+
{
85+
out_ports[idx] = ofs;
86+
idx++;
87+
}
88+
}
89+
return out_ports;
90+
}
91+
92+
public static MultiPortForward broadcast (int in_port)
93+
{
94+
return (new MultiPortForward (broadcast_raw (in_port)));
95+
}
7196
}
7297
}

Pax.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,14 @@ private static void Configure(CaptureDeviceList devices)
151151
JsonSerializer j = new JsonSerializer();
152152
j.DefaultValueHandling = DefaultValueHandling.Populate;
153153
PaxConfig.configFile = j.Deserialize<ConfigFile>(r);
154-
PaxConfig.no_interfaces = PaxConfig.config.Count;
155-
PaxConfig.deviceMap = new ICaptureDevice[PaxConfig.no_interfaces];
156-
PaxConfig.interface_lead_handler = new string[PaxConfig.no_interfaces];
157-
PaxConfig.interface_lead_handler_obj = new IPacketProcessor[PaxConfig.no_interfaces];
154+
PaxConfig_Lite.no_interfaces = PaxConfig.config.Count;
155+
PaxConfig.deviceMap = new ICaptureDevice[PaxConfig_Lite.no_interfaces];
156+
PaxConfig.interface_lead_handler = new string[PaxConfig_Lite.no_interfaces];
157+
PaxConfig.interface_lead_handler_obj = new IPacketProcessor[PaxConfig_Lite.no_interfaces];
158158

159159
int idx = 0;
160160
foreach (var i in PaxConfig.config) {
161-
Debug.Assert (idx < PaxConfig.no_interfaces);
161+
Debug.Assert (idx < PaxConfig_Lite.no_interfaces);
162162

163163
PaxConfig.deviceMap[idx] = null;
164164
//FIXME not using internal_name any more to avoid more lookups. Remove completely?
@@ -221,7 +221,7 @@ private static void LoadExternalHandlersFromDll()
221221
// Find which network interfaces this class is handling
222222
List<int> subscribed = new List<int>();
223223
IPacketProcessor pp = null;
224-
for (int idx = 0; idx < PaxConfig.no_interfaces; idx++)
224+
for (int idx = 0; idx < PaxConfig_Lite.no_interfaces; idx++)
225225
{
226226
// Does this interface have this type specified as the lead handler?
227227
if ((!String.IsNullOrEmpty(PaxConfig.interface_lead_handler[idx])) &&
@@ -311,7 +311,7 @@ private static void RegisterHandlers()
311311
});
312312
// Shutdown on ^C -- FIXME remove handling of ^C or ^D?
313313
Console.CancelKeyPress += new ConsoleCancelEventHandler(shutdown);
314-
for (int idx = 0; idx < PaxConfig.no_interfaces; idx++)
314+
for (int idx = 0; idx < PaxConfig_Lite.no_interfaces; idx++)
315315
{
316316
if (PaxConfig.interface_lead_handler_obj[idx] == null)
317317
{

Pax.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
<SpecificVersion>False</SpecificVersion>
2222
<HintPath>lib\Newtonsoft.Json.dll</HintPath>
2323
</Reference>
24+
<Reference Include="Pax_Lite, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
25+
<HintPath>..\Bin\Pax_Lite.dll</HintPath>
26+
<SpecificVersion>False</SpecificVersion>
27+
</Reference>
2428
</ItemGroup>
2529
<ItemGroup>
2630
<Compile Include="AssemblyInfo.cs" />

PaxConfig.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,6 @@ public class NetworkInterfaceConfig
5555

5656
// FIXME crude design
5757
public static class PaxConfig {
58-
// This is the number of interfaces in the configuration file.
59-
// This must be greater than 1.
60-
// Note that no_interfaces may be larger than the number of interfaces to which a packet processor has
61-
// been attached (i.e., interfaces that have a "lead_handler" defined in the configuration).
62-
// But this is fine, because there might be interface for which we don't want to process
63-
// their incoming packets, but we want to be able to forward packets to them nonetheless.
64-
public static int no_interfaces;
65-
6658
// Array "maps" from device offset to the device object.
6759
public static ICaptureDevice[] deviceMap;
6860
// Map from device name (e.g., "eth1") to device offset.

PaxConfig_Lite.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
Pax : tool support for prototyping packet processors
3+
Nik Sultana, Cambridge University Computer Lab, June 2016
4+
5+
Use of this source code is governed by the Apache 2.0 license; see LICENSE.
6+
*/
7+
8+
namespace Pax
9+
{
10+
public static class PaxConfig_Lite {
11+
// This is the number of interfaces that Pax processor instances can
12+
// forward to. When running in a full-fledged .NET VM, this indicates the
13+
// number of network interfaces in the configuration file. When running
14+
// in a constrained environment, this can be set directly by the
15+
// system after loading (from some static value, or using a configuration
16+
// source that it knows of).
17+
// This must be greater than 1.
18+
// Note that no_interfaces may be larger than the number of interfaces to which a packet processor has
19+
// been attached (i.e., interfaces that have a "lead_handler" defined in the configuration).
20+
// But this is fine, because there might be interface for which we don't want to process
21+
// their incoming packets, but we want to be able to forward packets to them nonetheless.
22+
public static int no_interfaces; //FIXME make uint?
23+
24+
// By "phantom forwarding" I mean forwarding to a network port
25+
// that doesn't exist (because it's greater than no_interfaces).
26+
// Phantom forwarding might occur if we are running a processor that has
27+
// been hardcoded to expect a number of network interfaces, but we lack
28+
// that number of interfaces in the configuration we're running it in.
29+
public static bool ignore_phantom_forwarding = false;
30+
31+
//#if LITE
32+
// We need static bounds on arrays, and these are
33+
// provided by such constants.
34+
public const uint MAX_PACKET_SIZE = 1500; // Maximum size of a packet in bytes.
35+
public const uint MAX_INTERFACES = 10; // Maximum number of interfaces we can use.
36+
//#endif
37+
}
38+
}

Pax_Lite.csproj

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- Hand-written .csproj file, based on instructions at https://msdn.microsoft.com/en-us/library/dd576348.aspx-->
3+
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
4+
<PropertyGroup>
5+
<AssemblyName>Pax_Lite</AssemblyName>
6+
<OutputPath>Bin\</OutputPath>
7+
<OutputType>Library</OutputType>
8+
<DefineConstants>DEBUG;TRACE</DefineConstants>
9+
</PropertyGroup>
10+
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
11+
<ItemGroup>
12+
<Compile Include="AssemblyInfo.cs" />
13+
<Compile Include="PaxConfig_Lite.cs" />
14+
<Compile Include="Paxifax_Lite.cs" />
15+
</ItemGroup>
16+
<!--
17+
<Target Name="Build">
18+
<MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
19+
<Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
20+
</Target>
21+
-->
22+
</Project>

Paxifax.cs

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
// FIXME use javadoc-style comments to describe the API
1717
namespace Pax {
1818

19-
// A more abstract interface to packet processors.
19+
// An abstract interface to packet processors.
2020
public interface IAbstract_PacketProcessor {
2121
ForwardingDecision process_packet (int in_port, ref Packet packet);
2222
}
@@ -113,23 +113,6 @@ public abstract class MultiInterface_SimplePacketProcessor : IPacketProcessor {
113113
// Return the offsets of network interfaces that "packet" is to be forwarded to.
114114
abstract public ForwardingDecision process_packet (int in_port, ref Packet packet);
115115

116-
public static int[] broadcast (int in_port)
117-
{
118-
int[] out_ports = new int[PaxConfig.no_interfaces - 1];
119-
// We retrieve number of interfaces in use from PaxConfig.
120-
// Naturally, we exclude in_port from the interfaces we're forwarding to since this is a broadcast.
121-
int idx = 0;
122-
for (int ofs = 0; ofs < PaxConfig.no_interfaces; ofs++)
123-
{
124-
if (ofs != in_port)
125-
{
126-
out_ports[idx] = ofs;
127-
idx++;
128-
}
129-
}
130-
return out_ports;
131-
}
132-
133116
public void packetHandler (object sender, CaptureEventArgs e)
134117
{
135118
var packet = PacketDotNet.Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);
@@ -140,24 +123,47 @@ public void packetHandler (object sender, CaptureEventArgs e)
140123
if (des is ForwardingDecision.MultiPortForward)
141124
{
142125
out_ports = ((ForwardingDecision.MultiPortForward)des).target_ports;
126+
/*
127+
Since MultiPortForward works with arrays, this increases the exposure
128+
to dud values:
129+
* negative values within arrays
130+
* repeated values within arrays
131+
* an array might be larger than intended, and contains rubbish data.
132+
These could manifest themselves as bugs or abused behaviour.
133+
FIXME determine how each of these cases will be treated.
134+
*/
143135
} else {
144136
throw (new Exception ("Expected MultiPortForward"));
145137
}
146138

147139
#if DEBUG
148140
Debug.Write(PaxConfig.deviceMap[in_port].Name + " -> ");
141+
// It's useful to know the width of the returned array during debugging,
142+
// since it might be that the array was wider than intended, and contained
143+
// repeated or rubbish values.
144+
Debug.Write("[" + out_ports.Length.ToString() + "] ");
149145
#endif
146+
150147
for (int idx = 0; idx < out_ports.Length; idx++)
151148
{
152-
PaxConfig.deviceMap[out_ports[idx]].SendPacket(packet);
149+
int out_port = out_ports[idx];
150+
// Check if trying to send over a non-existent port.
151+
if (out_port < PaxConfig_Lite.no_interfaces) {
152+
PaxConfig.deviceMap[out_port].SendPacket(packet);
153153
#if DEBUG
154-
if (idx < out_ports.Length - 1)
155-
{
156-
Debug.Write(PaxConfig.deviceMap[out_ports[idx]].Name + ", ");
157-
} else {
158-
Debug.Write(PaxConfig.deviceMap[out_ports[idx]].Name);
159-
}
154+
Debug.Write("(" + out_port.ToString() + ") "); // Show the network interface offset.
155+
// And now show the network interface name that the offset resolves to.
156+
if (idx < out_ports.Length - 1)
157+
{
158+
Debug.Write(PaxConfig.deviceMap[out_port].Name + ", ");
159+
} else {
160+
Debug.Write(PaxConfig.deviceMap[out_port].Name);
161+
}
160162
#endif
163+
} else if (!(out_port < PaxConfig_Lite.no_interfaces) &&
164+
!PaxConfig_Lite.ignore_phantom_forwarding) {
165+
throw (new Exception ("Tried forward to non-existant port"));
166+
}
161167
}
162168

163169
#if DEBUG

Paxifax_Lite.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
Pax : tool support for prototyping packet processors
3+
Nik Sultana, Cambridge University Computer Lab, June 2016
4+
5+
Use of this source code is governed by the Apache 2.0 license; see LICENSE.
6+
*/
7+
8+
using return_type = System.Int64; //FIXME can this be used to make the type of "forward" less arbitrary?
9+
10+
// FIXME use javadoc-style comments to describe the API
11+
namespace Pax {
12+
13+
// Packet will be retreivable from here, where it will
14+
// be deposited by another party (which depends on where
15+
// the packet processor is executing).
16+
public static class Packet_Buffer {
17+
public static byte[] packet = new byte[PaxConfig_Lite.MAX_PACKET_SIZE];
18+
public static return_type forward = 0; // FIXME might not be right place for this
19+
}
20+
21+
// Packet processors.
22+
public interface IBytePacket_Processor {
23+
// FIXME using "long" type is too arbitrary?
24+
void process_packet (byte in_port);
25+
}
26+
}

build.sh

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
11
#!/bin/bash
2+
# Rudimentary build script
3+
# Nik Sultana, Cambridge University Computer Lab, July 2016
4+
#
5+
# FIXME: replace this with an .sln file
26

3-
# FIXME: create a .sln file that includes both projects
4-
xbuild Pax.csproj && xbuild examples/Examples.csproj && echo Success
7+
set -e
8+
9+
# NOTE to not have any symbols, instead of an empty ${DEFINE} use a dud one like "NOTHING"
10+
if [ -z "${DEFINE}" ]
11+
then
12+
# Default symbols
13+
DEFINE="DEBUG TRACE LITE"
14+
fi
15+
16+
xbuild Pax_Lite.csproj /t:Rebuild /p:DefineConstants="${DEFINE}"
17+
xbuild Pax.csproj /p:DefineConstants="${DEFINE}"
18+
xbuild examples/Examples.csproj /p:DefineConstants="${DEFINE}"
19+
xbuild examples/Hub.csproj /p:DefineConstants="${DEFINE}"
20+
21+
echo Success

examples/Examples.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
<SpecificVersion>False</SpecificVersion>
2424
<HintPath>..\lib\Newtonsoft.Json.dll</HintPath>
2525
</Reference>
26+
<Reference Include="Pax_Lite, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
27+
<HintPath>..\Bin\Pax_Lite.dll</HintPath>
28+
<SpecificVersion>False</SpecificVersion>
29+
</Reference>
2630
<Reference Include="Pax, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
2731
<HintPath>..\Bin\Pax.exe</HintPath>
2832
<SpecificVersion>False</SpecificVersion>

examples/Hub.cs

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,65 @@
55
Use of this source code is governed by the Apache 2.0 license; see LICENSE.
66
*/
77

8-
using PacketDotNet;
98
using Pax;
109

11-
public class Hub : MultiInterface_SimplePacketProcessor {
10+
#if !LITE
11+
using PacketDotNet;
12+
#endif
13+
14+
15+
public
16+
#if LITE
17+
static
18+
#endif
19+
class Hub
20+
#if !LITE
21+
: MultiInterface_SimplePacketProcessor
22+
#endif
23+
{
24+
#if !LITE
1225
override public ForwardingDecision process_packet (int in_port, ref Packet packet)
1326
{
14-
int[] out_ports = MultiInterface_SimplePacketProcessor.broadcast(in_port);
15-
return (new ForwardingDecision.MultiPortForward(out_ports));
27+
/* NOTE disabled this since this processor doesn't look at packets, only at the in_port.
28+
// Extract the bytes and call the instance of IAbstract_ByteProcessor
29+
byte[] bs = packet.Bytes;
30+
*/
31+
/* FIXME ideally we should be able use a single implementation of the logic.
32+
This is possible, but requires some in-progress development.
33+
Specifically this conists of a phase that switches between
34+
the high-level and lower-level encoding of in_port, packet, and forward.
35+
Then we get two runtime options:
36+
* the Pax instance can use the Pax and Pax-Lite level logic (the latter
37+
by using the en/decoding)
38+
* the Pax_Lite instance can only use the low-level encoding since the
39+
types for the high-level encoding are not in its universe.
40+
41+
process_packet (in_port);
42+
TODO var forward = decode_forward();
43+
return forward;
44+
*/
45+
return (ForwardingDecision.broadcast(in_port));
46+
}
47+
#endif
48+
49+
public
50+
#if LITE
51+
static
52+
#endif
53+
void process_packet (byte in_port)
54+
{
55+
long forward = Packet_Buffer.forward;
56+
57+
for (int ofs = 0; ofs < PaxConfig_Lite.no_interfaces; ofs++)
58+
{
59+
forward = forward << 1;
60+
if (ofs != in_port)
61+
{
62+
forward |= 1;
63+
}
64+
}
65+
66+
Packet_Buffer.forward = forward;
67+
//Packet_Buffer.forward = 0xFAFF; // FIXME currently using a constant for debugging
1668
}
1769
}

0 commit comments

Comments
 (0)