]> Chaos Git - corbenik/ctrulib.git/commitdiff
added SOC:u getnameinfo
authorLectem <lectem@gmail.com>
Wed, 13 Jan 2016 17:18:16 +0000 (12:18 -0500)
committerLectem <lectem@gmail.com>
Thu, 14 Jan 2016 23:24:50 +0000 (18:24 -0500)
libctru/include/netdb.h
libctru/source/services/soc/soc_getnameinfo.c [new file with mode: 0644]

index 4e42861b05386960bfccf86c22c2a384dcec1944..5840deb5ec662891cdef6a2f7ad915339d72d9ae 100644 (file)
@@ -17,6 +17,21 @@ struct hostent {
        char    *h_addr;
 };
 
+#define NI_MAXHOST     1025
+#define NI_MAXSERV       32
+
+#define NI_NOFQDN      0x01
+#define NI_NUMERICHOST 0x02
+#define NI_NAMEREQD    0x04
+#define NI_NUMERICSERV 0x00 /* probably 0x08 but services names are never resolved */
+#define NI_DGRAM       0x00 /* probably 0x10 but services names are never resolved */
+
+#define EAI_FAMILY   (-303)
+#define EAI_MEMORY   (-304)
+#define EAI_NONAME   (-305)
+#define EAI_SOCKTYPE (-307)
+
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -27,6 +42,10 @@ extern "C" {
        void            herror(const char *s);
        const char*     hstrerror(int err);
 
+       int getnameinfo(const struct sockaddr *sa, socklen_t salen,
+               char *host, socklen_t hostlen,
+               char *serv, socklen_t servlen, int flags);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libctru/source/services/soc/soc_getnameinfo.c b/libctru/source/services/soc/soc_getnameinfo.c
new file mode 100644 (file)
index 0000000..05c9ab6
--- /dev/null
@@ -0,0 +1,68 @@
+#include "soc_common.h"
+#include <netdb.h>
+#include <3ds/ipc.h>
+#include <3ds/result.h>
+
+int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags)
+{
+       int i,tmp_addrlen;
+       u32 *cmdbuf = getThreadCommandBuffer();
+       u32 saved_threadstorage[4];
+       u8 tmpaddr[0x1c]; // sockaddr size for the kernel is 0x1C (sockaddr_in6?)
+
+       if((host == NULL || hostlen == 0) && (serv == NULL || servlen == 0))
+       {
+               return EAI_NONAME;
+       }
+
+       if(sa->sa_family == AF_INET)
+               tmp_addrlen = 8;
+       else
+               tmp_addrlen = 0x1c;
+
+       if(salen < tmp_addrlen) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       tmpaddr[0] = tmp_addrlen;
+       tmpaddr[1] = sa->sa_family;
+       memcpy(&tmpaddr[2], &sa->sa_data, tmp_addrlen-2);
+
+       cmdbuf[0] = IPC_MakeHeader(0x10,4,2); // 0x100102
+       cmdbuf[1] = sizeof(tmpaddr);
+       cmdbuf[2] = hostlen;
+       cmdbuf[3] = servlen;
+       cmdbuf[4] = flags;
+       cmdbuf[5] = IPC_Desc_StaticBuffer(sizeof(tmpaddr),8);
+       cmdbuf[6] = (u32)tmpaddr;
+
+       u32 * staticbufs = getThreadStaticBuffers();
+
+       // Save the thread storage values
+       for(i = 0 ; i < 4 ; ++i)
+               saved_threadstorage[i] = staticbufs[i];
+
+       staticbufs[0] = IPC_Desc_StaticBuffer(hostlen,0);
+       staticbufs[1] = (u32)host;
+       staticbufs[2] = IPC_Desc_StaticBuffer(servlen,0);
+       staticbufs[3] = (u32)serv;
+
+       Result ret = svcSendSyncRequest(SOCU_handle);
+
+       // Restore the thread storage values
+       for(i = 0 ; i < 4 ; ++i)
+               staticbufs[i] = saved_threadstorage[i];
+
+       if(R_FAILED(ret)) {
+               errno = SYNC_ERROR;
+               return ret;
+       }       
+
+       ret = cmdbuf[1];
+       if(R_FAILED(ret)) {
+               errno = SYNC_ERROR;
+               return ret;
+       }
+       return cmdbuf[2];
+}