4 changed files with 197 additions and 0 deletions
-
2src/core/CMakeLists.txt
-
3src/core/hle/service/sockets/bsd.cpp
-
155src/core/internal_network/socket_icmp.cpp
-
37src/core/internal_network/socket_icmp.h
@ -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 |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue