diff --git a/src/core/hle/service/mnpp/mnpp.h b/src/core/hle/service/mnpp/mnpp.h index 40d0395bdf..3cdcf14cac 100644 --- a/src/core/hle/service/mnpp/mnpp.h +++ b/src/core/hle/service/mnpp/mnpp.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 9ffaeedd4f..1a59444b4f 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -173,8 +173,26 @@ void BSD::Socket(HLERequestContext& ctx) { LOG_DEBUG(Service, "called. domain={} type={} protocol={}", domain, type, protocol); - const auto [fd, bsd_errno] = SocketImpl(static_cast(domain), static_cast(type), - static_cast(protocol)); + const auto [fd, bsd_errno] = SocketImpl(Domain(domain), Type(type), Protocol(protocol)); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(fd); + rb.PushEnum(bsd_errno); +} + +void BSD::SocketExempt(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u32 domain = rp.Pop(); + const u32 type = rp.Pop(); + const u32 protocol = rp.Pop(); + + LOG_DEBUG(Service, "called. domain={} type={} protocol={}", domain, type, protocol); + + auto [fd, bsd_errno] = SocketImpl(Domain(domain), Type(type), Protocol(protocol)); + if (bsd_errno == Errno::SUCCESS) { + bsd_errno = ShutdownImpl(fd, 0); + } IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); @@ -445,6 +463,7 @@ void BSD::Close(HLERequestContext& ctx) { BuildErrnoResponse(ctx, CloseImpl(fd)); } +/// @brief Only bsd:s is able to dup() void BSD::DuplicateSocket(HLERequestContext& ctx) { struct InputParameters { s32 fd; @@ -463,6 +482,13 @@ void BSD::DuplicateSocket(HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); + if (is_user) { + rb.PushRaw(OutputParameters{ + .ret = 0, + .bsd_errno = Errno::INVAL, + }); + return; + } auto const res_v = DuplicateSocketImpl(input.fd); if (auto* res = std::get_if(&res_v)) { @@ -496,11 +522,13 @@ void BSD::ExecuteWork(HLERequestContext& ctx, Work work) { } std::pair BSD::SocketImpl(Domain domain, Type type, Protocol protocol) { - - if (type == Type::SEQPACKET) { - UNIMPLEMENTED_MSG("SOCK_SEQPACKET errno management"); - } else if (type == Type::RAW && (domain != Domain::INET || protocol != Protocol::ICMP)) { - UNIMPLEMENTED_MSG("SOCK_RAW errno management"); + // user bsd:u has restrictions on SOCK_SEQPACKET and SOCK_RAW + if (is_user && (type == Type::SEQPACKET || type == Type::RAW)) { + if (type == Type::RAW && domain == Domain::INET && protocol == Protocol::ICMP) { + // fine, can use on bsd:s and bsd:u + } else { + return {-1, Errno::INVAL}; + } } [[maybe_unused]] const bool unk_flag = (static_cast(type) & 0x20000000) != 0; @@ -1052,14 +1080,15 @@ void BSD::OnProxyPacketReceived(const Network::ProxyPacket& packet) { } } -BSD::BSD(Core::System& system_, const char* name) - : ServiceFramework{system_, name} { +BSD::BSD(Core::System& system_, const char* name, bool is_user_) + : ServiceFramework{system_, name} + , is_user{is_user_} { // clang-format off static const FunctionInfo functions[] = { {0, &BSD::RegisterClient, "RegisterClient"}, {1, &BSD::StartMonitoring, "StartMonitoring"}, {2, &BSD::Socket, "Socket"}, - {3, nullptr, "SocketExempt"}, + {3, &BSD::SocketExempt, "SocketExempt"}, {4, nullptr, "Open"}, {5, &BSD::Select, "Select"}, {6, &BSD::Poll, "Poll"}, @@ -1125,7 +1154,8 @@ std::unique_lock BSD::LockService() noexcept { return {}; } -BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} { +BSDCFG::BSDCFG(Core::System& system_, const char *name) + : ServiceFramework{system_, name} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "SetIfUp"}, @@ -1152,4 +1182,16 @@ BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} { BSDCFG::~BSDCFG() = default; +BSD_NU::BSD_NU(Core::System& system_) + : ServiceFramework{system_, "bsd:nu"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "CreateUserService"}, + }; + // clang-format on + RegisterHandlers(functions); +} + +BSD_NU::~BSD_NU() = default; + } // namespace Service::Sockets diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h index 15e4a33592..c0c63f7df8 100644 --- a/src/core/hle/service/sockets/bsd.h +++ b/src/core/hle/service/sockets/bsd.h @@ -29,7 +29,7 @@ namespace Service::Sockets { class BSD final : public ServiceFramework { public: - explicit BSD(Core::System& system_, const char* name); + explicit BSD(Core::System& system_, const char* name, bool is_user); ~BSD() override; // These methods are called from SSL; the first two are also called from @@ -129,6 +129,7 @@ private: void RegisterClient(HLERequestContext& ctx); void StartMonitoring(HLERequestContext& ctx); void Socket(HLERequestContext& ctx); + void SocketExempt(HLERequestContext& ctx); void Select(HLERequestContext& ctx); void Poll(HLERequestContext& ctx); void Accept(HLERequestContext& ctx); @@ -155,8 +156,7 @@ private: void ExecuteWork(HLERequestContext& ctx, Work work); std::pair SocketImpl(Domain domain, Type type, Protocol protocol); - std::pair PollImpl(std::vector& write_buffer, std::span read_buffer, - s32 nfds, s32 timeout); + std::pair PollImpl(std::vector& write_buffer, std::span read_buffer, s32 nfds, s32 timeout); std::pair AcceptImpl(s32 fd, std::vector& write_buffer); Errno BindImpl(s32 fd, std::span addr); Errno ConnectImpl(s32 fd, std::span addr); @@ -189,12 +189,19 @@ private: protected: std::unique_lock LockService() noexcept override; + bool is_user = false; }; class BSDCFG final : public ServiceFramework { public: - explicit BSDCFG(Core::System& system_); + explicit BSDCFG(Core::System& system_, const char *name); ~BSDCFG() override; }; +class BSD_NU final : public ServiceFramework { +public: + explicit BSD_NU(Core::System& system_); + ~BSD_NU() override; +}; + } // namespace Service::Sockets diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index 9e71be3547..93c01bf786 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp @@ -406,4 +406,21 @@ void SFDNSRES::ResolverSetOptionRequest(HLERequestContext& ctx) { rb.Push(ResultSuccess); rb.Push(0); // bsd errno } + + +DNS_PRIV::DNS_PRIV(Core::System& system_) + : ServiceFramework{system_, "dns:priv"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Cmd0"}, + {1, nullptr, "Cmd1"}, + {2, nullptr, "Cmd2"}, + }; + // clang-format on + RegisterHandlers(functions); +} + +DNS_PRIV::~DNS_PRIV() = default; + + } // namespace Service::Sockets diff --git a/src/core/hle/service/sockets/sfdnsres.h b/src/core/hle/service/sockets/sfdnsres.h index 282ef9071f..4302edc43e 100644 --- a/src/core/hle/service/sockets/sfdnsres.h +++ b/src/core/hle/service/sockets/sfdnsres.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -25,4 +28,10 @@ private: void ResolverSetOptionRequest(HLERequestContext& ctx); }; +class DNS_PRIV final : public ServiceFramework { +public: + explicit DNS_PRIV(Core::System& system_); + ~DNS_PRIV() override; +}; + } // namespace Service::Sockets diff --git a/src/core/hle/service/sockets/sockets.cpp b/src/core/hle/service/sockets/sockets.cpp index 676d24e036..28fcbd3a41 100644 --- a/src/core/hle/service/sockets/sockets.cpp +++ b/src/core/hle/service/sockets/sockets.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -12,12 +15,16 @@ namespace Service::Sockets { void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); - server_manager->RegisterNamedService("bsd:s", std::make_shared(system, "bsd:s")); - server_manager->RegisterNamedService("bsd:u", std::make_shared(system, "bsd:u")); - server_manager->RegisterNamedService("bsdcfg", std::make_shared(system)); + server_manager->RegisterNamedService("bsd:s", std::make_shared(system, "bsd:s", false)); + server_manager->RegisterNamedService("bsd:u", std::make_shared(system, "bsd:u", true)); + server_manager->RegisterNamedService("bsd:a", std::make_shared(system, "bsd:a", true)); + server_manager->RegisterNamedService("bsd:nu", std::make_shared(system)); + server_manager->RegisterNamedService("bsdcfg", std::make_shared(system, "bsdcfg")); + server_manager->RegisterNamedService("ifcfg", std::make_shared(system, "ifcfg")); server_manager->RegisterNamedService("nsd:a", std::make_shared(system, "nsd:a")); server_manager->RegisterNamedService("nsd:u", std::make_shared(system, "nsd:u")); server_manager->RegisterNamedService("sfdnsres", std::make_shared(system)); + server_manager->RegisterNamedService("dns:priv", std::make_shared(system)); server_manager->StartAdditionalHostThreads("bsdsocket", 2); ServerManager::RunServer(std::move(server_manager)); }