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:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -36,4 +36,4 @@ BOLDelay = 5000
|
||||
|
||||
# Debug settings
|
||||
LogTypes = All
|
||||
LogComponents = Routing
|
||||
LogComponents = None
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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. I’d like to remove this restriction if I get a chance, so please don’t 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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user