implement ICMP stuff (on windows). should be very similar on *nix...might just be able to compile the current code :)
This commit is contained in:
parent
2046fb0457
commit
4e62015e9a
|
@ -320,6 +320,7 @@
|
|||
<ClCompile Include="Src\HW\WiimoteReal\WiimoteReal.cpp" />
|
||||
<ClCompile Include="Src\HW\WII_IOB.cpp" />
|
||||
<ClCompile Include="Src\HW\WII_IPC.cpp" />
|
||||
<ClCompile Include="Src\IPC_HLE\ICMPWin.cpp" />
|
||||
<ClCompile Include="Src\IPC_HLE\WiiMote_HID_Attr.cpp" />
|
||||
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE.cpp" />
|
||||
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_Device_DI.cpp" />
|
||||
|
@ -520,6 +521,7 @@
|
|||
<ClInclude Include="Src\HW\WII_IPC.h" />
|
||||
<ClInclude Include="Src\IPC_HLE\hci.h" />
|
||||
<ClInclude Include="Src\IPC_HLE\fakepoll.h" />
|
||||
<ClInclude Include="Src\IPC_HLE\ICMP.h" />
|
||||
<ClInclude Include="Src\IPC_HLE\l2cap.h" />
|
||||
<ClInclude Include="Src\IPC_HLE\WiiMote_HID_Attr.h" />
|
||||
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE.h" />
|
||||
|
|
|
@ -559,6 +559,9 @@
|
|||
<ClCompile Include="Src\HW\GCMemcard.cpp">
|
||||
<Filter>HW %28Flipper/Hollywood%29\GCMemcard</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Src\IPC_HLE\ICMPWin.cpp">
|
||||
<Filter>IPC HLE %28IOS/Starlet%29\Net</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Src\ConfigManager.h" />
|
||||
|
@ -1042,6 +1045,9 @@
|
|||
<ClInclude Include="Src\IPC_HLE\fakepoll.h">
|
||||
<Filter>IPC HLE %28IOS/Starlet%29\Net</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Src\IPC_HLE\ICMP.h">
|
||||
<Filter>IPC HLE %28IOS/Starlet%29\Net</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
int icmp_echo_req(u32 s, sockaddr_in *addr, u8 *data, u32 data_length);
|
||||
int icmp_echo_rep(u32 s, sockaddr_in *addr, const u8 *data, u32 data_length);
|
|
@ -0,0 +1,79 @@
|
|||
#include "ICMP.h"
|
||||
|
||||
enum
|
||||
{
|
||||
ICMP_ECHOREPLY = 0,
|
||||
ICMP_ECHOREQ = 8
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
// id/seq/data come from wii
|
||||
ICMP_HDR_LEN = 4,
|
||||
IP_HDR_LEN = 20
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct icmp_hdr
|
||||
{
|
||||
u8 type;
|
||||
u8 code;
|
||||
u16 checksum;
|
||||
u16 id;
|
||||
u16 seq;
|
||||
char data[1];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static u8 workspace[56];
|
||||
|
||||
/*
|
||||
* Description:
|
||||
* Calculate Internet checksum for data buffer and length (one's
|
||||
* complement sum of 16-bit words). Used in IP, ICMP, UDP, IGMP.
|
||||
*
|
||||
* NOTE: to handle odd number of bytes, last (even) byte in
|
||||
* buffer have a value of 0 (we assume that it does)
|
||||
*/
|
||||
u16 cksum(u16 *buffer, int length)
|
||||
{
|
||||
u32 sum = 0;
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
sum += *(buffer++);
|
||||
length -= 2;
|
||||
}
|
||||
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
sum += sum >> 16;
|
||||
|
||||
return (u16)~sum;
|
||||
}
|
||||
|
||||
int icmp_echo_req(u32 s, sockaddr_in *addr, u8 *data, u32 data_length)
|
||||
{
|
||||
memset(workspace, 0, sizeof(workspace));
|
||||
icmp_hdr *header = (icmp_hdr *)workspace;
|
||||
header->type = ICMP_ECHOREQ;
|
||||
header->code = 0;
|
||||
header->checksum = 0;
|
||||
memcpy(&header->id, data, data_length);
|
||||
|
||||
header->checksum = cksum((u16 *)header, ICMP_HDR_LEN + data_length);
|
||||
|
||||
return sendto((SOCKET)s, (LPSTR)header, ICMP_HDR_LEN + data_length, 0,
|
||||
(sockaddr *)addr, sizeof(sockaddr));
|
||||
}
|
||||
|
||||
int icmp_echo_rep(u32 s, sockaddr_in *addr, const u8 *data, u32 data_length)
|
||||
{
|
||||
memset(workspace, 0, sizeof(workspace));
|
||||
int addr_length = sizeof(sockaddr_in);
|
||||
int ret = recvfrom((SOCKET)s, (LPSTR)workspace,
|
||||
IP_HDR_LEN + ICMP_HDR_LEN + data_length,
|
||||
0, (sockaddr *)addr, &addr_length);
|
||||
|
||||
// TODO do we need to memcmp the data?
|
||||
return ret;
|
||||
}
|
|
@ -50,6 +50,7 @@ it failed)
|
|||
#include "FileUtil.h"
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include "ICMP.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
|
@ -969,10 +970,39 @@ u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommand(u32 _Command,
|
|||
break;
|
||||
}
|
||||
|
||||
case IOCTL_SO_ICMPSOCKET:
|
||||
{
|
||||
// AF type?
|
||||
u32 arg = Memory::Read_U32(_BufferIn);
|
||||
u32 sock = (u32)socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
|
||||
ERROR_LOG(WII_IPC_NET, "IOCTL_SO_ICMPSOCKET(%x) %x", arg, sock);
|
||||
return getNetErrorCode(sock, "IOCTL_SO_ICMPSOCKET", false);
|
||||
}
|
||||
|
||||
case IOCTL_SO_ICMPCANCEL:
|
||||
ERROR_LOG(WII_IPC_NET, "IOCTL_SO_ICMPCANCEL");
|
||||
goto default_;
|
||||
|
||||
case IOCTL_SO_ICMPCLOSE:
|
||||
{
|
||||
u32 sock = Memory::Read_U32(_BufferIn);
|
||||
u32 ret = closesocket(sock);
|
||||
ERROR_LOG(WII_IPC_NET, "IOCTL_SO_ICMPCLOSE(%x) %x", sock, ret);
|
||||
return getNetErrorCode(ret, "IOCTL_SO_ICMPCLOSE", false);
|
||||
}
|
||||
|
||||
default:
|
||||
WARN_LOG(WII_IPC_NET,"0x%x "
|
||||
"BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
|
||||
_Command, _BufferIn, BufferInSize, _BufferOut, BufferOutSize);
|
||||
default_:
|
||||
if (BufferInSize)
|
||||
{
|
||||
ERROR_LOG(WII_IPC_NET, "in addr %x size %x", _BufferIn, BufferInSize);
|
||||
ERROR_LOG(WII_IPC_NET, "\n%s",
|
||||
ArrayToString(Memory::GetPointer(_BufferIn), BufferInSize, 4).c_str()
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -980,7 +1010,7 @@ u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommand(u32 _Command,
|
|||
return 0;
|
||||
}
|
||||
|
||||
u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer CommandBuffer)
|
||||
u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommandV(SIOCtlVBuffer& CommandBuffer)
|
||||
{
|
||||
u32 _BufferIn = 0, _BufferIn2 = 0, _BufferIn3 = 0;
|
||||
u32 BufferInSize = 0, BufferInSize2 = 0, BufferInSize3 = 0;
|
||||
|
@ -1036,7 +1066,7 @@ u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffe
|
|||
|
||||
u32 param = 0, param2 = 0, param3, param4, param5 = 0;
|
||||
|
||||
switch (_Parameter)
|
||||
switch (CommandBuffer.Parameter)
|
||||
{
|
||||
case IOCTLV_SO_GETINTERFACEOPT:
|
||||
{
|
||||
|
@ -1342,32 +1372,83 @@ u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffe
|
|||
return ret;
|
||||
}
|
||||
|
||||
default:
|
||||
WARN_LOG(WII_IPC_NET,"0x%x (BufferIn: (%08x, %i), BufferIn2: (%08x, %i)",
|
||||
_Parameter, _BufferIn, BufferInSize, _BufferIn2, BufferInSize2);
|
||||
break;
|
||||
case IOCTLV_SO_ICMPPING:
|
||||
{
|
||||
struct
|
||||
{
|
||||
u8 length;
|
||||
u8 addr_family;
|
||||
u16 port;
|
||||
u32 ip;
|
||||
} ip_info;
|
||||
|
||||
u32 sock = Memory::Read_U32(_BufferIn);
|
||||
u32 num_ip = Memory::Read_U32(_BufferIn + 4);
|
||||
u64 timeout = Memory::Read_U64(_BufferIn + 8);
|
||||
|
||||
if (num_ip != 1)
|
||||
{
|
||||
WARN_LOG(WII_IPC_NET, "IOCTLV_SO_ICMPPING %i IPs", num_ip);
|
||||
}
|
||||
|
||||
ip_info.length = Memory::Read_U8(_BufferIn + 16);
|
||||
ip_info.addr_family = Memory::Read_U8(_BufferIn + 17);
|
||||
ip_info.port = Memory::Read_U16(_BufferIn + 18);
|
||||
ip_info.ip = Memory::Read_U32(_BufferIn + 20);
|
||||
|
||||
if (ip_info.length != 8 || ip_info.addr_family != AF_INET || ip_info.port != 0)
|
||||
{
|
||||
WARN_LOG(WII_IPC_NET, "IOCTLV_SO_ICMPPING strange IPInfo:\n"
|
||||
"length %x addr_family %x port %x",
|
||||
ip_info.length, ip_info.addr_family, ip_info.port);
|
||||
}
|
||||
|
||||
DEBUG_LOG(WII_IPC_NET, "IOCTLV_SO_ICMPPING %x", ip_info.ip);
|
||||
|
||||
sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.S_un.S_addr = Common::swap32(ip_info.ip);
|
||||
memset(addr.sin_zero, 0, 8);
|
||||
u8 *data = Memory::GetPointer(_BufferIn2);
|
||||
|
||||
int ret = icmp_echo_req(sock, &addr, data, BufferInSize2);
|
||||
if (ret >= 0)
|
||||
{
|
||||
icmp_echo_rep(sock, &addr, data, BufferInSize2);
|
||||
}
|
||||
// TODO proper error codes
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 _CommandAddress)
|
||||
{
|
||||
u32 ReturnValue = 0;
|
||||
SIOCtlVBuffer CommandBuffer(_CommandAddress);
|
||||
switch (CommandBuffer.Parameter)
|
||||
{
|
||||
case IOCTLV_SO_SENDTO:
|
||||
case IOCTL_SO_BIND:
|
||||
case IOCTLV_SO_RECVFROM:
|
||||
case IOCTL_SO_SOCKET:
|
||||
case IOCTL_SO_GETHOSTID:
|
||||
case IOCTL_SO_STARTUP:
|
||||
default:
|
||||
ReturnValue = ExecuteCommandV(CommandBuffer.Parameter, CommandBuffer);
|
||||
WARN_LOG(WII_IPC_NET,"0x%x (BufferIn: (%08x, %i), BufferIn2: (%08x, %i)",
|
||||
CommandBuffer.Parameter, _BufferIn, BufferInSize, _BufferIn2, BufferInSize2);
|
||||
default_:
|
||||
for (int i = 0; i < CommandBuffer.NumberInBuffer; ++i)
|
||||
{
|
||||
ERROR_LOG(WII_IPC_NET, "in %i addr %x size %x", i,
|
||||
CommandBuffer.InBuffer.at(i).m_Address, CommandBuffer.InBuffer.at(i).m_Size);
|
||||
ERROR_LOG(WII_IPC_NET, "\n%s",
|
||||
ArrayToString(
|
||||
Memory::GetPointer(CommandBuffer.InBuffer.at(i).m_Address),
|
||||
CommandBuffer.InBuffer.at(i).m_Size, 4).c_str()
|
||||
);
|
||||
}
|
||||
for (int i = 0; i < CommandBuffer.NumberPayloadBuffer; ++i)
|
||||
{
|
||||
ERROR_LOG(WII_IPC_NET, "out %i addr %x size %x", i,
|
||||
CommandBuffer.PayloadBuffer.at(i).m_Address, CommandBuffer.PayloadBuffer.at(i).m_Size, 4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress+4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CWII_IPC_HLE_Device_net_ip_top::IOCtlV(u32 CommandAddress)
|
||||
{
|
||||
u32 return_value = ExecuteCommandV(SIOCtlVBuffer(CommandAddress));
|
||||
Memory::Write_U32(return_value, CommandAddress + 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -409,7 +409,7 @@ private:
|
|||
};
|
||||
|
||||
u32 ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize);
|
||||
u32 ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer CommandBuffer);
|
||||
u32 ExecuteCommandV(SIOCtlVBuffer& CommandBuffer);
|
||||
};
|
||||
|
||||
// **********************************************************************************
|
||||
|
|
Loading…
Reference in New Issue