1
0
mirror of https://github.com/livingcomputermuseum/IFS.git synced 2026-04-07 13:50:06 +00:00

Changes to make IFS work correctly with npcap (which replaces WinPcap) in WinPcap compatibility mode.

This commit is contained in:
Josh Dersch
2019-02-21 16:34:57 -08:00
parent b926d1729b
commit 97d92450b3
7 changed files with 108 additions and 9 deletions

6
.gitignore vendored
View File

@@ -186,4 +186,8 @@ FakesAssemblies/
# LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
ModelManifest.xml
/PUP/.vs/IFS/v15/Server/sqlite3/db.lock
/PUP/.vs/IFS/v15/Server/sqlite3/storage.ide
/PUP/.vs/IFS/v15/Server/sqlite3/storage.ide-shm
/PUP/.vs/IFS/v15/Server/sqlite3/storage.ide-wal

View File

@@ -36,4 +36,4 @@ BOLDelay = 5000
# Debug settings
LogTypes = All
LogComponents = Routing
LogComponents = None

View File

@@ -85,7 +85,8 @@ namespace IFS
{
foreach (LivePacketDevice device in LivePacketDevice.AllLocalMachine)
{
if (device.GetNetworkInterface().Name.ToLowerInvariant() == Configuration.InterfaceName.ToLowerInvariant())
if (device.GetNetworkInterface() != null &&
device.GetNetworkInterface().Name.ToLowerInvariant() == Configuration.InterfaceName.ToLowerInvariant())
{
Router.Instance.RegisterRAWInterface(device);
bFound = true;

View File

@@ -139,7 +139,9 @@
<Content Include="Conf\networks.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="readme.txt" />
<Content Include="readme.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="Conf\ifs.cfg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

View File

@@ -113,7 +113,11 @@ namespace IFS
case PupType.MailCheckRequestLaurel:
SendMailCheckResponse(p);
break;
break;
case PupType.MicrocodeRequest:
SendMicrocodeResponse(p);
break;
default:
Log.Write(LogComponent.MiscServices, String.Format("Unhandled misc. protocol {0}", p.Type));
@@ -427,6 +431,90 @@ namespace IFS
}
}
private void SendMicrocodeResponse(PUP p)
{
//
// The request PUP contains the file number in the lower-order 16-bits of the pup ID.
// Assuming the number is a valid bootfile, we start sending it to the client's port via EFTP.
//
ushort fileNumber = (ushort)p.ID;
Log.Write(LogType.Verbose, LogComponent.MiscServices, "Microcode request is for file {0}.", fileNumber);
FileStream microcodeFile = BootServer.GetStreamForNumber(fileNumber);
if (microcodeFile == null)
{
Log.Write(LogType.Warning, LogComponent.MiscServices, "Microcode file {0} does not exist or could not be opened.", fileNumber);
}
else
{
// Send the file. The MicrocodeReply protocol is extremely simple:
// Just send a sequence of MicrocodeReply PUPs containing the microcode data,
// there are no acks or flow control of any kind.
Log.Write(LogType.Warning, LogComponent.MiscServices, "Sending microcode file {0}.", fileNumber);
SendMicrocodeFile(p.SourcePort, microcodeFile);
}
}
private void SendMicrocodeFile(PUPPort sourcePort, Stream microcodeFile)
{
//
// "For version 1 of the protocol, a server willing to supply the data simply sends a sequence of packets
// of type MicrocodeReply as fast as it can. The high half of its pupID contains the version number(1)
// and the low half of the pupID contains the packet sequence number. After all the data packets
// have been sent, the server sends an empty (0 data bytes) packet for an end marker. There are no
// acknowledgments. This protocol is used by Dolphins and Dorados.
// Currently, the version 1 servers send packets containing 3 * n words of data. This constraint is imposed by the
// Rev L Dolphin EPROM microcode. Id like to remove this restriction if I get a chance, so please dont take
// advantage of it unless you need to.The Rev L Dolphin EPROM also requires the second word of the source
// socket to be 4. / HGM May - 80."
//
// TODO: this should happen in a worker thread.
//
//
// We send 192 words of data per PUP (3 * 64) in an attempt to make the Dolphin happy.
// We space these out a bit to give the D-machine time to keep up, we're much much faster than they are.
//
PUPPort localPort = new PUPPort(DirectoryServices.Instance.LocalHostAddress, 4);
byte[] buffer = new byte[384];
bool done = false;
uint id = 0;
while (!done)
{
int read = microcodeFile.Read(buffer, 0, buffer.Length);
if (read < buffer.Length)
{
done = true;
}
if (read > 0)
{
PUP microcodeReply = new PUP(PupType.MicrocodeReply, (id | 0x00010000), sourcePort, localPort, buffer);
Router.Instance.SendPup(microcodeReply);
}
// Pause a bit to give the D0 time to breathe.
System.Threading.Thread.Sleep(5);
id++;
}
//
// Send an empty packet to conclude the transfer.
//
PUP endReply = new PUP(PupType.MicrocodeReply, (id | 0x00010000), sourcePort, localPort, new byte[] { });
Router.Instance.SendPup(endReply);
Log.Write(LogType.Warning, LogComponent.MiscServices, "Microcode file sent.");
}
private struct BootDirectoryBlock
{
public ushort FileNumber;

View File

@@ -97,7 +97,11 @@ namespace IFS
// Gateway Information Protocol
GatewayInformationRequest = 128,
GatewayInformationResponse = 129
GatewayInformationResponse = 129,
// D0 Microcode (handled by misc. services)
MicrocodeRequest = 180,
MicrocodeReply = 181,
}
public struct PUPPort

View File

@@ -53,7 +53,7 @@ namespace IFS.Transport
_routerCallback = callback;
// Now that we have a callback we can start receiving stuff.
Open(false /* not promiscuous */, int.MaxValue);
Open(false /* not promiscuous */, 0);
// Kick off the receiver thread, this will never return or exit.
Thread receiveThread = new Thread(new ThreadStart(BeginReceive));
@@ -207,7 +207,7 @@ namespace IFS.Transport
else
{
// Not a PUP, Discard the packet. We will not log this, so as to keep noise down.
//Log.Write(LogLevel.DroppedPacket, "Not a PUP. Dropping.");
// Log.Write(LogType.Verbose, LogComponent.Ethernet, "Not a PUP (type 0x{0:x}. Dropping.", p.Ethernet.EtherType);
}
}
@@ -215,7 +215,7 @@ namespace IFS.Transport
{
_communicator = _interface.Open(
0xffff,
promiscuous ? PacketDeviceOpenAttributes.Promiscuous | PacketDeviceOpenAttributes.NoCaptureLocal: PacketDeviceOpenAttributes.NoCaptureLocal,
promiscuous ? PacketDeviceOpenAttributes.Promiscuous : PacketDeviceOpenAttributes.None,
timeout);
_communicator.SetKernelMinimumBytesToCopy(1);