mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-17 21:57:52 +00:00
first fake icmp impl
This commit is contained in:
@@ -1133,6 +1133,8 @@ add_library(core STATIC
|
||||
internal_network/network_interface.h
|
||||
internal_network/socket_proxy.cpp
|
||||
internal_network/socket_proxy.h
|
||||
internal_network/socket_icmp.cpp
|
||||
internal_network/socket_icmp.h
|
||||
internal_network/socket_types.h
|
||||
internal_network/sockets.h
|
||||
internal_network/wifi_scanner.h
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "core/hle/service/sockets/sockets_translate.h"
|
||||
#include "core/internal_network/network.h"
|
||||
#include "core/internal_network/socket_proxy.h"
|
||||
#include "core/internal_network/socket_icmp.h"
|
||||
#include "core/internal_network/sockets.h"
|
||||
#include "network/network.h"
|
||||
#include <common/settings.h>
|
||||
@@ -520,6 +521,8 @@ std::pair<s32, Network::Errno> BSD::SocketImpl(Network::Domain domain, Network::
|
||||
auto room_member = Network::GetRoomMember().lock();
|
||||
if (room_member && room_member->IsConnected()) {
|
||||
descriptor.socket = std::make_shared<Network::ProxySocket>();
|
||||
} else if (protocol == Network::Protocol::ICMP || protocol == Network::Protocol::ICMPV6) {
|
||||
descriptor.socket = std::make_shared<Network::IcmpSocket>();
|
||||
} else {
|
||||
descriptor.socket = std::make_shared<Network::Socket>();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging.h"
|
||||
#include "core/internal_network/socket_icmp.h"
|
||||
|
||||
#ifdef __unix__
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
namespace Network {
|
||||
|
||||
namespace {
|
||||
|
||||
u16 ComputeChecksum(std::span<const u8> data) {
|
||||
u32 sum = 0;
|
||||
for (size_t i = 0; i < data.size(); i += 2) {
|
||||
u32 value = (u32(data[i + 0]) << 8ull) | u32(data[i + 1]); //big endian
|
||||
sum += value;
|
||||
}
|
||||
if (data.size() % 2 != 0){
|
||||
sum += u16(data[data.size() - 1]) << 8;
|
||||
}
|
||||
while ((sum >> 16) != 0)
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
return (~sum) & 0xffff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IcmpSocket::IcmpSocket() noexcept {}
|
||||
|
||||
IcmpSocket::~IcmpSocket() {
|
||||
if (fd == INVALID_SOCKET) {
|
||||
return;
|
||||
}
|
||||
fd = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
Errno IcmpSocket::SetSockOpt(Network::SocketLevel level, Network::OptName optname, std::span<const u8> optval) {
|
||||
LOG_WARNING(Network, "(stubbed) level={},optname={},optval={}", level, optname, optval.size());
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
Errno IcmpSocket::Initialize(Domain domain, Type type, Protocol socket_protocol) {
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
std::pair<IcmpSocket::AcceptResult, Errno> IcmpSocket::Accept() {
|
||||
LOG_WARNING(Network, "(stubbed) called");
|
||||
return {AcceptResult{}, Errno::SUCCESS};
|
||||
}
|
||||
|
||||
Errno IcmpSocket::Connect(Network::SockAddrIn addr_in) {
|
||||
LOG_WARNING(Network, "(stubbed) called");
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
std::pair<Network::SockAddrIn, Errno> IcmpSocket::GetPeerName() {
|
||||
LOG_WARNING(Network, "(stubbed) called");
|
||||
return {Network::SockAddrIn{}, Errno::SUCCESS};
|
||||
}
|
||||
|
||||
std::pair<Network::SockAddrIn, Errno> IcmpSocket::GetSockName() {
|
||||
LOG_WARNING(Network, "(stubbed) called");
|
||||
return {Network::SockAddrIn{}, Errno::SUCCESS};
|
||||
}
|
||||
|
||||
Errno IcmpSocket::Bind(Network::SockAddrIn addr) {
|
||||
LOG_WARNING(Network, "(stubbed) called");
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
Errno IcmpSocket::Listen(s32 backlog) {
|
||||
LOG_WARNING(Network, "(stubbed) called");
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
Errno IcmpSocket::Shutdown(ShutdownHow how) {
|
||||
LOG_WARNING(Network, "(stubbed) called");
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
std::pair<s32, Errno> IcmpSocket::Recv(int flags, std::span<u8> message) {
|
||||
LOG_DEBUG(Network, "(stubbed) called");
|
||||
return {s32(0), Errno::NOTCONN};
|
||||
}
|
||||
|
||||
std::pair<s32, Errno> IcmpSocket::RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) {
|
||||
LOG_DEBUG(Network, "(stubbed) called");
|
||||
ASSERT(flags == 0);
|
||||
ASSERT(message.size() < std::size_t((std::numeric_limits<int>::max)()));
|
||||
if (!data.empty()) {
|
||||
auto const n = (std::max)(data.size(), message.size());
|
||||
std::copy(data.begin(), data.begin() + n, message.begin());
|
||||
return {n, Errno::SUCCESS};
|
||||
}
|
||||
return {-1, Errno::TIMEDOUT};
|
||||
}
|
||||
|
||||
std::pair<s32, Errno> IcmpSocket::Send(std::span<const u8> message, int flags) {
|
||||
LOG_DEBUG(Network, "(stubbed) called");
|
||||
return {s32(0), Errno::NOTCONN};
|
||||
}
|
||||
|
||||
std::pair<s32, Errno> IcmpSocket::SendTo(u32 flags, std::span<const u8> message, const Network::SockAddrIn* addr) {
|
||||
LOG_DEBUG(Network, "(stubbed) called");
|
||||
// 0 -> 8 (IPv4), 128 (IPv6)
|
||||
// 1 -> 0
|
||||
// 2..4 -> checksum
|
||||
// 4..6 -> ident
|
||||
// 6..8 -> seq
|
||||
if (message.size() >= 8) {
|
||||
ASSERT(message[0] == 0);
|
||||
auto const csum_pos = data.size();
|
||||
data.push_back(8);
|
||||
data.push_back(0);
|
||||
data.push_back(0); //checksum (placeholder 0)
|
||||
data.push_back(0);
|
||||
data.push_back(message[4]); //ident
|
||||
data.push_back(message[5]);
|
||||
data.push_back(message[6]); //seq
|
||||
data.push_back(message[7]);
|
||||
auto const csum = ComputeChecksum(std::span<const u8>{data.begin() + csum_pos, data.end()});
|
||||
data[csum_pos + 2] = u8(csum >> 8); //hi
|
||||
data[csum_pos + 3] = u8(csum); //lo
|
||||
}
|
||||
return {s32(message.size()), Errno::SUCCESS};
|
||||
}
|
||||
|
||||
Errno IcmpSocket::Close() {
|
||||
LOG_DEBUG(Network, "called");
|
||||
fd = INVALID_SOCKET;
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
std::pair<Errno, Errno> IcmpSocket::GetPendingError() {
|
||||
LOG_DEBUG(Network, "called");
|
||||
return {Errno::SUCCESS, Errno::SUCCESS};
|
||||
}
|
||||
|
||||
bool IcmpSocket::IsOpened() const {
|
||||
return fd != INVALID_SOCKET;
|
||||
}
|
||||
|
||||
void IcmpSocket::HandleProxyPacket(const ProxyPacket& packet) {
|
||||
LOG_WARNING(Network, "(stubbed) called");
|
||||
}
|
||||
Errno IcmpSocket::SetNonBlock(bool enable) {
|
||||
LOG_WARNING(Network, "(stubbed) called");
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace Network
|
||||
@@ -0,0 +1,37 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <span>
|
||||
#include "core/internal_network/sockets.h"
|
||||
|
||||
namespace Network {
|
||||
|
||||
class IcmpSocket : public Network::SocketBase {
|
||||
public:
|
||||
explicit IcmpSocket() noexcept;
|
||||
~IcmpSocket() override;
|
||||
Errno Initialize(Domain domain, Type type, Protocol socket_protocol) override;
|
||||
Errno Close() override;
|
||||
std::pair<AcceptResult, Errno> Accept() override;
|
||||
Errno Connect(Network::SockAddrIn addr_in) override;
|
||||
std::pair<Network::SockAddrIn, Errno> GetPeerName() override;
|
||||
std::pair<Network::SockAddrIn, Errno> GetSockName() override;
|
||||
Errno Bind(Network::SockAddrIn addr) override;
|
||||
Errno Listen(s32 backlog) override;
|
||||
Errno Shutdown(ShutdownHow how) override;
|
||||
std::pair<s32, Errno> Recv(int flags, std::span<u8> message) override;
|
||||
std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) override;
|
||||
std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override;
|
||||
std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message, const Network::SockAddrIn* addr) override;
|
||||
Errno SetSockOpt(Network::SocketLevel level, Network::OptName option, std::span<const u8> value) override;
|
||||
std::pair<Errno, Errno> GetPendingError() override;
|
||||
bool IsOpened() const override;
|
||||
void HandleProxyPacket(const ProxyPacket& packet) override;
|
||||
Errno SetNonBlock(bool enable) override;
|
||||
|
||||
std::vector<u8> data;
|
||||
};
|
||||
|
||||
} // namespace Network
|
||||
Reference in New Issue
Block a user