diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp index 6947088352..994abe87a9 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp @@ -692,19 +692,10 @@ bool CWII_IPC_HLE_Device_net_ip_top::IOCtl(u32 _CommandAddress) } case IOCTL_SO_ACCEPT: { - WARN_LOG(WII_IPC_NET, "IOCTL_SO_ACCEPT " - "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); - u32 fd = Memory::Read_U32(BufferIn); - socklen_t addrlen; - - struct sockaddr* addr = (struct sockaddr*) Memory::GetPointer(BufferOut); - int ret = (s32)accept(fd, addr, &addrlen); - ReturnValue = WiiSockMan::getNetErrorCode(ret, "SO_ACCEPT", false); - addr->sa_family = ((addr->sa_family&0xFF) << 8) | (u8)addrlen; - Memory::Write_U32(addrlen, BufferOut + 0x04); - + WiiSockMan &sm = WiiSockMan::getInstance(); + sm.doSock(fd, _CommandAddress, (NET_IOCTL)Command); + return false; break; } diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h index 92ea07eddb..3f3c50926b 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h @@ -551,36 +551,6 @@ private: } }; - -struct bind_params -{ - u32 socket; - u32 has_name; - u8 name[28]; -}; - -struct GC_sockaddr -{ - u8 sa_len; - u8 sa_family; - s8 sa_data[14]; -}; - -struct GC_in_addr -{ - // this cannot be named s_addr under windows - collides with some crazy define. - u32 s_addr_; -}; - -struct GC_sockaddr_in -{ - u8 sin_len; - u8 sin_family; - u16 sin_port; - struct GC_in_addr sin_addr; - s8 sin_zero[8]; -}; - enum NET_IOCTL { IOCTL_SO_ACCEPT = 1, diff --git a/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp b/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp index 2ed615de25..adca7d9b3b 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_Socket.cpp @@ -174,6 +174,10 @@ void WiiSocket::update(bool read, bool write, bool except) if (!it->is_ssl && ct == COMMAND_IOCTL) { u32 BufferIn = Memory::Read_U32(it->_CommandAddress + 0x10); + u32 BufferInSize = Memory::Read_U32(it->_CommandAddress + 0x14); + u32 BufferOut = Memory::Read_U32(it->_CommandAddress + 0x18); + u32 BufferOutSize = Memory::Read_U32(it->_CommandAddress + 0x1C); + switch(it->net_type) { case IOCTL_SO_FCNTL: @@ -185,48 +189,57 @@ void WiiSocket::update(bool read, bool write, bool except) } case IOCTL_SO_BIND: { - //TODO: tidy - bind_params *addr = (bind_params*)Memory::GetPointer(BufferIn); - GC_sockaddr_in addrPC; - memcpy(&addrPC, addr->name, sizeof(GC_sockaddr_in)); - sockaddr_in address; - address.sin_family = addrPC.sin_family; - address.sin_addr.s_addr = addrPC.sin_addr.s_addr_; - address.sin_port = addrPC.sin_port; - - int ret = bind(fd, (sockaddr*)&address, sizeof(address)); + //u32 has_addr = Memory::Read_U32(BufferIn + 0x04); + sockaddr_in local_name; + WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(BufferIn + 0x08); + WiiSockMan::Convert(*wii_name, local_name); + + int ret = bind(fd, (sockaddr*)&local_name, sizeof(local_name)); ReturnValue = WiiSockMan::getNetErrorCode(ret, "SO_BIND", false); WARN_LOG(WII_IPC_NET, "IOCTL_SO_BIND (%08X %s:%d) = %d ", fd, - inet_ntoa(address.sin_addr), Common::swap16(address.sin_port), ret); + inet_ntoa(local_name.sin_addr), Common::swap16(local_name.sin_port), ret); break; } case IOCTL_SO_CONNECT: { + //u32 has_addr = Memory::Read_U32(BufferIn + 0x04); + sockaddr_in local_name; + WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(BufferIn + 0x08); + WiiSockMan::Convert(*wii_name, local_name); - //struct sockaddr_in echoServAddr; - u32 has_addr = Memory::Read_U32(BufferIn + 0x04); - sockaddr_in serverAddr; - - u8 addr[28]; - Memory::ReadBigEData(addr, BufferIn + 0x08, sizeof(addr)); - - if (has_addr != 1) - { - ReturnValue = -1; - break; - } - - memset(&serverAddr, 0, sizeof(serverAddr)); - memcpy(&serverAddr, addr, addr[0]); - // GC/Wii sockets have a length param as well, we dont really care :) - serverAddr.sin_family = serverAddr.sin_family >> 8; - - int ret = connect(fd, (sockaddr*)&serverAddr, sizeof(serverAddr)); + int ret = connect(fd, (sockaddr*)&local_name, sizeof(local_name)); ReturnValue = WiiSockMan::getNetErrorCode(ret, "SO_CONNECT", false); WARN_LOG(WII_IPC_NET,"IOCTL_SO_CONNECT (%08x, %s:%d)", - fd, inet_ntoa(serverAddr.sin_addr), Common::swap16(serverAddr.sin_port)); + fd, inet_ntoa(local_name.sin_addr), Common::swap16(local_name.sin_port)); + break; + } + case IOCTL_SO_ACCEPT: + { + + if (BufferOutSize > 0) + { + sockaddr_in local_name; + WiiSockAddrIn* wii_name = (WiiSockAddrIn*)Memory::GetPointer(BufferOut); + WiiSockMan::Convert(*wii_name, local_name); + + socklen_t addrlen = wii_name->len; + int ret = (s32)accept(fd, (sockaddr*)&local_name, &addrlen); + ReturnValue = WiiSockMan::getNetErrorCode(ret, "SO_ACCEPT", false); + + WiiSockMan::Convert(local_name, *wii_name, addrlen); + } + else + { + int ret = (s32)accept(fd, NULL, 0); + ReturnValue = WiiSockMan::getNetErrorCode(ret, "SO_ACCEPT", false); + } + + WARN_LOG(WII_IPC_NET, "IOCTL_SO_ACCEPT " + "BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + BufferIn, BufferInSize, BufferOut, BufferOutSize); + break; } default: @@ -605,5 +618,23 @@ void WiiSockMan::EnqueueReply(u32 CommandAddress, s32 ReturnValue) } +void WiiSockMan::Convert(WiiSockAddrIn& from, sockaddr_in& to) +{ + to.sin_addr.s_addr = from.addr.addr; + to.sin_family = from.family; + to.sin_port = from.port; +} + +void WiiSockMan::Convert(sockaddr_in& from, WiiSockAddrIn& to, s32 addrlen) +{ + to.addr.addr = from.sin_addr.s_addr; + to.family = from.sin_family; + to.port = from.sin_port; + if (addrlen < 0 || addrlen > sizeof(WiiSockAddrIn)) + to.len = sizeof(WiiSockAddrIn); + else + to.len = addrlen; +} + #undef ERRORCODE #undef EITHER diff --git a/Source/Core/Core/Src/IPC_HLE/WII_Socket.h b/Source/Core/Core/Src/IPC_HLE/WII_Socket.h index b473af6bf8..074f22b7bb 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_Socket.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_Socket.h @@ -139,6 +139,7 @@ enum { SO_EXDEV }; +#pragma pack(push, 1) struct WiiInAddr { u32 addr; @@ -158,6 +159,7 @@ struct WiiSockAddrIn u16 port; WiiInAddr addr; }; +#pragma pack(pop) class WiiSocket { @@ -204,7 +206,8 @@ public: } void Update(); static void EnqueueReply(u32 CommandAddress, s32 ReturnValue); - + static void Convert(WiiSockAddrIn& const from, sockaddr_in& to); + static void Convert(sockaddr_in& const from, WiiSockAddrIn& to, s32 addrlen=-1); // NON-BLOCKING FUNCTIONS s32 newSocket(s32 af, s32 type, s32 protocol); s32 delSocket(s32 s);