mirror of
https://github.com/livingcomputermuseum/ContrAlto.git
synced 2026-01-20 09:54:35 +00:00
Switched from PCap.net to SharpPcap for ethernet encapsulation; SharpPcap is cross-platform, this allows raw ethernet encapsulation to work on Linux and OS X.
This commit is contained in:
parent
aa9a2651ef
commit
c671b04ee8
@ -111,6 +111,9 @@ namespace Contralto
|
||||
break;
|
||||
}
|
||||
|
||||
// See if PCap is available.
|
||||
TestPCap();
|
||||
|
||||
ReadConfiguration();
|
||||
|
||||
// Special case: On first startup, AlternateBoot will come back as "None" which
|
||||
@ -201,6 +204,17 @@ namespace Contralto
|
||||
/// </summary>
|
||||
public static string AudioDACCapturePath;
|
||||
|
||||
/// <summary>
|
||||
/// The components to enable debug logging for.
|
||||
/// </summary>
|
||||
public static LogComponent LogComponents;
|
||||
|
||||
/// <summary>
|
||||
/// The types of logging to enable.
|
||||
/// </summary>
|
||||
public static LogType LogTypes;
|
||||
|
||||
|
||||
public static string GetAltoIRomPath(string romFileName)
|
||||
{
|
||||
return Path.Combine("ROM", "AltoI", romFileName);
|
||||
@ -262,7 +276,7 @@ namespace Contralto
|
||||
|
||||
private static void ReadConfigurationWindows()
|
||||
{
|
||||
Properties.Settings.Default.AudioDACCapturePath = Properties.Settings.Default.AudioDACCapturePath;
|
||||
AudioDACCapturePath = Properties.Settings.Default.AudioDACCapturePath;
|
||||
Drive0Image = Properties.Settings.Default.Drive0Image;
|
||||
Drive1Image = Properties.Settings.Default.Drive1Image;
|
||||
SystemType = (SystemType)Properties.Settings.Default.SystemType;
|
||||
@ -462,6 +476,23 @@ namespace Contralto
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void TestPCap()
|
||||
{
|
||||
// Just try enumerating interfaces, if this fails for any reason we assume
|
||||
// PCap is not properly installed.
|
||||
try
|
||||
{
|
||||
SharpPcap.CaptureDeviceList devices = SharpPcap.CaptureDeviceList.Instance;
|
||||
Configuration.HostRawEthernetInterfacesAvailable = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Configuration.HostRawEthernetInterfacesAvailable = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -101,29 +101,15 @@
|
||||
<HintPath>..\packages\NAudio.1.8.0\lib\net35\NAudio.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="PcapDotNet.Base, Version=1.0.4.25027, Culture=neutral, PublicKeyToken=06a20bc2fabb1931, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Pcap.Net.x86.1.0.4.1\lib\net45\PcapDotNet.Base.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="PcapDotNet.Core, Version=1.0.4.25067, Culture=neutral, PublicKeyToken=06a20bc2fabb1931, processorArchitecture=x86">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Pcap.Net.x86.1.0.4.1\lib\net45\PcapDotNet.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="PcapDotNet.Core.Extensions, Version=1.0.4.25069, Culture=neutral, PublicKeyToken=06a20bc2fabb1931, processorArchitecture=x86">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Pcap.Net.x86.1.0.4.1\lib\net45\PcapDotNet.Core.Extensions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="PcapDotNet.Packets, Version=1.0.4.25028, Culture=neutral, PublicKeyToken=06a20bc2fabb1931, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Pcap.Net.x86.1.0.4.1\lib\net45\PcapDotNet.Packets.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="PacketDotNet, Version=0.13.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Sharp_Pcap.4.2.0\lib\PacketDotNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SDL2-CS, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SDL2-CS.dll.2.0.0.0\lib\net20\SDL2-CS.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SharpPcap, Version=4.2.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Sharp_Pcap.4.2.0\lib\SharpPcap.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
|
||||
@ -62,9 +62,10 @@ namespace Contralto.IO
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
catch(Exception e)
|
||||
{
|
||||
_hostInterface = null;
|
||||
Log.Write(LogComponent.HostNetworkInterface, "Unable to configure network interface. Error {0}", e.Message);
|
||||
}
|
||||
|
||||
// More words than the Alto will ever send.
|
||||
|
||||
@ -15,20 +15,18 @@
|
||||
along with ContrAlto. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpPcap;
|
||||
using SharpPcap.WinPcap;
|
||||
using SharpPcap.LibPcap;
|
||||
using SharpPcap.AirPcap;
|
||||
using PacketDotNet;
|
||||
|
||||
using System;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
|
||||
using PcapDotNet.Base;
|
||||
using PcapDotNet.Core;
|
||||
using PcapDotNet.Core.Extensions;
|
||||
using PcapDotNet.Packets;
|
||||
using PcapDotNet.Packets.Ethernet;
|
||||
using System.IO;
|
||||
using Contralto.Logging;
|
||||
using System.Threading;
|
||||
|
||||
|
||||
namespace Contralto.IO
|
||||
{
|
||||
@ -39,29 +37,17 @@ namespace Contralto.IO
|
||||
{
|
||||
public EthernetInterface(string name, string description)
|
||||
{
|
||||
Name = name;
|
||||
Description = 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));
|
||||
}
|
||||
|
||||
return interfaces;
|
||||
}
|
||||
Name = name;
|
||||
Description = description;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0} ({1})", Name, Description);
|
||||
}
|
||||
|
||||
public string Name;
|
||||
public string Description;
|
||||
public string Name;
|
||||
public string Description;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -73,20 +59,35 @@ namespace Contralto.IO
|
||||
public class HostEthernetEncapsulation : IPacketEncapsulation
|
||||
{
|
||||
public HostEthernetEncapsulation(string name)
|
||||
{
|
||||
{
|
||||
// Find the specified device by name
|
||||
foreach (LivePacketDevice device in LivePacketDevice.AllLocalMachine)
|
||||
foreach (ICaptureDevice device in CaptureDeviceList.Instance)
|
||||
{
|
||||
if (device.GetNetworkInterface().Name.ToLowerInvariant() == Configuration.HostPacketInterfaceName.ToLowerInvariant())
|
||||
if (device is WinPcapDevice)
|
||||
{
|
||||
AttachInterface(device);
|
||||
break;
|
||||
//
|
||||
// We use the friendly name to make it easier to specify in config files.
|
||||
//
|
||||
if (((WinPcapDevice)device).Interface.FriendlyName.ToLowerInvariant() == name.ToLowerInvariant())
|
||||
{
|
||||
AttachInterface(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (device.Name.ToLowerInvariant() == name.ToLowerInvariant())
|
||||
{
|
||||
AttachInterface(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_interface == null)
|
||||
{
|
||||
throw new InvalidOperationException("Specified ethernet interface does not exist or is not compatible with WinPCAP.");
|
||||
Log.Write(LogComponent.HostNetworkInterface, "Specified ethernet interface does not exist or is not compatible with ContrAlto.");
|
||||
throw new InvalidOperationException("Specified ethernet interface does not exist or is not compatible with ContrAlto.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,20 +96,31 @@ namespace Contralto.IO
|
||||
_callback = callback;
|
||||
|
||||
// Now that we have a callback we can start receiving stuff.
|
||||
Open(false /* not promiscuous */, int.MaxValue);
|
||||
Open(false /* not promiscuous */, 0);
|
||||
BeginReceive();
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
if (_communicator != null)
|
||||
if (_interface != null)
|
||||
{
|
||||
_communicator.Break();
|
||||
}
|
||||
|
||||
if (_receiveThread != null)
|
||||
{
|
||||
_receiveThread.Abort();
|
||||
try
|
||||
{
|
||||
if (_interface.Started)
|
||||
{
|
||||
_interface.StopCapture();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Eat exceptions. The Pcap libs seem to throw on StopCapture on
|
||||
// Unix platforms, we don't really care about them (since we're shutting down anyway)
|
||||
// but this prevents debug spew from appearing on the console.
|
||||
}
|
||||
finally
|
||||
{
|
||||
_interface.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,50 +171,48 @@ namespace Contralto.IO
|
||||
Conversion.ToOctal(destinationHost),
|
||||
length);
|
||||
|
||||
MacAddress destinationMac = new MacAddress(_10mbitBroadcast);
|
||||
MacAddress sourceMac = new MacAddress((UInt48)(_10mbitMACPrefix | Configuration.HostAddress));
|
||||
_10mbitMACPrefix[5] = Configuration.HostAddress; // Stuff our current Alto host address into the 10mbit MAC
|
||||
|
||||
// Build the outgoing packet; place the source/dest addresses, type field and the raw data.
|
||||
EthernetLayer ethernetLayer = new EthernetLayer
|
||||
{
|
||||
Source = sourceMac,
|
||||
Destination = destinationMac,
|
||||
EtherType = (EthernetType)_3mbitFrameType,
|
||||
};
|
||||
EthernetPacket p = new EthernetPacket(
|
||||
new PhysicalAddress(_10mbitMACPrefix), // Source address
|
||||
_10mbitBroadcast, // Destnation (broadcast)
|
||||
(EthernetPacketType)_3mbitFrameType);
|
||||
|
||||
PayloadLayer payloadLayer = new PayloadLayer
|
||||
{
|
||||
Data = new Datagram(packetBytes),
|
||||
};
|
||||
|
||||
PacketBuilder builder = new PacketBuilder(ethernetLayer, payloadLayer);
|
||||
p.PayloadData = packetBytes;
|
||||
|
||||
// Send it over the 'net!
|
||||
_communicator.SendPacket(builder.Build(DateTime.Now));
|
||||
_interface.SendPacket(p);
|
||||
|
||||
Log.Write(LogComponent.HostNetworkInterface, "Encapsulated 3mbit packet sent.");
|
||||
}
|
||||
|
||||
private void ReceiveCallback(Packet p)
|
||||
private void ReceiveCallback(object sender, CaptureEventArgs e)
|
||||
{
|
||||
//
|
||||
// Filter out packets intended for the emulator, forward them on, drop everything else.
|
||||
//
|
||||
if ((int)p.Ethernet.EtherType == _3mbitFrameType && // encapsulated 3mbit frames
|
||||
(p.Ethernet.Source.ToValue() != (UInt48)(_10mbitMACPrefix | Configuration.HostAddress))) // and not sent by this emulator
|
||||
if (e.Packet.LinkLayerType == PacketDotNet.LinkLayers.Ethernet)
|
||||
{
|
||||
Log.Write(LogComponent.HostNetworkInterface, "Received encapsulated 3mbit packet.");
|
||||
_callback(p.Ethernet.Payload.ToMemoryStream());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not for us, discard the packet.
|
||||
EthernetPacket packet = (EthernetPacket)PacketDotNet.Packet.ParsePacket(PacketDotNet.LinkLayers.Ethernet, e.Packet.Data);
|
||||
|
||||
_10mbitMACPrefix[5] = Configuration.HostAddress;
|
||||
|
||||
if ((int)packet.Type == _3mbitFrameType && // encapsulated 3mbit frames
|
||||
(packet.SourceHwAddress != new System.Net.NetworkInformation.PhysicalAddress(_10mbitMACPrefix))) // and not sent by this emulator
|
||||
{
|
||||
Log.Write(LogComponent.HostNetworkInterface, "Received encapsulated 3mbit packet.");
|
||||
_callback(new System.IO.MemoryStream(packet.PayloadData));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not for us, discard the packet.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AttachInterface(LivePacketDevice iface)
|
||||
private void AttachInterface(ICaptureDevice iface)
|
||||
{
|
||||
_interface = iface;
|
||||
_interface = iface;
|
||||
|
||||
if (_interface == null)
|
||||
{
|
||||
@ -214,10 +224,18 @@ namespace Contralto.IO
|
||||
|
||||
private void Open(bool promiscuous, int timeout)
|
||||
{
|
||||
_communicator = _interface.Open(65536, promiscuous ? PacketDeviceOpenAttributes.MaximumResponsiveness | PacketDeviceOpenAttributes.Promiscuous : PacketDeviceOpenAttributes.MaximumResponsiveness, timeout);
|
||||
|
||||
// Set this to 1 so we'll get packets as soon as they arrive, no buffering.
|
||||
_communicator.SetKernelMinimumBytesToCopy(1);
|
||||
if (_interface is WinPcapDevice)
|
||||
{
|
||||
((WinPcapDevice)_interface).Open(promiscuous ? OpenFlags.MaxResponsiveness | OpenFlags.Promiscuous : OpenFlags.MaxResponsiveness, timeout);
|
||||
}
|
||||
else if (_interface is LibPcapLiveDevice)
|
||||
{
|
||||
((LibPcapLiveDevice)_interface).Open(promiscuous ? DeviceMode.Promiscuous : DeviceMode.Normal, timeout);
|
||||
}
|
||||
else if (_interface is AirPcapDevice)
|
||||
{
|
||||
((AirPcapDevice)_interface).Open(promiscuous ? OpenFlags.MaxResponsiveness | OpenFlags.Promiscuous : OpenFlags.MaxResponsiveness, timeout);
|
||||
}
|
||||
|
||||
Log.Write(LogComponent.HostNetworkInterface, "Host interface opened and receiving packets.");
|
||||
}
|
||||
@ -227,38 +245,23 @@ namespace Contralto.IO
|
||||
/// </summary>
|
||||
private void BeginReceive()
|
||||
{
|
||||
// Kick off receive thread.
|
||||
_receiveThread = new Thread(ReceiveThread);
|
||||
_receiveThread.Start();
|
||||
// Kick off receiver.
|
||||
_interface.OnPacketArrival += ReceiveCallback;
|
||||
_interface.StartCapture();
|
||||
}
|
||||
|
||||
private void ReceiveThread()
|
||||
{
|
||||
// Just call ReceivePackets, that's it. This will never return.
|
||||
// (probably need to make this more elegant so we can tear down the thread
|
||||
// properly.)
|
||||
Log.Write(LogComponent.HostNetworkInterface, "Receiver thread started.");
|
||||
|
||||
_communicator.ReceivePackets(-1, ReceiveCallback);
|
||||
}
|
||||
|
||||
private LivePacketDevice _interface;
|
||||
private PacketCommunicator _communicator;
|
||||
private ICaptureDevice _interface;
|
||||
private ReceivePacketDelegate _callback;
|
||||
|
||||
|
||||
// Thread used for receive
|
||||
private Thread _receiveThread;
|
||||
|
||||
private const int _3mbitFrameType = 0xbeef; // easy to identify, ostensibly unused by anything of any import
|
||||
|
||||
/// <summary>
|
||||
/// On output, these bytes are prepended to the Alto's 3mbit (1 byte) address to form a full
|
||||
/// 6 byte Ethernet MAC.
|
||||
/// On input, ethernet frames are checked for this prefix
|
||||
/// On input, ethernet frames are checked for this prefix.
|
||||
/// </summary>
|
||||
private UInt48 _10mbitMACPrefix = 0x0000aa010200; // 00-00-AA is the Xerox vendor code, used just to be cute.
|
||||
private byte[] _10mbitMACPrefix = { 0x00, 0x00, 0xaa, 0x01, 0x02, 0x00 }; // 00-00-AA is the Xerox vendor code, used just to be cute.
|
||||
|
||||
private UInt48 _10mbitBroadcast = (UInt48)0xffffffffffff;
|
||||
private PhysicalAddress _10mbitBroadcast = new PhysicalAddress(new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff });
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,11 +75,9 @@ namespace Contralto.Logging
|
||||
{
|
||||
static Log()
|
||||
{
|
||||
// TODO: make configurable
|
||||
_components = LogComponent.DAC;
|
||||
_type = LogType.Normal | LogType.Warning | LogType.Error | LogType.Verbose;
|
||||
_components = Configuration.LogComponents;
|
||||
_type = Configuration.LogTypes;
|
||||
|
||||
//_logStream = new StreamWriter("log.txt");
|
||||
}
|
||||
|
||||
public static LogComponent LogComponents
|
||||
@ -110,11 +108,6 @@ namespace Contralto.Logging
|
||||
// My log has something to tell you...
|
||||
// TODO: color based on type, etc.
|
||||
Console.WriteLine(component.ToString() + ": " + message, args);
|
||||
|
||||
if (_logStream != null)
|
||||
{
|
||||
_logStream.WriteLine(component.ToString() + ": " + message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
@ -132,6 +125,5 @@ namespace Contralto.Logging
|
||||
|
||||
private static LogComponent _components;
|
||||
private static LogType _type;
|
||||
private static StreamWriter _logStream;
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,10 +40,7 @@ namespace Contralto
|
||||
}
|
||||
|
||||
// Handle command-line args
|
||||
PrintHerald();
|
||||
|
||||
// See if WinPCap is installed and working
|
||||
TestPCap();
|
||||
PrintHerald();
|
||||
|
||||
_system = new AltoSystem();
|
||||
|
||||
@ -133,29 +130,7 @@ namespace Contralto
|
||||
Console.WriteLine("Bug reports to joshd@livingcomputers.org");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
private static void TestPCap()
|
||||
{
|
||||
if (Configuration.Platform == PlatformType.Windows)
|
||||
{
|
||||
// Just try enumerating interfaces, if this fails for any reason we assume
|
||||
// PCap is not properly installed.
|
||||
try
|
||||
{
|
||||
List<EthernetInterface> interfaces = EthernetInterface.EnumerateDevices();
|
||||
Configuration.HostRawEthernetInterfacesAvailable = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Configuration.HostRawEthernetInterfacesAvailable = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Configuration.HostRawEthernetInterfacesAvailable = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static AltoSystem _system;
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ namespace Contralto.SdlUI
|
||||
{
|
||||
if (_controller.IsRunning)
|
||||
{
|
||||
Console.WriteLine("Alto is already running. Use 'stop' to stop the Alto first.");
|
||||
_controller.Reset(AlternateBootType.Disk);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -169,10 +169,10 @@ namespace Contralto.SdlUI
|
||||
{
|
||||
if (_controller.IsRunning)
|
||||
{
|
||||
Console.WriteLine("Alto is already running. Use 'stop' to stop the Alto first.");
|
||||
_controller.Reset(AlternateBootType.Ethernet);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
_controller.StartExecution(AlternateBootType.Ethernet);
|
||||
}
|
||||
|
||||
|
||||
@ -16,10 +16,9 @@
|
||||
*/
|
||||
|
||||
using Contralto.IO;
|
||||
using PcapDotNet.Core;
|
||||
using PcapDotNet.Core.Extensions;
|
||||
using SharpPcap;
|
||||
using SharpPcap.WinPcap;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Windows.Forms;
|
||||
@ -79,7 +78,7 @@ namespace Contralto.UI
|
||||
|
||||
if (!Configuration.HostRawEthernetInterfacesAvailable)
|
||||
{
|
||||
// If PCAP isn't installed, the RAW Ethernet option is not available.
|
||||
// If PCAP isn't installed, the RAW Ethernet option is not available.
|
||||
RawEthernetRadioButton.Enabled = false;
|
||||
|
||||
// Ensure the option isn't set in the configuration.
|
||||
@ -102,7 +101,7 @@ namespace Contralto.UI
|
||||
case PacketInterfaceType.None:
|
||||
NoEncapsulationRadioButton.Checked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PopulateNetworkAdapterList(Configuration.HostPacketInterfaceType);
|
||||
|
||||
@ -153,22 +152,21 @@ namespace Contralto.UI
|
||||
case PacketInterfaceType.EthernetEncapsulation:
|
||||
if (Configuration.HostRawEthernetInterfacesAvailable)
|
||||
{
|
||||
foreach (LivePacketDevice device in LivePacketDevice.AllLocalMachine)
|
||||
{
|
||||
EthernetInterfaceListBox.Items.Add(new EthernetInterface(device.GetNetworkInterface().Name, device.GetNetworkInterface().Description));
|
||||
}
|
||||
}
|
||||
foreach (WinPcapDevice device in CaptureDeviceList.Instance)
|
||||
{
|
||||
EthernetInterfaceListBox.Items.Add(new EthernetInterface(device.Interface.FriendlyName, device.Interface.Description));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PacketInterfaceType.None:
|
||||
// Add nothing.
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Select the one that is already selected (if any)
|
||||
//
|
||||
//
|
||||
EthernetInterfaceListBox.SelectedIndex = 0;
|
||||
|
||||
if (!string.IsNullOrEmpty(Configuration.HostPacketInterfaceName))
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="NAudio" version="1.8.0" targetFramework="net452" />
|
||||
<package id="Pcap.Net.x86" version="1.0.4.1" targetFramework="net452" />
|
||||
<package id="SDL2-CS.dll" version="2.0.0.0" targetFramework="net452" />
|
||||
<package id="Sharp_Pcap" version="4.2.0" targetFramework="net452" />
|
||||
</packages>
|
||||
@ -282,8 +282,8 @@ Drive0Image and Drive1Image: Specifies a disk image to be loaded into the
|
||||
HostPacketInterfaceType: Specifies the type of interface to be used on the
|
||||
host for Ethernet emulation. One of:
|
||||
- UDPEncapsulation: Transmits Alto Ethernet packets over UDP broadcasts
|
||||
- RAWEncapsulation: Transmits Alto Ethernet packets over raw Ethernet packets.
|
||||
(not yet available on Unix / OS X platforms.)
|
||||
- EthernetEncapsulation: Transmits Alto Ethernet packets over raw Ethernet packets.
|
||||
(See Section 4.1 for configuration details)
|
||||
- None: No packet encapsulation.
|
||||
|
||||
HostPacketInterfaceName: Specifies the name of the host network interface
|
||||
@ -295,6 +295,24 @@ BootFile: The file number to use with a Keyboard Net Boot (again, Section 5.0
|
||||
AlternateBootType: The type of boot to default to (Section 5.0)
|
||||
|
||||
|
||||
4.1 Ethernet Encapsulation Setup
|
||||
================================
|
||||
|
||||
Encapsulation of Alto (3mbit) Ethernet packets in Ethernet broadcasts is supported
|
||||
on Linux and OS X using libpcap. While it is tested and works well, it may require some extra
|
||||
configuration on your system before it will work properly for you.
|
||||
|
||||
- Ensure that the latest libpcap libraries are installed. These should be present by default
|
||||
on OS X; on other platforms check your distribution's documentation for details.
|
||||
|
||||
- On many systems, libpcap requires additional privileges in order to capture packets.
|
||||
You can either run ContrAlto as root, or setuid ContrAlto to root. Depending on
|
||||
your operating system, there may be other options. See (for example)
|
||||
http://www.tcpdump.org/manpages/pcap.3pcap.html.
|
||||
|
||||
- You may need to modify SharpPcap.dll.config to point to the specific libpcap
|
||||
version you have installed on your system.
|
||||
|
||||
5.0 Console Interface
|
||||
=====================
|
||||
|
||||
@ -388,7 +406,7 @@ At the moment, the following issues are known and being worked on. If you find
|
||||
an issue not listed here, see section 7.0 to report a new bug.
|
||||
|
||||
- Smalltalk-80 does not run.
|
||||
- Audio and RAW ethernet packets are not available on Unix / OS X.
|
||||
- Audio is not available on Unix / OS X.
|
||||
|
||||
|
||||
7.0 Reporting Bugs
|
||||
@ -424,6 +442,9 @@ Contributions are welcome!
|
||||
ContrAlto would not have been possible without the amazing preservation work of
|
||||
the Computer History Museum.
|
||||
|
||||
Ethernet encapsulation is provided courtesy of SharpPcap, a WinPcap/LibPcap wrapper.
|
||||
See: https://github.com/chmorgan/sharppcap.
|
||||
|
||||
Audio output and capture on Windows is provided using the NAudio libraries, see:
|
||||
https://github.com/naudio/NAudio.
|
||||
|
||||
@ -442,6 +463,7 @@ V1.2
|
||||
- Initial implementation of Orbit rasterization device; Dover ROS is implemented
|
||||
but not working properly.
|
||||
- Added ability to load a configuration file at startup
|
||||
- Switched to cross-platform SharpPcap library for Ethernet encapsulation.
|
||||
|
||||
V1.1
|
||||
----
|
||||
|
||||
@ -247,19 +247,9 @@ encapsulation. ContrAlto can encapsulate the Alto's 3mbit ("experimental")
|
||||
Ethernet packets in either UDP datagrams or raw Ethernet packets on a network
|
||||
interface on the "host" computer (the computer running ContrAlto).
|
||||
|
||||
Raw packet encapsulation requires WinPCAP and the Microsoft Visual C++ 2010
|
||||
redistributable to be installed; these can be acquired from:
|
||||
Raw packet encapsulation requires WinPCAP libraries to be installed. See:
|
||||
http://www.winpcap.org/.
|
||||
|
||||
http://www.winpcap.org/
|
||||
and
|
||||
http://www.microsoft.com/en-us/download/details.aspx?id=5555
|
||||
|
||||
ContrAlto uses binaries from the Pcap.NET project to expose WinPCAP
|
||||
functionality to the emulator:
|
||||
|
||||
https://github.com/PcapDotNet/Pcap.Net
|
||||
|
||||
Pcap.NET is released under the BSD license.
|
||||
|
||||
4.2.1 Host Address
|
||||
------------------
|
||||
@ -443,8 +433,8 @@ CPU Registers:
|
||||
|
||||
General Registers:
|
||||
Shows the contents of the 32 R and 32 S registers (in octal).
|
||||
(The extra 7 sets of R and S registers on 3K CRAM machines are not yet
|
||||
displayed.)
|
||||
(The extra 7 sets of R and S registers on 3K CRAM machines are not yet
|
||||
displayed.)
|
||||
|
||||
Reserved Memory:
|
||||
Shows the contents of most "well known" memory locations. See the
|
||||
@ -493,6 +483,9 @@ Contributions are welcome!
|
||||
ContrAlto would not have been possible without the amazing preservation work of
|
||||
the Computer History Museum.
|
||||
|
||||
Ethernet encapsulation is provided courtesy of SharpPcap, a WinPcap/LibPcap wrapper.
|
||||
See: https://github.com/chmorgan/sharppcap.
|
||||
|
||||
Audio output and capture on Windows is provided using the NAudio libraries, see:
|
||||
https://github.com/naudio/NAudio.
|
||||
|
||||
@ -511,6 +504,7 @@ V1.2
|
||||
- Initial implementation of Orbit rasterization device; Dover ROS is implemented
|
||||
but not working properly.
|
||||
- Added ability to load a configuration file at startup
|
||||
- Switched to cross-platform SharpPcap library for Ethernet encapsulation.
|
||||
|
||||
V1.1
|
||||
----
|
||||
|
||||
@ -17,18 +17,18 @@
|
||||
-->
|
||||
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<Product Id="CE5F3D08-3BD6-4BDF-9C64-0C2B852B899C" Name="ContrAlto" Language="1033" Version="1.1.0" Manufacturer="Living Computers: Museum+Labs" UpgradeCode="38d6b09f-6e7b-4854-844a-5d4ab707a357">
|
||||
<Package Id="*" InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
|
||||
<Product Id="CE5F3D08-3BD6-4BDF-9C64-0C2B852B899C" Name="ContrAlto" Language="1033" Version="1.1.0" Manufacturer="Living Computers: Museum+Labs" UpgradeCode="38d6b09f-6e7b-4854-844a-5d4ab707a357">
|
||||
<Package Id="*" InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
|
||||
|
||||
<Upgrade Id="38d6b09f-6e7b-4854-844a-5d4ab707a357">
|
||||
<UpgradeVersion OnlyDetect="yes" Property="SELFFOUND"
|
||||
Minimum="1.1.0" IncludeMinimum="yes"
|
||||
Maximum="1.1.0" IncludeMaximum="yes" />
|
||||
Minimum="1.2.0" IncludeMinimum="yes"
|
||||
Maximum="1.2.0" IncludeMaximum="yes" />
|
||||
<UpgradeVersion OnlyDetect="yes" Property="NEWERFOUND"
|
||||
Minimum="1.1.0" IncludeMinimum="no" />
|
||||
Minimum="1.2.0" IncludeMinimum="no" />
|
||||
</Upgrade>
|
||||
|
||||
<CustomAction Id="AlreadyUpdated" Error="[ProductName] 1.0 has already been updated to 1.1.0 or newer." />
|
||||
<CustomAction Id="AlreadyUpdated" Error="[ProductName] 1.1 has already been updated to 1.2.0 or newer." />
|
||||
<CustomAction Id="NoDowngrade" Error="A later version of [ProductName] is already installed." />
|
||||
|
||||
<InstallExecuteSequence>
|
||||
@ -38,8 +38,8 @@
|
||||
|
||||
<Media Id="1" Cabinet="ContrAlto.cab" EmbedCab="yes"/>
|
||||
|
||||
<Feature Id="ProductFeature" Title="ContrAlto" Description="The ContrAlto Alto Emulator" Level="1" ConfigurableDirectory="INSTALLFOLDER">
|
||||
<ComponentGroupRef Id="ProductComponents" />
|
||||
<Feature Id="ProductFeature" Title="ContrAlto" Description="The ContrAlto Alto Emulator" Level="1" ConfigurableDirectory="INSTALLFOLDER">
|
||||
<ComponentGroupRef Id="ProductComponents" />
|
||||
<ComponentGroupRef Id="MicrocodeComponentsShared" />
|
||||
<ComponentGroupRef Id="MicrocodeComponentsAltoI" />
|
||||
<ComponentGroupRef Id="MicrocodeComponentsAltoII" />
|
||||
@ -47,7 +47,7 @@
|
||||
<ComponentGroupRef Id="DiskComponents" /> -->
|
||||
<ComponentGroupRef Id="CodeComponents" />
|
||||
<ComponentRef Id="ProgramMenuDir" />
|
||||
</Feature>
|
||||
</Feature>
|
||||
|
||||
<Icon Id="ContrAlto.exe" SourceFile="$(var.Contralto.TargetPath)"/>
|
||||
|
||||
@ -58,13 +58,13 @@
|
||||
|
||||
<WixVariable Id="WixUILicenseRtf" Value="EULA.rtf" />
|
||||
|
||||
</Product>
|
||||
</Product>
|
||||
|
||||
<Fragment>
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="ProgramFilesFolder">
|
||||
<Fragment>
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="ProgramFilesFolder">
|
||||
<Directory Id="LCM" Name="Living Computers">
|
||||
<Directory Id="INSTALLFOLDER" Name="Contralto">
|
||||
<Directory Id="INSTALLFOLDER" Name="Contralto">
|
||||
<Directory Id="ROMFOLDER" Name="ROM">
|
||||
<Directory Id="ROMFOLDERALTOI" Name="AltoI"/>
|
||||
<Directory Id="ROMFOLDERALTOII" Name="AltoII"/>
|
||||
@ -72,7 +72,7 @@
|
||||
<Directory Id="DISASSEMBLYFOLDER" Name="Disassembly"/>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
<Directory Id="ProgramMenuFolder" Name="Programs">
|
||||
<Directory Id="ProgramMenuDir" Name="ContrAlto">
|
||||
<Component Id="ProgramMenuDir" Guid="007ADB59-BCE4-43CB-9AEC-DD5962136A7D">
|
||||
@ -90,12 +90,12 @@
|
||||
</Component>
|
||||
</Directory>
|
||||
</Directory> -->
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Fragment>
|
||||
|
||||
<Fragment>
|
||||
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
|
||||
<!-- Main Contralto EXE and dependencies-->
|
||||
<Fragment>
|
||||
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
|
||||
<!-- Main Contralto EXE and dependencies-->
|
||||
<Component Id="ContraltoExecutable" Guid="0AF4F077-3858-4CEA-A3CD-CF8585F98AAA">
|
||||
<File Id="exe" Name="ContrAlto.exe" Source="$(var.Contralto.TargetPath)" KeyPath="yes">
|
||||
<Shortcut Id="shortcut" Directory="ProgramMenuDir" Name="ContrAlto"
|
||||
@ -103,10 +103,8 @@
|
||||
</File>
|
||||
|
||||
<!-- PCAP libs -->
|
||||
<File Source="$(var.Contralto.TargetDir)\PcapDotNet.Base.dll"/>
|
||||
<File Source="$(var.Contralto.TargetDir)\PcapDotNet.Core.dll"/>
|
||||
<File Source="$(var.Contralto.TargetDir)\PcapDotNet.Core.Extensions.dll"/>
|
||||
<File Source="$(var.Contralto.TargetDir)\PcapDotNet.Packets.dll"/>
|
||||
<File Source="$(var.Contralto.TargetDir)\PacketDotNet.dll"/>
|
||||
<File Source="$(var.Contralto.TargetDir)\SharpPcap.dll"/>
|
||||
|
||||
<!-- SDL2-CS libs - at this time we don't use SDL2 on Windows but the SDL2-CS wrapper
|
||||
still must be present. -->
|
||||
@ -120,7 +118,7 @@
|
||||
<Shortcut Id="docshortcut" Directory="ProgramMenuDir" Name="ContrAlto Readme" Advertise="yes" />
|
||||
</File>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
</ComponentGroup>
|
||||
|
||||
<ComponentGroup Id="MicrocodeComponentsShared" Directory="ROMFOLDER">
|
||||
<!-- Microcode and other ROM files shared between all Alto revisions -->
|
||||
@ -225,6 +223,6 @@
|
||||
<File Id="MesaROM" Name="MesaROM.mu" Source="$(var.Contralto.TargetDir)\Disassembly\MesaROM.mu"/>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
</Fragment>
|
||||
|
||||
</Wix>
|
||||
Loading…
x
Reference in New Issue
Block a user