Usermode/libpsocket - Working on BSD/POSIX socket emulation
authorJohn Hodge <[email protected]>
Sun, 27 May 2012 05:07:50 +0000 (13:07 +0800)
committerJohn Hodge <[email protected]>
Sun, 27 May 2012 05:07:50 +0000 (13:07 +0800)
Usermode/Libraries/libpsocket.so_src/Makefile [new file with mode: 0644]
Usermode/Libraries/libpsocket.so_src/getaddrinfo.c [new file with mode: 0644]
Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h [new file with mode: 0644]
Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h [new file with mode: 0644]
Usermode/Libraries/libpsocket.so_src/include_exp/sys/socket.h
Usermode/Libraries/libpsocket.so_src/main.c [new file with mode: 0644]
Usermode/Libraries/libpsocket.so_src/socket.c [new file with mode: 0644]

diff --git a/Usermode/Libraries/libpsocket.so_src/Makefile b/Usermode/Libraries/libpsocket.so_src/Makefile
new file mode 100644 (file)
index 0000000..ee0b579
--- /dev/null
@@ -0,0 +1,12 @@
+# Acess 2 - POSIX Sockets
+
+include ../Makefile.cfg
+
+CPPFLAGS +=
+CFLAGS   += -Wall
+LDFLAGS  += -lc -soname libpsocket.so
+
+OBJ = main.o getaddrinfo.o socket.o
+BIN = libpsocket.so
+
+include ../Makefile.tpl
diff --git a/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c b/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c
new file mode 100644 (file)
index 0000000..e122a5a
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Acess2 POSIX Sockets Library
+ * - By John Hodge (thePowersGang)
+ *
+ * getaddrinfo.c
+ * - getaddrinfo/freeaddrinfo/getnameinfo/gai_strerror
+ */
+#include <netdb.h>
+#include <netinet/in.h>
+
+// === CODE ===
+int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res)
+{
+       static struct addrinfo  info;
+       static struct sockaddr_in       addr;
+
+       addr.sin_family = 4;
+       addr.sin_addr.s_addr = 0x2701A8C0;
+       info.ai_family = 4;
+       info.ai_addr = (struct sockaddr *) &addr;
+
+       return 1;
+}
+
+void freeaddrinfo(struct addrinfo *res)
+{
+       
+}
+
+const char *gai_strerror(int errnum)
+{
+       switch(errnum)
+       {
+       case 0:         return "No error";
+       case 1:         return "Unimplemented";
+       default:        return "UNKNOWN";
+       }
+}
+
diff --git a/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h b/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h
new file mode 100644 (file)
index 0000000..cea819c
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _LIBPSOCKET__NETDB_H_
+#define _LIBPSOCKET__NETDB_H_
+
+typedef unsigned int   socklen_t;
+
+struct addrinfo
+{
+       int     ai_flags;
+       int     ai_family;
+       int     ai_socktype;
+       int     ai_protocol;
+       socklen_t       ai_addrlen;
+       struct sockaddr *ai_addr;
+       char    *ai_canonname;
+       struct addrinfo *ai_next;
+};
+
+extern int     getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
+extern void    freeaddrinfo(struct addrinfo *res);
+const char     *gai_strerror(int errorcode);
+
+
+#endif
+
diff --git a/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h b/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h
new file mode 100644 (file)
index 0000000..4bde06d
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _LIBPSOCKET__NETINET__IN_H_
+#define _LIBPSOCKET__NETINET__IN_H_
+
+#include <stdint.h>
+
+struct in_addr
+{
+       unsigned long s_addr;
+};
+
+struct sockaddr_in
+{
+       uint16_t        sin_family;
+       uint16_t        sin_port;
+       struct in_addr  sin_addr;
+};
+
+struct in6_addr
+{
+       unsigned char   s6_addr[16];
+};
+
+struct sockaddr_in6
+{
+       uint16_t        sin6_family;
+       uint16_t        sin6_port;
+       uint32_t        sin6_flowinfo;
+       struct in6_addr sin6_addr;
+       uint32_t        sin6_scope_id;
+};
+
+#endif
+
index 43cb3d6..ecf5ce8 100644 (file)
@@ -9,13 +9,16 @@
 #ifndef _SYS_SOCKETS_H_
 #define _SYS_SOCKETS_H_
 
