Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #10690 from schthack/BBA-tapless
BBA: Added BuiltIn device that allow BBA emulation without the need o…
  • Loading branch information
AdmiralCurtiss committed Jul 9, 2022
2 parents 5337943 + 087020b commit 5a7759e
Show file tree
Hide file tree
Showing 16 changed files with 1,414 additions and 46 deletions.
361 changes: 361 additions & 0 deletions Source/Core/Common/Network.cpp

Large diffs are not rendered by default.

154 changes: 151 additions & 3 deletions Source/Core/Common/Network.h
Expand Up @@ -7,6 +7,7 @@
#include <optional>
#include <string>
#include <string_view>
#include <vector>

#include "Common/CommonTypes.h"

Expand All @@ -22,11 +23,25 @@ enum class MACConsumer

enum
{
MAC_ADDRESS_SIZE = 6
BBA_HARDWARE_TYPE = 1,
MAC_ADDRESS_SIZE = 6,
IPV4_HEADER_TYPE = 8
};

enum DHCPConst
{
MESSAGE_QUERY = 1,
MESSAGE_REPLY = 2
};

using MACAddress = std::array<u8, MAC_ADDRESS_SIZE>;
constexpr std::size_t IPV4_ADDR_LEN = 4;
using IPAddress = std::array<u8, IPV4_ADDR_LEN>;
constexpr IPAddress IP_ADDR_ANY = {0, 0, 0, 0};
constexpr IPAddress IP_ADDR_BROADCAST = {255, 255, 255, 255};
constexpr IPAddress IP_ADDR_SSDP = {239, 255, 255, 250};
constexpr u16 IPV4_ETHERTYPE = 0x800;
constexpr u16 ARP_ETHERTYPE = 0x806;

struct EthernetHeader
{
Expand All @@ -47,6 +62,7 @@ struct IPv4Header
IPv4Header();
IPv4Header(u16 data_size, u8 ip_proto, const sockaddr_in& from, const sockaddr_in& to);
u16 Size() const;
u8 DefinedSize() const;

static constexpr std::size_t SIZE = 20;

Expand All @@ -58,15 +74,17 @@ struct IPv4Header
u8 ttl = 0;
u8 protocol = 0;
u16 header_checksum = 0;
std::array<u8, IPV4_ADDR_LEN> source_addr{};
std::array<u8, IPV4_ADDR_LEN> destination_addr{};
IPAddress source_addr{};
IPAddress destination_addr{};
};
static_assert(sizeof(IPv4Header) == IPv4Header::SIZE);

struct TCPHeader
{
TCPHeader();
TCPHeader(const sockaddr_in& from, const sockaddr_in& to, u32 seq, const u8* data, u16 length);
TCPHeader(const sockaddr_in& from, const sockaddr_in& to, u32 seq, u32 ack, u16 flags);
u8 GetHeaderSize() const;
u16 Size() const;
u8 IPProto() const;

Expand Down Expand Up @@ -99,6 +117,134 @@ struct UDPHeader
};
static_assert(sizeof(UDPHeader) == UDPHeader::SIZE);

#pragma pack(push, 1)
struct ARPHeader
{
ARPHeader();
ARPHeader(u32 from_ip, const MACAddress& from_mac, u32 to_ip, const MACAddress& to_mac);
u16 Size() const;

static constexpr std::size_t SIZE = 28;

u16 hardware_type = 0;
u16 protocol_type = 0;
u8 hardware_size = 0;
u8 protocol_size = 0;
u16 opcode = 0;
MACAddress sender_address{};
u32 sender_ip = 0;
MACAddress targer_address{};
u32 target_ip = 0;
};
static_assert(sizeof(ARPHeader) == ARPHeader::SIZE);
#pragma pack(pop)

