2017-06-05 02:02:04 +02:00
|
|
|
/*
|
2019-05-03 21:06:10 +02:00
|
|
|
* This file is part of Luma3DS.
|
2020-04-25 14:26:21 +02:00
|
|
|
* Copyright (C) 2016-2020 Aurora Wright, TuxSH
|
2017-06-05 02:02:04 +02:00
|
|
|
*
|
2019-05-03 21:06:10 +02:00
|
|
|
* SPDX-License-Identifier: (MIT OR GPL-2.0-or-later)
|
2017-06-05 02:02:04 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "minisoc.h"
|
|
|
|
#include <sys/socket.h>
|
2020-07-12 20:36:18 +02:00
|
|
|
#include <3ds.h>
|
2020-04-27 22:58:40 +02:00
|
|
|
#include <string.h>
|
2020-07-12 20:36:18 +02:00
|
|
|
#include "utils.h"
|
2017-06-05 02:02:04 +02:00
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
s32 miniSocRefCount = 0;
|
|
|
|
static u32 socContextAddr = 0x08000000;
|
|
|
|
static u32 socContextSize = 0x60000;
|
|
|
|
static Handle miniSocHandle;
|
|
|
|
static Handle miniSocMemHandle;
|
2020-07-15 19:57:53 +02:00
|
|
|
static bool exclusiveStateEntered = false;
|
2020-04-28 02:31:29 +02:00
|
|
|
|
|
|
|
bool miniSocEnabled = false;
|
|
|
|
|
2017-06-05 02:02:04 +02:00
|
|
|
s32 _net_convert_error(s32 sock_retval);
|
|
|
|
|
|
|
|
static Result SOCU_Initialize(Handle memhandle, u32 memsize)
|
|
|
|
{
|
|
|
|
Result ret = 0;
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x1,1,4); // 0x10044
|
|
|
|
cmdbuf[1] = memsize;
|
2019-03-11 00:17:01 +01:00
|
|
|
cmdbuf[2] = IPC_Desc_CurProcessId();
|
2017-06-05 02:02:04 +02:00
|
|
|
cmdbuf[4] = IPC_Desc_SharedHandles(1);
|
|
|
|
cmdbuf[5] = memhandle;
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2017-06-05 02:02:04 +02:00
|
|
|
if(ret != 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
return cmdbuf[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
static Result SOCU_Shutdown(void)
|
|
|
|
{
|
|
|
|
Result ret = 0;
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x19,0,0); // 0x190000
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2017-06-05 02:02:04 +02:00
|
|
|
if(ret != 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
return cmdbuf[1];
|
|
|
|
}
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
Result miniSocInit(void)
|
2017-06-05 02:02:04 +02:00
|
|
|
{
|
|
|
|
if(AtomicPostIncrement(&miniSocRefCount))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
u32 tmp = 0;
|
|
|
|
Result ret = 0;
|
2018-01-15 02:52:50 +01:00
|
|
|
bool isSocURegistered;
|
|
|
|
|
|
|
|
ret = srvIsServiceRegistered(&isSocURegistered, "soc:U");
|
|
|
|
if(ret != 0) goto cleanup;
|
|
|
|
if(!isSocURegistered)
|
|
|
|
{
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = srvGetServiceHandle(&miniSocHandle, "soc:U");
|
2018-01-15 02:52:50 +01:00
|
|
|
if(ret != 0) goto cleanup;
|
2017-06-05 02:02:04 +02:00
|
|
|
|
2020-05-18 23:15:34 +02:00
|
|
|
ret = svcControlMemoryEx(&tmp, socContextAddr, 0, socContextSize, MEMOP_ALLOC, MEMREGION_SYSTEM | MEMPERM_READ | MEMPERM_WRITE, true);
|
2017-06-05 02:02:04 +02:00
|
|
|
if(ret != 0) goto cleanup;
|
|
|
|
|
|
|
|
socContextAddr = tmp;
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcCreateMemoryBlock(&miniSocMemHandle, (u32)socContextAddr, socContextSize, 0, 3);
|
2017-06-05 02:02:04 +02:00
|
|
|
if(ret != 0) goto cleanup;
|
|
|
|
|
2018-01-15 02:52:50 +01:00
|
|
|
|
2017-06-05 02:02:04 +02:00
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = SOCU_Initialize(miniSocMemHandle, socContextSize);
|
2017-06-05 02:02:04 +02:00
|
|
|
if(ret != 0) goto cleanup;
|
|
|
|
|
2020-07-15 19:57:53 +02:00
|
|
|
if (!exclusiveStateEntered)
|
|
|
|
{
|
|
|
|
ndmuInit();
|
|
|
|
ret = NDMU_EnterExclusiveState(NDM_EXCLUSIVE_STATE_INFRASTRUCTURE);
|
|
|
|
if (R_SUCCEEDED(ret))
|
|
|
|
ret = NDMU_LockState(); // prevents ndm from switching to StreetPass when the lid is closed
|
|
|
|
//ndmuExit();
|
|
|
|
exclusiveStateEntered = R_SUCCEEDED(ret);
|
|
|
|
}
|
|
|
|
|
2020-07-14 23:10:13 +02:00
|
|
|
svcKernelSetState(0x10000, 0x10);
|
2017-06-15 17:38:45 +02:00
|
|
|
miniSocEnabled = true;
|
2020-07-12 20:36:18 +02:00
|
|
|
|
2017-06-05 02:02:04 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
AtomicDecrement(&miniSocRefCount);
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
if(miniSocMemHandle != 0)
|
2017-06-05 02:02:04 +02:00
|
|
|
{
|
2020-04-28 02:31:29 +02:00
|
|
|
svcCloseHandle(miniSocMemHandle);
|
|
|
|
miniSocMemHandle = 0;
|
2017-06-05 02:02:04 +02:00
|
|
|
}
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
if(miniSocHandle != 0)
|
2017-06-05 02:02:04 +02:00
|
|
|
{
|
|
|
|
SOCU_Shutdown();
|
2020-04-28 02:31:29 +02:00
|
|
|
svcCloseHandle(miniSocHandle);
|
|
|
|
miniSocHandle = 0;
|
2017-06-05 02:02:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if(tmp != 0)
|
|
|
|
svcControlMemory(&tmp, socContextAddr, socContextAddr, socContextSize, MEMOP_FREE, MEMPERM_DONTCARE);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
Result miniSocExitDirect(void)
|
2017-06-05 02:02:04 +02:00
|
|
|
{
|
|
|
|
Result ret = 0;
|
|
|
|
u32 tmp;
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
svcCloseHandle(miniSocMemHandle);
|
|
|
|
miniSocMemHandle = 0;
|
2017-06-05 02:02:04 +02:00
|
|
|
|
|
|
|
ret = SOCU_Shutdown();
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
svcCloseHandle(miniSocHandle);
|
|
|
|
miniSocHandle = 0;
|
2017-06-05 02:02:04 +02:00
|
|
|
|
|
|
|
svcControlMemory(&tmp, socContextAddr, socContextAddr, socContextSize, MEMOP_FREE, MEMPERM_DONTCARE);
|
|
|
|
if(ret == 0)
|
2017-06-15 17:38:45 +02:00
|
|
|
{
|
2020-07-15 19:57:53 +02:00
|
|
|
if (exclusiveStateEntered)
|
|
|
|
{
|
|
|
|
//ndmuInit();
|
|
|
|
ret = NDMU_UnlockState();
|
|
|
|
if (R_SUCCEEDED(ret))
|
|
|
|
ret = NDMU_LeaveExclusiveState();
|
|
|
|
ndmuExit();
|
|
|
|
exclusiveStateEntered = R_FAILED(ret);
|
|
|
|
}
|
|
|
|
|
2017-06-15 17:38:45 +02:00
|
|
|
miniSocEnabled = false;
|
2020-07-14 23:10:13 +02:00
|
|
|
svcKernelSetState(0x10000, 0x10);
|
2017-06-15 17:38:45 +02:00
|
|
|
}
|
2017-06-05 02:02:04 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
Result miniSocExit(void)
|
|
|
|
{
|
|
|
|
if(!miniSocEnabled || AtomicDecrement(&miniSocRefCount))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return miniSocExitDirect();
|
|
|
|
}
|
|
|
|
|
2017-06-05 02:02:04 +02:00
|
|
|
int socSocket(int domain, int type, int protocol)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
|
|
|
|
// The protocol on the 3DS *must* be 0 to work
|
|
|
|
// To that end, when appropriate, we will make the change for the user
|
|
|
|
if (domain == AF_INET
|
|
|
|
&& type == SOCK_STREAM
|
|
|
|
&& protocol == IPPROTO_TCP) {
|
|
|
|
protocol = 0; // TCP is the only option, so 0 will work as expected
|
|
|
|
}
|
|
|
|
if (domain == AF_INET
|
|
|
|
&& type == SOCK_DGRAM
|
|
|
|
&& protocol == IPPROTO_UDP) {
|
|
|
|
protocol = 0; // UDP is the only option, so 0 will work as expected
|
|
|
|
}
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x2,3,2); // 0x200C2
|
|
|
|
cmdbuf[1] = domain;
|
|
|
|
cmdbuf[2] = type;
|
|
|
|
cmdbuf[3] = protocol;
|
2019-03-11 00:17:01 +01:00
|
|
|
cmdbuf[4] = IPC_Desc_CurProcessId();
|
2017-06-05 02:02:04 +02:00
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2017-06-05 02:02:04 +02:00
|
|
|
if(ret != 0)
|
|
|
|
{
|
|
|
|
//errno = SYNC_ERROR;
|
2020-04-27 22:58:40 +02:00
|
|
|
return R_FAILED(ret) ? ret : -1;
|
2017-06-05 02:02:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = (int)cmdbuf[1];
|
|
|
|
if(ret == 0) ret = cmdbuf[2];
|
|
|
|
if(ret < 0)
|
|
|
|
{
|
|
|
|
//if(cmdbuf[1] == 0)errno = _net_convert_error(ret);
|
|
|
|
//if(cmdbuf[1] != 0)errno = SYNC_ERROR;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return cmdbuf[2];
|
|
|
|
}
|
|
|
|
|
|
|
|
int socBind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
|
|
|
{
|
|
|
|
Result ret = 0;
|
|
|
|
socklen_t tmp_addrlen = 0;
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
u8 tmpaddr[0x1c];
|
|
|
|
|
|
|
|
memset(tmpaddr, 0, 0x1c);
|
|
|
|
|
|
|
|
if(addr->sa_family == AF_INET)
|
|
|
|
tmp_addrlen = 8;
|
|
|
|
else
|
|
|
|
tmp_addrlen = 0x1c;
|
|
|
|
|
|
|
|
if(addrlen < tmp_addrlen)
|
|
|
|
{
|
|
|
|
//errno = EINVAL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpaddr[0] = tmp_addrlen;
|
|
|
|
tmpaddr[1] = addr->sa_family;
|
|
|
|
memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2);
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x5,2,4); // 0x50084
|
|
|
|
cmdbuf[1] = (u32)sockfd;
|
|
|
|
cmdbuf[2] = (u32)tmp_addrlen;
|
2019-03-11 00:17:01 +01:00
|
|
|
cmdbuf[3] = IPC_Desc_CurProcessId();
|
2017-06-05 02:02:04 +02:00
|
|
|
cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
|
|
|
|
cmdbuf[6] = (u32)tmpaddr;
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2017-06-05 02:02:04 +02:00
|
|
|
if(ret != 0) {
|
|
|
|
//errno = SYNC_ERROR;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = (int)cmdbuf[1];
|
|
|
|
if(ret == 0)
|
|
|
|
ret = _net_convert_error(cmdbuf[2]);
|
|
|
|
|
|
|
|
if(ret < 0) {
|
|
|
|
//errno = -ret;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int socListen(int sockfd, int max_connections)
|
|
|
|
{
|
|
|
|
Result ret = 0;
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x3,2,2); // 0x30082
|
|
|
|
cmdbuf[1] = (u32)sockfd;
|
|
|
|
cmdbuf[2] = (u32)max_connections;
|
2019-03-11 00:17:01 +01:00
|
|
|
cmdbuf[3] = IPC_Desc_CurProcessId();
|
2017-06-05 02:02:04 +02:00
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2017-06-05 02:02:04 +02:00
|
|
|
if(ret != 0)
|
|
|
|
{
|
|
|
|
//errno = SYNC_ERROR;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = (int)cmdbuf[1];
|
|
|
|
if(ret == 0)
|
|
|
|
ret = _net_convert_error(cmdbuf[2]);
|
|
|
|
|
|
|
|
if(ret < 0) {
|
|
|
|
//errno = -ret;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int socAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
|
|
|
{
|
|
|
|
Result ret = 0;
|
|
|
|
int tmp_addrlen = 0x1c;
|
|
|
|
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
u8 tmpaddr[0x1c];
|
|
|
|
u32 saved_threadstorage[2];
|
|
|
|
|
|
|
|
memset(tmpaddr, 0, 0x1c);
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x4,2,2); // 0x40082
|
|
|
|
cmdbuf[1] = (u32)sockfd;
|
|
|
|
cmdbuf[2] = (u32)tmp_addrlen;
|
2019-03-11 00:17:01 +01:00
|
|
|
cmdbuf[3] = IPC_Desc_CurProcessId();
|
2017-06-05 02:02:04 +02:00
|
|
|
|
|
|
|
u32 *staticbufs = getThreadStaticBuffers();
|
|
|
|
saved_threadstorage[0] = staticbufs[0];
|
|
|
|
saved_threadstorage[1] = staticbufs[1];
|
|
|
|
|
|
|
|
staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
|
|
|
|
staticbufs[1] = (u32)tmpaddr;
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2017-06-05 02:02:04 +02:00
|
|
|
|
|
|
|
staticbufs[0] = saved_threadstorage[0];
|
|
|
|
staticbufs[1] = saved_threadstorage[1];
|
|
|
|
|
|
|
|
if(ret != 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
ret = (int)cmdbuf[1];
|
|
|
|
if(ret == 0)
|
|
|
|
ret = _net_convert_error(cmdbuf[2]);
|
|
|
|
|
2018-07-05 22:01:53 +02:00
|
|
|
// if(ret < 0)
|
2017-06-05 02:02:04 +02:00
|
|
|
//errno = -ret;
|
|
|
|
|
|
|
|
if(ret >= 0 && addr != NULL)
|
|
|
|
{
|
|
|
|
addr->sa_family = tmpaddr[1];
|
|
|
|
if(*addrlen > tmpaddr[0])
|
|
|
|
*addrlen = tmpaddr[0];
|
|
|
|
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-06-03 00:43:44 +02:00
|
|
|
int socConnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
socklen_t tmp_addrlen = 0;
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
u8 tmpaddr[0x1c];
|
|
|
|
|
|
|
|
memset(tmpaddr, 0, 0x1c);
|
|
|
|
|
|
|
|
if(addr->sa_family == AF_INET)
|
|
|
|
tmp_addrlen = 8;
|
|
|
|
else
|
|
|
|
tmp_addrlen = 0x1c;
|
|
|
|
|
|
|
|
if(addrlen < tmp_addrlen)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
tmpaddr[0] = tmp_addrlen;
|
|
|
|
tmpaddr[1] = addr->sa_family;
|
|
|
|
memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2);
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x6,2,4); // 0x60084
|
|
|
|
cmdbuf[1] = (u32)sockfd;
|
|
|
|
cmdbuf[2] = (u32)addrlen;
|
|
|
|
cmdbuf[3] = IPC_Desc_CurProcessId();
|
|
|
|
cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
|
|
|
|
cmdbuf[6] = (u32)tmpaddr;
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2019-06-03 00:43:44 +02:00
|
|
|
if(ret != 0) return -1;
|
|
|
|
|
|
|
|
ret = (int)cmdbuf[1];
|
|
|
|
if(ret == 0)
|
|
|
|
ret = _net_convert_error(cmdbuf[2]);
|
|
|
|
|
|
|
|
if(ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-06-05 02:02:04 +02:00
|
|
|
int socPoll(struct pollfd *fds, nfds_t nfds, int timeout)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
nfds_t i;
|
|
|
|
u32 size = sizeof(struct pollfd)*nfds;
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
u32 saved_threadstorage[2];
|
|
|
|
|
|
|
|
if(nfds == 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(i = 0; i < nfds; ++i) {
|
|
|
|
fds[i].revents = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x14,2,4); // 0x140084
|
|
|
|
cmdbuf[1] = (u32)nfds;
|
|
|
|
cmdbuf[2] = (u32)timeout;
|
2019-03-11 00:17:01 +01:00
|
|
|
cmdbuf[3] = IPC_Desc_CurProcessId();
|
2017-06-05 02:02:04 +02:00
|
|
|
cmdbuf[5] = IPC_Desc_StaticBuffer(size,10);
|
|
|
|
cmdbuf[6] = (u32)fds;
|
|
|
|
|
|
|
|
u32 * staticbufs = getThreadStaticBuffers();
|
|
|
|
saved_threadstorage[0] = staticbufs[0];
|
|
|
|
saved_threadstorage[1] = staticbufs[1];
|
|
|
|
|
|
|
|
staticbufs[0] = IPC_Desc_StaticBuffer(size,0);
|
|
|
|
staticbufs[1] = (u32)fds;
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2017-06-05 02:02:04 +02:00
|
|
|
|
|
|
|
staticbufs[0] = saved_threadstorage[0];
|
|
|
|
staticbufs[1] = saved_threadstorage[1];
|
|
|
|
|
|
|
|
if(ret != 0) {
|
2020-04-27 22:58:40 +02:00
|
|
|
return R_FAILED(ret) ? ret : -1;
|
2017-06-05 02:02:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = (int)cmdbuf[1];
|
|
|
|
if(ret == 0)
|
|
|
|
ret = _net_convert_error(cmdbuf[2]);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int socClose(int sockfd)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0xB,1,2); // 0xB0042
|
|
|
|
cmdbuf[1] = (u32)sockfd;
|
2019-03-11 00:17:01 +01:00
|
|
|
cmdbuf[2] = IPC_Desc_CurProcessId();
|
2017-06-05 02:02:04 +02:00
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2017-06-05 02:02:04 +02:00
|
|
|
if(ret != 0) {
|
|
|
|
//errno = SYNC_ERROR;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = (int)cmdbuf[1];
|
|
|
|
if(ret == 0)
|
|
|
|
ret =_net_convert_error(cmdbuf[2]);
|
|
|
|
|
|
|
|
if(ret < 0) {
|
|
|
|
//errno = -ret;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int socSetsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x12,4,4); // 0x120104
|
|
|
|
cmdbuf[1] = (u32)sockfd;
|
|
|
|
cmdbuf[2] = (u32)level;
|
|
|
|
cmdbuf[3] = (u32)optname;
|
|
|
|
cmdbuf[4] = (u32)optlen;
|
2019-03-11 00:17:01 +01:00
|
|
|
cmdbuf[5] = IPC_Desc_CurProcessId();
|
2017-06-05 02:02:04 +02:00
|
|
|
cmdbuf[7] = IPC_Desc_StaticBuffer(optlen,9);
|
|
|
|
cmdbuf[8] = (u32)optval;
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2017-06-05 02:02:04 +02:00
|
|
|
if(ret != 0) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = (int)cmdbuf[1];
|
|
|
|
if(ret == 0)
|
|
|
|
ret = _net_convert_error(cmdbuf[2]);
|
|
|
|
|
|
|
|
if(ret < 0) {
|
|
|
|
//errno = -ret;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-04-26 13:07:17 +02:00
|
|
|
long socGethostid(void)
|
2017-06-05 02:02:04 +02:00
|
|
|
{
|
2020-04-26 13:07:17 +02:00
|
|
|
int ret = 0;
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x16,0,0); // 0x160000
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2020-04-26 13:07:17 +02:00
|
|
|
if(ret != 0) {
|
|
|
|
//errno = SYNC_ERROR;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = (int)cmdbuf[1];
|
|
|
|
if(ret == 0)
|
|
|
|
ret = cmdbuf[2];
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t _socuipc_cmd7(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
u32 tmp_addrlen = 0;
|
|
|
|
u8 tmpaddr[0x1c];
|
|
|
|
u32 saved_threadstorage[2];
|
|
|
|
|
|
|
|
memset(tmpaddr, 0, 0x1c);
|
|
|
|
|
|
|
|
if(src_addr)
|
|
|
|
tmp_addrlen = 0x1c;
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x7,4,4); // 0x70104
|
|
|
|
cmdbuf[1] = (u32)sockfd;
|
|
|
|
cmdbuf[2] = (u32)len;
|
|
|
|
cmdbuf[3] = (u32)flags;
|
|
|
|
cmdbuf[4] = (u32)tmp_addrlen;
|
|
|
|
cmdbuf[5] = IPC_Desc_CurProcessId();
|
|
|
|
cmdbuf[7] = IPC_Desc_Buffer(len,IPC_BUFFER_W);
|
|
|
|
cmdbuf[8] = (u32)buf;
|
|
|
|
|
|
|
|
u32 * staticbufs = getThreadStaticBuffers();
|
|
|
|
saved_threadstorage[0] = staticbufs[0];
|
|
|
|
saved_threadstorage[1] = staticbufs[1];
|
|
|
|
|
|
|
|
staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
|
|
|
|
staticbufs[1] = (u32)tmpaddr;
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2020-04-26 13:07:17 +02:00
|
|
|
|
|
|
|
staticbufs[0] = saved_threadstorage[0];
|
|
|
|
staticbufs[1] = saved_threadstorage[1];
|
|
|
|
|
|
|
|
if(ret != 0) {
|
|
|
|
//errno = SYNC_ERROR;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = (int)cmdbuf[1];
|
|
|
|
if(ret == 0)
|
|
|
|
ret = _net_convert_error(cmdbuf[2]);
|
|
|
|
|
|
|
|
if(ret < 0) {
|
|
|
|
//errno = -ret;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(src_addr != NULL) {
|
|
|
|
src_addr->sa_family = tmpaddr[1];
|
|
|
|
if(*addrlen > tmpaddr[0])
|
|
|
|
*addrlen = tmpaddr[0];
|
|
|
|
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t _socuipc_cmd8(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
u32 tmp_addrlen = 0;
|
|
|
|
u8 tmpaddr[0x1c];
|
|
|
|
u32 saved_threadstorage[4];
|
|
|
|
|
|
|
|
if(src_addr)
|
|
|
|
tmp_addrlen = 0x1c;
|
|
|
|
|
|
|
|
memset(tmpaddr, 0, 0x1c);
|
|
|
|
|
|
|
|
cmdbuf[0] = 0x00080102;
|
|
|
|
cmdbuf[1] = (u32)sockfd;
|
|
|
|
cmdbuf[2] = (u32)len;
|
|
|
|
cmdbuf[3] = (u32)flags;
|
|
|
|
cmdbuf[4] = (u32)tmp_addrlen;
|
|
|
|
cmdbuf[5] = 0x20;
|
|
|
|
|
|
|
|
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
|
|
|
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
|
|
|
saved_threadstorage[2] = cmdbuf[0x108>>2];
|
|
|
|
saved_threadstorage[3] = cmdbuf[0x10c>>2];
|
|
|
|
|
|
|
|
cmdbuf[0x100>>2] = (((u32)len)<<14) | 2;
|
|
|
|
cmdbuf[0x104>>2] = (u32)buf;
|
|
|
|
cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2;
|
|
|
|
cmdbuf[0x10c>>2] = (u32)tmpaddr;
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2020-04-26 13:07:17 +02:00
|
|
|
if(ret != 0) {
|
|
|
|
//errno = SYNC_ERROR;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmdbuf[0x100>>2] = saved_threadstorage[0];
|
|
|
|
cmdbuf[0x104>>2] = saved_threadstorage[1];
|
|
|
|
cmdbuf[0x108>>2] = saved_threadstorage[2];
|
|
|
|
cmdbuf[0x10c>>2] = saved_threadstorage[3];
|
|
|
|
|
|
|
|
ret = (int)cmdbuf[1];
|
|
|
|
if(ret == 0)
|
|
|
|
ret = _net_convert_error(cmdbuf[2]);
|
|
|
|
|
|
|
|
if(ret < 0) {
|
|
|
|
//errno = -ret;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(src_addr != NULL) {
|
|
|
|
src_addr->sa_family = tmpaddr[1];
|
|
|
|
if(*addrlen > tmpaddr[0])
|
|
|
|
*addrlen = tmpaddr[0];
|
|
|
|
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t _socuipc_cmd9(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
u32 tmp_addrlen = 0;
|
|
|
|
u8 tmpaddr[0x1c];
|
|
|
|
|
|
|
|
memset(tmpaddr, 0, 0x1c);
|
|
|
|
|
|
|
|
if(dest_addr) {
|
|
|
|
if(dest_addr->sa_family == AF_INET)
|
|
|
|
tmp_addrlen = 8;
|
|
|
|
else
|
|
|
|
tmp_addrlen = 0x1c;
|
|
|
|
|
|
|
|
if(addrlen < tmp_addrlen) {
|
|
|
|
//errno = EINVAL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpaddr[0] = tmp_addrlen;
|
|
|
|
tmpaddr[1] = dest_addr->sa_family;
|
|
|
|
memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2);
|
|
|
|
}
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0x9,4,6); // 0x90106
|
|
|
|
cmdbuf[1] = (u32)sockfd;
|
|
|
|
cmdbuf[2] = (u32)len;
|
|
|
|
cmdbuf[3] = (u32)flags;
|
|
|
|
cmdbuf[4] = (u32)tmp_addrlen;
|
|
|
|
cmdbuf[5] = IPC_Desc_CurProcessId();
|
|
|
|
cmdbuf[7] = IPC_Desc_StaticBuffer(tmp_addrlen,1);
|
|
|
|
cmdbuf[8] = (u32)tmpaddr;
|
|
|
|
cmdbuf[9] = IPC_Desc_Buffer(len,IPC_BUFFER_R);
|
|
|
|
cmdbuf[10] = (u32)buf;
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2020-04-26 13:07:17 +02:00
|
|
|
if(ret != 0) {
|
|
|
|
//errno = SYNC_ERROR;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = (int)cmdbuf[1];
|
|
|
|
if(ret == 0)
|
|
|
|
ret = _net_convert_error(cmdbuf[2]);
|
|
|
|
|
|
|
|
if(ret < 0) {
|
|
|
|
//errno = -ret;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t _socuipc_cmda(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
u32 *cmdbuf = getThreadCommandBuffer();
|
|
|
|
u32 tmp_addrlen = 0;
|
|
|
|
u8 tmpaddr[0x1c];
|
|
|
|
|
|
|
|
memset(tmpaddr, 0, 0x1c);
|
|
|
|
|
|
|
|
if(dest_addr) {
|
|
|
|
if(dest_addr->sa_family == AF_INET)
|
|
|
|
tmp_addrlen = 8;
|
|
|
|
else
|
|
|
|
tmp_addrlen = 0x1c;
|
|
|
|
|
|
|
|
if(addrlen < tmp_addrlen) {
|
|
|
|
//errno = EINVAL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpaddr[0] = tmp_addrlen;
|
|
|
|
tmpaddr[1] = dest_addr->sa_family;
|
|
|
|
memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2);
|
|
|
|
}
|
|
|
|
|
|
|
|
cmdbuf[0] = IPC_MakeHeader(0xA,4,6); // 0xA0106
|
|
|
|
cmdbuf[1] = (u32)sockfd;
|
|
|
|
cmdbuf[2] = (u32)len;
|
|
|
|
cmdbuf[3] = (u32)flags;
|
|
|
|
cmdbuf[4] = (u32)tmp_addrlen;
|
|
|
|
cmdbuf[5] = IPC_Desc_CurProcessId();
|
|
|
|
cmdbuf[7] = IPC_Desc_StaticBuffer(len,2);
|
|
|
|
cmdbuf[8] = (u32)buf;
|
|
|
|
cmdbuf[9] = IPC_Desc_StaticBuffer(tmp_addrlen,1);
|
|
|
|
cmdbuf[10] = (u32)tmpaddr;
|
|
|
|
|
2020-04-28 02:31:29 +02:00
|
|
|
ret = svcSendSyncRequest(miniSocHandle);
|
2020-04-26 13:07:17 +02:00
|
|
|
if(ret != 0) {
|
|
|
|
//errno = SYNC_ERROR;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = (int)cmdbuf[1];
|
|
|
|
if(ret == 0)
|
|
|
|
ret = _net_convert_error(cmdbuf[2]);
|
|
|
|
|
|
|
|
if(ret < 0) {
|
|
|
|
//errno = -ret;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ssize_t socRecvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
|
|
|
|
{
|
|
|
|
if(len < 0x2000)
|
|
|
|
return _socuipc_cmd8(sockfd, buf, len, flags, src_addr, addrlen);
|
|
|
|
return _socuipc_cmd7(sockfd, buf, len, flags, src_addr, addrlen);
|
2017-06-05 02:02:04 +02:00
|
|
|
}
|
|
|
|
|
2020-04-26 13:07:17 +02:00
|
|
|
ssize_t socSendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
|
2017-06-05 02:02:04 +02:00
|
|
|
{
|
2020-04-26 13:07:17 +02:00
|
|
|
if(len < 0x2000)
|
|
|
|
return _socuipc_cmda(sockfd, buf, len, flags, dest_addr, addrlen);
|
|
|
|
return _socuipc_cmd9(sockfd, buf, len, flags, dest_addr, addrlen);
|
2017-06-05 02:02:04 +02:00
|
|
|
}
|