diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index ea670cb846..a7468cb161 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -513,6 +513,8 @@ public: __forceinline AT GetAddr() const { return m_addr; } + __forceinline void SetAddr(AT addr) { m_addr = addr; } + __forceinline bool IsGood() const { return Memory.IsGoodAddr(m_addr, sizeof(T)); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp index 3b83186840..a171925f52 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp @@ -2,25 +2,119 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" +#include "sys_net.h" + +#ifdef _WIN32 +#include +#elif +#include +#include +#endif + void sys_net_init(); Module sys_net((u16)0x0000, sys_net_init); -int accept() +mem32_t g_lastError(NULL); + + +// Auxiliary Functions +int inet_pton4(const char *src, char *dst) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + const char digits[] = "0123456789"; + int saw_digit, octets, ch; + unsigned char tmp[4], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + unsigned int n = *tp * 10 + (pch - digits); + + if (n > 255) + return (0); + *tp = n; + if (! saw_digit) { + if (++octets > 4) + return (0); + saw_digit = 1; + } + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return 0; + *++tp = 0; + saw_digit = 0; + } else + return (0); + } + if (octets < 4) + return 0; + + memcpy(dst, tmp, 4); + return 1; } -int bind() +int inet_pton(int af, const char *src, char *dst) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + switch (af) { + case AF_INET: + return (inet_pton4(src, dst)); + + default: + errno = EAFNOSUPPORT; + return -1; + } } -int connect() +s32 getLastError() { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; +#ifdef _WIN32 + s32 ret = WSAGetLastError(); + if (ret > 10000 && ret < 11000) + return ret % 10000; + else + return -1; +#else + return errno; +#endif +} + + +// Functions +int sys_net_accept(s32 s, mem_ptr_t addr, mem32_t paddrlen) +{ + sys_net.Warning("accept(s=%d, family_addr=0x%x, paddrlen=0x%x)", s, addr.GetAddr(), paddrlen.GetAddr()); + sockaddr _addr; + memcpy(&_addr, Memory.VirtualToRealAddr(addr.GetAddr()), sizeof(sockaddr)); + _addr.sa_family = addr->sa_family; + s32 *_paddrlen = (s32 *)Memory.VirtualToRealAddr(paddrlen.GetAddr()); + int ret = accept(s, &_addr, _paddrlen); + g_lastError = getLastError(); + return ret; +} + +int sys_net_bind(s32 s, mem_ptr_t family, u32 addrlen) +{ + sys_net.Warning("bind(s=%d, family_addr=0x%x, addrlen=%u)", s, family.GetAddr(), addrlen); + sockaddr _family; + memcpy(&_family, Memory.VirtualToRealAddr(family.GetAddr()), sizeof(sockaddr)); + _family.sa_family = family->sa_family; + int ret = bind(s, &_family, addrlen); + g_lastError = getLastError(); + return ret; +} + +int sys_net_connect(s32 s, mem_ptr_t family, u32 addrlen) +{ + sys_net.Warning("connect(s=%d, family_addr=0x%x, addrlen=%u)", s, family.GetAddr(), addrlen); + sockaddr _family; + memcpy(&_family, Memory.VirtualToRealAddr(family.GetAddr()), sizeof(sockaddr)); + _family.sa_family = family->sa_family; + int ret = connect(s, &_family, addrlen); + g_lastError = getLastError(); + return ret; } int gethostbyaddr() @@ -101,10 +195,12 @@ int inet_ntop() return CELL_OK; } -int inet_pton() +int sys_net_inet_pton(s32 af, u32 src_addr, u32 dst_addr) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("inet_pton(af=%d, src_addr=0x%x, dst_addr=0x%x)", af, src_addr, dst_addr); + char *src = (char *)Memory.VirtualToRealAddr(src_addr); + char *dst = (char *)Memory.VirtualToRealAddr(dst_addr); + return inet_pton(af, src, dst); } int listen() @@ -113,16 +209,28 @@ int listen() return CELL_OK; } -int recv() +int sys_net_recv(s32 s, u32 buf_addr, u32 len, s32 flags) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("recv(s=%d, buf_addr=0x%x, len=%d, flags=0x%x)", s, buf_addr, len, flags); + char *buf = (char *)Memory.VirtualToRealAddr(buf_addr); + int ret = recv(s, buf, len, flags); + g_lastError = getLastError(); + return ret; } -int recvfrom() +int sys_net_recvfrom(s32 s, u32 buf_addr, u32 len, s32 flags, mem_ptr_t addr, mem32_t paddrlen) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("recvfrom(s=%d, buf_addr=0x%x, len=%u, flags=0x%x, addr_addr=0x%x, paddrlen=0x%x)", + s, buf_addr, len, flags, addr.GetAddr(), paddrlen.GetAddr()); + + char *_buf_addr = (char *)Memory.VirtualToRealAddr(buf_addr); + sockaddr _addr; + memcpy(&_addr, Memory.VirtualToRealAddr(addr.GetAddr()), sizeof(sockaddr)); + _addr.sa_family = addr->sa_family; + s32 *_paddrlen = (s32 *)Memory.VirtualToRealAddr(paddrlen.GetAddr()); + int ret = recvfrom(s, _buf_addr, len, flags, &_addr, _paddrlen); + g_lastError = getLastError(); + return ret; } int recvmsg() @@ -131,10 +239,13 @@ int recvmsg() return CELL_OK; } -int send() +int sys_net_send(s32 s, u32 buf_addr, u32 len, s32 flags) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("send(s=%d, buf_addr=0x%x, len=%d, flags=0x%x)", s, buf_addr, len, flags); + char *buf = (char *)Memory.VirtualToRealAddr(buf_addr); + int ret = send(s, buf, len, flags); + g_lastError = getLastError(); + return ret; } int sendmsg() @@ -143,34 +254,51 @@ int sendmsg() return CELL_OK; } -int sendto() +int sys_net_sendto(s32 s, u32 buf_addr, u32 len, s32 flags, mem_ptr_t addr, u32 addrlen) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("sendto(s=%d, buf_addr=0x%x, len=%u, flags=0x%x, addr=0x%x, addrlen=%u)", + s, buf_addr, len, flags, addr.GetAddr(), addrlen); + + char *_buf_addr = (char *)Memory.VirtualToRealAddr(buf_addr); + sockaddr _addr; + memcpy(&_addr, Memory.VirtualToRealAddr(addr.GetAddr()), sizeof(sockaddr)); + _addr.sa_family = addr->sa_family; + int ret = sendto(s, _buf_addr, len, flags, &_addr, addrlen); + g_lastError = getLastError(); + return ret; } -int setsockopt() +int sys_net_setsockopt(s32 s, s32 level, s32 optname, u32 optval_addr, u32 optlen) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("socket(s=%d, level=%d, optname=%d, optval_addr=0x%x, optlen=%u)", s, level, optname, optval_addr, optlen); + char *_optval_addr = (char *)Memory.VirtualToRealAddr(optval_addr); + int ret = setsockopt(s, level, optname, _optval_addr, optlen); + g_lastError = getLastError(); + return ret; } -int shutdown() +int sys_net_shutdown(s32 s, s32 how) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("shutdown(s=%d, how=%d)", s, how); + int ret = shutdown(s, how); + g_lastError = getLastError(); + return ret; } -int socket() +int sys_net_socket(s32 family, s32 type, s32 protocol) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("socket(family=%d, type=%d, protocol=%d", family, type, protocol); + int ret = socket(family, type, protocol); + g_lastError = getLastError(); + return ret; } -int socketclose() +int sys_net_socketclose(s32 s) { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("socket(s=%d)", s); + int ret = closesocket(s); + g_lastError = getLastError(); + return ret; } int socketpoll() @@ -185,9 +313,17 @@ int socketselect() return CELL_OK; } -int sys_net_initialize_network_ex() +int sys_net_initialize_network_ex(mem_ptr_t param) { - UNIMPLEMENTED_FUNC(sys_net); + sys_net.Warning("sys_net_initialize_network_ex(param_addr=0x%x)", param.GetAddr()); + g_lastError.SetAddr(Memory.Alloc(4, 1)); +#ifdef _WIN32 + WSADATA wsaData; + WORD wVersionRequested = MAKEWORD(1,1); + WSAStartup(wVersionRequested, &wsaData); +#elif + // TODO ? +#endif return CELL_OK; } @@ -245,10 +381,10 @@ int sys_net_show_nameserver() return CELL_OK; } -int _sys_net_errno_loc() +s32 _sys_net_errno_loc() { - UNIMPLEMENTED_FUNC(sys_net); - return CELL_OK; + sys_net.Warning("_sys_net_errno_loc()"); + return g_lastError.GetAddr(); } int sys_net_set_resolver_configurations() @@ -313,7 +449,14 @@ int sys_net_show_ifconfig() int sys_net_finalize_network() { - UNIMPLEMENTED_FUNC(sys_net); + sys_net.Warning("sys_net_initialize_network_ex()"); + Memory.Free(g_lastError.GetAddr()); + g_lastError.SetAddr(NULL); +#ifdef _WIN32 + WSACleanup(); +#else + // TODO ? +#endif return CELL_OK; } @@ -337,40 +480,39 @@ int sys_net_free_thread_context() void sys_net_init() { - // (TODO: Fix function overloading problem due to winsock.h and find addresses for ntohl and ntohs) - - //sys_net.AddFunc(0xc94f6939, accept); - //sys_net.AddFunc(0xb0a59804, bind); - //sys_net.AddFunc(0x64f66d35, connect); - //sys_net.AddFunc(0xf7ac8941, gethostbyaddr); - //sys_net.AddFunc(0x71f4c717, gethostbyname); - //sys_net.AddFunc(0xf9ec2db6, getpeername); - //sys_net.AddFunc(0x13efe7f5, getsockname); - //sys_net.AddFunc(0x5a045bd1, getsockopt); - //sys_net.AddFunc(0xdabbc2c0, inet_addr); - sys_net.AddFunc(0xa9a079e0, inet_aton); - sys_net.AddFunc(0x566893ce, inet_lnaof); - sys_net.AddFunc(0xb4152c74, inet_makeaddr); - sys_net.AddFunc(0xe39a62a7, inet_netof); - sys_net.AddFunc(0x506ad863, inet_network); - //sys_net.AddFunc(0x858a930b, inet_ntoa); - sys_net.AddFunc(0xc98a3146, inet_ntop); - sys_net.AddFunc(0x8af3825e, inet_pton); - //sys_net.AddFunc(0x28e208bb, listen); - //sys_net.AddFunc(, ntohl); - //sys_net.AddFunc(, ntohs); - //sys_net.AddFunc(0xfba04f37, recv); - //sys_net.AddFunc(0x1f953b9f, recvfrom); - sys_net.AddFunc(0xc9d09c34, recvmsg); - //sys_net.AddFunc(0xdc751b40, send); - sys_net.AddFunc(0xad09481b, sendmsg); - //sys_net.AddFunc(0x9647570b, sendto); - //sys_net.AddFunc(0x88f03575, setsockopt); - //sys_net.AddFunc(0xa50777c6, shutdown); - //sys_net.AddFunc(0x9c056962, socket); - sys_net.AddFunc(0x6db6e8cd, socketclose); - sys_net.AddFunc(0x051ee3ee, socketpoll); - sys_net.AddFunc(0x3f09e20a, socketselect); + // The names of the following functions are modified to avoid overloading problems + sys_net.AddFunc(0xc94f6939, sys_net_accept); + sys_net.AddFunc(0xb0a59804, sys_net_bind); + sys_net.AddFunc(0x64f66d35, sys_net_connect); + //sys_net.AddFunc(0xf7ac8941, sys_net_gethostbyaddr); + //sys_net.AddFunc(0x71f4c717, sys_net_gethostbyname); + //sys_net.AddFunc(0xf9ec2db6, sys_net_getpeername); + //sys_net.AddFunc(0x13efe7f5, sys_net_getsockname); + //sys_net.AddFunc(0x5a045bd1, sys_net_getsockopt); + //sys_net.AddFunc(0xdabbc2c0, sys_net_inet_addr); + //sys_net.AddFunc(0xa9a079e0, sys_net_inet_aton); + //sys_net.AddFunc(0x566893ce, sys_net_inet_lnaof); + //sys_net.AddFunc(0xb4152c74, sys_net_inet_makeaddr); + //sys_net.AddFunc(0xe39a62a7, sys_net_inet_netof); + //sys_net.AddFunc(0x506ad863, sys_net_inet_network); + //sys_net.AddFunc(0x858a930b, sys_net_inet_ntoa); + //sys_net.AddFunc(0xc98a3146, sys_net_inet_ntop); + sys_net.AddFunc(0x8af3825e, sys_net_inet_pton); + //sys_net.AddFunc(0x28e208bb, sys_net_listen); + //sys_net.AddFunc(, sys_net_ntohl); + //sys_net.AddFunc(, sys_net_ntohs); + sys_net.AddFunc(0xfba04f37, sys_net_recv); + sys_net.AddFunc(0x1f953b9f, sys_net_recvfrom); + //sys_net.AddFunc(0xc9d09c34, sys_net_recvmsg); + sys_net.AddFunc(0xdc751b40, sys_net_send); + //sys_net.AddFunc(0xad09481b, sys_net_sendmsg); + sys_net.AddFunc(0x9647570b, sys_net_sendto); + sys_net.AddFunc(0x88f03575, sys_net_setsockopt); + sys_net.AddFunc(0xa50777c6, sys_net_shutdown); + sys_net.AddFunc(0x9c056962, sys_net_socket); + sys_net.AddFunc(0x6db6e8cd, sys_net_socketclose); + //sys_net.AddFunc(0x051ee3ee, sys_net_socketpoll); + //sys_net.AddFunc(0x3f09e20a, sys_net_socketselect); sys_net.AddFunc(0x139a9e9b, sys_net_initialize_network_ex); sys_net.AddFunc(0x05bd4438, sys_net_get_udpp2p_test_param); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.h b/rpcs3/Emu/SysCalls/Modules/sys_net.h new file mode 100644 index 0000000000..770a6958c2 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/sys_net.h @@ -0,0 +1,16 @@ +#pragma once + +struct sys_net_initialize_parameter +{ + u32 memory_addr; + int memory_size; + int flags; +}; + +// The names of the following structs are modified to avoid overloading problems +struct sys_net_sockaddr +{ + u8 sa_len; + u8 sa_family; // sa_family_t + u8 sa_data[14]; +}; diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 80630f36d2..5a9fa6fb3f 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -312,6 +312,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index c045ad6bbe..6f796ff3fe 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -460,6 +460,9 @@ Emu\Audio\AL + + Emu\SysCalls\Modules +