struct DHCPBody
{
DHCPBody();
DHCPBody(u32 transaction, const MACAddress& client_address, u32 new_ip, u32 serv_ip);
static constexpr std::size_t SIZE = 240;
u8 message_type = 0;
u8 hardware_type = 0;
u8 hardware_addr = 0;
u8 hops = 0;
u32 transaction_id = 0;
u16 seconds = 0;
u16 boot_flag = 0;
u32 client_ip = 0;
u32 your_ip = 0;
u32 server_ip = 0;
u32 relay_ip = 0;
MACAddress client_mac{};
unsigned char padding[10]{};
unsigned char hostname[0x40]{};
unsigned char boot_file[0x80]{};
u8 magic_cookie[4] = {0x63, 0x82, 0x53, 0x63};
};
static_assert(sizeof(DHCPBody) == DHCPBody::SIZE);

struct DHCPPacket
{
DHCPPacket();
DHCPPacket(const std::vector<u8>& data);
void AddOption(u8 fnc, const std::vector<u8>& params);
std::vector<u8> Build() const;

DHCPBody body;
std::vector<std::vector<u8>> options;
};

// The compiler might add 2 bytes after EthernetHeader to enforce 16-bytes alignment
#pragma pack(push, 1)
struct ARPPacket
{
ARPPacket();
ARPPacket(const MACAddress& destination, const MACAddress& source);
std::vector<u8> Build() const;
u16 Size() const;

EthernetHeader eth_header;
ARPHeader arp_header;

static constexpr std::size_t SIZE = EthernetHeader::SIZE + ARPHeader::SIZE;
};
static_assert(sizeof(ARPPacket) == ARPPacket::SIZE);
#pragma pack(pop)

struct TCPPacket
{
TCPPacket();
TCPPacket(const MACAddress& destination, const MACAddress& source);
TCPPacket(const MACAddress& destination, const MACAddress& source, const sockaddr_in& from,
const sockaddr_in& to, u32 seq, u32 ack, u16 flags);
std::vector<u8> Build();
u16 Size() const;

EthernetHeader eth_header;
IPv4Header ip_header;
TCPHeader tcp_header;
std::vector<u8> ipv4_options;
std::vector<u8> tcp_options;
std::vector<u8> data;

static constexpr std::size_t MIN_SIZE = EthernetHeader::SIZE + IPv4Header::SIZE + TCPHeader::SIZE;
};

struct UDPPacket
{
UDPPacket();
UDPPacket(const MACAddress& destination, const MACAddress& source);
UDPPacket(const MACAddress& destination, const MACAddress& source, const sockaddr_in& from,
const sockaddr_in& to, const std::vector<u8>& payload);
std::vector<u8> Build();
u16 Size() const;

EthernetHeader eth_header;
IPv4Header ip_header;
UDPHeader udp_header;

std::vector<u8> ipv4_options;
std::vector<u8> data;

static constexpr std::size_t MIN_SIZE = EthernetHeader::SIZE + IPv4Header::SIZE + UDPHeader::SIZE;
};

class PacketView
{
public:
PacketView(const u8* ptr, std::size_t size);

std::optional<u16> GetEtherType() const;
std::optional<ARPPacket> GetARPPacket() const;
std::optional<u8> GetIPProto() const;
std::optional<TCPPacket> GetTCPPacket() const;
std::optional<UDPPacket> GetUDPPacket() const;

private:
const u8* m_ptr;
std::size_t m_size;
};

