mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
407 lines
7.8 KiB
C
407 lines
7.8 KiB
C
// Copyright 2017 plutoo
|
|
#include <switch.h>
|
|
|
|
static Handle g_bsdHandle = -1;
|
|
static u32 g_bsdObjectId = -1;
|
|
static int g_Errno = 0;
|
|
|
|
#define EPIPE 32
|
|
|
|
Result bsdInitialize(TransferMemory* tmem) {
|
|
Result rc = smGetService(&g_bsdHandle, "bsd:s");
|
|
|
|
if (R_FAILED(rc)) {
|
|
rc = smGetService(&g_bsdHandle, "bsd:u");
|
|
}
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
IpcCommand c;
|
|
ipcInitialize(&c);
|
|
ipcSendPid(&c);
|
|
ipcSendHandleCopy(&c, tmem->MemHandle);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 cmd_id;
|
|
u64 unk0[5];
|
|
u64 tmem_sz;
|
|
u64 pad[2];
|
|
} *raw;
|
|
|
|
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
|
|
|
raw->magic = SFCI_MAGIC;
|
|
raw->cmd_id = 0;
|
|
raw->unk0[0] = 0x4000;
|
|
raw->unk0[1] = 0x4000;
|
|
raw->unk0[2] = 0x4000;
|
|
raw->unk0[3] = 0x4000;
|
|
raw->unk0[4] = 0;
|
|
raw->tmem_sz = tmem->Size;
|
|
|
|
rc = ipcDispatch(g_bsdHandle);
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
IpcCommandResponse r;
|
|
ipcParseResponse(&r);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 result;
|
|
} *resp = r.Raw;
|
|
|
|
rc = resp->result;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
rc = ipcConvertSessionToDomain(g_bsdHandle, &g_bsdObjectId);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (R_FAILED(rc)) {
|
|
g_Errno = EPIPE;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
int bsdGetErrno() {
|
|
return g_Errno;
|
|
}
|
|
|
|
int bsdSocket(int domain, int type, int protocol) {
|
|
IpcCommand c;
|
|
ipcInitialize(&c);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 cmd_id;
|
|
u32 domain;
|
|
u32 type;
|
|
u32 protocol;
|
|
u32 pad[4];
|
|
} *raw;
|
|
|
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
|
|
|
raw->magic = SFCI_MAGIC;
|
|
raw->cmd_id = 2;
|
|
raw->domain = domain;
|
|
raw->type = type;
|
|
raw->protocol = protocol;
|
|
|
|
Result rc = ipcDispatch(g_bsdHandle);
|
|
int fd = -1;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
IpcCommandResponse r;
|
|
ipcParseResponseForDomain(&r);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 result;
|
|
u32 fd;
|
|
u32 errno;
|
|
} *resp = r.Raw;
|
|
|
|
rc = resp->result;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
g_Errno = resp->errno;
|
|
fd = resp->fd;
|
|
}
|
|
}
|
|
|
|
if (R_FAILED(rc)) {
|
|
g_Errno = EPIPE;
|
|
}
|
|
|
|
return fd;
|
|
}
|
|
int bsdRecv(int sockfd, void* buffer, size_t length, int flags) {
|
|
IpcCommand c;
|
|
ipcInitialize(&c);
|
|
ipcAddRecvBuffer(&c, buffer, length, 0);
|
|
ipcAddRecvStatic(&c, buffer, length, 0);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 cmd_id;
|
|
u32 sockfd;
|
|
u32 flags;
|
|
} *raw;
|
|
|
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
|
|
|
raw->magic = SFCI_MAGIC;
|
|
raw->cmd_id = 8;
|
|
raw->sockfd = sockfd;
|
|
raw->flags = flags;
|
|
|
|
Result rc = ipcDispatch(g_bsdHandle);
|
|
int ret = -1;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
IpcCommandResponse r;
|
|
ipcParseResponseForDomain(&r);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 result;
|
|
u32 ret;
|
|
u32 errno;
|
|
} *resp = r.Raw;
|
|
|
|
rc = resp->result;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
g_Errno = resp->errno;
|
|
ret = resp->ret;
|
|
}
|
|
}
|
|
|
|
if (R_FAILED(rc)) {
|
|
g_Errno = rc; //EPIPE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int bsdSend(int sockfd, void* buffer, size_t length, int flags) {
|
|
IpcCommand c;
|
|
ipcInitialize(&c);
|
|
ipcAddSendBuffer(&c, buffer, length, 0);
|
|
ipcAddSendStatic(&c, buffer, length, 0);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 cmd_id;
|
|
u32 sockfd;
|
|
u32 flags;
|
|
} *raw;
|
|
|
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
|
|
|
raw->magic = SFCI_MAGIC;
|
|
raw->cmd_id = 10;
|
|
raw->sockfd = sockfd;
|
|
raw->flags = flags;
|
|
|
|
Result rc = ipcDispatch(g_bsdHandle);
|
|
int ret = -1;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
IpcCommandResponse r;
|
|
ipcParseResponseForDomain(&r);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 result;
|
|
u32 ret;
|
|
u32 errno;
|
|
} *resp = r.Raw;
|
|
|
|
rc = resp->result;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
g_Errno = resp->errno;
|
|
ret = resp->ret;
|
|
}
|
|
}
|
|
|
|
if (R_FAILED(rc)) {
|
|
g_Errno = EPIPE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int bsdConnect(int sockfd, void* addr, u32 addrlen) {
|
|
IpcCommand c;
|
|
ipcInitialize(&c);
|
|
ipcAddSendBuffer(&c, addr, addrlen, 0);
|
|
ipcAddSendStatic(&c, addr, addrlen, 0);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 cmd_id;
|
|
u32 sockfd;
|
|
u32 pad[4];
|
|
} *raw;
|
|
|
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
|
|
|
raw->magic = SFCI_MAGIC;
|
|
raw->cmd_id = 14;
|
|
raw->sockfd = sockfd;
|
|
|
|
Result rc = ipcDispatch(g_bsdHandle);
|
|
int fd = -1;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
IpcCommandResponse r;
|
|
ipcParseResponseForDomain(&r);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 result;
|
|
u32 fd;
|
|
u32 errno;
|
|
} *resp = r.Raw;
|
|
|
|
rc = resp->result;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
g_Errno = resp->errno;
|
|
fd = resp->fd;
|
|
}
|
|
}
|
|
|
|
if (R_FAILED(rc)) {
|
|
g_Errno = EPIPE;
|
|
}
|
|
|
|
return fd;
|
|
}
|
|
|
|
int bsdBind(int sockfd, void* addr, u32 addrlen) {
|
|
IpcCommand c;
|
|
ipcInitialize(&c);
|
|
ipcAddSendBuffer(&c, addr, addrlen, 0);
|
|
ipcAddSendStatic(&c, addr, addrlen, 0);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 cmd_id;
|
|
u32 pad[5];
|
|
} *raw;
|
|
|
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
|
|
|
raw->magic = SFCI_MAGIC;
|
|
raw->cmd_id = 13;
|
|
|
|
Result rc = ipcDispatch(g_bsdHandle);
|
|
int ret = -1;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
IpcCommandResponse r;
|
|
ipcParseResponseForDomain(&r);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 result;
|
|
u32 ret;
|
|
u32 errno;
|
|
} *resp = r.Raw;
|
|
|
|
rc = resp->result;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
g_Errno = resp->errno;
|
|
ret = resp->ret;
|
|
}
|
|
}
|
|
|
|
if (R_FAILED(rc)) {
|
|
g_Errno = EPIPE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int bsdListen(int sockfd, int backlog) {
|
|
IpcCommand c;
|
|
ipcInitialize(&c);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 cmd_id;
|
|
u32 sockfd;
|
|
u32 backlog;
|
|
u32 pad[4];
|
|
} *raw;
|
|
|
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
|
|
|
raw->magic = SFCI_MAGIC;
|
|
raw->cmd_id = 18;
|
|
raw->sockfd = sockfd;
|
|
raw->backlog = backlog;
|
|
|
|
Result rc = ipcDispatch(g_bsdHandle);
|
|
int ret = -1;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
IpcCommandResponse r;
|
|
ipcParseResponseForDomain(&r);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 result;
|
|
u32 ret;
|
|
u32 errno;
|
|
} *resp = r.Raw;
|
|
|
|
rc = resp->result;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
g_Errno = resp->errno;
|
|
ret = resp->ret;
|
|
}
|
|
}
|
|
|
|
if (R_FAILED(rc)) {
|
|
g_Errno = EPIPE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int bsdWrite(int sockfd, void* buffer, size_t length) {
|
|
IpcCommand c;
|
|
ipcInitialize(&c);
|
|
ipcAddSendBuffer(&c, buffer, length, 0);
|
|
ipcAddSendStatic(&c, buffer, length, 0);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 cmd_id;
|
|
u32 sockfd;
|
|
} *raw;
|
|
|
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
|
|
|
raw->magic = SFCI_MAGIC;
|
|
raw->cmd_id = 24;
|
|
raw->sockfd = sockfd;
|
|
|
|
Result rc = ipcDispatch(g_bsdHandle);
|
|
int ret = -1;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
IpcCommandResponse r;
|
|
ipcParseResponseForDomain(&r);
|
|
|
|
struct {
|
|
u64 magic;
|
|
u64 result;
|
|
u32 ret;
|
|
u32 errno;
|
|
} *resp = r.Raw;
|
|
|
|
rc = resp->result;
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
g_Errno = resp->errno;
|
|
ret = resp->ret;
|
|
}
|
|
}
|
|
|
|
if (R_FAILED(rc)) {
|
|
g_Errno = EPIPE;
|
|
}
|
|
|
|
return ret;
|
|
}
|