diff --git a/libctru/include/3ds/services/soc.h b/libctru/include/3ds/services/soc.h index b5ac85e..60f7b27 100644 --- a/libctru/include/3ds/services/soc.h +++ b/libctru/include/3ds/services/soc.h @@ -27,3 +27,6 @@ Result socExit(void); */ long gethostid(void); +int SOCU_ShutdownSockets(); + +int SOCU_CloseSockets(); diff --git a/libctru/include/arpa/inet.h b/libctru/include/arpa/inet.h index 197877b..5e044a9 100644 --- a/libctru/include/arpa/inet.h +++ b/libctru/include/arpa/inet.h @@ -27,9 +27,12 @@ static inline uint16_t ntohs(uint16_t netshort) extern "C" { #endif - in_addr_t inet_addr(const char *cp); - int inet_aton(const char *cp, struct in_addr *inp); - char* inet_ntoa(struct in_addr in); + in_addr_t inet_addr(const char *cp); + int inet_aton(const char *cp, struct in_addr *inp); + char* inet_ntoa(struct in_addr in); + + const char *inet_ntop(int af, const void *restrict src, char *restrict dst, socklen_t size); + int inet_pton(int af, const char *restrict src, void *restrict dst); #ifdef __cplusplus } diff --git a/libctru/source/services/soc/soc_closesockets.c b/libctru/source/services/soc/soc_closesockets.c new file mode 100644 index 0000000..6b5a8aa --- /dev/null +++ b/libctru/source/services/soc/soc_closesockets.c @@ -0,0 +1,15 @@ +#include "soc_common.h" +#include <3ds/ipc.h> +#include <3ds/result.h> + +int SOCU_CloseSockets() +{ + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x21,0,2); // 0x210002; + cmdbuf[1] = IPC_Desc_CurProcessHandle(); + + int ret = svcSendSyncRequest(SOCU_handle); + if(R_FAILED(ret))return ret; + return cmdbuf[1]; +} diff --git a/libctru/source/services/soc/soc_inet_ntop.c b/libctru/source/services/soc/soc_inet_ntop.c new file mode 100644 index 0000000..68016d4 --- /dev/null +++ b/libctru/source/services/soc/soc_inet_ntop.c @@ -0,0 +1,28 @@ +#include "soc_common.h" +#include +#include + + +static const char *inet_ntop4(const void *restrict src, char *restrict dst, socklen_t size) +{ + const u8 * ip = src; + if(size < INET_ADDRSTRLEN) + { + errno = ENOSPC; + return NULL; + } + snprintf(dst,size,"%hhu.%hhu.%hhu.%hhu",ip[0], ip[1], ip[2], ip[3]); + return dst; +} + + +const char *inet_ntop(int af, const void *restrict src, char *restrict dst, socklen_t size) +{ + if(af == AF_INET) + { + return inet_ntop4(src,dst,size); + } + // only support IPv4 + errno = EAFNOSUPPORT; + return NULL; +} diff --git a/libctru/source/services/soc/soc_inet_pton.c b/libctru/source/services/soc/soc_inet_pton.c new file mode 100644 index 0000000..dc8bba9 --- /dev/null +++ b/libctru/source/services/soc/soc_inet_pton.c @@ -0,0 +1,24 @@ +#include "soc_common.h" +#include +#include + + +static int inet_pton4(const char *restrict src, void *restrict dst) +{ + u8 ip[4]; + if(sscanf(src,"%hhu.%hhu.%hhu.%hhu",&ip[0], &ip[1], &ip[2], &ip[3]) != 4) return 0; + *(u32*)dst = *(u32*)ip; + return 1; +} + + +int inet_pton(int af, const char *restrict src, void *restrict dst) +{ + if(af == AF_INET) + { + return inet_pton4(src,dst); + } + // only support IPv4 + errno = EAFNOSUPPORT; + return -1; +} diff --git a/libctru/source/services/soc/soc_shutdownsockets.c b/libctru/source/services/soc/soc_shutdownsockets.c new file mode 100644 index 0000000..1649846 --- /dev/null +++ b/libctru/source/services/soc/soc_shutdownsockets.c @@ -0,0 +1,14 @@ +#include "soc_common.h" +#include <3ds/ipc.h> +#include <3ds/result.h> + +int SOCU_ShutdownSockets() +{ + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x19,0,0); // 0x190000 + + int ret = svcSendSyncRequest(SOCU_handle); + if(R_FAILED(ret))return ret; + return cmdbuf[1]; +}