struct NetworkErrorState
{
int error;
Expand All @@ -111,6 +257,8 @@ MACAddress GenerateMacAddress(MACConsumer type);
std::string MacAddressToString(const MACAddress& mac);
std::optional<MACAddress> StringToMacAddress(std::string_view mac_string);
u16 ComputeNetworkChecksum(const void* data, u16 length, u32 initial_value = 0);
u16 ComputeTCPNetworkChecksum(const IPAddress& from, const IPAddress& to, const void* data,
u16 length, u8 protocol);
NetworkErrorState SaveNetworkErrorState();
void RestoreNetworkErrorState(const NetworkErrorState& state);
} // namespace Common
6 changes: 6 additions & 0 deletions Source/Core/Core/CMakeLists.txt
Expand Up @@ -647,6 +647,8 @@ if(WIN32)
HW/EXI/BBA/TAP_Win32.cpp
HW/EXI/BBA/TAP_Win32.h
HW/EXI/BBA/XLINK_KAI_BBA.cpp
HW/EXI/BBA/BuiltIn.cpp
HW/EXI/BBA/BuiltIn.h
HW/WiimoteReal/IOWin.cpp
HW/WiimoteReal/IOWin.h
)
Expand All @@ -662,12 +664,16 @@ elseif(APPLE)
HW/EXI/BBA/TAP_Apple.cpp
HW/EXI/BBA/TAPServer_Apple.cpp
HW/EXI/BBA/XLINK_KAI_BBA.cpp
HW/EXI/BBA/BuiltIn.cpp
HW/EXI/BBA/BuiltIn.h
)
target_link_libraries(core PUBLIC ${IOB_LIBRARY})
elseif(UNIX)
target_sources(core PRIVATE
HW/EXI/BBA/TAP_Unix.cpp
HW/EXI/BBA/XLINK_KAI_BBA.cpp
HW/EXI/BBA/BuiltIn.cpp
HW/EXI/BBA/BuiltIn.h
)
if(ANDROID)
target_sources(core PRIVATE
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/Core/Config/MainSettings.cpp
Expand Up @@ -116,6 +116,11 @@ const Info<std::string> MAIN_BBA_MAC{{System::Main, "Core", "BBA_MAC"}, ""};
const Info<std::string> MAIN_BBA_XLINK_IP{{System::Main, "Core", "BBA_XLINK_IP"}, "127.0.0.1"};
const Info<bool> MAIN_BBA_XLINK_CHAT_OSD{{System::Main, "Core", "BBA_XLINK_CHAT_OSD"}, true};

// Schthack PSO Server - https://schtserv.com/
const Info<std::string> MAIN_BBA_BUILTIN_DNS{{System::Main, "Core", "BBA_BUILTIN_DNS"},
"149.56.167.128"};
const Info<std::string> MAIN_BBA_BUILTIN_IP{{System::Main, "Core", "BBA_BUILTIN_IP"}, ""};

const Info<SerialInterface::SIDevices>& GetInfoForSIDevice(int channel)
{
static const std::array<const Info<SerialInterface::SIDevices>, 4> infos{
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/Config/MainSettings.h
Expand Up @@ -86,6 +86,8 @@ const Info<ExpansionInterface::EXIDeviceType>& GetInfoForEXIDevice(ExpansionInte
extern const Info<std::string> MAIN_BBA_MAC;
extern const Info<std::string> MAIN_BBA_XLINK_IP;
extern const Info<bool> MAIN_BBA_XLINK_CHAT_OSD;
extern const Info<std::string> MAIN_BBA_BUILTIN_DNS;
extern const Info<std::string> MAIN_BBA_BUILTIN_IP;
const Info<SerialInterface::SIDevices>& GetInfoForSIDevice(int channel);
const Info<bool>& GetInfoForAdapterRumble(int channel);
const Info<bool>& GetInfoForSimulateKonga(int channel);
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp
Expand Up @@ -81,6 +81,8 @@ bool IsSettingSaveable(const Config::Location& config_location)
&Config::MAIN_AGP_CART_B_PATH.GetLocation(),
&Config::MAIN_BBA_MAC.GetLocation(),
&Config::MAIN_BBA_XLINK_IP.GetLocation(),
&Config::MAIN_BBA_BUILTIN_DNS.GetLocation(),
&Config::MAIN_BBA_BUILTIN_IP.GetLocation(),
&Config::MAIN_BBA_XLINK_CHAT_OSD.GetLocation(),
&Config::MAIN_OVERRIDE_REGION_SETTINGS.GetLocation(),
&Config::MAIN_CUSTOM_RTC_ENABLE.GetLocation(),
Expand Down

0 comments on commit 5a7759e

Please sign in to comment.