feat(kernel): translate guest IP address conversion APIs
This commit is contained in:
parent
97e6ce992b
commit
ff725218cb
|
|
@ -104,6 +104,15 @@ endforeach()
|
|||
add_custom_target(libs DEPENDS ${PATCHED_OUTPUTS})
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_executable(guest_address_tests tests/GuestAddressConversion.cpp)
|
||||
target_include_directories(guest_address_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_address_tests PRIVATE libkernel libc)
|
||||
configure_windows_unwind(guest_address_tests)
|
||||
add_test(NAME guest_addresses COMMAND guest_address_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_addresses PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libkernel>")
|
||||
endif()
|
||||
add_executable(guest_error_tests tests/GuestErrors.cpp)
|
||||
target_include_directories(guest_error_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_error_tests PRIVATE libc)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ add_library(libkernel SHARED EXCLUDE_FROM_ALL
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/Pthread/Posix/Tsd.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Pthread/Posix/Sem.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Socket/src/Socket.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Socket/src/AddressConversion.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/EventFlag/src/EventFlag.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Module/src/Module.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Aio/src/Aio.cpp
|
||||
|
|
@ -41,6 +42,7 @@ add_library(libkernel SHARED EXCLUDE_FROM_ALL
|
|||
target_include_directories(libkernel PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(libkernel PRIVATE libc)
|
||||
if(WIN32)
|
||||
target_link_libraries(libkernel PRIVATE ws2_32)
|
||||
target_compile_definitions(libkernel PRIVATE _WIN32_WINNT=0x0602)
|
||||
endif()
|
||||
configure_windows_unwind(libkernel)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
extern "C" int* APS5_VABI __error_nid_postfix();
|
||||
|
||||
extern "C" {
|
||||
int APS5_VABI __inet_pton_nid_postfix(int family, const char* text, void* destination) {
|
||||
if (family != 2 && family != 28) { *__error_nid_postfix() = 47; return -1; }
|
||||
if (!text || !destination) { *__error_nid_postfix() = 14; return -1; }
|
||||
unsigned char address[16]{};
|
||||
const int nativeFamily = family == 2 ? AF_INET : AF_INET6;
|
||||
#ifdef _WIN32
|
||||
const int result = InetPtonA(nativeFamily, text, address);
|
||||
#else
|
||||
const int result = ::inet_pton(nativeFamily, text, address);
|
||||
#endif
|
||||
if (result == 1) std::memcpy(destination, address, family == 2 ? 4 : 16);
|
||||
else if (result == -1) *__error_nid_postfix() = 22;
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* APS5_VABI __inet_ntop_nid_postfix(int family, const void* source,
|
||||
char* destination, std::uint32_t capacity) {
|
||||
if (family != 2 && family != 28) { *__error_nid_postfix() = 47; return nullptr; }
|
||||
if (!source || !destination) { *__error_nid_postfix() = 14; return nullptr; }
|
||||
char text[INET6_ADDRSTRLEN]{};
|
||||
const int nativeFamily = family == 2 ? AF_INET : AF_INET6;
|
||||
#ifdef _WIN32
|
||||
const auto* result = InetNtopA(nativeFamily, const_cast<void*>(source), text, sizeof(text));
|
||||
#else
|
||||
const auto* result = ::inet_ntop(nativeFamily, source, text, sizeof(text));
|
||||
#endif
|
||||
if (!result) { *__error_nid_postfix() = 22; return nullptr; }
|
||||
const auto size = std::strlen(text) + 1;
|
||||
if (size > capacity) { *__error_nid_postfix() = 28; return nullptr; }
|
||||
std::memcpy(destination, text, size);
|
||||
return destination;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
extern "C" {
|
||||
int APS5_VABI __inet_pton_nid_postfix(int, const char*, void*);
|
||||
const char* APS5_VABI __inet_ntop_nid_postfix(int, const void*, char*, std::uint32_t);
|
||||
int* APS5_VABI __error_nid_postfix();
|
||||
}
|
||||
static void Require(bool value) { if (!value) std::abort(); }
|
||||
int main() {
|
||||
for (int family : {2, 28}) {
|
||||
const char* input = family == 2 ? "192.0.2.17" : "2001:db8::17";
|
||||
std::array<unsigned char, 16> address{};
|
||||
Require(__inet_pton_nid_postfix(family, input, address.data()) == 1);
|
||||
char output[64]{};
|
||||
Require(__inet_ntop_nid_postfix(family, address.data(), output, sizeof(output)) == output);
|
||||
Require(std::strcmp(input, output) == 0);
|
||||
output[0] = 'x';
|
||||
Require(__inet_ntop_nid_postfix(family, address.data(), output, 1) == nullptr);
|
||||
Require(*__error_nid_postfix() == 28 && output[0] == 'x');
|
||||
const auto original = address;
|
||||
Require(__inet_pton_nid_postfix(family, "not-an-address", address.data()) == 0);
|
||||
Require(address == original);
|
||||
}
|
||||
std::array<unsigned char, 16> address{};
|
||||
Require(__inet_pton_nid_postfix(10, "::1", address.data()) == -1);
|
||||
Require(*__error_nid_postfix() == 47); // Linux AF_INET6 is not PS5 AF_INET6
|
||||
Require(__inet_pton_nid_postfix(2, "256.1.2.3", address.data()) == 0);
|
||||
Require(__inet_pton_nid_postfix(28, "::ffff:192.0.2.17", address.data()) == 1);
|
||||
Require(address[10] == 255 && address[11] == 255 && address[12] == 192 && address[15] == 17);
|
||||
}
|
||||
Loading…
Reference in New Issue