first fake icmp impl

This commit is contained in:
lizzie
2026-08-15 01:06:19 +00:00
parent a4e1c4b20e
commit ecc28bd9c3
4 changed files with 197 additions and 0 deletions
+2
View File
@@ -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
+3
View File
@@ -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>();
}
+155
View File
@@ -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
+37
View File
@@ -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