mirror of
https://github.com/livingcomputermuseum/IFS.git
synced 2026-04-09 14:23:16 +00:00
Basics completed (still rough). No testing done (awaiting running Alto.)
This commit is contained in:
@@ -25,7 +25,7 @@ namespace IFS
|
||||
|
||||
_inputWriteEvent = new AutoResetEvent(false);
|
||||
|
||||
_inputQueue = new MemoryStream(65536);
|
||||
_inputQueue = new Queue<byte>(65536);
|
||||
|
||||
// TODO: init IDs, etc. based on RFC PUP
|
||||
_start_pos = _recv_pos = _send_pos = rfcPup.ID;
|
||||
@@ -161,13 +161,15 @@ namespace IFS
|
||||
_outputAckEvent.Set();
|
||||
}
|
||||
|
||||
/*
|
||||
public void Mark(byte type);
|
||||
public void Interrupt();
|
||||
|
||||
public void Abort(int code, string message);
|
||||
public void Error(int code, string message);
|
||||
|
||||
public void End();
|
||||
public void End();
|
||||
*/
|
||||
|
||||
// TODO:
|
||||
// Events for:
|
||||
@@ -235,10 +237,11 @@ namespace IFS
|
||||
case PupType.RFC:
|
||||
{
|
||||
BSPChannel newChannel = new BSPChannel(p);
|
||||
_activeChannels.Add(newChannel.ClientPort.Socket);
|
||||
_activeChannels.Add(newChannel.ClientPort.Socket, newChannel);
|
||||
|
||||
return newChannel;
|
||||
}
|
||||
break;
|
||||
|
||||
case PupType.Data:
|
||||
case PupType.AData:
|
||||
@@ -253,11 +256,13 @@ namespace IFS
|
||||
break;
|
||||
|
||||
case PupType.Ack:
|
||||
BSPChannel channel = FindChannelForPup(p);
|
||||
{
|
||||
BSPChannel channel = FindChannelForPup(p);
|
||||
|
||||
if (channel != null)
|
||||
{
|
||||
channel.Ack(p);
|
||||
if (channel != null)
|
||||
{
|
||||
channel.Ack(p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -267,7 +272,7 @@ namespace IFS
|
||||
|
||||
if (channel != null)
|
||||
{
|
||||
channel.EndReply();
|
||||
//channel.EndReply();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
64
PUP/BreathOfLife.cs
Normal file
64
PUP/BreathOfLife.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IFS
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements the BreathOfLife services.
|
||||
/// It spins up a worker thread that wakes up every few seconds and broadcasts
|
||||
/// a BreathOfLife packet.
|
||||
/// </summary>
|
||||
public class BreathOfLife
|
||||
{
|
||||
public BreathOfLife()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
ushort[] _bolPacket =
|
||||
{
|
||||
0,0,
|
||||
|
||||
|
||||
|
||||
|
||||
0022574, 0100000, 0040437, 0102000, 0034431, 0164000,
|
||||
0061005, 0102460, 0024567, 0034572, 0061006, 0024565, 0034570, 0061006,
|
||||
0024564, 0034566, 0061006, 0020565, 0034565, 0061005, 0125220, 0046573,
|
||||
0020576, 0061004, 0123400, 0030551, 0041211, 0004416, 0000000, 0001000,
|
||||
0000026, 0000244, 0000000, 0000000, 0000000, 0000000, 0000004, 0000000,
|
||||
0000000, 0000020, 0177777, 0055210, 0025400, 0107000, 0045400, 0041411,
|
||||
0020547, 0041207, 0020544, 0061004, 0006531, 0034517, 0030544, 0051606,
|
||||
0020510, 0041605, 0042526, 0102460, 0041601, 0020530, 0061004, 0021601,
|
||||
0101014, 0000414, 0061020, 0014737, 0000773, 0014517, 0000754, 0020517,
|
||||
0061004, 0030402, 0002402, 0000000, 0000732, 0034514, 0162414, 0000746,
|
||||
0021001, 0024511, 0106414, 0000742, 0021003, 0163400, 0035005, 0024501,
|
||||
0106415, 0175014, 0000733, 0021000, 0042465, 0034457, 0056445, 0055775,
|
||||
0055776, 0101300, 0041400, 0020467, 0041401, 0020432, 0041402, 0121400,
|
||||
0041403, 0021006, 0041411, 0021007, 0041412, 0021010, 0041413, 0021011,
|
||||
0041406, 0021012, 0041407, 0021013, 0041410, 0015414, 0006427, 0012434,
|
||||
0006426, 0020421, 0024437, 0134000, 0030417, 0002422, 0177035, 0000026,
|
||||
0000415, 0000427, 0000567, 0000607, 0000777, 0177751, 0177641, 0177600,
|
||||
0000225, 0177624, 0001013, 0000764, 0000431, 0000712, 0000634, 0000735,
|
||||
0000611, 0000567, 0000564, 0000566, 0000036, 0000002, 0000003, 0000015,
|
||||
0000030, 0000377, 0001000, 0177764, 0000436, 0054731, 0050750, 0020753,
|
||||
0040745, 0102460, 0040737, 0020762, 0061004, 0020734, 0105304, 0000406,
|
||||
0020743, 0101014, 0014741, 0000772, 0002712, 0034754, 0167700, 0116415,
|
||||
0024752, 0021001, 0106414, 0000754, 0021000, 0024703, 0106414, 0000750,
|
||||
0021003, 0163400, 0024736, 0106405, 0000404, 0121400, 0101404, 0000740,
|
||||
0044714, 0021005, 0042732, 0024664, 0122405, 0000404, 0101405, 0004404,
|
||||
0000727, 0010656, 0034654, 0024403, 0120500, 0101404, 0000777, 0040662,
|
||||
0040664, 0040664, 0102520, 0061004, 0020655, 0101015, 0000776, 0106415,
|
||||
0001400, 0014634, 0000761, 0020673, 0061004, 0000400, 0061005, 0102000,
|
||||
0143000, 0034672, 0024667, 0166400, 0061005, 0004670, 0020663, 0034664,
|
||||
0164000, 0147000, 0061005, 0024762, 0132414, 0133000, 0020636, 0034416,
|
||||
0101015, 0156415, 0131001, 0000754, 0024643, 0044625, 0101015, 0000750,
|
||||
0014623, 0004644, 0020634, 0061004, 0002000, 0176764, 0001401, 0041002
|
||||
}; */
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,18 @@ namespace IFS
|
||||
_localHost = new HostAddress(1, 34);
|
||||
}
|
||||
|
||||
public string AddressLookup(HostAddress address)
|
||||
{
|
||||
// TODO: actually look things up
|
||||
return "Alto";
|
||||
}
|
||||
|
||||
public HostAddress NameLookup(string hostName)
|
||||
{
|
||||
// TODO: actually look things up
|
||||
return new HostAddress(1, 0x80);
|
||||
}
|
||||
|
||||
public static DirectoryServices Instance
|
||||
{
|
||||
get { return _instance; }
|
||||
|
||||
@@ -6,6 +6,9 @@ using System.Threading.Tasks;
|
||||
|
||||
using IFS.Transport;
|
||||
using PcapDotNet.Packets;
|
||||
using PcapDotNet.Packets.Ethernet;
|
||||
using IFS.Logging;
|
||||
using PcapDotNet.Base;
|
||||
|
||||
namespace IFS
|
||||
{
|
||||
@@ -22,9 +25,7 @@ namespace IFS
|
||||
/// </summary>
|
||||
private Dispatcher()
|
||||
{
|
||||
_dispatchMap = new Dictionary<uint, PUPProtocolEntry>();
|
||||
|
||||
_packetInterface = new Ethernet(iface, OnPacketReceived);
|
||||
_dispatchMap = new Dictionary<uint, PUPProtocolEntry>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -35,6 +36,13 @@ namespace IFS
|
||||
get { return _instance; }
|
||||
}
|
||||
|
||||
public void RegisterInterface(EthernetInterface i)
|
||||
{
|
||||
// TODO: support multiple interfaces (for gateway routing, for example.)
|
||||
// Also, this should not be ethernet-specific.
|
||||
_packetInterface = new Ethernet(i, OnPacketReceived);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a new protocol with the dispatcher
|
||||
/// </summary>
|
||||
@@ -45,7 +53,7 @@ namespace IFS
|
||||
if (_dispatchMap.ContainsKey(entry.Socket))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
String.Format("Socket {0} has already been registered for protocol {1}", impl.Socket, _dispatchMap[impl.Socket].FriendlyName));
|
||||
String.Format("Socket {0} has already been registered for protocol {1}", entry.Socket, _dispatchMap[entry.Socket].FriendlyName));
|
||||
}
|
||||
|
||||
_dispatchMap[entry.Socket] = entry;
|
||||
@@ -53,7 +61,41 @@ namespace IFS
|
||||
|
||||
public void SendPup(PUP p)
|
||||
{
|
||||
// TODO: Write PUP to ethernet
|
||||
//
|
||||
// Write PUP to ethernet:
|
||||
// Get destination network & host address from PUP and route to correct ethernet address.
|
||||
// For now, no actual routing (Gateway not implemented yet), everthing is on the same 'net.
|
||||
// Just look up host address and find the MAC of the host to send it to.
|
||||
// TODO: this translation should be at the Interface level, not here (we shouldn't be doing
|
||||
// ethernet-specific things here -- at the moment it doesn't matter since we're only speaking
|
||||
// ethernet, but this should be fixed.)
|
||||
//
|
||||
if (_pupToEthernetMap.ContainsKey(p.DestinationPort.Host))
|
||||
{
|
||||
MacAddress destinationMac = _pupToEthernetMap[p.SourcePort.Host];
|
||||
|
||||
// Build the outgoing packet; place the source/dest addresses, type field and the PUP data.
|
||||
EthernetLayer ethernetLayer = new EthernetLayer
|
||||
{
|
||||
Source = (MacAddress)_packetInterface.GetDeviceAddress(),
|
||||
Destination = destinationMac,
|
||||
EtherType = (EthernetType)512, // PUP type (TODO: move to constant)
|
||||
};
|
||||
|
||||
PayloadLayer payloadLayer = new PayloadLayer
|
||||
{
|
||||
Data = new Datagram(p.RawData),
|
||||
};
|
||||
|
||||
PacketBuilder builder = new PacketBuilder(ethernetLayer, payloadLayer);
|
||||
|
||||
_packetInterface.SendPacket(builder.Build(DateTime.Now));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Log error, this should not happen.
|
||||
Log.Write(LogLevel.Error, String.Format("PUP destination address {0} is unknown.", p.DestinationPort.Host));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -65,19 +107,64 @@ namespace IFS
|
||||
{
|
||||
PUP pup = new PUP(p.Ethernet.Payload.ToMemoryStream());
|
||||
|
||||
if (_dispatchMap.ContainsKey(pup.DestinationPort.Socket))
|
||||
//
|
||||
// Check the network -- if this is not network zero (coming from a host that doesn't yet know what
|
||||
// network it's on) or the network we're on, we will ignore it (for now...). Once we implement
|
||||
// Gateway services we will handle these appropriately.
|
||||
//
|
||||
if (pup.SourcePort.Network == 0 || pup.SourcePort.Network == DirectoryServices.Instance.LocalHostAddress.Network)
|
||||
{
|
||||
PUPProtocolEntry entry = _dispatchMap[pup.DestinationPort.Socket];
|
||||
entry.ProtocolImplementation.RecvData(pup);
|
||||
UpdateMACTable(pup, p);
|
||||
|
||||
if (_dispatchMap.ContainsKey(pup.DestinationPort.Socket))
|
||||
{
|
||||
PUPProtocolEntry entry = _dispatchMap[pup.DestinationPort.Socket];
|
||||
entry.ProtocolImplementation.RecvData(pup);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a protocol we handle; TODO: log it.
|
||||
Log.Write(LogLevel.UnhandledProtocol | LogLevel.DroppedPacket, String.Format("Unhandled PUP protocol, socket {0}, dropped packet.", pup.DestinationPort.Socket));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a protocol we handle; TODO: log it.
|
||||
// Not for our network; eventually we will look into routing...
|
||||
Log.Write(LogLevel.DroppedPacket, String.Format("PUP is for network {0}, dropping.", pup.SourcePort.Network));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a PUP, Discard the packet.
|
||||
// Not a PUP, Discard the packet. We will not log this to keep noise down.
|
||||
//Log.Write(LogLevel.DroppedPacket, "Not a PUP. Dropping.");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMACTable(PUP p, Packet e)
|
||||
{
|
||||
//
|
||||
// See if we already have this entry.
|
||||
//
|
||||
if (_pupToEthernetMap.ContainsKey(p.SourcePort.Host))
|
||||
{
|
||||
//
|
||||
// We do; ensure that the mac addresses match -- if not we have a duplicate
|
||||
// PUP id on the network.
|
||||
//
|
||||
if (_pupToEthernetMap[p.SourcePort.Host] != e.Ethernet.Source)
|
||||
{
|
||||
Log.Write(LogLevel.DuplicateHostNumber,
|
||||
String.Format("Duplicate host number {0} for MAC {1} (currently mapped to MAC {2})",
|
||||
p.SourcePort.Host,
|
||||
e.Ethernet.Source,
|
||||
_pupToEthernetMap[p.SourcePort.Host]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add a mapping in both directions
|
||||
_pupToEthernetMap.Add(p.SourcePort.Host, e.Ethernet.Source);
|
||||
_ethernetToPupMap.Add(e.Ethernet.Source, p.SourcePort.Host);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +178,12 @@ namespace IFS
|
||||
/// </summary>
|
||||
private Dictionary<UInt32, PUPProtocolEntry> _dispatchMap;
|
||||
|
||||
/// <summary>
|
||||
/// PUP<->Ethernet address map
|
||||
/// </summary>
|
||||
private Dictionary<byte, MacAddress> _pupToEthernetMap;
|
||||
private Dictionary<MacAddress, byte> _ethernetToPupMap;
|
||||
|
||||
private static Dispatcher _instance = new Dispatcher();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using IFS.Transport;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -10,6 +11,20 @@ namespace IFS
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
|
||||
Logging.Log.Level = Logging.LogLevel.All;
|
||||
|
||||
List<EthernetInterface> ifaces = EthernetInterface.EnumerateDevices();
|
||||
|
||||
Console.WriteLine("available interfaces are:");
|
||||
foreach(EthernetInterface i in ifaces)
|
||||
{
|
||||
Console.WriteLine(String.Format("{0} - address {1}", i.Name, i.MacAddress));
|
||||
}
|
||||
|
||||
// TODO: MAKE THIS CONFIGURABLE.
|
||||
Dispatcher.Instance.RegisterInterface(ifaces[1]);
|
||||
|
||||
// Set up protocols:
|
||||
|
||||
// Connectionless
|
||||
@@ -19,5 +34,10 @@ namespace IFS
|
||||
// RTP/BSP based:
|
||||
Dispatcher.Instance.RegisterProtocol(new PUPProtocolEntry("CopyDisk", 0x15 /* 25B */, ConnectionType.BSP, new CopyDiskServer()));
|
||||
|
||||
while (true)
|
||||
{
|
||||
System.Threading.Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,18 +32,36 @@
|
||||
<PropertyGroup>
|
||||
<StartupObject />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="PcapDotNet.Base">
|
||||
<HintPath>..\Ethernet\pcap\PcapDotNet.Base.dll</HintPath>
|
||||
<HintPath>pcap\PcapDotNet.Base.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PcapDotNet.Core">
|
||||
<HintPath>..\Ethernet\pcap\PcapDotNet.Core.dll</HintPath>
|
||||
<HintPath>pcap\PcapDotNet.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PcapDotNet.Core.Extensions">
|
||||
<HintPath>..\Ethernet\pcap\PcapDotNet.Core.Extensions.dll</HintPath>
|
||||
<HintPath>pcap\PcapDotNet.Core.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PcapDotNet.Packets">
|
||||
<HintPath>..\Ethernet\pcap\PcapDotNet.Packets.dll</HintPath>
|
||||
<HintPath>pcap\PcapDotNet.Packets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
@@ -55,11 +73,13 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BCPLString.cs" />
|
||||
<Compile Include="BreathOfLife.cs" />
|
||||
<Compile Include="BSPManager.cs" />
|
||||
<Compile Include="CopyDiskServer.cs" />
|
||||
<Compile Include="DirectoryServices.cs" />
|
||||
<Compile Include="EchoProtocol.cs" />
|
||||
<Compile Include="Entrypoint.cs" />
|
||||
<Compile Include="Logging\Log.cs" />
|
||||
<Compile Include="MiscServicesProtocol.cs" />
|
||||
<Compile Include="Transport\Ethernet.cs" />
|
||||
<Compile Include="PUPProtocolBase.cs" />
|
||||
|
||||
@@ -8,13 +8,19 @@ EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{5C0BBE4B-76AB-4AC1-8691-F19D8D282DCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5C0BBE4B-76AB-4AC1-8691-F19D8D282DCB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5C0BBE4B-76AB-4AC1-8691-F19D8D282DCB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5C0BBE4B-76AB-4AC1-8691-F19D8D282DCB}.Debug|x64.Build.0 = Debug|x64
|
||||
{5C0BBE4B-76AB-4AC1-8691-F19D8D282DCB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5C0BBE4B-76AB-4AC1-8691-F19D8D282DCB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5C0BBE4B-76AB-4AC1-8691-F19D8D282DCB}.Release|x64.ActiveCfg = Release|x64
|
||||
{5C0BBE4B-76AB-4AC1-8691-F19D8D282DCB}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
48
PUP/Logging/Log.cs
Normal file
48
PUP/Logging/Log.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IFS.Logging
|
||||
{
|
||||
[Flags]
|
||||
public enum LogLevel
|
||||
{
|
||||
None = 0,
|
||||
Normal = 1,
|
||||
Warning = 2,
|
||||
Error = 4,
|
||||
DroppedPacket = 8,
|
||||
InvalidPacket = 0x10,
|
||||
UnhandledProtocol = 0x20,
|
||||
DuplicateHostNumber = 0x40,
|
||||
|
||||
All = 0x7fffffff,
|
||||
}
|
||||
|
||||
public static class Log
|
||||
{
|
||||
static Log()
|
||||
{
|
||||
_level = LogLevel.None;
|
||||
}
|
||||
|
||||
public static LogLevel Level
|
||||
{
|
||||
get { return _level; }
|
||||
set { _level = value; }
|
||||
}
|
||||
|
||||
public static void Write(LogLevel level, string message)
|
||||
{
|
||||
if ((level & _level) != 0)
|
||||
{
|
||||
// My log has something to tell you...
|
||||
Console.WriteLine("{0}: {1} - {2}", DateTime.Now, level, message);
|
||||
}
|
||||
}
|
||||
|
||||
private static LogLevel _level;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using IFS.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -48,7 +49,7 @@ namespace IFS
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unhandled, TODO: log it
|
||||
Log.Write(LogLevel.UnhandledProtocol, String.Format("Unhandled misc. protocol {0}", p.Type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -144,7 +145,7 @@ namespace IFS
|
||||
// and see if we have a match.
|
||||
//
|
||||
PUPPort lookupAddress = new PUPPort(p.Contents, 0);
|
||||
string hostName = DirectoryServices.Instance.AddressLookup(lookupAddress);
|
||||
string hostName = DirectoryServices.Instance.AddressLookup(new HostAddress(lookupAddress.Network, lookupAddress.Host));
|
||||
|
||||
if (!String.IsNullOrEmpty(hostName))
|
||||
{
|
||||
|
||||
@@ -5,20 +5,36 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using PcapDotNet.Core;
|
||||
using PcapDotNet.Core.Extensions;
|
||||
using PcapDotNet.Packets;
|
||||
using PcapDotNet.Packets.Ethernet;
|
||||
|
||||
namespace IFS.Transport
|
||||
{
|
||||
public struct EthernetInterface
|
||||
{
|
||||
public EthernetInterface(string name, string description)
|
||||
public EthernetInterface(string name, string description, MacAddress macAddress)
|
||||
{
|
||||
Name = name;
|
||||
Description = description;
|
||||
MacAddress = macAddress;
|
||||
}
|
||||
|
||||
public string Name;
|
||||
public string Description;
|
||||
public static List<EthernetInterface> EnumerateDevices()
|
||||
{
|
||||
List<EthernetInterface> interfaces = new List<EthernetInterface>();
|
||||
|
||||
foreach (LivePacketDevice device in LivePacketDevice.AllLocalMachine)
|
||||
{
|
||||
interfaces.Add(new EthernetInterface(device.Name, device.Description, device.GetMacAddress()));
|
||||
}
|
||||
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
public string Name;
|
||||
public string Description;
|
||||
public MacAddress MacAddress;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -30,23 +46,14 @@ namespace IFS.Transport
|
||||
{
|
||||
AttachInterface(iface);
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
public static List<EthernetInterface> EnumerateDevices()
|
||||
{
|
||||
List<EthernetInterface> interfaces = new List<EthernetInterface>();
|
||||
|
||||
foreach(LivePacketDevice device in LivePacketDevice.AllLocalMachine)
|
||||
{
|
||||
interfaces.Add(new EthernetInterface(device.Name, device.Description));
|
||||
}
|
||||
|
||||
return interfaces;
|
||||
Open(false, int.MaxValue);
|
||||
BeginReceive();
|
||||
}
|
||||
|
||||
public void Open(bool promiscuous, int timeout)
|
||||
{
|
||||
_communicator = _interface.Open(0xffff, promiscuous ? PacketDeviceOpenAttributes.Promiscuous : PacketDeviceOpenAttributes.None, timeout);
|
||||
_communicator = _interface.Open(0xffff, promiscuous ? PacketDeviceOpenAttributes.Promiscuous : PacketDeviceOpenAttributes.None, timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -57,9 +64,19 @@ namespace IFS.Transport
|
||||
_communicator.ReceivePackets(-1, ReceiveCallback);
|
||||
}
|
||||
|
||||
public void SendPacket(Packet p)
|
||||
{
|
||||
_communicator.SendPacket(p);
|
||||
}
|
||||
|
||||
public object GetDeviceAddress()
|
||||
{
|
||||
return (object)_interface.GetMacAddress();
|
||||
}
|
||||
|
||||
private void ReceiveCallback(Packet p)
|
||||
{
|
||||
_callback(p);
|
||||
{
|
||||
_callback(p);
|
||||
}
|
||||
|
||||
private void AttachInterface(EthernetInterface iface)
|
||||
@@ -69,7 +86,7 @@ namespace IFS.Transport
|
||||
// Find the specified device by name
|
||||
foreach (LivePacketDevice device in LivePacketDevice.AllLocalMachine)
|
||||
{
|
||||
if (device.Name == iface.Name)
|
||||
if (device.Name == iface.Name && device.GetMacAddress() == iface.MacAddress)
|
||||
{
|
||||
_interface = device;
|
||||
break;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using PcapDotNet.Packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -10,7 +11,10 @@ namespace IFS.Transport
|
||||
/// PacketInterface provides an abstraction over a transport (Ethernet, IP, Carrier Pigeon)
|
||||
/// which can provide raw packets.
|
||||
/// </summary>
|
||||
interface IPacketInterface
|
||||
public interface IPacketInterface
|
||||
{
|
||||
void SendPacket(Packet p);
|
||||
|
||||
object GetDeviceAddress();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user