DEV9: Add internal DHCP Server

This commit is contained in:
TheLastRar 2021-03-08 15:26:12 +00:00 committed by lightningterror
parent 221a8dc530
commit 3d1b79464c
15 changed files with 1290 additions and 28 deletions

View File

@ -327,6 +327,7 @@ set(pcsx2DEV9Sources
DEV9/ATA/ATA_State.cpp
DEV9/ATA/ATA_Transfer.cpp
DEV9/ATA/HddCreate.cpp
DEV9/InternalServers/DHCP_Server.cpp
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Options.cpp
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Packet.cpp
DEV9/PacketReader/IP/UDP/DNS/DNS_Classes.cpp
@ -351,6 +352,7 @@ set(pcsx2DEV9Headers
DEV9/ATA/ATA.h
DEV9/ATA/HddCreate.h
DEV9/DEV9.h
DEV9/InternalServers/DHCP_Server.cpp
DEV9/net.h
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Options.h
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Packet.h

View File

@ -28,6 +28,7 @@
#include "PS2Edefs.h"
#include "PS2Eext.h"
#include "net.h"
#include "PacketReader/IP/IP_Address.h"
#include "ATA/ATA.h"
#ifdef _WIN32
@ -60,6 +61,16 @@ struct Config
{
char Eth[256];
NetApi EthApi;
bool InterceptDHCP;
PacketReader::IP::IP_Address PS2IP;
PacketReader::IP::IP_Address Mask;
PacketReader::IP::IP_Address Gateway;
PacketReader::IP::IP_Address DNS1;
PacketReader::IP::IP_Address DNS2;
int AutoMask;
int AutoGateway;
int AutoDNS1;
int AutoDNS2;
#ifdef _WIN32
wchar_t Hdd[256];
#else

View File

@ -0,0 +1,497 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 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 PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include <algorithm>
#ifdef __POSIX__
#include <string>
#include <vector>
#include <fstream>
#include <arpa/inet.h>
#endif
#include "DHCP_Server.h"
#include "../PacketReader/IP/UDP/UDP_Packet.h"
#include "../PacketReader/IP/UDP/DHCP/DHCP_Packet.h"
#include "../DEV9.h"
using namespace PacketReader;
using namespace PacketReader::IP;
using namespace PacketReader::IP::UDP;
using namespace PacketReader::IP::UDP::DHCP;
namespace InternalServers
{
DHCP_Server::DHCP_Server(std::function<void()> receivedcallback)
: callback{receivedcallback}
{
}
#ifdef _WIN32
void DHCP_Server::Init(PIP_ADAPTER_ADDRESSES adapter)
#elif defined(__POSIX__)
void DHCP_Server::Init(ifaddrs* adapter)
#endif
{
ps2IP = config.PS2IP;
netmask = {0};
gateway = {0};
dns1 = {0};
dns2 = {0};
broadcastIP = {0};
if (config.AutoMask)
AutoNetmask(adapter);
else
netmask = config.Mask;
if (config.AutoGateway)
AutoGateway(adapter);
else
gateway = config.Gateway;
if (!config.AutoDNS1)
dns1 = config.DNS1;
if (!config.AutoDNS2)
dns2 = config.DNS2;
AutoDNS(adapter, config.AutoDNS1, config.AutoDNS2);
AutoBroadcast(ps2IP, netmask);
}
#ifdef __POSIX__
//skipsEmpty
std::vector<std::string> DHCP_Server::SplitString(std::string str, char delimiter)
{
std::vector<std::string> ret;
size_t last = 0;
size_t next = 0;
std::string token;
while ((next = str.find(delimiter, last)) != std::string::npos)
{
token = str.substr(last, next - last);
if (next != last)
ret.push_back(token);
last = next + 1;
}
token = str.substr(last);
if (next != last)
ret.push_back(token);
return ret;
}
#ifdef __linux__
std::vector<IP_Address> DHCP_Server::GetGatewaysLinux(char* interfaceName)
{
///proc/net/route contains some information about gateway addresses,
//and separates the information about by each interface.
std::vector<IP_Address> collection;
std::vector<std::string> routeLines;
std::fstream route("/proc/net/route", std::ios::in);
if (route.fail())
{
route.close();
Console.Error("DHCP: Failed to open /proc/net/route");
return collection;
}
std::string line;
while (std::getline(route, line))
routeLines.push_back(line);
route.close();
//Columns are as follows (first-line header):
//Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
for (size_t i = 1; i < routeLines.size(); i++)
{
std::string line = routeLines[i];
if (line.rfind(interfaceName, 0) == 0)
{
std::vector<std::string> split = SplitString(line, '\t');
std::string gatewayIPHex = split[2];
int addressValue = std::stoi(gatewayIPHex, 0, 16);
//Skip device routes without valid NextHop IP address
if (addressValue != 0)
{
IP_Address gwIP = *(IP_Address*)&addressValue;
collection.push_back(gwIP);
}
}
}
return collection;
}
#endif
std::vector<IP_Address> DHCP_Server::GetDNSUnix()
{
//On Linux and OSX, DNS is system wide, not adapter specific, so we can ignore adapter
// Parse /etc/resolv.conf for all of the "nameserver" entries.
// These are the DNS servers the machine is configured to use.
// On OSX, this file is not directly used by most processes for DNS
// queries/routing, but it is automatically generated instead, with
// the machine's DNS servers listed in it.
std::vector<IP_Address> collection;
std::fstream servers("/etc/resolv.conf", std::ios::in);
if (servers.fail())
{
servers.close();
Console.Error("DHCP: Failed to open /etc/resolv.conf");
return collection;
}
std::string line;
std::vector<std::string> serversLines;
while (std::getline(servers, line))
serversLines.push_back(line);
servers.close();
const IP_Address systemdDNS{127, 0, 0, 53};
for (size_t i = 1; i < serversLines.size(); i++)
{
std::string line = serversLines[i];
if (line.rfind("nameserver", 0) == 0)
{
std::vector<std::string> split = SplitString(line, '\t');
if (split.size() == 1)
split = SplitString(line, ' ');
std::string dns = split[1];
IP_Address address;
if (inet_pton(AF_INET, dns.c_str(), &address) != 1)
continue;
if (address == systemdDNS)
Console.Error("DHCP: systemd-resolved DNS server is not supported");
collection.push_back(address);
}
}
return collection;
}
#endif
#ifdef _WIN32
void DHCP_Server::AutoNetmask(PIP_ADAPTER_ADDRESSES adapter)
{
if (adapter != nullptr)
{
PIP_ADAPTER_UNICAST_ADDRESS address = adapter->FirstUnicastAddress;
while (address != nullptr && address->Address.lpSockaddr->sa_family != AF_INET)
address = address->Next;
if (address != nullptr)
{
ULONG mask;
if (ConvertLengthToIpv4Mask(address->OnLinkPrefixLength, &mask) == NO_ERROR)
netmask.integer = mask;
}
}
}
void DHCP_Server::AutoGateway(PIP_ADAPTER_ADDRESSES adapter)
{
if (adapter != nullptr)
{
PIP_ADAPTER_GATEWAY_ADDRESS address = adapter->FirstGatewayAddress;
while (address != nullptr && address->Address.lpSockaddr->sa_family != AF_INET)
address = address->Next;
if (address != nullptr)
{
sockaddr_in* sockaddr = (sockaddr_in*)address->Address.lpSockaddr;
gateway = *(IP_Address*)&sockaddr->sin_addr;
}
}
}
#elif defined(__POSIX__)
void DHCP_Server::AutoNetmask(ifaddrs* adapter)
{
if (adapter != nullptr)
{
if (adapter->ifa_netmask != nullptr && adapter->ifa_netmask->sa_family == AF_INET)
{
sockaddr_in* sockaddr = (sockaddr_in*)adapter->ifa_netmask;
netmask = *(IP_Address*)&sockaddr->sin_addr;
}
}
}
void DHCP_Server::AutoGateway(ifaddrs* adapter)
{
if (adapter != nullptr)
{
#ifdef __linux__
std::vector<IP_Address> gateways = GetGatewaysLinux(adapter->ifa_name);
if (gateways.size() > 0)
gateway = gateways[0];
#else
Console.Error("DHCP: Unsupported OS, can't find Gateway");
#endif
}
}
#endif
#ifdef _WIN32
void DHCP_Server::AutoDNS(PIP_ADAPTER_ADDRESSES adapter, bool autoDNS1, bool autoDNS2)
{
std::vector<IP_Address> dnsIPs;
if (adapter != nullptr)
{
PIP_ADAPTER_DNS_SERVER_ADDRESS address = adapter->FirstDnsServerAddress;
while (address != nullptr)
{
if (address->Address.lpSockaddr->sa_family == AF_INET)
{
sockaddr_in* sockaddr = (sockaddr_in*)address->Address.lpSockaddr;
dnsIPs.push_back(*(IP_Address*)&sockaddr->sin_addr);
}
address = address->Next;
}
}
#elif defined(__POSIX__)
void DHCP_Server::AutoDNS(ifaddrs* adapter, bool autoDNS1, bool autoDNS2)
{
std::vector<IP_Address> dnsIPs = GetDNSUnix();
#endif
if (autoDNS1)
{
//Auto DNS1
//If Adapter has DNS, add 1st entry
if (dnsIPs.size() >= 1)
dns1 = dnsIPs[0];
//Auto DNS1 & AutoDNS2
if (autoDNS2 && dnsIPs.size() >= 2)
dns2 = dnsIPs[1];
}
else if (autoDNS2)
{
//Manual DNS1 & Auto DNS2
//Use adapter's DNS2 if it has one
//otherwise use adapter's DNS1
if (dnsIPs.size() >= 1)
dns2 = dnsIPs[std::min((size_t)2, dnsIPs.size())];
}
if (dns1.integer == 0 && dns2.integer != 0)
{
Console.Error("DHCP: DNS1 is zero, but DNS2 is valid, using DNS2 as DNS1");
//no value for DNS1, but we have a value for DNS2
//set DNS1 to DNS2 and zero DNS2
dns1 = dns2;
dns2 = {0, 0, 0, 0};
}
}
void DHCP_Server::AutoBroadcast(IP_Address parPS2IP, IP_Address parNetmask)
{
if (parNetmask.integer != 0)
{
for (int i = 0; i < 4; i++)
broadcastIP.bytes[i] = ((parPS2IP.bytes[i]) | (~parNetmask.bytes[i]));
}
}
UDP_Packet* DHCP_Server::Recv()
{
UDP_Packet* payload;
if (recvBuff.Dequeue(&payload))
return payload;
return nullptr;
}
bool DHCP_Server::Send(UDP_Packet* payload)
{
UDP_Packet* udpPacket = static_cast<UDP_Packet*>(payload);
PayloadPtr* udpPayload = static_cast<PayloadPtr*>(udpPacket->GetPayload());
DHCP_Packet dhcp = DHCP_Packet(udpPayload->data, udpPayload->GetLength());
//State
u8 hType = dhcp.hardwareType;
u8 hLen = dhcp.hardwareAddressLength;
u32 xID = dhcp.transactionID;
u8* cMac = dhcp.clientHardwareAddress;
u32 cookie = dhcp.magicCookie;
u8 msg = 0;
std::vector<u8> reqList;
uint leaseTime = 86400;
for (size_t i = 0; i < dhcp.options.size(); i++)
{
switch (dhcp.options[i]->GetCode())
{
case 0:
continue;
case 1:
if (netmask != ((DHCPopSubnet*)dhcp.options[i])->subnetMask)
Console.Error("DHCP: SubnetMask missmatch");
break;
case 3:
if (((DHCPopRouter*)dhcp.options[i])->routers.size() != 1)
Console.Error("DHCP: Routers count missmatch");
if (gateway != ((DHCPopRouter*)dhcp.options[i])->routers[0])
Console.Error("DHCP: RouterIP missmatch");
break;
case 6:
if (((((DHCPopDNS*)dhcp.options[i])->dnsServers.size() == 0 && dns1.integer == 0) ||
(((DHCPopDNS*)dhcp.options[i])->dnsServers.size() == 1 && dns1.integer != 0 && dns2.integer == 0) ||
(((DHCPopDNS*)dhcp.options[i])->dnsServers.size() == 2 && dns2.integer != 0)) == false)
Console.Error("DHCP: DNS count missmatch");
if ((((DHCPopDNS*)dhcp.options[i])->dnsServers.size() > 0 && dns1 != ((DHCPopDNS*)dhcp.options[i])->dnsServers[0]) ||
(((DHCPopDNS*)dhcp.options[i])->dnsServers.size() > 1 && dns2 != ((DHCPopDNS*)dhcp.options[i])->dnsServers[1]))
Console.Error("DHCP: DNS missmatch");
break;
case 12:
//TODO use name?
break;
case 50:
if (ps2IP != ((DHCPopREQIP*)dhcp.options[i])->requestedIP)
Console.Error("DHCP: ReqIP missmatch");
break;
case 51:
leaseTime = ((DHCPopIPLT*)(dhcp.options[i]))->ipLeaseTime;
break;
case 53:
msg = ((DHCPopMSG*)(dhcp.options[i]))->message;
break;
case 54:
if (NetAdapter::internalIP != ((DHCPopSERVIP*)dhcp.options[i])->serverIP)
Console.Error("DHCP: ServIP missmatch");
break;
case 55:
reqList = ((DHCPopREQLIST*)(dhcp.options[i]))->requests;
break;
case 56: //String message
break;
case 57:
maxMs = ((DHCPopMMSGS*)(dhcp.options[i]))->maxMessageSize;
break;
case 60: //ClassID
case 61: //ClientID
case 255: //End
break;
default:
Console.Error("DHCP: Got Unhandled Option %d", dhcp.options[i]->GetCode());
break;
}
}
DHCP_Packet* retPay = new DHCP_Packet();
retPay->op = 2,
retPay->hardwareType = hType,
retPay->hardwareAddressLength = hLen,
retPay->transactionID = xID,
retPay->yourIP = ps2IP;
retPay->serverIP = NetAdapter::internalIP;
memcpy(retPay->clientHardwareAddress, cMac, 6);
retPay->magicCookie = cookie;
if (msg == 1 || msg == 3) //Fill out Requests
{
if (msg == 1)
retPay->options.push_back(new DHCPopMSG(2));
if (msg == 3)
retPay->options.push_back(new DHCPopMSG(5));
for (size_t i = 0; i < reqList.size(); i++)
{
switch (reqList[i])
{
case 1:
retPay->options.push_back(new DHCPopSubnet(netmask));
break;
case 3:
if (gateway.integer != 0)
{
std::vector<IP_Address> routers;
routers.push_back(gateway);
retPay->options.push_back(new DHCPopRouter(routers));
}
break;
case 6:
if (dns1.integer != 0)
{
std::vector<IP_Address> dns;
dns.push_back(dns1);
if (dns2.integer != 0)
dns.push_back(dns2);
retPay->options.push_back(new DHCPopDNS(dns));
}
break;
case 15:
retPay->options.push_back(new DHCPopDnsName("PCSX2"));
break;
case 28:
retPay->options.push_back(new DHCPopBCIP(broadcastIP));
break;
case 50:
retPay->options.push_back(new DHCPopREQIP(ps2IP));
break;
case 53: //Msg (Already added)
case 54: //Server Identifier (Already Added)
break;
default:
Console.Error("DHCP: Got Unhandled Request %d", reqList[i]);
break;
}
}
retPay->options.push_back(new DHCPopIPLT(leaseTime));
}
else if (msg == 7)
return true;
retPay->options.push_back(new DHCPopSERVIP(NetAdapter::internalIP));
retPay->options.push_back(new DHCPopEND());
retPay->maxLenth = maxMs;
UDP_Packet* retUdp = new UDP_Packet(retPay);
retUdp->sourcePort = 67;
retUdp->destinationPort = 68;
recvBuff.Enqueue(retUdp);
callback();
return true;
}
DHCP_Server::~DHCP_Server()
{
//Delete entries in queue
while (!recvBuff.IsQueueEmpty())
{
UDP_Packet* retPay = nullptr;
if (!recvBuff.Dequeue(&retPay))
{
std::this_thread::yield();
continue;
}
delete retPay;
}
}
} // namespace InternalServers

View File

@ -0,0 +1,86 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 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 PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <functional>
#include "../SimpleQueue.h"
#include "../PacketReader/IP/IP_Address.h"
#include "../PacketReader/IP/UDP/UDP_Packet.h"
#ifdef _WIN32
#include <winsock2.h>
#include <iphlpapi.h>
#elif defined(__POSIX__)
#include <sys/types.h>
#include <ifaddrs.h>
#endif
namespace InternalServers
{
class DHCP_Server
{
public:
PacketReader::IP::IP_Address ps2IP;
PacketReader::IP::IP_Address gateway;
PacketReader::IP::IP_Address broadcastIP;
private:
std::function<void()> callback;
PacketReader::IP::IP_Address dns1{0};
PacketReader::IP::IP_Address dns2{0};
PacketReader::IP::IP_Address netmask{0};
SimpleQueue<PacketReader::IP::UDP::UDP_Packet*> recvBuff;
u16 maxMs = 576;
public:
DHCP_Server(std::function<void()> receivedcallback);
#ifdef _WIN32
void Init(PIP_ADAPTER_ADDRESSES adapter);
#elif defined(__POSIX__)
void Init(ifaddrs* adapter);
#endif
PacketReader::IP::UDP::UDP_Packet* Recv();
bool Send(PacketReader::IP::UDP::UDP_Packet* payload);
~DHCP_Server();
private:
#ifdef __POSIX__
static std::vector<std::string> SplitString(std::string str, char delimiter);
#ifdef __linux__
static std::vector<PacketReader::IP::IP_Address> GetGatewaysLinux(char* interfaceName);
#endif
static std::vector<PacketReader::IP::IP_Address> GetDNSUnix();
#endif
#ifdef _WIN32
void AutoNetmask(PIP_ADAPTER_ADDRESSES adapter);
void AutoGateway(PIP_ADAPTER_ADDRESSES adapter);
void AutoDNS(PIP_ADAPTER_ADDRESSES adapter, bool autoDNS1, bool autoDNS2);
#elif defined(__POSIX__)
void AutoNetmask(ifaddrs* adapter);
void AutoGateway(ifaddrs* adapter);
void AutoDNS(ifaddrs* adapter, bool autoDNS1, bool autoDNS2);
#endif
void AutoBroadcast(PacketReader::IP::IP_Address parPS2IP, PacketReader::IP::IP_Address parNetmask);
};
} // namespace InternalServers

View File

@ -16,8 +16,8 @@
#include "PrecompiledHeader.h"
#include <stdlib.h>
#include <arpa/inet.h>
//#include <winsock2.h>
#include "../DEV9.h"
#include "AppConfig.h"
@ -50,6 +50,46 @@ void SaveConf()
xmlNewChild(root_node, NULL, BAD_CAST "EthApi",
BAD_CAST buff);
sprintf(buff, "%d", config.InterceptDHCP);
xmlNewChild(root_node, NULL, BAD_CAST "InterceptDHCP",
BAD_CAST buff);
inet_ntop(AF_INET, &config.PS2IP, buff, 256);
xmlNewChild(root_node, NULL, BAD_CAST "PS2IP",
BAD_CAST buff);
inet_ntop(AF_INET, &config.Mask, buff, 256);
xmlNewChild(root_node, NULL, BAD_CAST "Subnet",
BAD_CAST buff);
sprintf(buff, "%d", config.AutoMask);
xmlNewChild(root_node, NULL, BAD_CAST "AutoSubnet",
BAD_CAST buff);
inet_ntop(AF_INET, &config.Gateway, buff, 256);
xmlNewChild(root_node, NULL, BAD_CAST "Gateway",
BAD_CAST buff);
sprintf(buff, "%d", config.AutoGateway);
xmlNewChild(root_node, NULL, BAD_CAST "AutoGateway",
BAD_CAST buff);
inet_ntop(AF_INET, &config.DNS1, buff, 256);
xmlNewChild(root_node, NULL, BAD_CAST "DNS1",
BAD_CAST buff);
sprintf(buff, "%d", config.AutoDNS1);
xmlNewChild(root_node, NULL, BAD_CAST "AutoDNS1",
BAD_CAST buff);
inet_ntop(AF_INET, &config.DNS2, buff, 256);
xmlNewChild(root_node, NULL, BAD_CAST "DNS2",
BAD_CAST buff);
sprintf(buff, "%d", config.AutoDNS2);
xmlNewChild(root_node, NULL, BAD_CAST "AutoDNS2",
BAD_CAST buff);
xmlNewChild(root_node, NULL, BAD_CAST "Hdd",
BAD_CAST config.Hdd);
@ -94,6 +134,7 @@ void LoadConf()
return;
memset(&config, 0, sizeof(config));
config.EthApi = NetApi::PCAP_Switched;
// Read the files
xmlDoc* doc = NULL;
@ -106,7 +147,6 @@ void LoadConf()
SysMessage("Unable to parse configuration file! Suggest deleting it and starting over.");
}
bool foundEthType = false;
for (cur_node = xmlDocGetRootElement(doc)->children; cur_node; cur_node = cur_node->next)
{
if (cur_node->type == XML_ELEMENT_NODE)
@ -118,9 +158,48 @@ void LoadConf()
}
if (0 == strcmp((const char*)cur_node->name, "EthApi"))
{
foundEthType = true;
config.EthApi = (NetApi)atoi((const char*)xmlNodeGetContent(cur_node));
}
if (0 == strcmp((const char*)cur_node->name, "InterceptDHCP"))
{
config.InterceptDHCP = atoi((const char*)xmlNodeGetContent(cur_node));
}
if (0 == strcmp((const char*)cur_node->name, "PS2IP"))
{
inet_pton(AF_INET, (const char*)xmlNodeGetContent(cur_node), &config.PS2IP);
}
if (0 == strcmp((const char*)cur_node->name, "Subnet"))
{
inet_pton(AF_INET, (const char*)xmlNodeGetContent(cur_node), &config.Mask);
}
if (0 == strcmp((const char*)cur_node->name, "AutoSubnet"))
{
config.AutoMask = atoi((const char*)xmlNodeGetContent(cur_node));
}
if (0 == strcmp((const char*)cur_node->name, "Gateway"))
{
inet_pton(AF_INET, (const char*)xmlNodeGetContent(cur_node), &config.Gateway);
}
if (0 == strcmp((const char*)cur_node->name, "AutoGateway"))
{
config.AutoGateway = atoi((const char*)xmlNodeGetContent(cur_node));
}
if (0 == strcmp((const char*)cur_node->name, "DNS1"))
{
inet_pton(AF_INET, (const char*)xmlNodeGetContent(cur_node), &config.DNS1);
}
if (0 == strcmp((const char*)cur_node->name, "AutoDNS1"))
{
config.AutoDNS1 = atoi((const char*)xmlNodeGetContent(cur_node));
}
if (0 == strcmp((const char*)cur_node->name, "DNS2"))
{
inet_pton(AF_INET, (const char*)xmlNodeGetContent(cur_node), &config.DNS2);
}
if (0 == strcmp((const char*)cur_node->name, "AutoDNS2"))
{
config.AutoDNS2 = atoi((const char*)xmlNodeGetContent(cur_node));
}
if (0 == strcmp((const char*)cur_node->name, "Hdd"))
{
strcpy(config.Hdd, (const char*)xmlNodeGetContent(cur_node));
@ -140,9 +219,6 @@ void LoadConf()
}
}
if (!foundEthType)
config.EthApi = NetApi::PCAP_Switched;
// free(configFile);
xmlFreeDoc(doc);
xmlCleanupParser();

View File

@ -16,6 +16,7 @@
#include "PrecompiledHeader.h"
#include <stdio.h>
#include <arpa/inet.h>
#include <gtk/gtk.h>
@ -34,13 +35,109 @@
#include "pcap.h"
#include "../pcap_io.h"
#include "../net.h"
#include "../PacketReader/IP/IP_Address.h"
#include "AppCoreThread.h"
#include "../ATA/HddCreate.h"
using PacketReader::IP::IP_Address;
static GtkBuilder* builder = nullptr;
std::vector<AdapterEntry> adapters;
void IPControl_SetValue(GtkEntry* entryCtl, IP_Address value)
{
char addrBuff[INET_ADDRSTRLEN] = {0};
inet_ntop(AF_INET, &value, addrBuff, INET_ADDRSTRLEN);
gtk_entry_set_text(entryCtl, addrBuff);
}
IP_Address IPControl_GetValue(GtkEntry* entryCtl)
{
IP_Address ret;
if (inet_pton(AF_INET, gtk_entry_get_text(entryCtl), &ret) == 1)
return ret;
Console.Error("Invalid IP address entered");
return {0};
}
void IPControl_Enable(GtkEntry *ipEntry, bool enabled, IP_Address value)
{
if (enabled)
{
gtk_widget_set_sensitive((GtkWidget*)ipEntry, true);
IPControl_SetValue(ipEntry, value);
}
else
{
gtk_widget_set_sensitive((GtkWidget*)ipEntry, false);
IPControl_SetValue(ipEntry, {0});
}
}
void OnAutoMaskChanged(GtkToggleButton *togglebutton, gpointer usr_data)
{
IPControl_Enable((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_SUBNET"), !gtk_toggle_button_get_active(togglebutton), config.Mask);
}
void OnAutoGatewayChanged(GtkToggleButton *togglebutton, gpointer usr_data)
{
IPControl_Enable((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_GATEWAY"), !gtk_toggle_button_get_active(togglebutton), config.Gateway);
}
void OnAutoDNS1Changed(GtkToggleButton *togglebutton, gpointer usr_data)
{
IPControl_Enable((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_DNS1"), !gtk_toggle_button_get_active(togglebutton), config.DNS1);
}
void OnAutoDNS2Changed(GtkToggleButton *togglebutton, gpointer usr_data)
{
IPControl_Enable((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_DNS2"), !gtk_toggle_button_get_active(togglebutton), config.DNS2);
}
void OnInterceptChanged(GtkToggleButton *togglebutton, gpointer usr_data)
{
if (gtk_toggle_button_get_active(togglebutton))
{
gtk_widget_set_sensitive((GtkWidget*)gtk_builder_get_object(builder, "IDC_IPADDRESS_IP"), true);
IPControl_SetValue((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_IP"), config.PS2IP);
gtk_widget_set_sensitive((GtkWidget*)gtk_builder_get_object(builder, "IDC_CHECK_SUBNET"), true);
gtk_widget_set_sensitive((GtkWidget*)gtk_builder_get_object(builder, "IDC_CHECK_GATEWAY"), true);
gtk_widget_set_sensitive((GtkWidget*)gtk_builder_get_object(builder, "IDC_CHECK_DNS1"), true);
gtk_widget_set_sensitive((GtkWidget*)gtk_builder_get_object(builder, "IDC_CHECK_DNS2"), true);
gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_SUBNET"), config.AutoMask);
gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_GATEWAY"), config.AutoGateway);
gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_DNS1"), config.AutoDNS1);
gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_DNS2"), config.AutoDNS2);
OnAutoMaskChanged((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_SUBNET"), nullptr);
OnAutoGatewayChanged((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_GATEWAY"), nullptr);
OnAutoDNS1Changed((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_DNS1"), nullptr);
OnAutoDNS2Changed((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_DNS2"), nullptr);
}
else
{
gtk_widget_set_sensitive((GtkWidget*)gtk_builder_get_object(builder, "IDC_IPADDRESS_IP"), false);
IPControl_SetValue((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_IP"), {0});
gtk_widget_set_sensitive((GtkWidget*)gtk_builder_get_object(builder, "IDC_CHECK_SUBNET"), false);
gtk_widget_set_sensitive((GtkWidget*)gtk_builder_get_object(builder, "IDC_CHECK_GATEWAY"), false);
gtk_widget_set_sensitive((GtkWidget*)gtk_builder_get_object(builder, "IDC_CHECK_DNS1"), false);
gtk_widget_set_sensitive((GtkWidget*)gtk_builder_get_object(builder, "IDC_CHECK_DNS2"), false);
gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_SUBNET"), true);
gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_GATEWAY"), true);
gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_DNS1"), true);
gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_DNS2"), true);
IPControl_Enable((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_SUBNET"), false, config.Mask);
IPControl_Enable((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_GATEWAY"), false, config.Gateway);
IPControl_Enable((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_DNS1"), false, config.DNS1);
IPControl_Enable((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_DNS2"), false, config.DNS2);
}
}
void OnInitDialog()
{
gint idx = 0;
@ -67,6 +164,9 @@ void OnInitDialog()
idx++;
}
gtk_toggle_button_set_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_DHCP"), config.InterceptDHCP);
OnInterceptChanged((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_DHCP"), nullptr);
gtk_entry_set_text((GtkEntry*)gtk_builder_get_object(builder, "IDC_HDDFILE"), config.Hdd);
//HDDSpin
@ -147,6 +247,28 @@ void OnOk()
config.EthApi = adapters[ethIndex].type;
}
config.InterceptDHCP = gtk_toggle_button_get_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_DHCP"));
if (config.InterceptDHCP)
{
config.PS2IP = IPControl_GetValue((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_IP"));
config.AutoMask = gtk_toggle_button_get_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_SUBNET"));
if (!config.AutoMask)
config.Mask = IPControl_GetValue((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_SUBNET"));
config.AutoGateway = gtk_toggle_button_get_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_GATEWAY"));
if (!config.AutoGateway)
config.Gateway = IPControl_GetValue((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_GATEWAY"));
config.AutoDNS1 = gtk_toggle_button_get_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_DNS1"));
if (!config.AutoDNS1)
config.DNS1 = IPControl_GetValue((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_DNS1"));
config.AutoDNS2 = gtk_toggle_button_get_active((GtkToggleButton*)gtk_builder_get_object(builder, "IDC_CHECK_DNS2"));
if (!config.AutoDNS2)
config.DNS2 = IPControl_GetValue((GtkEntry*)gtk_builder_get_object(builder, "IDC_IPADDRESS_DNS2"));
}
strcpy(config.Hdd, gtk_entry_get_text((GtkEntry*)gtk_builder_get_object(builder, "IDC_HDDFILE")));
config.HddSize = gtk_spin_button_get_value((GtkSpinButton*)gtk_builder_get_object(builder, "IDC_HDDSIZE_SPIN")) * 1024;
@ -184,6 +306,11 @@ void DEV9configure()
{
builder = gtk_builder_new();
gtk_builder_add_callback_symbols(builder,
"OnInterceptChanged", G_CALLBACK(&OnInterceptChanged),
"OnAutoMaskChanged", G_CALLBACK(&OnAutoMaskChanged),
"OnAutoGatewayChanged", G_CALLBACK(&OnAutoGatewayChanged),
"OnAutoDNS1Changed", G_CALLBACK(&OnAutoDNS1Changed),
"OnAutoDNS2Changed", G_CALLBACK(&OnAutoDNS2Changed),
"OnBrowse", G_CALLBACK(&OnBrowse),
"OnSpin", G_CALLBACK(&OnSpin),
"OnSlide", G_CALLBACK(&OnSlide), nullptr);

View File

@ -120,12 +120,14 @@
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Ethernet Device: </property>
</object>
<packing>
@ -133,6 +135,212 @@
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Intercept DHCP:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="IDC_CHECK_DHCP">
<property name="label" translatable="yes">Enabled</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="OnInterceptChanged" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">PS2 Address:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Subnet Mask:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Gateway Address:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">DNS1 Address:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">DNS2 Address:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="IDC_IPADDRESS_IP">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="max_length">15</property>
<property name="text" translatable="yes">0.0.0.0</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="IDC_IPADDRESS_SUBNET">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="max_length">15</property>
<property name="text" translatable="yes">0.0.0.0</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="IDC_IPADDRESS_GATEWAY">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="max_length">15</property>
<property name="text" translatable="yes">0.0.0.0</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="IDC_IPADDRESS_DNS1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="max_length">15</property>
<property name="text" translatable="yes">0.0.0.0</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="IDC_IPADDRESS_DNS2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="max_length">15</property>
<property name="text" translatable="yes">0.0.0.0</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">6</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="IDC_CHECK_SUBNET">
<property name="label" translatable="yes">Auto</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="OnAutoMaskChanged" swapped="no"/>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="IDC_CHECK_GATEWAY">
<property name="label" translatable="yes">Auto</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="OnAutoGatewayChanged" swapped="no"/>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="IDC_CHECK_DNS1">
<property name="label" translatable="yes">Auto</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="OnAutoDNS1Changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="IDC_CHECK_DNS2">
<property name="label" translatable="yes">Auto</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="OnAutoDNS2Changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">6</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>

View File

@ -19,10 +19,11 @@
#include <fstream>
//#include <winsock2.h>
#include "..\DEV9.h"
#include "AppConfig.h"
#include "ws2tcpip.h"
BOOL WritePrivateProfileInt(LPCWSTR lpAppName, LPCWSTR lpKeyName, int intvar, LPCWSTR lpFileName)
{
return WritePrivateProfileString(lpAppName, lpKeyName, std::to_wstring(intvar).c_str(), lpFileName);
@ -47,13 +48,37 @@ void SaveConf()
nfile.write((char*)L"[DEV9]", 14);
nfile.close();
wchar_t addrBuff[INET_ADDRSTRLEN] = {0};
wchar_t wEth[sizeof(config.Eth)] = {0};
mbstowcs(wEth, config.Eth, sizeof(config.Eth) - 1);
WritePrivateProfileString(L"DEV9", L"Eth", wEth, file.c_str());
WritePrivateProfileInt(L"DEV9", L"EthApi", (int)config.EthApi, file.c_str());
WritePrivateProfileString(L"DEV9", L"Hdd", config.Hdd, file.c_str());
WritePrivateProfileInt(L"DEV9", L"EthApi", (int)config.EthApi, file.c_str());
WritePrivateProfileInt(L"DEV9", L"InterceptDHCP", config.InterceptDHCP, file.c_str());
InetNtop(AF_INET, &config.PS2IP, addrBuff, INET_ADDRSTRLEN);
WritePrivateProfileString(L"DEV9", L"PS2IP", addrBuff, file.c_str());
InetNtop(AF_INET, &config.Mask, addrBuff, INET_ADDRSTRLEN);
WritePrivateProfileString(L"DEV9", L"Subnet", addrBuff, file.c_str());
WritePrivateProfileInt(L"DEV9", L"AutoSubnet", config.AutoMask, file.c_str());
InetNtop(AF_INET, &config.Gateway, addrBuff, INET_ADDRSTRLEN);
WritePrivateProfileString(L"DEV9", L"Gateway", addrBuff, file.c_str());
WritePrivateProfileInt(L"DEV9", L"AutoGateway", config.AutoGateway, file.c_str());
InetNtop(AF_INET, &config.DNS1, addrBuff, INET_ADDRSTRLEN);
WritePrivateProfileString(L"DEV9", L"DNS1", addrBuff, file.c_str());
WritePrivateProfileInt(L"DEV9", L"AutoDNS1", config.AutoDNS1, file.c_str());
InetNtop(AF_INET, &config.DNS2, addrBuff, INET_ADDRSTRLEN);
WritePrivateProfileString(L"DEV9", L"DNS2", addrBuff, file.c_str());
WritePrivateProfileInt(L"DEV9", L"AutoDNS2", config.AutoDNS2, file.c_str());
WritePrivateProfileString(L"DEV9", L"Hdd", config.Hdd, file.c_str());
WritePrivateProfileInt(L"DEV9", L"HddSize", config.HddSize, file.c_str());
WritePrivateProfileInt(L"DEV9", L"ethEnable", config.ethEnable, file.c_str());
WritePrivateProfileInt(L"DEV9", L"hddEnable", config.hddEnable, file.c_str());
}
@ -64,15 +89,38 @@ void LoadConf()
if (FileExists(file.c_str()) == false)
return;
wchar_t addrBuff[INET_ADDRSTRLEN] = {0};
wchar_t wEth[sizeof(config.Eth)] = {0};
mbstowcs(wEth, ETH_DEF, sizeof(config.Eth) - 1);
GetPrivateProfileString(L"DEV9", L"Eth", wEth, wEth, sizeof(config.Eth), file.c_str());
wcstombs(config.Eth, wEth, sizeof(config.Eth) - 1);
config.EthApi = (NetApi)GetPrivateProfileInt(L"DEV9", L"EthApi", (int)NetApi::TAP, file.c_str());
config.InterceptDHCP = GetPrivateProfileInt(L"DEV9", L"InterceptDHCP", config.InterceptDHCP, file.c_str());
GetPrivateProfileString(L"DEV9", L"PS2IP", L"0.0.0.0", addrBuff, INET_ADDRSTRLEN, file.c_str());
InetPton(AF_INET, addrBuff, &config.PS2IP);
GetPrivateProfileString(L"DEV9", L"Subnet", L"0.0.0.0", addrBuff, INET_ADDRSTRLEN, file.c_str());
InetPton(AF_INET, addrBuff, &config.Mask);
config.AutoMask = GetPrivateProfileInt(L"DEV9", L"AutoSubnet", config.AutoMask, file.c_str());
GetPrivateProfileString(L"DEV9", L"Gateway", L"0.0.0.0", addrBuff, INET_ADDRSTRLEN, file.c_str());
InetPton(AF_INET, addrBuff, &config.Gateway);
config.AutoGateway = GetPrivateProfileInt(L"DEV9", L"AutoGateway", config.AutoGateway, file.c_str());
GetPrivateProfileString(L"DEV9", L"DNS1", L"0.0.0.0", addrBuff, INET_ADDRSTRLEN, file.c_str());
InetPton(AF_INET, addrBuff, &config.DNS1);
config.AutoDNS1 = GetPrivateProfileInt(L"DEV9", L"AutoDNS1", config.AutoDNS1, file.c_str());
GetPrivateProfileString(L"DEV9", L"DNS2", L"0.0.0.0", addrBuff, INET_ADDRSTRLEN, file.c_str());
InetPton(AF_INET, addrBuff, &config.DNS2);
config.AutoDNS2 = GetPrivateProfileInt(L"DEV9", L"AutoDNS2", config.AutoDNS2, file.c_str());
GetPrivateProfileString(L"DEV9", L"Hdd", HDD_DEF, config.Hdd, sizeof(config.Hdd), file.c_str());
config.HddSize = GetPrivateProfileInt(L"DEV9", L"HddSize", config.HddSize, file.c_str());
config.ethEnable = GetPrivateProfileInt(L"DEV9", L"ethEnable", config.ethEnable, file.c_str());
config.hddEnable = GetPrivateProfileInt(L"DEV9", L"hddEnable", config.hddEnable, file.c_str());
}

View File

@ -54,30 +54,46 @@ END
// Dialog
//
IDD_CONFIG DIALOGEX 0, 0, 290, 205
IDD_CONFIG DIALOGEX 0, 0, 291, 320
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Network and HDD Settings"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,92,185,50,14
PUSHBUTTON "Cancel",IDCANCEL,148,185,50,14
DEFPUSHBUTTON "OK",IDOK,92,300,50,14
PUSHBUTTON "Cancel",IDCANCEL,148,300,50,14
LTEXT "DEV9 Type:",IDC_STATIC,15,10,41,11,SS_CENTERIMAGE
COMBOBOX IDC_BAYTYPE,61,8,223,47,CBS_DROPDOWNLIST | CBS_SORT | WS_DISABLED
GROUPBOX "Ethernet",IDC_STATIC,7,30,277,50
GROUPBOX "Ethernet",IDC_STATIC,7,30,277,164
CONTROL "Enabled",IDC_ETHENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,45,42,8
LTEXT "Ethernet Device:",IDC_STATIC,26,60,60,8,SS_CENTERIMAGE
COMBOBOX IDC_ETHDEV,94,58,182,82,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Hard Disk Drive",IDC_STATIC,7,90,277,85
CONTROL "Enabled",IDC_HDDENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,105,42,8
LTEXT "HDD File:",IDC_STATIC,26,120,60,8,SS_CENTERIMAGE
EDITTEXT IDC_HDDFILE,94,118,130,13,ES_AUTOHSCROLL
CONTROL "",IDC_HDDSIZE_SLIDER,"msctls_trackbar32",WS_TABSTOP,90,141,150,15
LTEXT "HDD Size (GiB):",IDC_STATIC,26,143,60,8,SS_CENTERIMAGE
EDITTEXT IDC_HDDSIZE_TEXT,240,141,25,13,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_HDDSIZE_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,265,141,11,13
LTEXT "8 GiB",IDC_STATIC,89,158,17,8
LTEXT "120 GiB",IDC_STATIC,219,157,25,8,0,WS_EX_RIGHT
PUSHBUTTON "Browse",IDC_BROWSE,226,117,50,15
GROUPBOX "Hard Disk Drive",IDC_STATIC,7,205,277,85
CONTROL "Enabled",IDC_HDDENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,220,42,8
LTEXT "HDD File:",IDC_STATIC,26,235,60,8,SS_CENTERIMAGE
EDITTEXT IDC_HDDFILE,94,233,130,13,ES_AUTOHSCROLL
CONTROL "",IDC_HDDSIZE_SLIDER,"msctls_trackbar32",WS_TABSTOP,90,256,150,15
LTEXT "HDD Size (GiB):",IDC_STATIC,26,258,60,8,SS_CENTERIMAGE
EDITTEXT IDC_HDDSIZE_TEXT,240,256,25,13,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_HDDSIZE_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,265,256,11,13
LTEXT "8 GiB",IDC_STATIC,89,273,17,8
LTEXT "120 GiB",IDC_STATIC,219,272,25,8,0,WS_EX_RIGHT
PUSHBUTTON "Browse",IDC_BROWSE,226,232,50,15
CONTROL "",IDC_IPADDRESS_IP,"SysIPAddress32",WS_TABSTOP,95,92,100,15
LTEXT "Intercept DHCP:",IDC_STATIC,26,77,60,8,SS_CENTERIMAGE
LTEXT "PS2 Address:",IDC_STATIC,26,94,60,8,SS_CENTERIMAGE
CONTROL "Enabled",IDC_CHECK_DHCP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,95,77,41,10
CONTROL "",IDC_IPADDRESS_SUBNET,"SysIPAddress32",WS_TABSTOP,95,111,100,15
LTEXT "Subnet Mask:",IDC_STATIC,26,113,60,8,SS_CENTERIMAGE
CONTROL "",IDC_IPADDRESS_GATEWAY,"SysIPAddress32",WS_TABSTOP,95,130,100,15
LTEXT "Gateway Address:",IDC_STATIC,25,132,60,8,SS_CENTERIMAGE
CONTROL "",IDC_IPADDRESS_DNS1,"SysIPAddress32",WS_TABSTOP,95,150,100,15
LTEXT "DNS1 Address:",IDC_STATIC,25,152,60,8,SS_CENTERIMAGE
CONTROL "",IDC_IPADDRESS_DNS2,"SysIPAddress32",WS_TABSTOP,95,170,100,15
LTEXT "DNS2 Address:",IDC_STATIC,25,172,60,8,SS_CENTERIMAGE
CONTROL "Auto",IDC_CHECK_SUBNET,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,113,31,10
CONTROL "Auto",IDC_CHECK_GATEWAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,132,31,10
CONTROL "Auto",IDC_CHECK_DNS1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,152,31,10
CONTROL "Auto",IDC_CHECK_DNS2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,172,31,10
END
@ -92,9 +108,9 @@ BEGIN
IDD_CONFIG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 284
RIGHTMARGIN, 285
TOPMARGIN, 7
BOTTOMMARGIN, 273
BOTTOMMARGIN, 314
END
END
#endif // APSTUDIO_INVOKED

View File

@ -26,11 +26,14 @@
#include "..\DEV9.h"
#include "..\pcap_io.h"
#include "..\net.h"
#include "..\PacketReader\IP\IP_Address.h"
#include "tap.h"
#include "AppCoreThread.h"
#include "../ATA/HddCreate.h"
using PacketReader::IP::IP_Address;
extern HINSTANCE hInst;
//HANDLE handleDEV9Thread = NULL;
//DWORD dwThreadId, dwThrdParam;
@ -47,6 +50,101 @@ void SysMessage(char* fmt, ...)
MessageBoxA(0, tmp, "Dev9 Msg", 0);
}
void IPControl_SetValue(HWND hwndCtl, IP_Address value)
{
int tmp = MAKEIPADDRESS(value.bytes[0], value.bytes[1], value.bytes[2], value.bytes[3]);
SendMessage(hwndCtl, IPM_SETADDRESS, (WPARAM)0, (LPARAM)tmp);
}
IP_Address IPControl_GetValue(HWND hwndCtl)
{
int tmp;
SendMessage(hwndCtl, IPM_GETADDRESS, (WPARAM)0, (LPARAM)&tmp);
IP_Address ret;
ret.bytes[0] = FIRST_IPADDRESS(tmp);
ret.bytes[1] = SECOND_IPADDRESS(tmp);
ret.bytes[2] = THIRD_IPADDRESS(tmp);
ret.bytes[3] = FOURTH_IPADDRESS(tmp);
return ret;
}
void IPControl_Enable(HWND hwndCtl, bool enabled, IP_Address value)
{
if (enabled)
{
EnableWindow(hwndCtl, true);
IPControl_SetValue(hwndCtl, value);
}
else
{
EnableWindow(hwndCtl, false);
IPControl_SetValue(hwndCtl, {0});
}
}
void AutoMaskChanged(HWND hW)
{
IPControl_Enable(GetDlgItem(hW, IDC_IPADDRESS_SUBNET), !Button_GetCheck(GetDlgItem(hW, IDC_CHECK_SUBNET)), config.Mask);
}
void AutoGatewayChanged(HWND hW)
{
IPControl_Enable(GetDlgItem(hW, IDC_IPADDRESS_GATEWAY), !Button_GetCheck(GetDlgItem(hW, IDC_CHECK_GATEWAY)), config.Gateway);
}
void AutoDNS1Changed(HWND hW)
{
IPControl_Enable(GetDlgItem(hW, IDC_IPADDRESS_DNS1), !Button_GetCheck(GetDlgItem(hW, IDC_CHECK_DNS1)), config.DNS1);
}
void AutoDNS2Changed(HWND hW)
{
IPControl_Enable(GetDlgItem(hW, IDC_IPADDRESS_DNS2), !Button_GetCheck(GetDlgItem(hW, IDC_CHECK_DNS2)), config.DNS1);
}
void InterceptChanged(HWND hW)
{
if (Button_GetCheck(GetDlgItem(hW, IDC_CHECK_DHCP)))
{
EnableWindow(GetDlgItem(hW, IDC_IPADDRESS_IP), true);
IPControl_SetValue(GetDlgItem(hW, IDC_IPADDRESS_IP), config.PS2IP);
Button_Enable(GetDlgItem(hW, IDC_CHECK_SUBNET), true);
Button_Enable(GetDlgItem(hW, IDC_CHECK_GATEWAY), true);
Button_Enable(GetDlgItem(hW, IDC_CHECK_DNS1), true);
Button_Enable(GetDlgItem(hW, IDC_CHECK_DNS2), true);
Button_SetCheck(GetDlgItem(hW, IDC_CHECK_SUBNET), config.AutoMask);
Button_SetCheck(GetDlgItem(hW, IDC_CHECK_GATEWAY), config.AutoGateway);
Button_SetCheck(GetDlgItem(hW, IDC_CHECK_DNS1), config.AutoDNS1);
Button_SetCheck(GetDlgItem(hW, IDC_CHECK_DNS2), config.AutoDNS2);
AutoMaskChanged(hW);
AutoGatewayChanged(hW);
AutoDNS1Changed(hW);
AutoDNS2Changed(hW);
}
else
{
EnableWindow(GetDlgItem(hW, IDC_IPADDRESS_IP), false);
IPControl_SetValue(GetDlgItem(hW, IDC_IPADDRESS_IP), {0});
Button_Enable(GetDlgItem(hW, IDC_CHECK_SUBNET), false);
Button_Enable(GetDlgItem(hW, IDC_CHECK_GATEWAY), false);
Button_Enable(GetDlgItem(hW, IDC_CHECK_DNS1), false);
Button_Enable(GetDlgItem(hW, IDC_CHECK_DNS2), false);
Button_SetCheck(GetDlgItem(hW, IDC_CHECK_SUBNET), true);
Button_SetCheck(GetDlgItem(hW, IDC_CHECK_GATEWAY), true);
Button_SetCheck(GetDlgItem(hW, IDC_CHECK_DNS1), true);
Button_SetCheck(GetDlgItem(hW, IDC_CHECK_DNS2), true);
IPControl_Enable(GetDlgItem(hW, IDC_IPADDRESS_SUBNET), false, config.Mask);
IPControl_Enable(GetDlgItem(hW, IDC_IPADDRESS_GATEWAY), false, config.Gateway);
IPControl_Enable(GetDlgItem(hW, IDC_IPADDRESS_DNS1), false, config.DNS1);
IPControl_Enable(GetDlgItem(hW, IDC_IPADDRESS_DNS2), false, config.DNS1);
}
}
void OnInitDialog(HWND hW)
{
//int i;
@ -75,6 +173,9 @@ void OnInitDialog(HWND hW)
ComboBox_SetCurSel(GetDlgItem(hW, IDC_ETHDEV), itm);
}
Button_SetCheck(GetDlgItem(hW, IDC_CHECK_DHCP), config.InterceptDHCP);
InterceptChanged(hW);
SetWindowText(GetDlgItem(hW, IDC_HDDFILE), config.Hdd);
//HDDText
@ -188,6 +289,28 @@ void OnOk(HWND hW)
strcpy(config.Eth, guid_char);
}
config.InterceptDHCP = Button_GetCheck(GetDlgItem(hW, IDC_CHECK_DHCP));
if (config.InterceptDHCP)
{
config.PS2IP = IPControl_GetValue(GetDlgItem(hW, IDC_IPADDRESS_IP));
config.AutoMask = Button_GetCheck(GetDlgItem(hW, IDC_CHECK_SUBNET));
if (!config.AutoMask)
config.Mask = IPControl_GetValue(GetDlgItem(hW, IDC_IPADDRESS_SUBNET));
config.AutoGateway = Button_GetCheck(GetDlgItem(hW, IDC_CHECK_GATEWAY));
if (!config.AutoGateway)
config.Gateway = IPControl_GetValue(GetDlgItem(hW, IDC_IPADDRESS_GATEWAY));
config.AutoDNS1 = Button_GetCheck(GetDlgItem(hW, IDC_CHECK_DNS1));
if (!config.AutoDNS1)
config.DNS1 = IPControl_GetValue(GetDlgItem(hW, IDC_IPADDRESS_DNS1));
config.AutoDNS2 = Button_GetCheck(GetDlgItem(hW, IDC_CHECK_DNS2));
if (!config.AutoDNS2)
config.DNS2 = IPControl_GetValue(GetDlgItem(hW, IDC_IPADDRESS_DNS2));
}
GetWindowText(GetDlgItem(hW, IDC_HDDFILE), config.Hdd, 256);
if (Edit_GetTextLength(GetDlgItem(hW, IDC_HDDSIZE_TEXT)) == 0)
@ -259,6 +382,21 @@ BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
OnOk(hW);
return TRUE;
case IDC_CHECK_DHCP:
InterceptChanged(hW);
return TRUE;
case IDC_CHECK_SUBNET:
AutoMaskChanged(hW);
return TRUE;
case IDC_CHECK_GATEWAY:
AutoGatewayChanged(hW);
return TRUE;
case IDC_CHECK_DNS1:
AutoDNS1Changed(hW);
return TRUE;
case IDC_CHECK_DNS2:
AutoDNS2Changed(hW);
return TRUE;
case IDC_BROWSE:
OnBrowse(hW);
return TRUE;

View File

@ -15,6 +15,16 @@
#define IDC_HDDSIZE_SPIN 8013
#define IDC_HDDSIZE_TEXT 8015
#define IDC_BROWSE 8017
#define IDC_IPADDRESS_IP 8018
#define IDC_CHECK_DHCP 8019
#define IDC_IPADDRESS_SUBNET 8020
#define IDC_IPADDRESS_GATEWAY 8021
#define IDC_IPADDRESS_DNS1 8022
#define IDC_IPADDRESS_DNS2 8023
#define IDC_CHECK_SUBNET 8024
#define IDC_CHECK_GATEWAY 8025
#define IDC_CHECK_DNS1 8026
#define IDC_CHECK_DNS2 8027
#define IDC_STATIC -1
// Next default values for new objects
@ -23,7 +33,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 806
#define _APS_NEXT_COMMAND_VALUE 40002
#define _APS_NEXT_CONTROL_VALUE 8018
#define _APS_NEXT_CONTROL_VALUE 8025
#define _APS_NEXT_SYMED_VALUE 801
#endif
#endif

View File

@ -275,6 +275,9 @@ void NetAdapter::InitInternalServer(ifaddrs* adapter)
if (adapter == nullptr)
Console.Error("DEV9: InitInternalServer() got nullptr for adapter");
if (config.InterceptDHCP)
dhcpServer.Init(adapter);
if (blocks())
{
internalRxThreadRunning.store(true);
@ -290,10 +293,26 @@ void NetAdapter::ReloadInternalServer(ifaddrs* adapter)
{
if (adapter == nullptr)
Console.Error("DEV9: ReloadInternalServer() got nullptr for adapter");
if (config.InterceptDHCP)
dhcpServer.Init(adapter);
}
bool NetAdapter::InternalServerRecv(NetPacket* pkt)
{
IP_Payload* updpkt = dhcpServer.Recv();
if (updpkt != nullptr)
{
IP_Packet* ippkt = new IP_Packet(updpkt);
ippkt->destinationIP = {255, 255, 255, 255};
ippkt->sourceIP = internalIP;
EthernetFrame frame(ippkt);
memcpy(frame.sourceMAC, internalMAC, 6);
memcpy(frame.destinationMAC, ps2MAC, 6);
frame.protocol = (u16)EtherType::IPv4;
frame.WritePacket(pkt);
return true;
}
return false;
}
@ -305,6 +324,19 @@ bool NetAdapter::InternalServerSend(NetPacket* pkt)
PayloadPtr* payload = static_cast<PayloadPtr*>(frame.GetPayload());
IP_Packet ippkt(payload->data, payload->GetLength());
if (ippkt.protocol == (u16)IP_Type::UDP)
{
IP_PayloadPtr* ipPayload = static_cast<IP_PayloadPtr*>(ippkt.GetPayload());
UDP_Packet udppkt(ipPayload->data, ipPayload->GetLength());
if (udppkt.destinationPort == 67)
{
//Send DHCP
if (config.InterceptDHCP)
return dhcpServer.Send(&udppkt);
}
}
if (ippkt.destinationIP == internalIP)
{
return true;

View File

@ -32,6 +32,7 @@
#endif
#include "PacketReader/IP/IP_Address.h"
#include "InternalServers/DHCP_Server.h"
struct Config;
@ -93,6 +94,8 @@ private:
std::condition_variable internalRxCV;
bool internalRxHasData = false;
InternalServers::DHCP_Server dhcpServer = InternalServers::DHCP_Server([&] { InternalSignalReceived(); });
public:
NetAdapter();
virtual bool blocks() = 0;

View File

@ -286,6 +286,7 @@
<ClCompile Include="..\..\DEV9\ATA\HddCreate.cpp" />
<ClCompile Include="..\..\DEV9\DEV9.cpp" />
<ClCompile Include="..\..\DEV9\flash.cpp" />
<ClCompile Include="..\..\DEV9\InternalServers\DHCP_Server.cpp" />
<ClCompile Include="..\..\DEV9\PacketReader\EthernetFrame.cpp" />
<ClCompile Include="..\..\DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.cpp" />
<ClCompile Include="..\..\DEV9\PacketReader\IP\UDP\DHCP\DHCP_Packet.cpp" />
@ -657,6 +658,7 @@
<ClInclude Include="..\..\DEV9\ATA\HddCreate.h" />
<ClInclude Include="..\..\DEV9\Config.h" />
<ClInclude Include="..\..\DEV9\DEV9.h" />
<ClInclude Include="..\..\DEV9\InternalServers\DHCP_Server.h" />
<ClInclude Include="..\..\DEV9\net.h" />
<ClInclude Include="..\..\DEV9\PacketReader\EthernetFrame.h" />
<ClInclude Include="..\..\DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.h" />

View File

@ -1108,6 +1108,9 @@
<ClCompile Include="..\..\DEV9\flash.cpp">
<Filter>System\Ps2\DEV9</Filter>
</ClCompile>
<ClCompile Include="..\..\DEV9\InternalServers\DHCP_Server.cpp">
<Filter>System\Ps2\DEV9\InternalServers</Filter>
</ClCompile>
<ClCompile Include="..\..\DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.cpp">
<Filter>System\Ps2\DEV9\PacketReader\IP\UDP\DHCP</Filter>
</ClCompile>
@ -1890,6 +1893,9 @@
<ClInclude Include="..\..\DEV9\DEV9.h">
<Filter>System\Ps2\DEV9</Filter>
</ClInclude>
<ClInclude Include="..\..\DEV9\InternalServers\DHCP_Server.h">
<Filter>System\Ps2\DEV9\InternalServers</Filter>
</ClInclude>
<ClInclude Include="..\..\DEV9\net.h">
<Filter>System\Ps2\DEV9</Filter>
</ClInclude>