From 3db154a8f061b0b2c6b2202ffe92d1b900ae1d3c Mon Sep 17 00:00:00 2001 From: shinyquagsire23 Date: Sun, 19 Nov 2017 01:45:15 -0700 Subject: [PATCH] Add bsdSendTo and bsdSetSockOpt --- nx/include/switch/services/bsd.h | 42 +++++++------ nx/source/services/bsd.c | 104 +++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 18 deletions(-) diff --git a/nx/include/switch/services/bsd.h b/nx/include/switch/services/bsd.h index 8c2b2975..fc63804b 100644 --- a/nx/include/switch/services/bsd.h +++ b/nx/include/switch/services/bsd.h @@ -1,21 +1,3 @@ -Result bsdInitialize(TransferMemory* tmem); -int bsdGetErrno(); -int bsdConnect(int sockfd, void* addr, u32 addrlen); -int bsdSocket(int domain, int type, int protocol); -int bsdBind(int sockfd, void* addr, u32 addrlen); -int bsdListen(int sockfd, int backlog); -int bsdSend(int sockfd, void* buffer, size_t length, int flags); -int bsdRecv(int sockfd, void* buffer, size_t length, int flags); -int bsdWrite(int sockfd, void* buffer, size_t length); - -#define BSD_AF_INET 2 -#define BSD_AF_INET6 10 - -#define BSD_SOCK_STREAM 1 -#define BSD_SOCK_DGRAM 2 - -#define BSD_MSG_RECV_ALL 0x40 - struct bsd_sockaddr_in { u8 sin_len; u8 sin_family; @@ -23,3 +5,27 @@ struct bsd_sockaddr_in { u32 sin_addr; u8 sin_zero[8]; }; + +Result bsdInitialize(TransferMemory* tmem); +int bsdGetErrno(); +int bsdConnect(int sockfd, void* addr, u32 addrlen); +int bsdSocket(int domain, int type, int protocol); +int bsdBind(int sockfd, void* addr, u32 addrlen); +int bsdListen(int sockfd, int backlog); +int bsdSend(int sockfd, void* buffer, size_t length, int flags); +int bsdSendTo(int sockfd, void* buffer, size_t length, int flags, const struct bsd_sockaddr_in *dest_addr, size_t dest_len); +int bsdRecv(int sockfd, void* buffer, size_t length, int flags); +int bsdSetSockOpt(int sockfd, int level, int option_name, const void *option_value, size_t option_size); +int bsdWrite(int sockfd, void* buffer, size_t length); + +#define BSD_AF_INET 2 +#define BSD_AF_INET6 10 + +#define BSD_IPPROTO_IP 0 +#define BSD_IPPROTO_TCP 6 +#define BSD_IPPROTO_UDP 17 + +#define BSD_SOCK_STREAM 1 +#define BSD_SOCK_DGRAM 2 + +#define BSD_MSG_RECV_ALL 0x40 diff --git a/nx/source/services/bsd.c b/nx/source/services/bsd.c index 2d4141a8..b37f059b 100644 --- a/nx/source/services/bsd.c +++ b/nx/source/services/bsd.c @@ -261,6 +261,58 @@ int bsdSend(int sockfd, void* buffer, size_t length, int flags) { return ret; } +int bsdSendTo(int sockfd, void* buffer, size_t length, int flags, const struct bsd_sockaddr_in *dest_addr, size_t dest_len) { + IpcCommand c; + ipcInitialize(&c); + ipcAddSendBuffer(&c, buffer, length, 0); + ipcAddSendStatic(&c, buffer, length, 0); + + ipcAddSendBuffer(&c, dest_addr, dest_len, 0); + ipcAddSendStatic(&c, dest_addr, dest_len, 0); + + struct { + u64 magic; + u64 cmd_id; + u32 sockfd; + u32 flags; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 11; + raw->sockfd = sockfd; + raw->flags = flags; + + Result rc = ipcDispatch(g_bsdClientHandle); + int ret = -1; + + if (R_SUCCEEDED(rc)) { + IpcCommandResponse r; + ipcParseResponse(&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); @@ -403,6 +455,58 @@ int bsdListen(int sockfd, int backlog) { return ret; } +int bsdSetSockOpt(int sockfd, int level, int option_name, const void *option_value, size_t option_size) { + IpcCommand c; + ipcInitialize(&c); + + ipcAddSendBuffer(&c, option_value, option_size, 0); + ipcAddSendStatic(&c, option_value, option_size, 0); + + struct { + u64 magic; + u64 cmd_id; + u32 sockfd; + u32 level; + u32 option_name; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 21; + raw->sockfd = sockfd; + raw->level = level; + raw->option_name = option_name; + + Result rc = ipcDispatch(g_bsdClientHandle); + int ret = -1; + + if (R_SUCCEEDED(rc)) { + IpcCommandResponse r; + ipcParseResponse(&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);