+#include <sys/types.h>
+
 typedef int    socklen_t;
 
 typedef enum
 {
        AF_UNSPEC       = 0,
+       AF_PACKET       = 1,
        AF_INET         = 4,
-       AF_INET6        = 6
+       AF_INET6        = 6,
 } sa_family_t;
 
 struct sockaddr
@@ -71,5 +74,10 @@ extern int   listen(int sockfd, int backlog);
  */
 extern int     accept(int sockfd, struct sockaddr *clientaddr, socklen_t addrlen);
 
+extern int     recvfrom(int sockfd, void *buffer, size_t length, int flags, struct sockaddr *clientaddr, socklen_t *addrlen);
+extern int     recv(int sockfd, void *buffer, size_t length, int flags);
+extern int     sendto(int sockfd, const void *buffer, size_t length, int flags, const struct sockaddr *clientaddr, socklen_t addrlen);
+extern int     send(int sockfd, void *buffer, size_t length, int flags);
+
 #endif
 
diff --git a/Usermode/Libraries/libpsocket.so_src/main.c b/Usermode/Libraries/libpsocket.so_src/main.c
new file mode 100644 (file)
index 0000000..09b3987
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Acess2 POSIX Sockets Library
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Entrypoint and misc code
+ */
+
+int SoMain(void)
+{
+       return 0;
+}
+
diff --git a/Usermode/Libraries/libpsocket.so_src/socket.c b/Usermode/Libraries/libpsocket.so_src/socket.c
new file mode 100644 (file)
index 0000000..913f72f
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Acess2 POSIX Sockets Library
+ * - By John Hodge (thePowersGang)
+ *
+ * socket.c
+ * - sys/socket.h calls
+ */
+#include <sys/socket.h>
+#include <unistd.h>
+#include <stdlib.h>    // malloc/free
+#include <string.h>
+#include <netinet/in.h>
+
+#define MAXFD  32
+
+typedef struct s_sockinfo
+{
+        int    fd;
+       char    domain;
+       char    type;
+       char    protocol;
+       struct sockaddr *local;
+       struct sockaddr *remote;
+} t_sockinfo;
+
+struct s_sockinfo      gSockInfo[MAXFD];
+static int     giNumPreinit = 0;
+
+// === CODE ===
+static t_sockinfo *_GetInfo(int FD)
+{
+        int    i, nInit = 0;;
+       if( FD == 0 && giNumPreinit == MAXFD )
+               return NULL;
+       for( i = 0; i < MAXFD; i ++ )
+       {
+               if( gSockInfo[i].fd == FD )
+                       return &gSockInfo[i];
+               if( gSockInfo[i].fd )
+                       nInit ++;
+               if( FD != 0 && nInit == giNumPreinit )
+                       return NULL;
+       }
+       return NULL;
+}
+
+int socket(int domain, int type, int protocol)
+{
+       t_sockinfo      *si = NULL;
+       
+       if( domain < 0 || domain > AF_INET6 )   return -1;
+       if( type < 0 || type > SOCK_RDM )       return -1;
+
+       // Allocate an info struct
+       si = _GetInfo(0);
+       if( !si )       return -1;
+
+       int fd = open("/Devices/null", O_RDWR);
+       if( fd == -1 )  return -1;
+
+       giNumPreinit ++;
+       si->fd = fd;
+       si->domain = domain;
+       si->type = type;
+       si->protocol = protocol;
+       si->local = NULL;
+       si->remote = NULL;
+
+       return fd;
+} 
+
+int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
+{
+       t_sockinfo      *si = _GetInfo(sockfd);;
+       if( !si )       return -1;
+
+       if( si->local ) {
+               // Oops?
+               return -1;
+       }
+
+       si->local = malloc( addrlen );
+       memcpy(si->local, addr, addrlen);
+
+       return 0;
+}
+
+int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
+{
+       t_sockinfo      *si = _GetInfo(sockfd);;
+       if( !si )       return -1;
+
+       if( si->remote ) {
+               // Oops?
+               return -1;
+       }
+
+       si->remote = malloc( addrlen );
+       memcpy(si->remote, addr, addrlen);
+
+       return 0;
+}
+
+int listen(int sockfd, int backlog)
+{
+       // TODO: Save this to the t_sockinfo structure
+       return 0;
+}
+
+void _ClearInfo(t_sockinfo *si)
+{
+       if( si->local ) {
+               free(si->local);
+               si->local = NULL;
+       }
+       
+       if( si->remote ) {
+               free(si->remote);
+               si->remote = NULL;
+       }
+       
+       si->fd = 0;
+       giNumPreinit --;
+}
+
+void _CommitServer(int sockfd)
+{
+       t_sockinfo      *si = _GetInfo(sockfd);
+       if( !si )       return ;
+
+       const char      *file;
+       
+       file = "tcps";
+
+       if( !si->local ) {
+               // Um... oops?
+               return ;
+       }       
+
+       uint8_t *addrBuffer = NULL;
+       size_t addrLen = 0;
+       switch( si->local->sa_family )
+       {
+       case AF_INET:
+               addrBuffer = (void*)&((struct sockaddr_in*)si->local)->sin_addr;
+               addrLen = 4;
+               break;
+       case AF_INET6:
+               addrBuffer = (void*)&((struct sockaddr_in6*)si->local)->sin6_addr;
+               addrLen = 16;
+               break;
+       default:
+               return ;
+       }
+       
+       char    hexAddr[addrLen*2+1];
+        int    bNonZero = 0, i;
+       for( i = 0; i < addrLen; i ++ ) {
+               hexAddr[i*2+0] = "0123456789ABCDEF"[addrBuffer[i] >> 4];
+               hexAddr[i*2+1] = "0123456789ABCDEF"[addrBuffer[i] & 15];
+               if(addrBuffer[i]) bNonZero = 1;
+       }
+       
+       char    *path;
+       if( bNonZero )
+               path = mkstr("/Devices/ip/routes/@%i:%s/%s", si->local->sa_family, file);
+       else
+               path = mkstr("/Devices/ip/*%i/%s", si->local->sa_family, file);
+
+       reopen(si->fd, path, O_RDWR);
+       // TODO: Error-check
+       
+       free(path);
+
+       // TODO: Set up socket
+
+       _ClearInfo(si);
+}
+
+void _CommitClient(int sockfd)
+{
+       t_sockinfo      *si = _GetInfo(sockfd);
+       if( !si )       return ;
+
+       _ClearInfo(si);
+}
+
+int accept(int sockfd, struct sockaddr *clientaddr, socklen_t addrlen)
+{
+       _CommitServer(sockfd);
+        int    child;
+
+
+       child = _SysOpenChild(sockfd, "", O_RDWR);
+       if( child == -1 )       return -1;
+       
+       ioctl(child, 8, clientaddr);
+       
+       return child;
+}
+
+int recvfrom(int sockfd, void *buffer, size_t length, int flags, struct sockaddr *clientaddr, socklen_t *addrlen)
+{
+       _CommitClient(sockfd);
+       // TODO: Determine socket type (TCP/UDP) and use a bounce-buffer for UDP
+       return read(sockfd, buffer, length);
+}
+
+int recv(int sockfd, void *buffer, size_t length, int flags)
+{
+       _CommitClient(sockfd);
+       return read(sockfd, buffer, length);
+}
+
+int sendto(int sockfd, const void *buffer, size_t length, int flags, const struct sockaddr *clientaddr, socklen_t addrlen)
+{
+       _CommitClient(sockfd);
+       // TODO: Determine socket type (TCP/UDP) and use a bounce-buffer for UDP
+       return write(sockfd, buffer, length);
+}
+
+int send(int sockfd, void *buffer, size_t length, int flags)
+{
+       _CommitClient(sockfd);
+       return write(sockfd, buffer, length);
+}
+

UCC git Repository :: git.ucc.asn.au