mirror of
https://github.com/AppleWin/AppleWin.git
synced 2025-01-20 04:30:54 +00:00
Uthernet II: add virtual DNS feature (PR #1097)
Uthernet II: add extended feature to virtualise DNS requests. . This allows pure TCP/UDP sockets to run *without* MACRAW requests (and so without libpcap). . Raw sockets will not work. . Add configuration for Virtual DNS. libpcap: ensure all functions check if the library is loaded before using it. Uthernet 1: do NOT overwrite tfe_cannot_use as it should only reflect the availability of npcap on *this* system. Add Copyright notice, and mention Virtual DNS in html.
This commit is contained in:
parent
ccb4582bf9
commit
6a5ea92a4e
@ -114,6 +114,7 @@
|
|||||||
<ClInclude Include="source\StrFormat.h" />
|
<ClInclude Include="source\StrFormat.h" />
|
||||||
<ClInclude Include="source\SynchronousEventManager.h" />
|
<ClInclude Include="source\SynchronousEventManager.h" />
|
||||||
<ClInclude Include="source\Tape.h" />
|
<ClInclude Include="source\Tape.h" />
|
||||||
|
<ClInclude Include="source\Tfe\DNS.h" />
|
||||||
<ClInclude Include="source\Tfe\IPRaw.h" />
|
<ClInclude Include="source\Tfe\IPRaw.h" />
|
||||||
<ClInclude Include="source\Tfe\NetworkBackend.h" />
|
<ClInclude Include="source\Tfe\NetworkBackend.h" />
|
||||||
<ClInclude Include="source\Tfe\Bpf.h" />
|
<ClInclude Include="source\Tfe\Bpf.h" />
|
||||||
@ -157,6 +158,7 @@
|
|||||||
<ClCompile Include="source\CardManager.cpp" />
|
<ClCompile Include="source\CardManager.cpp" />
|
||||||
<ClCompile Include="source\CmdLine.cpp" />
|
<ClCompile Include="source\CmdLine.cpp" />
|
||||||
<ClCompile Include="source\Configuration\About.cpp" />
|
<ClCompile Include="source\Configuration\About.cpp" />
|
||||||
|
<ClCompile Include="source\Configuration\Config.cpp" />
|
||||||
<ClCompile Include="source\Configuration\PageAdvanced.cpp" />
|
<ClCompile Include="source\Configuration\PageAdvanced.cpp" />
|
||||||
<ClCompile Include="source\Configuration\PageConfig.cpp" />
|
<ClCompile Include="source\Configuration\PageConfig.cpp" />
|
||||||
<ClCompile Include="source\Configuration\PageConfigTfe.cpp" />
|
<ClCompile Include="source\Configuration\PageConfigTfe.cpp" />
|
||||||
@ -223,6 +225,7 @@
|
|||||||
<ClCompile Include="source\StrFormat.cpp" />
|
<ClCompile Include="source\StrFormat.cpp" />
|
||||||
<ClCompile Include="source\SynchronousEventManager.cpp" />
|
<ClCompile Include="source\SynchronousEventManager.cpp" />
|
||||||
<ClCompile Include="source\Tape.cpp" />
|
<ClCompile Include="source\Tape.cpp" />
|
||||||
|
<ClCompile Include="source\Tfe\DNS.cpp" />
|
||||||
<ClCompile Include="source\Tfe\IPRaw.cpp" />
|
<ClCompile Include="source\Tfe\IPRaw.cpp" />
|
||||||
<ClCompile Include="source\Tfe\NetworkBackend.cpp" />
|
<ClCompile Include="source\Tfe\NetworkBackend.cpp" />
|
||||||
<ClCompile Include="source\Tfe\PCapBackend.cpp" />
|
<ClCompile Include="source\Tfe\PCapBackend.cpp" />
|
||||||
|
@ -262,6 +262,12 @@
|
|||||||
<ClCompile Include="source\Tfe\IPRaw.cpp">
|
<ClCompile Include="source\Tfe\IPRaw.cpp">
|
||||||
<Filter>Source Files\Uthernet</Filter>
|
<Filter>Source Files\Uthernet</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="source\Tfe\DNS.cpp">
|
||||||
|
<Filter>Source Files\Uthernet</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="source\Configuration\Config.cpp">
|
||||||
|
<Filter>Source Files\Configuration</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="source\CommonVICE\6510core.h">
|
<ClInclude Include="source\CommonVICE\6510core.h">
|
||||||
@ -600,6 +606,9 @@
|
|||||||
<ClInclude Include="source\Tfe\IPRaw.h">
|
<ClInclude Include="source\Tfe\IPRaw.h">
|
||||||
<Filter>Source Files\Uthernet</Filter>
|
<Filter>Source Files\Uthernet</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="source\Tfe\DNS.h">
|
||||||
|
<Filter>Source Files\Uthernet</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="resource\Applewin.bmp">
|
<Image Include="resource\Applewin.bmp">
|
||||||
|
@ -97,5 +97,8 @@
|
|||||||
<li>after loading a save-state file, TCP and UDP sockets are closed</li>
|
<li>after loading a save-state file, TCP and UDP sockets are closed</li>
|
||||||
</ul>
|
</ul>
|
||||||
</P>
|
</P>
|
||||||
|
<P>The card implements a <A href="https://github.com/a2retrosystems/uthernet2/wiki/Virtual-W5100-with-DNS">Virtual DNS</A>
|
||||||
|
interface (not found on real hardware) for Apple II software to run without raw sockets:
|
||||||
|
this allows operation on any type of network.</P>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -206,19 +206,22 @@ BEGIN
|
|||||||
PUSHBUTTON "&Browse...",IDC_CIDERPRESS_BROWSE,161,202,50,14
|
PUSHBUTTON "&Browse...",IDC_CIDERPRESS_BROWSE,161,202,50,14
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_TFE_SETTINGS_DIALOG DIALOGEX 0, 0, 270, 100
|
IDD_TFE_SETTINGS_DIALOG DIALOGEX 0, 0, 271, 155
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
CAPTION "Ethernet Settings"
|
CAPTION "Ethernet Settings"
|
||||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "Ethernet",IDC_TFE_SETTINGS_ENABLE_T,9,7,30,8
|
LTEXT "Ethernet",IDC_TFE_SETTINGS_ENABLE_T,9,7,30,8
|
||||||
COMBOBOX IDC_TFE_SETTINGS_ENABLE,45,5,60,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_TFE_SETTINGS_ENABLE,45,5,60,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||||
|
CONTROL "Virtual DNS",IDC_CHECK_TFE_VIRTUAL_DNS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,7,50,8
|
||||||
LTEXT "Interface",IDC_TFE_SETTINGS_INTERFACE_T,9,24,30,8
|
LTEXT "Interface",IDC_TFE_SETTINGS_INTERFACE_T,9,24,30,8
|
||||||
COMBOBOX IDC_TFE_SETTINGS_INTERFACE,45,22,210,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_TFE_SETTINGS_INTERFACE,45,22,210,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||||
LTEXT "",IDC_TFE_SETTINGS_INTERFACE_NAME,9,44,250,8
|
LTEXT "",IDC_TFE_SETTINGS_INTERFACE_NAME,9,44,250,8
|
||||||
LTEXT "",IDC_TFE_SETTINGS_INTERFACE_DESC,9,60,250,8
|
LTEXT "",IDC_TFE_SETTINGS_INTERFACE_DESC,9,60,250,8
|
||||||
DEFPUSHBUTTON "Ok",IDOK,20,75,50,14
|
GROUPBOX "Npcap",IDC_STATIC,5,75,260,55
|
||||||
PUSHBUTTON "Cancel",IDCANCEL,80,75,50,14
|
LTEXT "",IDC_TFE_NPCAP_INFO,12,86,240,36
|
||||||
|
DEFPUSHBUTTON "Ok",IDOK,20,135,50,14
|
||||||
|
PUSHBUTTON "Cancel",IDCANCEL,80,135,50,14
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_PROPPAGE_ADVANCED DIALOGEX 0, 0, 210, 217
|
IDD_PROPPAGE_ADVANCED DIALOGEX 0, 0, 210, 217
|
||||||
|
@ -119,6 +119,8 @@
|
|||||||
#define IDC_FOURPLAY_CONFIG 1087
|
#define IDC_FOURPLAY_CONFIG 1087
|
||||||
#define IDC_SNESMAX_CONFIG 1088
|
#define IDC_SNESMAX_CONFIG 1088
|
||||||
#define IDC_CHECK_VIDHD_IN_SLOT3 1089
|
#define IDC_CHECK_VIDHD_IN_SLOT3 1089
|
||||||
|
#define IDC_CHECK_TFE_VIRTUAL_DNS 1090
|
||||||
|
#define IDC_TFE_NPCAP_INFO 1091
|
||||||
#define IDM_EXIT 40001
|
#define IDM_EXIT 40001
|
||||||
#define IDM_HELP 40002
|
#define IDM_HELP 40002
|
||||||
#define IDM_ABOUT 40003
|
#define IDM_ABOUT 40003
|
||||||
|
@ -108,6 +108,7 @@ enum AppMode_e
|
|||||||
#define REGVALUE_WINDOW_SCALE "Window Scale"
|
#define REGVALUE_WINDOW_SCALE "Window Scale"
|
||||||
#define REGVALUE_UTHERNET_ACTIVE "Uthernet Active" // GH#977: Deprecated from 1.30.5
|
#define REGVALUE_UTHERNET_ACTIVE "Uthernet Active" // GH#977: Deprecated from 1.30.5
|
||||||
#define REGVALUE_UTHERNET_INTERFACE "Uthernet Interface"
|
#define REGVALUE_UTHERNET_INTERFACE "Uthernet Interface"
|
||||||
|
#define REGVALUE_UTHERNET_VIRTUAL_DNS "Uthernet Virtual DNS"
|
||||||
#define REGVALUE_SLOT4 "Slot 4" // GH#977: Deprecated from 1.30.4
|
#define REGVALUE_SLOT4 "Slot 4" // GH#977: Deprecated from 1.30.4
|
||||||
#define REGVALUE_SLOT5 "Slot 5" // GH#977: Deprecated from 1.30.4
|
#define REGVALUE_SLOT5 "Slot 5" // GH#977: Deprecated from 1.30.4
|
||||||
#define REGVALUE_VERSION "Version"
|
#define REGVALUE_VERSION "Version"
|
||||||
|
98
source/Configuration/Config.cpp
Normal file
98
source/Configuration/Config.cpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
AppleWin : An Apple //e emulator for Windows
|
||||||
|
|
||||||
|
Copyright (C) 1994-1996, Michael O'Brien
|
||||||
|
Copyright (C) 1999-2001, Oliver Schmidt
|
||||||
|
Copyright (C) 2002-2005, Tom Charlesworth
|
||||||
|
Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski
|
||||||
|
|
||||||
|
AppleWin is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
AppleWin is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with AppleWin; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
#include "Config.h"
|
||||||
|
#include "../CardManager.h"
|
||||||
|
#include "../Interface.h" // VideoRefreshRate_e, GetVideoRefreshRate()
|
||||||
|
#include "../Uthernet2.h"
|
||||||
|
#include "../Tfe/PCapBackend.h"
|
||||||
|
|
||||||
|
// zero initialise
|
||||||
|
CConfigNeedingRestart::CConfigNeedingRestart()
|
||||||
|
{
|
||||||
|
m_Apple2Type = A2TYPE_APPLE2;
|
||||||
|
m_CpuType = CPU_UNKNOWN;
|
||||||
|
memset(m_Slot, 0, sizeof(m_Slot));
|
||||||
|
m_SlotAux = CT_Empty;
|
||||||
|
m_tfeVirtualDNS = false;
|
||||||
|
m_bEnableTheFreezesF8Rom = 0;
|
||||||
|
m_uSaveLoadStateMsg = 0;
|
||||||
|
m_videoRefreshRate = VR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create from current global configuration
|
||||||
|
CConfigNeedingRestart CConfigNeedingRestart::Create()
|
||||||
|
{
|
||||||
|
CConfigNeedingRestart config;
|
||||||
|
config.Reload();
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update from current global configuration
|
||||||
|
void CConfigNeedingRestart::Reload()
|
||||||
|
{
|
||||||
|
m_Apple2Type = GetApple2Type();
|
||||||
|
m_CpuType = GetMainCpu();
|
||||||
|
CardManager& cardManager = GetCardMgr();
|
||||||
|
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
||||||
|
m_Slot[slot] = cardManager.QuerySlot(slot);
|
||||||
|
m_SlotAux = cardManager.QueryAux();
|
||||||
|
m_tfeInterface = PCapBackend::GetRegistryInterface(SLOT3);
|
||||||
|
m_tfeVirtualDNS = Uthernet2::GetRegistryVirtualDNS(SLOT3);
|
||||||
|
m_bEnableTheFreezesF8Rom = GetPropertySheet().GetTheFreezesF8Rom();
|
||||||
|
m_uSaveLoadStateMsg = 0;
|
||||||
|
m_videoRefreshRate = GetVideo().GetVideoRefreshRate();
|
||||||
|
}
|
||||||
|
|
||||||
|
const CConfigNeedingRestart& CConfigNeedingRestart::operator= (const CConfigNeedingRestart& other)
|
||||||
|
{
|
||||||
|
m_Apple2Type = other.m_Apple2Type;
|
||||||
|
m_CpuType = other.m_CpuType;
|
||||||
|
memcpy(m_Slot, other.m_Slot, sizeof(m_Slot));
|
||||||
|
m_SlotAux = other.m_SlotAux;
|
||||||
|
m_tfeInterface = other.m_tfeInterface;
|
||||||
|
m_tfeVirtualDNS = other.m_tfeVirtualDNS;
|
||||||
|
m_bEnableTheFreezesF8Rom = other.m_bEnableTheFreezesF8Rom;
|
||||||
|
m_uSaveLoadStateMsg = other.m_uSaveLoadStateMsg;
|
||||||
|
m_videoRefreshRate = other.m_videoRefreshRate;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CConfigNeedingRestart::operator== (const CConfigNeedingRestart& other) const
|
||||||
|
{
|
||||||
|
return m_Apple2Type == other.m_Apple2Type &&
|
||||||
|
m_CpuType == other.m_CpuType &&
|
||||||
|
memcmp(m_Slot, other.m_Slot, sizeof(m_Slot)) == 0 &&
|
||||||
|
m_SlotAux == other.m_SlotAux &&
|
||||||
|
m_tfeInterface == other.m_tfeInterface &&
|
||||||
|
m_tfeVirtualDNS == other.m_tfeVirtualDNS &&
|
||||||
|
m_bEnableTheFreezesF8Rom == other.m_bEnableTheFreezesF8Rom &&
|
||||||
|
m_uSaveLoadStateMsg == other.m_uSaveLoadStateMsg &&
|
||||||
|
m_videoRefreshRate == other.m_videoRefreshRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CConfigNeedingRestart::operator!= (const CConfigNeedingRestart& other) const
|
||||||
|
{
|
||||||
|
return !operator==(other);
|
||||||
|
}
|
@ -1,86 +1,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../Core.h"
|
#include "../Core.h"
|
||||||
#include "../CardManager.h"
|
|
||||||
#include "../CPU.h"
|
#include "../CPU.h"
|
||||||
#include "../DiskImage.h" // Disk_Status_e
|
#include "../Video.h"
|
||||||
#include "../Harddisk.h"
|
|
||||||
#include "../Interface.h" // VideoRefreshRate_e, GetVideoRefreshRate()
|
|
||||||
#include "../Tfe/PCapBackend.h"
|
|
||||||
|
|
||||||
class CConfigNeedingRestart
|
class CConfigNeedingRestart
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// zero initialise
|
// zero initialise
|
||||||
CConfigNeedingRestart()
|
CConfigNeedingRestart();
|
||||||
{
|
|
||||||
m_Apple2Type = A2TYPE_APPLE2;
|
|
||||||
m_CpuType = CPU_UNKNOWN;
|
|
||||||
memset(m_Slot, 0, sizeof(m_Slot));
|
|
||||||
m_SlotAux = CT_Empty;
|
|
||||||
m_bEnableTheFreezesF8Rom = 0;
|
|
||||||
m_uSaveLoadStateMsg = 0;
|
|
||||||
m_videoRefreshRate = VR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create from current global configuration
|
// create from current global configuration
|
||||||
static CConfigNeedingRestart Create()
|
static CConfigNeedingRestart Create();
|
||||||
{
|
|
||||||
CConfigNeedingRestart config;
|
|
||||||
config.Reload();
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update from current global configuration
|
// update from current global configuration
|
||||||
void Reload()
|
void Reload();
|
||||||
{
|
|
||||||
m_Apple2Type = GetApple2Type();
|
|
||||||
m_CpuType = GetMainCpu();
|
|
||||||
CardManager& cardManager = GetCardMgr();
|
|
||||||
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
|
||||||
m_Slot[slot] = cardManager.QuerySlot(slot);
|
|
||||||
m_SlotAux = cardManager.QueryAux();
|
|
||||||
m_tfeInterface = PCapBackend::tfe_interface;
|
|
||||||
m_bEnableTheFreezesF8Rom = GetPropertySheet().GetTheFreezesF8Rom();
|
|
||||||
m_uSaveLoadStateMsg = 0;
|
|
||||||
m_videoRefreshRate = GetVideo().GetVideoRefreshRate();
|
|
||||||
}
|
|
||||||
|
|
||||||
const CConfigNeedingRestart& operator= (const CConfigNeedingRestart& other)
|
const CConfigNeedingRestart& operator= (const CConfigNeedingRestart& other);
|
||||||
{
|
|
||||||
m_Apple2Type = other.m_Apple2Type;
|
|
||||||
m_CpuType = other.m_CpuType;
|
|
||||||
memcpy(m_Slot, other.m_Slot, sizeof(m_Slot));
|
|
||||||
m_SlotAux = other.m_SlotAux;
|
|
||||||
m_tfeInterface = other.m_tfeInterface;
|
|
||||||
m_bEnableTheFreezesF8Rom = other.m_bEnableTheFreezesF8Rom;
|
|
||||||
m_uSaveLoadStateMsg = other.m_uSaveLoadStateMsg;
|
|
||||||
m_videoRefreshRate = other.m_videoRefreshRate;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator== (const CConfigNeedingRestart& other) const
|
bool operator== (const CConfigNeedingRestart& other) const;
|
||||||
{
|
|
||||||
return m_Apple2Type == other.m_Apple2Type &&
|
|
||||||
m_CpuType == other.m_CpuType &&
|
|
||||||
memcmp(m_Slot, other.m_Slot, sizeof(m_Slot)) == 0 &&
|
|
||||||
m_SlotAux == other.m_SlotAux &&
|
|
||||||
m_tfeInterface == other.m_tfeInterface &&
|
|
||||||
m_bEnableTheFreezesF8Rom == other.m_bEnableTheFreezesF8Rom &&
|
|
||||||
m_uSaveLoadStateMsg == other.m_uSaveLoadStateMsg &&
|
|
||||||
m_videoRefreshRate == other.m_videoRefreshRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!= (const CConfigNeedingRestart& other) const
|
bool operator!= (const CConfigNeedingRestart& other) const;
|
||||||
{
|
|
||||||
return !operator==(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
eApple2Type m_Apple2Type;
|
eApple2Type m_Apple2Type;
|
||||||
eCpuType m_CpuType;
|
eCpuType m_CpuType;
|
||||||
SS_CARDTYPE m_Slot[NUM_SLOTS];
|
SS_CARDTYPE m_Slot[NUM_SLOTS];
|
||||||
SS_CARDTYPE m_SlotAux;
|
SS_CARDTYPE m_SlotAux;
|
||||||
std::string m_tfeInterface;
|
std::string m_tfeInterface;
|
||||||
|
bool m_tfeVirtualDNS;
|
||||||
UINT m_bEnableTheFreezesF8Rom;
|
UINT m_bEnableTheFreezesF8Rom;
|
||||||
UINT m_uSaveLoadStateMsg;
|
UINT m_uSaveLoadStateMsg;
|
||||||
VideoRefreshRate_e m_videoRefreshRate;
|
VideoRefreshRate_e m_videoRefreshRate;
|
||||||
|
@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "../ParallelPrinter.h"
|
#include "../ParallelPrinter.h"
|
||||||
#include "../Registry.h"
|
#include "../Registry.h"
|
||||||
#include "../SaveState.h"
|
#include "../SaveState.h"
|
||||||
|
#include "../CardManager.h"
|
||||||
#include "../resource/resource.h"
|
#include "../resource/resource.h"
|
||||||
|
|
||||||
CPageAdvanced* CPageAdvanced::ms_this = 0; // reinit'd in ctor
|
CPageAdvanced* CPageAdvanced::ms_this = 0; // reinit'd in ctor
|
||||||
|
@ -30,6 +30,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "../Windows/Win32Frame.h"
|
#include "../Windows/Win32Frame.h"
|
||||||
#include "../Registry.h"
|
#include "../Registry.h"
|
||||||
#include "../SerialComms.h"
|
#include "../SerialComms.h"
|
||||||
|
#include "../CardManager.h"
|
||||||
|
#include "../Uthernet2.h"
|
||||||
|
#include "../Tfe/PCapBackend.h"
|
||||||
|
#include "../Interface.h"
|
||||||
#include "../resource/resource.h"
|
#include "../resource/resource.h"
|
||||||
|
|
||||||
CPageConfig* CPageConfig::ms_this = 0; // reinit'd in ctor
|
CPageConfig* CPageConfig::ms_this = 0; // reinit'd in ctor
|
||||||
@ -114,6 +118,7 @@ INT_PTR CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPA
|
|||||||
ui_tfe_settings_dialog(hWnd);
|
ui_tfe_settings_dialog(hWnd);
|
||||||
m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT3] = m_PageConfigTfe.m_tfe_selected;
|
m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT3] = m_PageConfigTfe.m_tfe_selected;
|
||||||
m_PropertySheetHelper.GetConfigNew().m_tfeInterface = m_PageConfigTfe.m_tfe_interface_name;
|
m_PropertySheetHelper.GetConfigNew().m_tfeInterface = m_PageConfigTfe.m_tfe_interface_name;
|
||||||
|
m_PropertySheetHelper.GetConfigNew().m_tfeVirtualDNS = m_PageConfigTfe.m_tfe_virtual_dns;
|
||||||
InitOptions(hWnd);
|
InitOptions(hWnd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -261,7 +266,8 @@ INT_PTR CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPA
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_PageConfigTfe.m_tfe_interface_name = PCapBackend::tfe_interface;
|
m_PageConfigTfe.m_tfe_interface_name = PCapBackend::GetRegistryInterface(SLOT3);
|
||||||
|
m_PageConfigTfe.m_tfe_virtual_dns = Uthernet2::GetRegistryVirtualDNS(SLOT3);
|
||||||
}
|
}
|
||||||
|
|
||||||
InitOptions(hWnd);
|
InitOptions(hWnd);
|
||||||
|
@ -135,37 +135,16 @@ BOOL CPageConfigTfe::get_tfename(int number, std::string & name, std::string & d
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CPageConfigTfe::gray_ungray_items(HWND hwnd)
|
void CPageConfigTfe::gray_ungray_items(HWND hwnd)
|
||||||
{
|
{
|
||||||
int enable;
|
const int enable = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE), CB_GETCURSEL, 0, 0);
|
||||||
int number;
|
|
||||||
|
|
||||||
int disabled = 0;
|
|
||||||
PCapBackend::get_disabled_state(&disabled);
|
|
||||||
|
|
||||||
if (disabled)
|
|
||||||
{
|
|
||||||
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE_T), 0);
|
|
||||||
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE), 0);
|
|
||||||
EnableWindow(GetDlgItem(hwnd, IDOK), 0);
|
|
||||||
SetWindowText(GetDlgItem(hwnd,IDC_TFE_SETTINGS_INTERFACE_NAME), "");
|
|
||||||
SetWindowText(GetDlgItem(hwnd,IDC_TFE_SETTINGS_INTERFACE_DESC), "");
|
|
||||||
enable = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
enable = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE), CB_GETCURSEL, 0, 0) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_T), enable);
|
|
||||||
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE), enable);
|
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string description;
|
std::string description;
|
||||||
|
|
||||||
number = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE), CB_GETCURSEL, 0, 0);
|
const int number = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE), CB_GETCURSEL, 0, 0);
|
||||||
|
|
||||||
if (get_tfename(number, name, description))
|
if (get_tfename(number, name, description))
|
||||||
{
|
{
|
||||||
@ -179,7 +158,7 @@ int CPageConfigTfe::gray_ungray_items(HWND hwnd)
|
|||||||
SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_DESC), "");
|
SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_DESC), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
return disabled ? 1 : 0;
|
EnableWindow(GetDlgItem(hwnd, IDC_CHECK_TFE_VIRTUAL_DNS), enable == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
||||||
@ -193,6 +172,23 @@ void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
|||||||
uilib_adjust_group_width(hwnd, ms_leftgroup);
|
uilib_adjust_group_width(hwnd, ms_leftgroup);
|
||||||
uilib_move_group(hwnd, ms_rightgroup, xsize + 30);
|
uilib_move_group(hwnd, ms_rightgroup, xsize + 30);
|
||||||
|
|
||||||
|
if (PCapBackend::tfe_is_npcap_loaded())
|
||||||
|
{
|
||||||
|
const char * version = PCapBackend::tfe_lib_version();
|
||||||
|
SetWindowText(GetDlgItem(hwnd, IDC_TFE_NPCAP_INFO), version);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE), 0);
|
||||||
|
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_NAME), 0);
|
||||||
|
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_DESC), 0);
|
||||||
|
|
||||||
|
SetWindowText(GetDlgItem(hwnd, IDC_TFE_NPCAP_INFO),
|
||||||
|
"Limited Uthernet support is available on your system.\n\n"
|
||||||
|
"Install Npcap from https://npcap.com\n"
|
||||||
|
"or select Uthernet II with Virtual DNS.");
|
||||||
|
}
|
||||||
|
|
||||||
switch (m_tfe_selected)
|
switch (m_tfe_selected)
|
||||||
{
|
{
|
||||||
case CT_Uthernet:
|
case CT_Uthernet:
|
||||||
@ -206,6 +202,8 @@ void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckDlgButton(hwnd, IDC_CHECK_TFE_VIRTUAL_DNS, m_tfe_virtual_dns ? BST_CHECKED : BST_UNCHECKED);
|
||||||
|
|
||||||
temp_hwnd=GetDlgItem(hwnd,IDC_TFE_SETTINGS_ENABLE);
|
temp_hwnd=GetDlgItem(hwnd,IDC_TFE_SETTINGS_ENABLE);
|
||||||
SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)"Disabled");
|
SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)"Disabled");
|
||||||
SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)"Uthernet");
|
SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)"Uthernet");
|
||||||
@ -244,22 +242,7 @@ void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
|||||||
PCapBackend::tfe_enumadapter_close();
|
PCapBackend::tfe_enumadapter_close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gray_ungray_items(hwnd))
|
gray_ungray_items(hwnd);
|
||||||
{
|
|
||||||
/* we have a problem: TFE is disabled. Give a message to the user */
|
|
||||||
// TC (18 Dec 2017) this vicekb URL is a broken link now, so I copied it to the AppleWin repo, here:
|
|
||||||
// . https://github.com/AppleWin/AppleWin/blob/master/docs/VICE%20Knowledge%20Base%20-%20Article%2013-005.htm
|
|
||||||
MessageBox( hwnd,
|
|
||||||
"Uthernet support is not available on your system,\n"
|
|
||||||
"WPCAP.DLL cannot be loaded.\n\n"
|
|
||||||
"Install Npcap from\n\n"
|
|
||||||
" https://npcap.com\n\n"
|
|
||||||
"to activate networking with AppleWin.",
|
|
||||||
"Uthernet support", MB_ICONINFORMATION|MB_OK);
|
|
||||||
|
|
||||||
/* just quit the dialog before it is open */
|
|
||||||
SendMessage( hwnd, WM_COMMAND, IDCANCEL, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPageConfigTfe::save_tfe_dialog(HWND hwnd)
|
void CPageConfigTfe::save_tfe_dialog(HWND hwnd)
|
||||||
@ -270,10 +253,8 @@ void CPageConfigTfe::save_tfe_dialog(HWND hwnd)
|
|||||||
buffer[255] = 0;
|
buffer[255] = 0;
|
||||||
GetDlgItemText(hwnd, IDC_TFE_SETTINGS_INTERFACE, buffer, sizeof(buffer)-1);
|
GetDlgItemText(hwnd, IDC_TFE_SETTINGS_INTERFACE, buffer, sizeof(buffer)-1);
|
||||||
|
|
||||||
// RGJ - Added check for NULL interface so we don't set it active without a valid interface selected
|
|
||||||
if (strlen(buffer) > 0)
|
|
||||||
{
|
|
||||||
m_tfe_interface_name = buffer;
|
m_tfe_interface_name = buffer;
|
||||||
|
|
||||||
active_value = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE), CB_GETCURSEL, 0, 0);
|
active_value = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE), CB_GETCURSEL, 0, 0);
|
||||||
switch (active_value)
|
switch (active_value)
|
||||||
{
|
{
|
||||||
@ -287,10 +268,6 @@ void CPageConfigTfe::save_tfe_dialog(HWND hwnd)
|
|||||||
m_tfe_selected = CT_Empty;
|
m_tfe_selected = CT_Empty;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
m_tfe_virtual_dns = IsDlgButtonChecked(hwnd, IDC_CHECK_TFE_VIRTUAL_DNS) ? 1 : 0;
|
||||||
{
|
|
||||||
m_tfe_selected = CT_Empty;
|
|
||||||
m_tfe_interface_name.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ public:
|
|||||||
{
|
{
|
||||||
CPageConfigTfe::ms_this = this;
|
CPageConfigTfe::ms_this = this;
|
||||||
m_tfe_selected = CT_Empty;
|
m_tfe_selected = CT_Empty;
|
||||||
|
m_tfe_virtual_dns = false;
|
||||||
}
|
}
|
||||||
virtual ~CPageConfigTfe(){}
|
virtual ~CPageConfigTfe(){}
|
||||||
|
|
||||||
@ -20,6 +21,7 @@ public:
|
|||||||
|
|
||||||
SS_CARDTYPE m_tfe_selected;
|
SS_CARDTYPE m_tfe_selected;
|
||||||
std::string m_tfe_interface_name;
|
std::string m_tfe_interface_name;
|
||||||
|
bool m_tfe_virtual_dns;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// IPropertySheetPage
|
// IPropertySheetPage
|
||||||
@ -29,7 +31,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
BOOL get_tfename(int number, std::string & name, std::string & description);
|
BOOL get_tfename(int number, std::string & name, std::string & description);
|
||||||
int gray_ungray_items(HWND hwnd);
|
void gray_ungray_items(HWND hwnd);
|
||||||
void init_tfe_dialog(HWND hwnd);
|
void init_tfe_dialog(HWND hwnd);
|
||||||
void save_tfe_dialog(HWND hwnd);
|
void save_tfe_dialog(HWND hwnd);
|
||||||
|
|
||||||
|
@ -29,7 +29,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "../Windows/AppleWin.h"
|
#include "../Windows/AppleWin.h"
|
||||||
#include "../CardManager.h"
|
#include "../CardManager.h"
|
||||||
#include "../Disk.h" // Drive_e, Disk_Status_e
|
#include "../Disk.h" // Drive_e, Disk_Status_e
|
||||||
|
#include "../HardDisk.h"
|
||||||
#include "../Registry.h"
|
#include "../Registry.h"
|
||||||
|
#include "../Interface.h"
|
||||||
#include "../resource/resource.h"
|
#include "../resource/resource.h"
|
||||||
|
|
||||||
CPageDisk* CPageDisk::ms_this = 0; // reinit'd in ctor
|
CPageDisk* CPageDisk::ms_this = 0; // reinit'd in ctor
|
||||||
|
@ -33,6 +33,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "../Log.h"
|
#include "../Log.h"
|
||||||
#include "../Registry.h"
|
#include "../Registry.h"
|
||||||
#include "../SaveState.h"
|
#include "../SaveState.h"
|
||||||
|
#include "../Interface.h"
|
||||||
|
#include "../Uthernet2.h"
|
||||||
#include "../Tfe/PCapBackend.h"
|
#include "../Tfe/PCapBackend.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -336,7 +338,8 @@ void CPropertySheetHelper::ApplyNewConfig(const CConfigNeedingRestart& ConfigNew
|
|||||||
SetSlot(slot, ConfigNew.m_Slot[slot]);
|
SetSlot(slot, ConfigNew.m_Slot[slot]);
|
||||||
|
|
||||||
// unconditionally save it, as the previous SetSlot might have removed the setting
|
// unconditionally save it, as the previous SetSlot might have removed the setting
|
||||||
PCapBackend::tfe_SetRegistryInterface(slot, ConfigNew.m_tfeInterface);
|
PCapBackend::SetRegistryInterface(slot, ConfigNew.m_tfeInterface);
|
||||||
|
Uthernet2::SetRegistryVirtualDNS(slot, ConfigNew.m_tfeVirtualDNS);
|
||||||
|
|
||||||
slot = SLOT4;
|
slot = SLOT4;
|
||||||
if (CONFIG_CHANGED_LOCAL(m_Slot[slot]))
|
if (CONFIG_CHANGED_LOCAL(m_Slot[slot]))
|
||||||
@ -455,6 +458,9 @@ bool CPropertySheetHelper::HardwareConfigChanged(HWND hWnd)
|
|||||||
if (CONFIG_CHANGED(m_tfeInterface))
|
if (CONFIG_CHANGED(m_tfeInterface))
|
||||||
strMsgMain += ". Uthernet interface has changed\n";
|
strMsgMain += ". Uthernet interface has changed\n";
|
||||||
|
|
||||||
|
if (CONFIG_CHANGED(m_tfeVirtualDNS))
|
||||||
|
strMsgMain += ". Uthernet Virtual DNS has changed\n";
|
||||||
|
|
||||||
if (CONFIG_CHANGED(m_Slot[SLOT4]))
|
if (CONFIG_CHANGED(m_Slot[SLOT4]))
|
||||||
strMsgMain += GetSlot(SLOT4);
|
strMsgMain += GetSlot(SLOT4);
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ public:
|
|||||||
|
|
||||||
// create the network backed for Uthernet 1 and 2
|
// create the network backed for Uthernet 1 and 2
|
||||||
// useful to use libslirp in Linux
|
// useful to use libslirp in Linux
|
||||||
virtual std::shared_ptr<NetworkBackend> CreateNetworkBackend() = 0;
|
virtual std::shared_ptr<NetworkBackend> CreateNetworkBackend(const std::string & interfaceName) = 0;
|
||||||
|
|
||||||
// FindResource, MAKEINTRESOURCE, SizeofResource, LoadResource, LockResource
|
// FindResource, MAKEINTRESOURCE, SizeofResource, LoadResource, LockResource
|
||||||
// Return pointer to resource if size is correct.
|
// Return pointer to resource if size is correct.
|
||||||
|
@ -41,6 +41,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "Pravets.h"
|
#include "Pravets.h"
|
||||||
#include "Speaker.h"
|
#include "Speaker.h"
|
||||||
#include "Speech.h"
|
#include "Speech.h"
|
||||||
|
#include "HardDisk.h"
|
||||||
|
|
||||||
#include "Configuration/Config.h"
|
#include "Configuration/Config.h"
|
||||||
#include "Configuration/IPropertySheet.h"
|
#include "Configuration/IPropertySheet.h"
|
||||||
|
49
source/Tfe/DNS.cpp
Normal file
49
source/Tfe/DNS.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
AppleWin : An Apple //e emulator for Windows
|
||||||
|
|
||||||
|
Copyright (C) 2022, Andrea Odetti
|
||||||
|
|
||||||
|
AppleWin is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
AppleWin is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with AppleWin; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "DNS.h"
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t getHostByName(const std::string & name)
|
||||||
|
{
|
||||||
|
const hostent * host = gethostbyname(name.c_str());
|
||||||
|
if (host && host->h_addrtype == AF_INET && host->h_length == sizeof(uint32_t))
|
||||||
|
{
|
||||||
|
const in_addr * addr = (const in_addr *)host->h_addr_list[0];
|
||||||
|
if (addr)
|
||||||
|
{
|
||||||
|
return addr->s_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * formatIP(const uint32_t address)
|
||||||
|
{
|
||||||
|
in_addr in;
|
||||||
|
in.s_addr = address;
|
||||||
|
return inet_ntoa(in);
|
||||||
|
}
|
4
source/Tfe/DNS.h
Normal file
4
source/Tfe/DNS.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
uint32_t getHostByName(const std::string & name);
|
||||||
|
const char * formatIP(const uint32_t address);
|
@ -39,4 +39,7 @@ public:
|
|||||||
|
|
||||||
// if the backend is usable
|
// if the backend is usable
|
||||||
virtual bool isValid() = 0;
|
virtual bool isValid() = 0;
|
||||||
|
|
||||||
|
// get interface name
|
||||||
|
virtual const std::string & getInterfaceName() = 0;
|
||||||
};
|
};
|
||||||
|
@ -29,17 +29,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string PCapBackend::tfe_interface;
|
PCapBackend::PCapBackend(const std::string & interfaceName) : m_interfaceName(interfaceName)
|
||||||
|
|
||||||
PCapBackend::PCapBackend(const std::string & pcapInterface)
|
|
||||||
{
|
{
|
||||||
tfePcapFP = TfePcapOpenAdapter(pcapInterface);
|
m_tfePcapFP = TfePcapOpenAdapter(interfaceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
PCapBackend::~PCapBackend()
|
PCapBackend::~PCapBackend()
|
||||||
{
|
{
|
||||||
TfePcapCloseAdapter(tfePcapFP);
|
TfePcapCloseAdapter(m_tfePcapFP);
|
||||||
tfePcapFP = NULL;
|
m_tfePcapFP = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCapBackend::transmit(
|
void PCapBackend::transmit(
|
||||||
@ -47,17 +45,17 @@ void PCapBackend::transmit(
|
|||||||
uint8_t *txframe /* Pointer to the frame to be transmitted */
|
uint8_t *txframe /* Pointer to the frame to be transmitted */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (tfePcapFP)
|
if (m_tfePcapFP)
|
||||||
{
|
{
|
||||||
tfe_arch_transmit(tfePcapFP, txlength, txframe);
|
tfe_arch_transmit(m_tfePcapFP, txlength, txframe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int PCapBackend::receive(const int size, uint8_t * rxframe)
|
int PCapBackend::receive(const int size, uint8_t * rxframe)
|
||||||
{
|
{
|
||||||
if (tfePcapFP)
|
if (m_tfePcapFP)
|
||||||
{
|
{
|
||||||
return tfe_arch_receive(tfePcapFP, size, rxframe);
|
return tfe_arch_receive(m_tfePcapFP, size, rxframe);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -67,7 +65,7 @@ int PCapBackend::receive(const int size, uint8_t * rxframe)
|
|||||||
|
|
||||||
bool PCapBackend::isValid()
|
bool PCapBackend::isValid()
|
||||||
{
|
{
|
||||||
return tfePcapFP;
|
return m_tfePcapFP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCapBackend::update(const ULONG /* nExecutedCycles */)
|
void PCapBackend::update(const ULONG /* nExecutedCycles */)
|
||||||
@ -85,6 +83,11 @@ void PCapBackend::getMACAddress(const uint32_t address, MACAddress & mac)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string & PCapBackend::getInterfaceName()
|
||||||
|
{
|
||||||
|
return m_interfaceName;
|
||||||
|
}
|
||||||
|
|
||||||
int PCapBackend::tfe_enumadapter_open(void)
|
int PCapBackend::tfe_enumadapter_open(void)
|
||||||
{
|
{
|
||||||
return tfe_arch_enumadapter_open();
|
return tfe_arch_enumadapter_open();
|
||||||
@ -100,13 +103,26 @@ int PCapBackend::tfe_enumadapter_close(void)
|
|||||||
return tfe_arch_enumadapter_close();
|
return tfe_arch_enumadapter_close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCapBackend::tfe_SetRegistryInterface(UINT slot, const std::string& name)
|
const char * PCapBackend::tfe_lib_version(void)
|
||||||
|
{
|
||||||
|
return tfe_arch_lib_version();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCapBackend::SetRegistryInterface(UINT slot, const std::string& name)
|
||||||
{
|
{
|
||||||
std::string regSection = RegGetConfigSlotSection(slot);
|
std::string regSection = RegGetConfigSlotSection(slot);
|
||||||
RegSaveString(regSection.c_str(), REGVALUE_UTHERNET_INTERFACE, 1, name);
|
RegSaveString(regSection.c_str(), REGVALUE_UTHERNET_INTERFACE, 1, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCapBackend::get_disabled_state(int * param)
|
std::string PCapBackend::GetRegistryInterface(UINT slot)
|
||||||
{
|
{
|
||||||
*param = tfe_cannot_use;
|
char interfaceName[MAX_PATH];
|
||||||
|
std::string regSection = RegGetConfigSlotSection(slot);
|
||||||
|
RegLoadString(regSection.c_str(), REGVALUE_UTHERNET_INTERFACE, TRUE, interfaceName, sizeof(interfaceName), TEXT(""));
|
||||||
|
return interfaceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PCapBackend::tfe_is_npcap_loaded()
|
||||||
|
{
|
||||||
|
return tfe_arch_is_npcap_loaded();
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ typedef struct pcap pcap_t;
|
|||||||
class PCapBackend : public NetworkBackend
|
class PCapBackend : public NetworkBackend
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PCapBackend(const std::string & pcapInterface);
|
PCapBackend(const std::string & interfaceName);
|
||||||
|
|
||||||
virtual ~PCapBackend();
|
virtual ~PCapBackend();
|
||||||
|
|
||||||
@ -32,8 +32,12 @@ public:
|
|||||||
// get MAC for IPRAW (it is only supposed to handle addresses on the local network)
|
// get MAC for IPRAW (it is only supposed to handle addresses on the local network)
|
||||||
virtual void getMACAddress(const uint32_t address, MACAddress & mac);
|
virtual void getMACAddress(const uint32_t address, MACAddress & mac);
|
||||||
|
|
||||||
static void tfe_SetRegistryInterface(UINT slot, const std::string& name);
|
// get interface name
|
||||||
static void get_disabled_state(int * param);
|
virtual const std::string & getInterfaceName();
|
||||||
|
|
||||||
|
// global registry functions
|
||||||
|
static void SetRegistryInterface(UINT slot, const std::string& name);
|
||||||
|
static std::string GetRegistryInterface(UINT slot);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These functions let the UI enumerate the available interfaces.
|
These functions let the UI enumerate the available interfaces.
|
||||||
@ -59,9 +63,10 @@ public:
|
|||||||
static int tfe_enumadapter_open(void);
|
static int tfe_enumadapter_open(void);
|
||||||
static int tfe_enumadapter(std::string & name, std::string & description);
|
static int tfe_enumadapter(std::string & name, std::string & description);
|
||||||
static int tfe_enumadapter_close(void);
|
static int tfe_enumadapter_close(void);
|
||||||
|
static const char * tfe_lib_version(void);
|
||||||
static std::string tfe_interface;
|
static int tfe_is_npcap_loaded();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pcap_t * tfePcapFP;
|
const std::string m_interfaceName;
|
||||||
|
pcap_t * m_tfePcapFP;
|
||||||
};
|
};
|
||||||
|
@ -28,6 +28,11 @@
|
|||||||
/* #define WPCAP */
|
/* #define WPCAP */
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "pcap.h"
|
#include "pcap.h"
|
||||||
#else
|
#else
|
||||||
// on Linux and Mac OS X, we use system's pcap.h, which needs to be included as <>
|
// on Linux and Mac OS X, we use system's pcap.h, which needs to be included as <>
|
||||||
@ -51,7 +56,8 @@
|
|||||||
|
|
||||||
#define TFE_DEBUG_WARN 1 /* this should not be deactivated */
|
#define TFE_DEBUG_WARN 1 /* this should not be deactivated */
|
||||||
|
|
||||||
int tfe_cannot_use = 0;
|
// once this is set, no further attempts to load npcap will be made
|
||||||
|
static int tfe_cannot_use = 0;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
@ -113,7 +119,19 @@ void TfePcapFreeLibrary(void)
|
|||||||
static
|
static
|
||||||
BOOL TfePcapLoadLibrary(void)
|
BOOL TfePcapLoadLibrary(void)
|
||||||
{
|
{
|
||||||
if (!pcap_library) {
|
if (pcap_library)
|
||||||
|
{
|
||||||
|
// already loaded
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tfe_cannot_use)
|
||||||
|
{
|
||||||
|
// already failed
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to load
|
||||||
if (!SetDllDirectory("C:\\Windows\\System32\\Npcap\\")) // Prefer Npcap over WinPcap (GH#822)
|
if (!SetDllDirectory("C:\\Windows\\System32\\Npcap\\")) // Prefer Npcap over WinPcap (GH#822)
|
||||||
{
|
{
|
||||||
const char* error = "Warning: SetDllDirectory() failed for Npcap";
|
const char* error = "Warning: SetDllDirectory() failed for Npcap";
|
||||||
@ -123,7 +141,8 @@ BOOL TfePcapLoadLibrary(void)
|
|||||||
|
|
||||||
pcap_library = LoadLibrary("wpcap.dll");
|
pcap_library = LoadLibrary("wpcap.dll");
|
||||||
|
|
||||||
if (!pcap_library) {
|
if (!pcap_library)
|
||||||
|
{
|
||||||
tfe_cannot_use = 1;
|
tfe_cannot_use = 1;
|
||||||
if(g_fh) fprintf(g_fh, "LoadLibrary WPCAP.DLL failed!\n" );
|
if(g_fh) fprintf(g_fh, "LoadLibrary WPCAP.DLL failed!\n" );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -141,7 +160,6 @@ BOOL TfePcapLoadLibrary(void)
|
|||||||
GET_PROC_ADDRESS_AND_TEST(pcap_geterr);
|
GET_PROC_ADDRESS_AND_TEST(pcap_geterr);
|
||||||
LogOutput("%s\n", p_pcap_lib_version());
|
LogOutput("%s\n", p_pcap_lib_version());
|
||||||
LogFileOutput("%s\n", p_pcap_lib_version());
|
LogFileOutput("%s\n", p_pcap_lib_version());
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -438,7 +456,7 @@ void TfePcapPacketHandler(u_char *param, const struct pcap_pkthdr *header, const
|
|||||||
/* determine the count of bytes which has been returned,
|
/* determine the count of bytes which has been returned,
|
||||||
* but make sure not to overrun the buffer
|
* but make sure not to overrun the buffer
|
||||||
*/
|
*/
|
||||||
pinternal->rxlength = min(pinternal->size, header->caplen);
|
pinternal->rxlength = std::min(pinternal->size, header->caplen);
|
||||||
|
|
||||||
memcpy(pinternal->buffer, pkt_data, pinternal->rxlength);
|
memcpy(pinternal->buffer, pkt_data, pinternal->rxlength);
|
||||||
}
|
}
|
||||||
@ -551,4 +569,19 @@ int tfe_arch_receive(pcap_t * TfePcapFP,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char * tfe_arch_lib_version()
|
||||||
|
{
|
||||||
|
if (!TfePcapLoadLibrary())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p_pcap_lib_version();
|
||||||
|
}
|
||||||
|
|
||||||
|
int tfe_arch_is_npcap_loaded()
|
||||||
|
{
|
||||||
|
return TfePcapLoadLibrary();
|
||||||
|
}
|
||||||
|
|
||||||
//#endif /* #ifdef HAVE_TFE */
|
//#endif /* #ifdef HAVE_TFE */
|
||||||
|
@ -34,9 +34,6 @@
|
|||||||
extern void tfe_arch_set_mac(const BYTE mac[6]);
|
extern void tfe_arch_set_mac(const BYTE mac[6]);
|
||||||
extern void tfe_arch_set_hashfilter(const DWORD hash_mask[2]);
|
extern void tfe_arch_set_hashfilter(const DWORD hash_mask[2]);
|
||||||
|
|
||||||
/* Flag: Can we even use TFE, or is the hardware not available? */
|
|
||||||
extern int tfe_cannot_use;
|
|
||||||
|
|
||||||
struct pcap;
|
struct pcap;
|
||||||
typedef struct pcap pcap_t;
|
typedef struct pcap pcap_t;
|
||||||
|
|
||||||
@ -67,8 +64,11 @@ int tfe_arch_receive(pcap_t * TfePcapFP,
|
|||||||
BYTE *pbuffer /* where to store a frame */
|
BYTE *pbuffer /* where to store a frame */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
extern int tfe_arch_is_npcap_loaded();
|
||||||
extern int tfe_arch_enumadapter_open(void);
|
extern int tfe_arch_enumadapter_open(void);
|
||||||
extern int tfe_arch_enumadapter(std::string & name, std::string & description);
|
extern int tfe_arch_enumadapter(std::string & name, std::string & description);
|
||||||
extern int tfe_arch_enumadapter_close(void);
|
extern int tfe_arch_enumadapter_close(void);
|
||||||
|
|
||||||
|
extern const char * tfe_arch_lib_version();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1011,7 +1011,8 @@ static BYTE __stdcall TfeIo (WORD programcounter, WORD address, BYTE write, BYTE
|
|||||||
|
|
||||||
void Uthernet1::InitializeIO(LPBYTE pCxRomPeripheral)
|
void Uthernet1::InitializeIO(LPBYTE pCxRomPeripheral)
|
||||||
{
|
{
|
||||||
networkBackend = GetFrame().CreateNetworkBackend();
|
const std::string interfaceName = PCapBackend::GetRegistryInterface(m_slot);
|
||||||
|
networkBackend = GetFrame().CreateNetworkBackend(interfaceName);
|
||||||
if (networkBackend->isValid())
|
if (networkBackend->isValid())
|
||||||
{
|
{
|
||||||
RegisterIoHandler(m_slot, TfeIo, TfeIo, TfeIoCxxx, TfeIoCxxx, this, NULL);
|
RegisterIoHandler(m_slot, TfeIo, TfeIo, TfeIoCxxx, TfeIoCxxx, this, NULL);
|
||||||
@ -1058,10 +1059,10 @@ void Uthernet1::SaveSnapshot(class YamlSaveHelper& yamlSaveHelper)
|
|||||||
YamlSaveHelper::Label unit(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
YamlSaveHelper::Label unit(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||||
|
|
||||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_ENABLED, networkBackend->isValid() ? true : false);
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_ENABLED, networkBackend->isValid() ? true : false);
|
||||||
yamlSaveHelper.SaveString(SS_YAML_KEY_NETWORK_INTERFACE, PCapBackend::tfe_interface);
|
yamlSaveHelper.SaveString(SS_YAML_KEY_NETWORK_INTERFACE, networkBackend->getInterfaceName());
|
||||||
|
|
||||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_STARTED_TX, tfe_started_tx ? true : false);
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_STARTED_TX, tfe_started_tx ? true : false);
|
||||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_CANNOT_USE, tfe_cannot_use ? true : false);
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_CANNOT_USE, PCapBackend::tfe_is_npcap_loaded() ? false : false);
|
||||||
|
|
||||||
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_TXCOLLECT_BUFFER, txcollect_buffer);
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_TXCOLLECT_BUFFER, txcollect_buffer);
|
||||||
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_RX_BUFFER, rx_buffer);
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_RX_BUFFER, rx_buffer);
|
||||||
@ -1083,10 +1084,13 @@ bool Uthernet1::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||||||
ThrowErrorInvalidVersion(version);
|
ThrowErrorInvalidVersion(version);
|
||||||
|
|
||||||
yamlLoadHelper.LoadBool(SS_YAML_KEY_ENABLED); // FIXME: what is the point of this?
|
yamlLoadHelper.LoadBool(SS_YAML_KEY_ENABLED); // FIXME: what is the point of this?
|
||||||
PCapBackend::tfe_interface = yamlLoadHelper.LoadString(SS_YAML_KEY_NETWORK_INTERFACE);
|
PCapBackend::SetRegistryInterface(m_slot, yamlLoadHelper.LoadString(SS_YAML_KEY_NETWORK_INTERFACE));
|
||||||
|
|
||||||
tfe_started_tx = yamlLoadHelper.LoadBool(SS_YAML_KEY_STARTED_TX) ? true : false;
|
tfe_started_tx = yamlLoadHelper.LoadBool(SS_YAML_KEY_STARTED_TX) ? true : false;
|
||||||
tfe_cannot_use = yamlLoadHelper.LoadBool(SS_YAML_KEY_CANNOT_USE) ? true : false;
|
|
||||||
|
// it is meaningless to restore this boolean flag
|
||||||
|
// as it depends on the availability of npcap on *this* pc
|
||||||
|
const bool tfe_cannot_use = yamlLoadHelper.LoadBool(SS_YAML_KEY_CANNOT_USE);
|
||||||
|
|
||||||
txcollect_buffer = yamlLoadHelper.LoadUint(SS_YAML_KEY_TXCOLLECT_BUFFER);
|
txcollect_buffer = yamlLoadHelper.LoadUint(SS_YAML_KEY_TXCOLLECT_BUFFER);
|
||||||
rx_buffer = yamlLoadHelper.LoadUint(SS_YAML_KEY_RX_BUFFER);
|
rx_buffer = yamlLoadHelper.LoadUint(SS_YAML_KEY_RX_BUFFER);
|
||||||
@ -1117,7 +1121,5 @@ bool Uthernet1::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||||||
for (UINT i = 0; i < 6; i++)
|
for (UINT i = 0; i < 6; i++)
|
||||||
tfe_sideeffects_write_pp((TFE_PP_ADDR_MAC_ADDR + i) & ~1, i & 1); // set tfe_ia_mac
|
tfe_sideeffects_write_pp((TFE_PP_ADDR_MAC_ADDR + i) & ~1, i & 1); // set tfe_ia_mac
|
||||||
|
|
||||||
PCapBackend::tfe_SetRegistryInterface(m_slot, PCapBackend::tfe_interface);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,18 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "Tfe/NetworkBackend.h"
|
#include "Tfe/NetworkBackend.h"
|
||||||
#include "Tfe/PCapBackend.h"
|
#include "Tfe/PCapBackend.h"
|
||||||
#include "Tfe/IPRaw.h"
|
#include "Tfe/IPRaw.h"
|
||||||
|
#include "Tfe/DNS.h"
|
||||||
#include "W5100.h"
|
#include "W5100.h"
|
||||||
|
#include "../Registry.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Virtual DNS
|
||||||
|
// Virtual DNS is an extension to the W5100
|
||||||
|
// It enables DNS resolution by setting P3 = 1 for IP / TCP and UDP
|
||||||
|
// the length-prefixed hostname is in 0x2A-0xFF is each socket memory
|
||||||
|
// it can be identified with PTIMER = 0.
|
||||||
|
// this means, one can use TCP & UDP without a NetworkBackend.
|
||||||
|
|
||||||
|
|
||||||
// Linux uses EINPROGRESS while Windows returns WSAEWOULDBLOCK
|
// Linux uses EINPROGRESS while Windows returns WSAEWOULDBLOCK
|
||||||
// when the connect() calls is ongoing
|
// when the connect() calls is ongoing
|
||||||
@ -297,7 +308,6 @@ bool Socket::LoadSnapshot(YamlLoadHelper &yamlLoadHelper)
|
|||||||
sn_sr = yamlLoadHelper.LoadUint(SS_YAML_KEY_SOCKET_REGISTER);
|
sn_sr = yamlLoadHelper.LoadUint(SS_YAML_KEY_SOCKET_REGISTER);
|
||||||
|
|
||||||
// transmit and receive sizes are restored from the card common registers
|
// transmit and receive sizes are restored from the card common registers
|
||||||
|
|
||||||
switch (sn_sr)
|
switch (sn_sr)
|
||||||
{
|
{
|
||||||
case W5100_SN_SR_SOCK_MACRAW:
|
case W5100_SN_SR_SOCK_MACRAW:
|
||||||
@ -323,9 +333,30 @@ const std::string& Uthernet2::GetSnapshotCardName()
|
|||||||
|
|
||||||
Uthernet2::Uthernet2(UINT slot) : Card(CT_Uthernet2, slot)
|
Uthernet2::Uthernet2(UINT slot) : Card(CT_Uthernet2, slot)
|
||||||
{
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
WSADATA wsaData;
|
||||||
|
myWSAStartup = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||||
|
if (myWSAStartup)
|
||||||
|
{
|
||||||
|
const int error = sock_error();
|
||||||
|
LogFileOutput("U2: WSAStartup: error %" ERROR_FMT "\n", STRERROR(error));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
myVirtualDNSEnabled = GetRegistryVirtualDNS(slot);
|
||||||
Reset(true);
|
Reset(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Uthernet2::~Uthernet2()
|
||||||
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
if (myWSAStartup == 0)
|
||||||
|
{
|
||||||
|
WSACleanup();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void Uthernet2::setSocketModeRegister(const size_t i, const uint16_t address, const uint8_t value)
|
void Uthernet2::setSocketModeRegister(const size_t i, const uint16_t address, const uint8_t value)
|
||||||
{
|
{
|
||||||
myMemory[address] = value;
|
myMemory[address] = value;
|
||||||
@ -338,16 +369,19 @@ void Uthernet2::setSocketModeRegister(const size_t i, const uint16_t address, co
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case W5100_SN_MR_TCP:
|
case W5100_SN_MR_TCP:
|
||||||
|
case W5100_SN_MR_TCP_DNS:
|
||||||
#ifdef U2_LOG_STATE
|
#ifdef U2_LOG_STATE
|
||||||
LogFileOutput("U2: Mode[%" SIZE_T_FMT "]: TCP\n", i);
|
LogFileOutput("U2: Mode[%" SIZE_T_FMT "]: TCP\n", i);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case W5100_SN_MR_UDP:
|
case W5100_SN_MR_UDP:
|
||||||
|
case W5100_SN_MR_UDP_DNS:
|
||||||
#ifdef U2_LOG_STATE
|
#ifdef U2_LOG_STATE
|
||||||
LogFileOutput("U2: Mode[%" SIZE_T_FMT "]: UDP\n", i);
|
LogFileOutput("U2: Mode[%" SIZE_T_FMT "]: UDP\n", i);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case W5100_SN_MR_IPRAW:
|
case W5100_SN_MR_IPRAW:
|
||||||
|
case W5100_SN_MR_IPRAW_DNS:
|
||||||
#ifdef U2_LOG_STATE
|
#ifdef U2_LOG_STATE
|
||||||
LogFileOutput("U2: Mode[%" SIZE_T_FMT "]: IPRAW\n", i);
|
LogFileOutput("U2: Mode[%" SIZE_T_FMT "]: IPRAW\n", i);
|
||||||
#endif
|
#endif
|
||||||
@ -698,13 +732,13 @@ void Uthernet2::sendDataIPRaw(const size_t i, std::vector<uint8_t> &payload)
|
|||||||
const uint8_t tos = myMemory[socket.registerAddress + W5100_SN_TOS];
|
const uint8_t tos = myMemory[socket.registerAddress + W5100_SN_TOS];
|
||||||
const uint8_t protocol = myMemory[socket.registerAddress + W5100_SN_PROTO];
|
const uint8_t protocol = myMemory[socket.registerAddress + W5100_SN_PROTO];
|
||||||
const uint32_t source = readAddress(myMemory.data() + W5100_SIPR0);
|
const uint32_t source = readAddress(myMemory.data() + W5100_SIPR0);
|
||||||
const uint32_t destination = readAddress(myMemory.data() + socket.registerAddress + W5100_SN_DIPR0);
|
const uint32_t dest = readAddress(myMemory.data() + socket.registerAddress + W5100_SN_DIPR0);
|
||||||
|
|
||||||
const MACAddress * sourceMac = reinterpret_cast<const MACAddress *>(myMemory.data() + W5100_SHAR0);
|
const MACAddress * sourceMac = reinterpret_cast<const MACAddress *>(myMemory.data() + W5100_SHAR0);
|
||||||
const MACAddress * destinationMac;
|
const MACAddress * destinationMac;
|
||||||
getMACAddress(destination, destinationMac);
|
getMACAddress(dest, destinationMac);
|
||||||
|
|
||||||
std::vector<uint8_t> packet = createETH2Frame(payload, sourceMac, destinationMac, ttl, tos, protocol, source, destination);
|
std::vector<uint8_t> packet = createETH2Frame(payload, sourceMac, destinationMac, ttl, tos, protocol, source, dest);
|
||||||
|
|
||||||
#ifdef U2_LOG_TRAFFIC
|
#ifdef U2_LOG_TRAFFIC
|
||||||
LogFileOutput("U2: Send IPRAW[%" SIZE_T_FMT "]: %" SIZE_T_FMT " (%" SIZE_T_FMT ") bytes\n", i, payload.size(), packet.size());
|
LogFileOutput("U2: Send IPRAW[%" SIZE_T_FMT "]: %" SIZE_T_FMT " (%" SIZE_T_FMT ") bytes\n", i, payload.size(), packet.size());
|
||||||
@ -738,10 +772,9 @@ void Uthernet2::sendDataToSocket(const size_t i, std::vector<uint8_t> &data)
|
|||||||
sockaddr_in destination = {};
|
sockaddr_in destination = {};
|
||||||
destination.sin_family = AF_INET;
|
destination.sin_family = AF_INET;
|
||||||
|
|
||||||
// already in network order
|
|
||||||
// this seems to be ignored for TCP, and so we reuse the same code
|
// this seems to be ignored for TCP, and so we reuse the same code
|
||||||
const uint8_t *dest = myMemory.data() + socket.registerAddress + W5100_SN_DIPR0;
|
const uint32_t dest = readAddress(myMemory.data() + socket.registerAddress + W5100_SN_DIPR0);
|
||||||
destination.sin_addr.s_addr = *reinterpret_cast<const uint32_t *>(dest);
|
destination.sin_addr.s_addr = dest;
|
||||||
destination.sin_port = *reinterpret_cast<const uint16_t *>(myMemory.data() + socket.registerAddress + W5100_SN_DPORT0);
|
destination.sin_port = *reinterpret_cast<const uint16_t *>(myMemory.data() + socket.registerAddress + W5100_SN_DPORT0);
|
||||||
|
|
||||||
const ssize_t res = sendto(socket.myFD, reinterpret_cast<const char *>(data.data()), data.size(), 0, (const struct sockaddr *)&destination, sizeof(destination));
|
const ssize_t res = sendto(socket.myFD, reinterpret_cast<const char *>(data.data()), data.size(), 0, (const struct sockaddr *)&destination, sizeof(destination));
|
||||||
@ -853,21 +886,38 @@ void Uthernet2::openSystemSocket(const size_t i, const int type, const int proto
|
|||||||
void Uthernet2::openSocket(const size_t i)
|
void Uthernet2::openSocket(const size_t i)
|
||||||
{
|
{
|
||||||
Socket &socket = mySockets[i];
|
Socket &socket = mySockets[i];
|
||||||
|
socket.clearFD();
|
||||||
|
|
||||||
const uint8_t mr = myMemory[socket.registerAddress + W5100_SN_MR];
|
const uint8_t mr = myMemory[socket.registerAddress + W5100_SN_MR];
|
||||||
const uint8_t protocol = mr & W5100_SN_MR_PROTO_MASK;
|
const uint8_t protocol = mr & W5100_SN_MR_PROTO_MASK;
|
||||||
|
const bool virtual_dns = protocol & W5100_SN_VIRTUAL_DNS;
|
||||||
|
|
||||||
|
// if virtual_dns is requested, but not enabled, we cannot handle it here.
|
||||||
|
if (virtual_dns && !myVirtualDNSEnabled)
|
||||||
|
{
|
||||||
|
#ifdef U2_LOG_STATE
|
||||||
|
LogFileOutput("U2: Open[%" SIZE_T_FMT "]: virtual DNS not supported: %02x\n", i, mr);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t &sr = socket.sn_sr;
|
uint8_t &sr = socket.sn_sr;
|
||||||
|
|
||||||
switch (protocol)
|
switch (protocol)
|
||||||
{
|
{
|
||||||
case W5100_SN_MR_IPRAW:
|
case W5100_SN_MR_IPRAW:
|
||||||
|
case W5100_SN_MR_IPRAW_DNS:
|
||||||
sr = W5100_SN_SR_SOCK_IPRAW;
|
sr = W5100_SN_SR_SOCK_IPRAW;
|
||||||
break;
|
break;
|
||||||
case W5100_SN_MR_MACRAW:
|
case W5100_SN_MR_MACRAW:
|
||||||
sr = W5100_SN_SR_SOCK_MACRAW;
|
sr = W5100_SN_SR_SOCK_MACRAW;
|
||||||
break;
|
break;
|
||||||
case W5100_SN_MR_TCP:
|
case W5100_SN_MR_TCP:
|
||||||
|
case W5100_SN_MR_TCP_DNS:
|
||||||
openSystemSocket(i, SOCK_STREAM, IPPROTO_TCP, W5100_SN_SR_SOCK_INIT);
|
openSystemSocket(i, SOCK_STREAM, IPPROTO_TCP, W5100_SN_SR_SOCK_INIT);
|
||||||
break;
|
break;
|
||||||
case W5100_SN_MR_UDP:
|
case W5100_SN_MR_UDP:
|
||||||
|
case W5100_SN_MR_UDP_DNS:
|
||||||
openSystemSocket(i, SOCK_DGRAM, IPPROTO_UDP, W5100_SN_SR_SOCK_UDP);
|
openSystemSocket(i, SOCK_DGRAM, IPPROTO_UDP, W5100_SN_SR_SOCK_UDP);
|
||||||
break;
|
break;
|
||||||
#ifdef U2_LOG_UNKNOWN
|
#ifdef U2_LOG_UNKNOWN
|
||||||
@ -875,6 +925,16 @@ void Uthernet2::openSocket(const size_t i)
|
|||||||
LogFileOutput("U2: Open[%" SIZE_T_FMT "]: unknown mode: %02x\n", i, mr);
|
LogFileOutput("U2: Open[%" SIZE_T_FMT "]: unknown mode: %02x\n", i, mr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (protocol)
|
||||||
|
{
|
||||||
|
case W5100_SN_MR_IPRAW_DNS:
|
||||||
|
case W5100_SN_MR_TCP_DNS:
|
||||||
|
case W5100_SN_MR_UDP_DNS:
|
||||||
|
resolveDNS(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
resetRXTXBuffers(i); // needed?
|
resetRXTXBuffers(i); // needed?
|
||||||
#ifdef U2_LOG_STATE
|
#ifdef U2_LOG_STATE
|
||||||
LogFileOutput("U2: Open[%" SIZE_T_FMT "]: SR = %02x\n", i, sr);
|
LogFileOutput("U2: Open[%" SIZE_T_FMT "]: SR = %02x\n", i, sr);
|
||||||
@ -890,17 +950,44 @@ void Uthernet2::closeSocket(const size_t i)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Uthernet2::resolveDNS(const size_t i)
|
||||||
|
{
|
||||||
|
Socket &socket = mySockets[i];
|
||||||
|
uint32_t *dest = reinterpret_cast<uint32_t *>(myMemory.data() + socket.registerAddress + W5100_SN_DIPR0);
|
||||||
|
*dest = 0; // 0.0.0.0 signals failure by any reason
|
||||||
|
|
||||||
|
const uint8_t length = myMemory[socket.registerAddress + W5100_SN_DNS_NAME_LEN];
|
||||||
|
if (length <= W5100_SN_DNS_NAME_CPTY)
|
||||||
|
{
|
||||||
|
const uint8_t * start = myMemory.data() + socket.registerAddress + W5100_SN_DNS_NAME_BEGIN;
|
||||||
|
const std::string name(start, start + length);
|
||||||
|
const std::map<std::string, uint32_t>::iterator it = myDNSCache.find(name);
|
||||||
|
if (it != myDNSCache.end())
|
||||||
|
{
|
||||||
|
*dest = it->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*dest = getHostByName(name);
|
||||||
|
myDNSCache[name] = *dest;
|
||||||
|
#ifdef U2_LOG_STATE
|
||||||
|
LogFileOutput("U2: DNS[%" SIZE_T_FMT "]: %s = %s\n", i, name.c_str(), formatIP(*dest));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Uthernet2::connectSocket(const size_t i)
|
void Uthernet2::connectSocket(const size_t i)
|
||||||
{
|
{
|
||||||
Socket &socket = mySockets[i];
|
Socket &socket = mySockets[i];
|
||||||
const uint8_t *dest = myMemory.data() + socket.registerAddress + W5100_SN_DIPR0;
|
const uint32_t dest = readAddress(myMemory.data() + socket.registerAddress + W5100_SN_DIPR0);
|
||||||
|
|
||||||
sockaddr_in destination = {};
|
sockaddr_in destination = {};
|
||||||
destination.sin_family = AF_INET;
|
destination.sin_family = AF_INET;
|
||||||
|
|
||||||
// already in network order
|
// already in network order
|
||||||
destination.sin_port = *reinterpret_cast<const uint16_t *>(myMemory.data() + socket.registerAddress + W5100_SN_DPORT0);
|
destination.sin_port = *reinterpret_cast<const uint16_t *>(myMemory.data() + socket.registerAddress + W5100_SN_DPORT0);
|
||||||
destination.sin_addr.s_addr = *reinterpret_cast<const uint32_t *>(dest);
|
destination.sin_addr.s_addr = dest;
|
||||||
|
|
||||||
const int res = connect(socket.myFD, (struct sockaddr *)&destination, sizeof(destination));
|
const int res = connect(socket.myFD, (struct sockaddr *)&destination, sizeof(destination));
|
||||||
|
|
||||||
@ -910,7 +997,7 @@ void Uthernet2::connectSocket(const size_t i)
|
|||||||
socket.myErrno = 0;
|
socket.myErrno = 0;
|
||||||
#ifdef U2_LOG_STATE
|
#ifdef U2_LOG_STATE
|
||||||
const uint16_t port = readNetworkWord(myMemory.data() + socket.registerAddress + W5100_SN_DPORT0);
|
const uint16_t port = readNetworkWord(myMemory.data() + socket.registerAddress + W5100_SN_DPORT0);
|
||||||
LogFileOutput("U2: TCP[%" SIZE_T_FMT "]: CONNECT to %d.%d.%d.%d:%d\n", i, dest[0], dest[1], dest[2], dest[3], port);
|
LogFileOutput("U2: TCP[%" SIZE_T_FMT "]: CONNECT to %s:%d\n", i, formatIP(dest), port);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1130,11 +1217,18 @@ void Uthernet2::writeSocketRegister(const uint16_t address, const uint8_t value)
|
|||||||
case W5100_SN_RX_RD1:
|
case W5100_SN_RX_RD1:
|
||||||
myMemory[address] = value;
|
myMemory[address] = value;
|
||||||
break;
|
break;
|
||||||
#ifdef U2_LOG_UNKNOWN
|
|
||||||
default:
|
default:
|
||||||
|
if (myVirtualDNSEnabled && loc >= W5100_SN_DNS_NAME_LEN)
|
||||||
|
{
|
||||||
|
myMemory[address] = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef U2_LOG_UNKNOWN
|
||||||
LogFileOutput("U2: Set unknown socket register[%d]: %04x\n", i, address);
|
LogFileOutput("U2: Set unknown socket register[%d]: %04x\n", i, address);
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1216,8 +1310,10 @@ void Uthernet2::Reset(const bool powerCycle)
|
|||||||
{
|
{
|
||||||
// dataAddress is NOT reset, see page 10 of Uthernet II
|
// dataAddress is NOT reset, see page 10 of Uthernet II
|
||||||
myDataAddress = 0;
|
myDataAddress = 0;
|
||||||
myNetworkBackend = GetFrame().CreateNetworkBackend();
|
const std::string interfaceName = PCapBackend::GetRegistryInterface(m_slot);
|
||||||
|
myNetworkBackend = GetFrame().CreateNetworkBackend(interfaceName);
|
||||||
myARPCache.clear();
|
myARPCache.clear();
|
||||||
|
myDNSCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
mySockets.clear();
|
mySockets.clear();
|
||||||
@ -1247,8 +1343,12 @@ void Uthernet2::Reset(const bool powerCycle)
|
|||||||
myMemory[W5100_RCR] = 0x08;
|
myMemory[W5100_RCR] = 0x08;
|
||||||
setRXSizes(W5100_RMSR, 0x55);
|
setRXSizes(W5100_RMSR, 0x55);
|
||||||
setTXSizes(W5100_TMSR, 0x55);
|
setTXSizes(W5100_TMSR, 0x55);
|
||||||
|
if (!myVirtualDNSEnabled)
|
||||||
|
{
|
||||||
|
// this is 0 if we support Virtual DNS
|
||||||
myMemory[W5100_PTIMER] = 0x28;
|
myMemory[W5100_PTIMER] = 0x28;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BYTE Uthernet2::IO_C0(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles)
|
BYTE Uthernet2::IO_C0(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles)
|
||||||
{
|
{
|
||||||
@ -1367,7 +1467,11 @@ void Uthernet2::Update(const ULONG nExecutedCycles)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const UINT kUNIT_VERSION = 1;
|
// Unit version history:
|
||||||
|
// 2: Added: Virtual DNS
|
||||||
|
static const UINT kUNIT_VERSION = 2;
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_VIRTUAL_DNS "Virtual DNS"
|
||||||
#define SS_YAML_KEY_NETWORK_INTERFACE "Network Interface"
|
#define SS_YAML_KEY_NETWORK_INTERFACE "Network Interface"
|
||||||
|
|
||||||
#define SS_YAML_KEY_COMMON_REGISTERS "Common Registers"
|
#define SS_YAML_KEY_COMMON_REGISTERS "Common Registers"
|
||||||
@ -1385,7 +1489,8 @@ void Uthernet2::SaveSnapshot(YamlSaveHelper &yamlSaveHelper)
|
|||||||
YamlSaveHelper::Slot slot(yamlSaveHelper, GetSnapshotCardName(), m_slot, kUNIT_VERSION);
|
YamlSaveHelper::Slot slot(yamlSaveHelper, GetSnapshotCardName(), m_slot, kUNIT_VERSION);
|
||||||
|
|
||||||
YamlSaveHelper::Label unit(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
YamlSaveHelper::Label unit(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||||
yamlSaveHelper.SaveString(SS_YAML_KEY_NETWORK_INTERFACE, PCapBackend::tfe_interface);
|
yamlSaveHelper.SaveString(SS_YAML_KEY_NETWORK_INTERFACE, myNetworkBackend->getInterfaceName());
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_VIRTUAL_DNS, myVirtualDNSEnabled);
|
||||||
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_MODE_REGISTER, myModeRegister);
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_MODE_REGISTER, myModeRegister);
|
||||||
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_DATA_ADDRESS, myDataAddress);
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_DATA_ADDRESS, myDataAddress);
|
||||||
|
|
||||||
@ -1428,10 +1533,19 @@ bool Uthernet2::LoadSnapshot(YamlLoadHelper &yamlLoadHelper, UINT version)
|
|||||||
if (version < 1 || version > kUNIT_VERSION)
|
if (version < 1 || version > kUNIT_VERSION)
|
||||||
ThrowErrorInvalidVersion(version);
|
ThrowErrorInvalidVersion(version);
|
||||||
|
|
||||||
PCapBackend::tfe_interface = yamlLoadHelper.LoadString(SS_YAML_KEY_NETWORK_INTERFACE);
|
PCapBackend::SetRegistryInterface(m_slot, yamlLoadHelper.LoadString(SS_YAML_KEY_NETWORK_INTERFACE));
|
||||||
PCapBackend::tfe_SetRegistryInterface(m_slot, PCapBackend::tfe_interface);
|
|
||||||
|
|
||||||
Reset(true); // AFTER the interface name has been restored
|
if (version >= 2)
|
||||||
|
{
|
||||||
|
myVirtualDNSEnabled = yamlLoadHelper.LoadBool(SS_YAML_KEY_VIRTUAL_DNS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
myVirtualDNSEnabled = false;
|
||||||
|
}
|
||||||
|
SetRegistryVirtualDNS(m_slot, myVirtualDNSEnabled);
|
||||||
|
|
||||||
|
Reset(true); // AFTER the parameters have been restored
|
||||||
|
|
||||||
myModeRegister = yamlLoadHelper.LoadUint(SS_YAML_KEY_MODE_REGISTER);
|
myModeRegister = yamlLoadHelper.LoadUint(SS_YAML_KEY_MODE_REGISTER);
|
||||||
myDataAddress = yamlLoadHelper.LoadUint(SS_YAML_KEY_DATA_ADDRESS);
|
myDataAddress = yamlLoadHelper.LoadUint(SS_YAML_KEY_DATA_ADDRESS);
|
||||||
@ -1475,3 +1589,17 @@ bool Uthernet2::LoadSnapshot(YamlLoadHelper &yamlLoadHelper, UINT version)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Uthernet2::SetRegistryVirtualDNS(UINT slot, const bool enabled)
|
||||||
|
{
|
||||||
|
const std::string regSection = RegGetConfigSlotSection(slot);
|
||||||
|
RegSaveValue(regSection.c_str(), REGVALUE_UTHERNET_VIRTUAL_DNS, TRUE, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Uthernet2::GetRegistryVirtualDNS(UINT slot)
|
||||||
|
{
|
||||||
|
const std::string regSection = RegGetConfigSlotSection(slot);
|
||||||
|
DWORD enabled = 0;
|
||||||
|
RegLoadValue(regSection.c_str(), REGVALUE_UTHERNET_VIRTUAL_DNS, TRUE, &enabled, 0);
|
||||||
|
return enabled != 0;
|
||||||
|
}
|
||||||
|
@ -61,6 +61,7 @@ public:
|
|||||||
enum PacketDestination { HOST, BROADCAST, OTHER };
|
enum PacketDestination { HOST, BROADCAST, OTHER };
|
||||||
|
|
||||||
Uthernet2(UINT slot);
|
Uthernet2(UINT slot);
|
||||||
|
virtual ~Uthernet2();
|
||||||
|
|
||||||
virtual void Destroy(void) {}
|
virtual void Destroy(void) {}
|
||||||
virtual void InitializeIO(LPBYTE pCxRomPeripheral);
|
virtual void InitializeIO(LPBYTE pCxRomPeripheral);
|
||||||
@ -71,7 +72,17 @@ public:
|
|||||||
|
|
||||||
BYTE IO_C0(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);
|
BYTE IO_C0(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);
|
||||||
|
|
||||||
|
// global registry functions
|
||||||
|
static void SetRegistryVirtualDNS(UINT slot, const bool enabled);
|
||||||
|
static bool GetRegistryVirtualDNS(UINT slot);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool myVirtualDNSEnabled; // extended virtualisation of DNS (not present in the real U II card)
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
int myWSAStartup;
|
||||||
|
#endif
|
||||||
|
|
||||||
std::vector<uint8_t> myMemory;
|
std::vector<uint8_t> myMemory;
|
||||||
std::vector<Socket> mySockets;
|
std::vector<Socket> mySockets;
|
||||||
uint8_t myModeRegister;
|
uint8_t myModeRegister;
|
||||||
@ -82,8 +93,10 @@ private:
|
|||||||
// but in the interest of speeding up the emulator
|
// but in the interest of speeding up the emulator
|
||||||
// we introduce one
|
// we introduce one
|
||||||
std::map<uint32_t, MACAddress> myARPCache;
|
std::map<uint32_t, MACAddress> myARPCache;
|
||||||
|
std::map<std::string, uint32_t> myDNSCache;
|
||||||
|
|
||||||
void getMACAddress(const uint32_t address, const MACAddress * & mac);
|
void getMACAddress(const uint32_t address, const MACAddress * & mac);
|
||||||
|
void resolveDNS(const size_t i);
|
||||||
|
|
||||||
void setSocketModeRegister(const size_t i, const uint16_t address, const uint8_t value);
|
void setSocketModeRegister(const size_t i, const uint16_t address, const uint8_t value);
|
||||||
void setTXSizes(const uint16_t address, uint8_t value);
|
void setTXSizes(const uint16_t address, uint8_t value);
|
||||||
|
@ -239,27 +239,15 @@ void LoadConfiguration(bool loadImages)
|
|||||||
|
|
||||||
if (RegLoadValue(regSection.c_str(), REGVALUE_CARD_TYPE, TRUE, &dwTmp))
|
if (RegLoadValue(regSection.c_str(), REGVALUE_CARD_TYPE, TRUE, &dwTmp))
|
||||||
{
|
{
|
||||||
if (slot == SLOT3)
|
|
||||||
{
|
|
||||||
// this must happen before the card is instantitated
|
|
||||||
// TODO move to the card
|
|
||||||
if ((SS_CARDTYPE)dwTmp == CT_Uthernet || (SS_CARDTYPE)dwTmp == CT_Uthernet2) // TODO: move this to when UthernetCard object is instantiated
|
|
||||||
{
|
|
||||||
std::string regSection = RegGetConfigSlotSection(slot);
|
|
||||||
if (RegLoadString(regSection.c_str(), REGVALUE_UTHERNET_INTERFACE, TRUE, szFilename, MAX_PATH, TEXT("")))
|
|
||||||
PCapBackend::tfe_interface = szFilename;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GetCardMgr().Insert(slot, (SS_CARDTYPE)dwTmp, false);
|
GetCardMgr().Insert(slot, (SS_CARDTYPE)dwTmp, false);
|
||||||
}
|
}
|
||||||
else // legacy (AppleWin 1.30.3 or earlier)
|
else // legacy (AppleWin 1.30.3 or earlier)
|
||||||
{
|
{
|
||||||
if (slot == SLOT3)
|
if (slot == SLOT3)
|
||||||
{
|
{
|
||||||
// TODO: move this to when UthernetCard object is instantiated
|
|
||||||
RegLoadString(TEXT(REG_CONFIG), TEXT(REGVALUE_UTHERNET_INTERFACE), 1, szFilename, MAX_PATH, TEXT(""));
|
RegLoadString(TEXT(REG_CONFIG), TEXT(REGVALUE_UTHERNET_INTERFACE), 1, szFilename, MAX_PATH, TEXT(""));
|
||||||
PCapBackend::tfe_interface = szFilename;
|
// copy it to the new location
|
||||||
|
PCapBackend::SetRegistryInterface(slot, szFilename);
|
||||||
|
|
||||||
DWORD tfeEnabled;
|
DWORD tfeEnabled;
|
||||||
REGLOAD_DEFAULT(TEXT(REGVALUE_UTHERNET_ACTIVE), &tfeEnabled, 0);
|
REGLOAD_DEFAULT(TEXT(REGVALUE_UTHERNET_ACTIVE), &tfeEnabled, 0);
|
||||||
|
@ -46,6 +46,10 @@
|
|||||||
#define W5100_SN_MR_IPRAW 0x03
|
#define W5100_SN_MR_IPRAW 0x03
|
||||||
#define W5100_SN_MR_MACRAW 0x04
|
#define W5100_SN_MR_MACRAW 0x04
|
||||||
#define W5100_SN_MR_PPPOE 0x05
|
#define W5100_SN_MR_PPPOE 0x05
|
||||||
|
#define W5100_SN_VIRTUAL_DNS 0x08 // not present on real hardware, see comment in Uthernet2.cpp
|
||||||
|
#define W5100_SN_MR_TCP_DNS (W5100_SN_VIRTUAL_DNS | W5100_SN_MR_TCP)
|
||||||
|
#define W5100_SN_MR_UDP_DNS (W5100_SN_VIRTUAL_DNS | W5100_SN_MR_UDP)
|
||||||
|
#define W5100_SN_MR_IPRAW_DNS (W5100_SN_VIRTUAL_DNS | W5100_SN_MR_IPRAW)
|
||||||
|
|
||||||
#define W5100_SN_CR_OPEN 0x01
|
#define W5100_SN_CR_OPEN 0x01
|
||||||
#define W5100_SN_CR_LISTENT 0x02
|
#define W5100_SN_CR_LISTENT 0x02
|
||||||
@ -88,6 +92,11 @@
|
|||||||
#define W5100_SN_RX_RD0 0x28 // RX Read Pointer
|
#define W5100_SN_RX_RD0 0x28 // RX Read Pointer
|
||||||
#define W5100_SN_RX_RD1 0x29 // RX Read Pointer
|
#define W5100_SN_RX_RD1 0x29 // RX Read Pointer
|
||||||
|
|
||||||
|
#define W5100_SN_DNS_NAME_LEN 0x2A // these are not present on real hardware, see comment in Uthernet2.cpp
|
||||||
|
#define W5100_SN_DNS_NAME_BEGIN 0x2B
|
||||||
|
#define W5100_SN_DNS_NAME_END 0xFF
|
||||||
|
#define W5100_SN_DNS_NAME_CPTY (W5100_SN_DNS_NAME_END - W5100_SN_DNS_NAME_BEGIN)
|
||||||
|
|
||||||
#define W5100_SN_SR_CLOSED 0x00
|
#define W5100_SN_SR_CLOSED 0x00
|
||||||
#define W5100_SN_SR_SOCK_INIT 0x13
|
#define W5100_SN_SR_SOCK_INIT 0x13
|
||||||
#define W5100_SN_SR_ESTABLISHED 0x17
|
#define W5100_SN_SR_ESTABLISHED 0x17
|
||||||
|
@ -46,6 +46,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "SoundCore.h"
|
#include "SoundCore.h"
|
||||||
#include "Speaker.h"
|
#include "Speaker.h"
|
||||||
#include "LanguageCard.h"
|
#include "LanguageCard.h"
|
||||||
|
#include "CardManager.h"
|
||||||
#ifdef USE_SPEECH_API
|
#ifdef USE_SPEECH_API
|
||||||
#include "Speech.h"
|
#include "Speech.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -625,8 +625,8 @@ std::string Win32Frame::Video_GetScreenShotFolder() const
|
|||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<NetworkBackend> Win32Frame::CreateNetworkBackend()
|
std::shared_ptr<NetworkBackend> Win32Frame::CreateNetworkBackend(const std::string & interfaceName)
|
||||||
{
|
{
|
||||||
std::shared_ptr<NetworkBackend> backend(new PCapBackend(PCapBackend::tfe_interface));
|
std::shared_ptr<NetworkBackend> backend(new PCapBackend(interfaceName));
|
||||||
return backend;
|
return backend;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ public:
|
|||||||
|
|
||||||
virtual std::string Video_GetScreenShotFolder() const;
|
virtual std::string Video_GetScreenShotFolder() const;
|
||||||
|
|
||||||
virtual std::shared_ptr<NetworkBackend> CreateNetworkBackend();
|
virtual std::shared_ptr<NetworkBackend> CreateNetworkBackend(const std::string & interfaceName);
|
||||||
|
|
||||||
bool GetFullScreenShowSubunitStatus(void);
|
bool GetFullScreenShowSubunitStatus(void);
|
||||||
int GetFullScreenOffsetX(void);
|
int GetFullScreenOffsetX(void);
|
||||||
|
@ -48,6 +48,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "Uthernet2.h"
|
#include "Uthernet2.h"
|
||||||
#include "Speaker.h"
|
#include "Speaker.h"
|
||||||
#include "Utilities.h"
|
#include "Utilities.h"
|
||||||
|
#include "CardManager.h"
|
||||||
#include "../resource/resource.h"
|
#include "../resource/resource.h"
|
||||||
#include "Configuration/PropertySheet.h"
|
#include "Configuration/PropertySheet.h"
|
||||||
#include "Debugger/Debug.h"
|
#include "Debugger/Debug.h"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user