Overhauled soc service.

This commit is contained in:
mtheall 2014-11-20 15:36:50 -06:00
parent 919917b7ed
commit 55608adaad
39 changed files with 1406 additions and 989 deletions

View File

@ -21,6 +21,7 @@ SOURCES := source \
source/allocator \
source/gpu \
source/services \
source/services/soc \
source/util
DATA := data
INCLUDES := include

View File

@ -4,4 +4,9 @@ Result SOC_Initialize(u32 *context_addr, u32 context_size);//Example context_siz
Result SOC_Shutdown();
int SOC_GetErrno();
long gethostid();
Result SOC_Shutdown(void);
int SOC_GetErrno(void);
/* this is supposed to be in unistd.h but newlib only puts it for cygwin */
long gethostid(void);

View File

@ -0,0 +1,36 @@
#pragma once
#include <netinet/in.h>
#include <stdint.h>
static inline uint32_t htonl(uint32_t hostlong)
{
return __builtin_bswap32(hostlong);
}
static inline uint16_t htons(uint16_t hostshort)
{
return __builtin_bswap16(hostshort);
}
static inline uint32_t ntohl(uint32_t netlong)
{
return __builtin_bswap32(netlong);
}
static inline uint16_t ntohs(uint16_t netshort)
{
return __builtin_bswap16(netshort);
}
#ifdef __cplusplus
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);
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,12 @@
#ifndef NETDB_H
#define NETDB_H
#pragma once
#include <netinet/in.h>
#define HOST_NOT_FOUND 1
#define NO_DATA 2
#define NO_ADDRESS NO_DATA
#define NO_RECOVERY 3
#define TRY_AGAIN 4
struct hostent {
char *h_name;
@ -9,16 +16,13 @@ struct hostent {
char **h_addr_list;
};
#ifdef __cplusplus
extern "C" {
#endif
extern int h_errno;
struct hostent* gethostbyname(const char *name);
#ifdef __cplusplus
};
}
#endif
#endif // NETDB_H

View File

@ -1,34 +1,28 @@
#ifndef NETINET_IN_H
#define NETINET_IN_H
#pragma once
#include "sys/socket.h"
#include <stdint.h>
#include <sys/socket.h>
#define INADDR_ANY 0x00000000
#define INADDR_BROADCAST 0xFFFFFFFF
#define INADDR_NONE 0xFFFFFFFF
#define INET_ADDRSTRLEN 16
//#define IPPROTO_IP ???
//#define IPPROTO_TCP ???
//#define IPPROTO_UDP ???
typedef uint16_t in_port_t;
typedef uint32_t in_addr_t;
struct in_addr {
unsigned long s_addr;
in_addr_t s_addr;
};
struct sockaddr_in {
unsigned short sin_family;
unsigned short sin_port;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
#ifdef __cplusplus
extern "C" {
#endif
// actually from arpa/inet.h - but is included through netinet/in.h
unsigned long inet_addr(const char *cp);
int inet_aton(const char *cp, struct in_addr *inp);
char *inet_ntoa(struct in_addr in);
#ifdef __cplusplus
};
#endif
#endif // NETINET_IN_H

View File

@ -0,0 +1,5 @@
#pragma once
//#define SOL_TCP ???
//#define TCP_NODELAY ???

34
libctru/include/poll.h Normal file
View File

@ -0,0 +1,34 @@
#pragma once
#include <3ds/types.h>
/* only POLLIN confirmed to work so far */
#define POLLIN 0x001
#define POLLPRI 0x002
#define POLLOUT 0x004
#define POLLERR 0x008
#define POLLHUP 0x010
#define POLLNVAL 0x020
#define POLLRDNORM 0x040
#define POLLRDBAND 0x080
#define POLLWRNORM 0x100
#define POLLWRBAND 0x200
typedef u32 nfds_t;
struct pollfd
{
int fd;
int events;
int revents;
};
#ifdef __cplusplus
extern "C" {
#endif
int poll(struct pollfd *fds, nfds_t nfsd, int timeout);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,13 @@
#pragma once
#define FIONBIO 1
#ifdef __cplusplus
extern "C" {
#endif
int ioctl(int fd, int request, ...);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,13 @@
#pragma once
#include <sys/time.h>
#ifdef __cplusplus
extern "C" {
#endif
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
#ifdef __cplusplus
}
#endif

View File

@ -1,13 +1,9 @@
#ifndef SYS_SOCKET_H
#define SYS_SOCKET_H
#pragma once
#include <stdint.h>
#include <sys/time.h>
/*
* Level number for (get/set)sockopt() to apply to socket itself.
*/
#define SOL_SOCKET 0xfff /* options for socket level */
# define SOL_TCP 6 /* TCP level */
#define SOL_SOCKET 0xFFFF
#define PF_UNSPEC 0
#define PF_INET 2
@ -20,100 +16,76 @@
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
// need to sync FIO* values with commonly accepted ones sometime
#define FIONBIO 1
#define FIONREAD 2
#define SOCKET_ERROR -1
// send()/recv()/etc flags
// at present, only MSG_PEEK is implemented though.
#define MSG_WAITALL 0x40000000
#define MSG_TRUNC 0x20000000
#define MSG_PEEK 0x10000000
#define MSG_OOB 0x08000000
#define MSG_EOR 0x04000000
#define MSG_DONTROUTE 0x02000000
#define MSG_CTRUNC 0x01000000
#define MSG_DONTROUTE 0x02000000
#define MSG_EOR 0x04000000
#define MSG_OOB 0x08000000
#define MSG_PEEK 0x10000000
#define MSG_TRUNC 0x20000000
#define MSG_WAITALL 0x40000000
// shutdown() flags:
#define SHUT_RD 1
#define SHUT_WR 2
#define SHUT_RDWR 3
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
/*
* Option flags per-socket.
*/
#define SO_DEBUG 0x0001 /* turn on debugging info recording */
#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
#define SO_REUSEADDR 0x0004 /* allow local address reuse */
#define SO_KEEPALIVE 0x0008 /* keep connections alive */
#define SO_DONTROUTE 0x0010 /* just use interface addresses */
#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
#define SO_LINGER 0x0080 /* linger on close if data present */
#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */
#define SO_DEBUG 0x0001
#define SO_ACCEPTCONN 0x0002
#define SO_REUSEADDR 0x0004
#define SO_KEEPALIVE 0x0008
#define SO_DONTROUTE 0x0010
#define SO_BROADCAST 0x0020
#define SO_USELOOPBACK 0x0040
#define SO_LINGER 0x0080
#define SO_OOBINLINE 0x0100
#define SO_REUSEPORT 0x0200
#define SO_SNDBUF 0x1001
#define SO_RCVBUF 0x1002
#define SO_SNDLOWAT 0x1003
#define SO_RCVLOWAT 0x1004
#define SO_SNDTIMEO 0x1005
#define SO_RCVTIMEO 0x1006
#define SO_ERROR 0x1007
#define SO_TYPE 0x1008
#define SO_DONTLINGER (int)(~SO_LINGER)
/*
* Additional options, not kept in so_options.
*/
#define SO_SNDBUF 0x1001 /* send buffer size */
#define SO_RCVBUF 0x1002 /* receive buffer size */
#define SO_SNDLOWAT 0x1003 /* send low-water mark */
#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
#define SO_SNDTIMEO 0x1005 /* send timeout */
#define SO_RCVTIMEO 0x1006 /* receive timeout */
#define SO_ERROR 0x1007 /* get error status and clear */
#define SO_TYPE 0x1008 /* get socket type */
typedef uint32_t socklen_t;
typedef uint16_t sa_family_t;
struct sockaddr {
unsigned short sa_family;
char sa_data[14];
sa_family_t sa_family;
char sa_data[];
};
#ifndef ntohs
#define ntohs(num) htons(num)
#define ntohl(num) htonl(num)
#endif
struct sockaddr_storage {
sa_family_t ss_family;
char __ss_padding[14];
};
struct linger {
int l_onoff;
int l_linger;
};
#ifdef __cplusplus
extern "C" {
#endif
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
int closesocket(int sockfd);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
int listen(int sockfd, int backlog);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
int shutdown(int sockfd, int how);
int socket(int domain, int type, int protocol);
int bind(int socket, const struct sockaddr * addr, int addr_len);
int connect(int socket, const struct sockaddr * addr, int addr_len);
int send(int socket, const void * data, int sendlength, int flags);
int recv(int socket, void * data, int recvlength, int flags);
int sendto(int socket, const void * data, int sendlength, int flags, const struct sockaddr * addr, int addr_len);
int recvfrom(int socket, void * data, int recvlength, int flags, struct sockaddr * addr, int * addr_len);
int listen(int socket, int max_connections);
int accept(int socket, struct sockaddr * addr, int * addr_len);
int shutdown(int socket, int shutdown_type);
int closesocket(int socket);
int ioctl(int socket, long cmd, void * arg);
int setsockopt(int socket, int level, int option_name, const void * data, int data_len);
int getsockopt(int socket, int level, int option_name, void * data, int * data_len);
int getpeername(int socket, struct sockaddr *addr, int * addr_len);
int getsockname(int socket, struct sockaddr *addr, int * addr_len);
int gethostname(char *name, size_t len);
int sethostname(const char *name, size_t len);
unsigned short htons(unsigned short num);
unsigned long htonl(unsigned long num);
extern int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);
int sockatmark(int sockfd);
#ifdef __cplusplus
};
}
#endif
#endif // SYS_SOCKET_H

View File

@ -1,856 +0,0 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <3ds.h>
Handle SOCU_handle = 0;
static int SOCU_errno = 0;
static Handle socMemhandle = 0;
#define NET_UNKNOWN_ERROR_OFFSET -10000//This is from libogc network_wii.c.
static u8 _net_error_code_map[] = { //This is based on the array from libogc network_wii.c.
0, // 0
E2BIG,
EACCES,
EADDRINUSE,
EADDRNOTAVAIL,
EAFNOSUPPORT, // 5
EAGAIN,
EALREADY,
EBADF,
EBADMSG,
EBUSY, // 10
ECANCELED,
ECHILD,
ECONNABORTED,
ECONNREFUSED,
ECONNRESET, // 15
EDEADLK,
EDESTADDRREQ,
EDOM,
EDQUOT,
EEXIST, // 20
EFAULT,
EFBIG,
EHOSTUNREACH,
EIDRM,
EILSEQ, // 25
EINPROGRESS,
EINTR,
EINVAL,
EIO,
EISCONN, // 30
EISDIR,
ELOOP,
EMFILE,
EMLINK,
EMSGSIZE, // 35
EMULTIHOP,
ENAMETOOLONG,
ENETDOWN,
ENETRESET,
ENETUNREACH, // 40
ENFILE,
ENOBUFS,
ENODATA,
ENODEV,
ENOENT, // 45
ENOEXEC,
ENOLCK,
ENOLINK,
ENOMEM,
ENOMSG, // 50
ENOPROTOOPT,
ENOSPC,
ENOSR,
ENOSTR,
ENOSYS, // 55
ENOTCONN,
ENOTDIR,
ENOTEMPTY,
ENOTSOCK,
ENOTSUP, // 60
ENOTTY,
ENXIO,
EOPNOTSUPP,
EOVERFLOW,
EPERM, // 65
EPIPE,
EPROTO,
EPROTONOSUPPORT,
EPROTOTYPE,
ERANGE, // 70
EROFS,
ESPIPE,
ESRCH,
ESTALE,
ETIME, // 75
ETIMEDOUT,
};
static s32 _net_convert_error(s32 sock_retval)//This is based on the function from libogc network_wii.c.
{
if (sock_retval >= 0) return sock_retval;
if (sock_retval < -sizeof(_net_error_code_map)
|| !_net_error_code_map[-sock_retval])
return NET_UNKNOWN_ERROR_OFFSET + sock_retval;
return -_net_error_code_map[-sock_retval];
}
Result socu_cmd1(Handle memhandle, u32 memsize)
{
Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00010044;
cmdbuf[1] = memsize;
cmdbuf[2] = 0x20;
cmdbuf[4] = 0;
cmdbuf[5] = memhandle;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
return cmdbuf[1];
}
Result SOC_Shutdown()
{
Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00190000;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
svcCloseHandle(SOCU_handle);
svcCloseHandle(socMemhandle);
return cmdbuf[1];
}
Result SOC_Initialize(u32 *context_addr, u32 context_size)
{
Result ret=0;
ret = svcCreateMemoryBlock(&socMemhandle, (u32)context_addr, context_size, 0, 3);
if(ret!=0)return ret;
if((ret = srvGetServiceHandle(&SOCU_handle, "soc:U"))!=0)return ret;
return socu_cmd1(socMemhandle, context_size);
}
int SOC_GetErrno()
{
return SOCU_errno;
}
int socket(int domain, int type, int protocol)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000200C2;
cmdbuf[1] = domain;
cmdbuf[2] = type;
cmdbuf[3] = protocol;
cmdbuf[4] = 0x20;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
SOCU_errno = ret;
if(ret!=0)return -1;
return _net_convert_error(cmdbuf[2]);
}
int closesocket(int sockfd)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000B0042;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x20;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret =_net_convert_error(cmdbuf[2]);
SOCU_errno = ret;
if(ret!=0)return -1;
return 0;
}
int shutdown(int sockfd, int shutdown_type)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000C0082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)shutdown_type;
cmdbuf[3] = 0x20;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
SOCU_errno = ret;
if(ret!=0)return -1;
return 0;
}
int listen(int sockfd, int max_connections)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00030082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)max_connections;
cmdbuf[3] = 0x20;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
SOCU_errno = ret;
if(ret!=0)return -1;
return 0;
}
int accept(int sockfd, struct sockaddr *addr, int *addrlen)
{
int ret=0;
int tmp_addrlen=0x1c;
u32 *cmdbuf = getThreadCommandBuffer();
u8 tmpaddr[0x1c];
u32 saved_threadstorage[2];
memset(tmpaddr, 0, 0x1c);
cmdbuf[0] = 0x00040082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)tmp_addrlen;
cmdbuf[3] = 0x20;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = (tmp_addrlen<<14) | 2;
cmdbuf[0x104>>2] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret>=0 && addr!=NULL)
{
addr->sa_family = tmpaddr[1];
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
}
if(ret<0)return -1;
return ret;
}
int bind(int sockfd, const struct sockaddr *addr, int addrlen)
{
int ret=0;
int tmp_addrlen=0;
u32 *cmdbuf = getThreadCommandBuffer();
u8 tmpaddr[0x1c];
memset(tmpaddr, 0, 0x1c);
if(addr->sa_family == AF_INET)
{
tmp_addrlen = 8;
}
else
{
tmp_addrlen = 0x1c;
}
if(addrlen < tmp_addrlen)
{
SOCU_errno = -EINVAL;
return -1;
}
tmpaddr[0] = tmp_addrlen;
tmpaddr[1] = addr->sa_family;
memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2);
cmdbuf[0] = 0x00050084;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)tmp_addrlen;
cmdbuf[3] = 0x20;
cmdbuf[5] = (((u32)tmp_addrlen)<<14) | 2;
cmdbuf[6] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
SOCU_errno = ret;
if(ret<0)return -1;
return 0;
}
int connect(int sockfd, const struct sockaddr *addr, int addrlen)
{
int ret=0;
int tmp_addrlen=0;
u32 *cmdbuf = getThreadCommandBuffer();
u8 tmpaddr[0x1c];
memset(tmpaddr, 0, 0x1c);
if(addr->sa_family == AF_INET)
{
tmp_addrlen = 8;
}
else
{
tmp_addrlen = 0x1c;
}
if(addrlen < tmp_addrlen)
{
SOCU_errno = -EINVAL;
return -1;
}
tmpaddr[0] = tmp_addrlen;
tmpaddr[1] = addr->sa_family;
memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2);
cmdbuf[0] = 0x00060084;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)addrlen;
cmdbuf[3] = 0x20;
cmdbuf[5] = (((u32)tmp_addrlen)<<14) | 2;
cmdbuf[6] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
SOCU_errno = ret;
if(ret<0)return -1;
return 0;
}
int socuipc_cmd7(int sockfd, void *buf, int len, int flags, struct sockaddr *src_addr, int *addrlen)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 tmp_addrlen=0;
u8 tmpaddr[0x1c];
u32 saved_threadstorage[2];
memset(tmpaddr, 0, 0x1c);
if(src_addr)tmp_addrlen = 0x1c;
cmdbuf[0] = 0x00070104;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)len;
cmdbuf[3] = (u32)flags;
cmdbuf[4] = (u32)tmp_addrlen;
cmdbuf[5] = 0x20;
cmdbuf[7] = (((u32)len)<<4) | 12;
cmdbuf[8] = (u32)buf;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = (tmp_addrlen<<14) | 2;
cmdbuf[0x104>>2] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret>0 && src_addr!=NULL)
{
src_addr->sa_family = tmpaddr[1];
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
}
if(ret<0)return -1;
return ret;
}
int socuipc_cmd8(int sockfd, void *buf, int len, int flags, struct sockaddr *src_addr, int *addrlen)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 tmp_addrlen=0;
u8 tmpaddr[0x1c];
u32 saved_threadstorage[4];
if(src_addr)tmp_addrlen = 0x1c;
memset(tmpaddr, 0, 0x1c);
cmdbuf[0] = 0x00080102;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)len;
cmdbuf[3] = (u32)flags;
cmdbuf[4] = (u32)tmp_addrlen;
cmdbuf[5] = 0x20;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
saved_threadstorage[2] = cmdbuf[0x108>>2];
saved_threadstorage[3] = cmdbuf[0x10c>>2];
cmdbuf[0x100>>2] = (((u32)len)<<14) | 2;
cmdbuf[0x104>>2] = (u32)buf;
cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2;
cmdbuf[0x10c>>2] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
cmdbuf[0x108>>2] = saved_threadstorage[2];
cmdbuf[0x10c>>2] = saved_threadstorage[3];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret>0 && src_addr!=NULL)
{
src_addr->sa_family = tmpaddr[1];
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
}
if(ret<0)return -1;
return ret;
}
int socuipc_cmd9(int sockfd, const void *buf, int len, int flags, const struct sockaddr *dest_addr, int addrlen)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 tmp_addrlen=0;
u8 tmpaddr[0x1c];
memset(tmpaddr, 0, 0x1c);
if(dest_addr)
{
if(dest_addr->sa_family == AF_INET)
{
tmp_addrlen = 8;
}
else
{
tmp_addrlen = 0x1c;
}
if(addrlen < tmp_addrlen)
{
SOCU_errno = -EINVAL;
return -1;
}
tmpaddr[0] = tmp_addrlen;
tmpaddr[1] = dest_addr->sa_family;
memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2);
}
cmdbuf[0] = 0x00090106;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)len;
cmdbuf[3] = (u32)flags;
cmdbuf[4] = (u32)tmp_addrlen;
cmdbuf[5] = 0x20;
cmdbuf[7] = (tmp_addrlen<<14) | 0x402;
cmdbuf[8] = (u32)tmpaddr;
cmdbuf[9] = (((u32)len)<<4) | 10;
cmdbuf[10] = (u32)buf;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret<0)return -1;
return ret;
}
int socuipc_cmda(int sockfd, const void *buf, int len, int flags, const struct sockaddr *dest_addr, int addrlen)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 tmp_addrlen=0;
u8 tmpaddr[0x1c];
memset(tmpaddr, 0, 0x1c);
if(dest_addr)
{
if(dest_addr->sa_family == AF_INET)
{
tmp_addrlen = 8;
}
else
{
tmp_addrlen = 0x1c;
}
if(addrlen < tmp_addrlen)
{
SOCU_errno = -EINVAL;
return -1;
}
tmpaddr[0] = tmp_addrlen;
tmpaddr[1] = dest_addr->sa_family;
memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2);
}
cmdbuf[0] = 0x000A0106;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)len;
cmdbuf[3] = (u32)flags;
cmdbuf[4] = (u32)tmp_addrlen;
cmdbuf[5] = 0x20;
cmdbuf[7] = (((u32)len)<<14) | 0x802;
cmdbuf[8] = (u32)buf;
cmdbuf[9] = (tmp_addrlen<<14) | 0x402;
cmdbuf[10] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret<0)return -1;
return ret;
}
int recvfrom(int sockfd, void *buf, int len, int flags, struct sockaddr *src_addr, int *addrlen)
{
if(len<0x2000)return socuipc_cmd8(sockfd, buf, len, flags, src_addr, addrlen);
return socuipc_cmd7(sockfd, buf, len, flags, src_addr, addrlen);
}
int sendto(int sockfd, const void *buf, int len, int flags, const struct sockaddr *dest_addr, int addrlen)
{
if(len<0x2000)return socuipc_cmda(sockfd, buf, len, flags, dest_addr, addrlen);
return socuipc_cmd9(sockfd, buf, len, flags, (struct sockaddr*)dest_addr, addrlen);
}
int recv(int sockfd, void *buf, int len, int flags)
{
return recvfrom(sockfd, buf, len, flags, NULL, 0);
}
int send(int sockfd, const void *buf, int len, int flags)
{
return sendto(sockfd, buf, len, flags, NULL, 0);
}
int getsockopt(int sockfd, int level, int option_name, void * data, int * data_len)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
cmdbuf[0] = 0x00110102;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)level;
cmdbuf[3] = (u32)option_name;
cmdbuf[4] = (u32)*data_len;
cmdbuf[5] = 0x20;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = ((*data_len)<<14) | 2;
cmdbuf[0x104>>2] = (u32)data;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret==0)*data_len = cmdbuf[3];
if(ret<0)return -1;
return ret;
}
int setsockopt(int sockfd, int level, int option_name, const void * data, int data_len)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00120104;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)level;
cmdbuf[3] = (u32)option_name;
cmdbuf[4] = (u32)data_len;
cmdbuf[5] = 0x20;
cmdbuf[7] = (data_len<<14) | 0x2402;
cmdbuf[8] = (u32)data;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret<0)return -1;
return ret;
}
int fcntl(int sockfd, int cmd, ...)
{
int ret=0;
int arg=0;
u32 *cmdbuf = getThreadCommandBuffer();
va_list args;
if(cmd!=F_GETFL && cmd!=F_SETFL)
{
SOCU_errno = -EINVAL;
return -1;
}
va_start(args, cmd);
if(cmd==F_SETFL)
{
arg = va_arg(args, int);
if(arg && arg!=O_NONBLOCK)
{
SOCU_errno = -EINVAL;
va_end(args);
return -1;
}
if(arg==O_NONBLOCK)arg = 0x4;
}
va_end(args);
cmdbuf[0] = 0x001300C2;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)cmd;
cmdbuf[3] = (u32)arg;
cmdbuf[4] = 0x20;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret<0)return -1;
return ret;
}
int sockatmark(int sockfd)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00150042;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x20;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret<0)return -1;
return ret;
}
long gethostid()
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00160000;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = cmdbuf[2];
return ret;
}
int getsockname(int sockfd, struct sockaddr *addr, int * addr_len)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
u8 tmpaddr[0x1c];
cmdbuf[0] = 0x00170082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x1c;
cmdbuf[3] = 0x20;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = (0x1c<<14) | 2;
cmdbuf[0x104>>2] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret==0)
{
addr->sa_family = tmpaddr[1];
if(*addr_len > tmpaddr[0])*addr_len = tmpaddr[0];
memset(addr, 0, sizeof(struct sockaddr));
memcpy(addr->sa_data, &tmpaddr[2], *addr_len - 2);
}
if(ret<0)return -1;
return ret;
}
int getpeername(int sockfd, struct sockaddr *addr, int * addr_len)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
u8 tmpaddr[0x1c];
cmdbuf[0] = 0x00180082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x1c;
cmdbuf[3] = 0x20;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = (0x1c<<14) | 2;
cmdbuf[0x104>>2] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret==0)
{
addr->sa_family = tmpaddr[1];
if(*addr_len > tmpaddr[0])*addr_len = tmpaddr[0];
memset(addr, 0, sizeof(struct sockaddr));
memcpy(addr->sa_data, &tmpaddr[2], *addr_len - 2);
}
if(ret<0)return -1;
return ret;
}
#define MAX_HOSTENT_RESULTS 16
static struct hostent SOC_hostent;
static char *SOC_hostent_results[MAX_HOSTENT_RESULTS+1];
static char *SOC_hostent_alias = NULL;
struct hostent * gethostbyname(const char * name)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
static u8 outbuf[0x1A88];
cmdbuf[0] = 0x000D0082;
cmdbuf[1] = strlen(name)+1;
cmdbuf[2] = sizeof(outbuf);
cmdbuf[3] = ((strlen(name)+1) << 14) | 0xC02;
cmdbuf[4] = (u32)name;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = (sizeof(outbuf) << 14) | 2;
cmdbuf[0x104>>2] = (u32)outbuf;
if(( ret = svcSendSyncRequest(SOCU_handle))!=0)return NULL;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret<0)return NULL;
u32 num_results, i;
memcpy(&num_results, (char*)outbuf+4, sizeof(num_results));
if(num_results > MAX_HOSTENT_RESULTS)
num_results = MAX_HOSTENT_RESULTS;
SOC_hostent.h_name = (char*)outbuf + 8;
SOC_hostent.h_aliases = &SOC_hostent_alias;
SOC_hostent.h_addrtype = AF_INET;
SOC_hostent.h_length = 4;
SOC_hostent.h_addr_list = SOC_hostent_results;
SOC_hostent_alias = NULL;
for(i = 0; i < num_results; ++i)
SOC_hostent_results[i] = (char*)outbuf + 0x1908 + i*0x10;
SOC_hostent_results[num_results] = NULL;
return &SOC_hostent;
}

View File

@ -0,0 +1,43 @@
#include "soc_common.h"
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
int ret=0;
int tmp_addrlen=0x1c;
u32 *cmdbuf = getThreadCommandBuffer();
u8 tmpaddr[0x1c];
u32 saved_threadstorage[2];
memset(tmpaddr, 0, 0x1c);
cmdbuf[0] = 0x00040082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)tmp_addrlen;
cmdbuf[3] = 0x20;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = (tmp_addrlen<<14) | 2;
cmdbuf[0x104>>2] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret>=0 && addr!=NULL)
{
addr->sa_family = tmpaddr[1];
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
}
if(ret<0)return -1;
return ret;
}

View File

@ -0,0 +1,48 @@
#include "soc_common.h"
#include <errno.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
int ret=0;
int tmp_addrlen=0;
u32 *cmdbuf = getThreadCommandBuffer();
u8 tmpaddr[0x1c];
memset(tmpaddr, 0, 0x1c);
if(addr->sa_family == AF_INET)
{
tmp_addrlen = 8;
}
else
{
tmp_addrlen = 0x1c;
}
if(addrlen < tmp_addrlen)
{
SOCU_errno = EINVAL;
return -1;
}
tmpaddr[0] = tmp_addrlen;
tmpaddr[1] = addr->sa_family;
memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2);
cmdbuf[0] = 0x00050084;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)tmp_addrlen;
cmdbuf[3] = 0x20;
cmdbuf[5] = (((u32)tmp_addrlen)<<14) | 2;
cmdbuf[6] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
SOCU_errno = ret;
if(ret<0)return -1;
return 0;
}

View File

@ -0,0 +1,21 @@
#include "soc_common.h"
#include <sys/socket.h>
int closesocket(int sockfd)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000B0042;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x20;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret =_net_convert_error(cmdbuf[2]);
SOCU_errno = ret;
if(ret!=0)return -1;
return 0;
}

View File

@ -0,0 +1,104 @@
#include "soc_common.h"
#include <errno.h>
Handle SOCU_handle = 0;
int SOCU_errno = 0;
Handle socMemhandle = 0;
//This is based on the array from libogc network_wii.c.
static u8 _net_error_code_map[] = {
0, // 0
E2BIG,
EACCES,
EADDRINUSE,
EADDRNOTAVAIL,
EAFNOSUPPORT, // 5
EAGAIN,
EALREADY,
EBADF,
EBADMSG,
EBUSY, // 10
ECANCELED,
ECHILD,
ECONNABORTED,
ECONNREFUSED,
ECONNRESET, // 15
EDEADLK,
EDESTADDRREQ,
EDOM,
EDQUOT,
EEXIST, // 20
EFAULT,
EFBIG,
EHOSTUNREACH,
EIDRM,
EILSEQ, // 25
EINPROGRESS,
EINTR,
EINVAL,
EIO,
EISCONN, // 30
EISDIR,
ELOOP,
EMFILE,
EMLINK,
EMSGSIZE, // 35
EMULTIHOP,
ENAMETOOLONG,
ENETDOWN,
ENETRESET,
ENETUNREACH, // 40
ENFILE,
ENOBUFS,
ENODATA,
ENODEV,
ENOENT, // 45
ENOEXEC,
ENOLCK,
ENOLINK,
ENOMEM,
ENOMSG, // 50
ENOPROTOOPT,
ENOSPC,
ENOSR,
ENOSTR,
ENOSYS, // 55
ENOTCONN,
ENOTDIR,
ENOTEMPTY,
ENOTSOCK,
ENOTSUP, // 60
ENOTTY,
ENXIO,
EOPNOTSUPP,
EOVERFLOW,
EPERM, // 65
EPIPE,
EPROTO,
EPROTONOSUPPORT,
EPROTOTYPE,
ERANGE, // 70
EROFS,
ESPIPE,
ESRCH,
ESTALE,
ETIME, // 75
ETIMEDOUT,
};
#define NET_UNKNOWN_ERROR_OFFSET -10000//This is from libogc network_wii.c.
//This is based on the function from libogc network_wii.c.
s32 _net_convert_error(s32 sock_retval)
{
if (sock_retval >= 0) return sock_retval;
if (sock_retval < -sizeof(_net_error_code_map)
|| !_net_error_code_map[-sock_retval])
return NET_UNKNOWN_ERROR_OFFSET + sock_retval;
return -_net_error_code_map[-sock_retval];
}
int SOC_GetErrno(void)
{
return SOCU_errno;
}

View File

@ -0,0 +1,9 @@
#pragma once
#include <3ds.h>
extern Handle SOCU_handle;
extern int SOCU_errno;
extern Handle socMemhandle;
s32 _net_convert_error(s32 sock_retval);

View File

@ -0,0 +1,48 @@
#include "soc_common.h"
#include <errno.h>
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
int ret=0;
int tmp_addrlen=0;
u32 *cmdbuf = getThreadCommandBuffer();
u8 tmpaddr[0x1c];
memset(tmpaddr, 0, 0x1c);
if(addr->sa_family == AF_INET)
{
tmp_addrlen = 8;
}
else
{
tmp_addrlen = 0x1c;
}
if(addrlen < tmp_addrlen)
{
SOCU_errno = -EINVAL;
return -1;
}
tmpaddr[0] = tmp_addrlen;
tmpaddr[1] = addr->sa_family;
memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2);
cmdbuf[0] = 0x00060084;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)addrlen;
cmdbuf[3] = 0x20;
cmdbuf[5] = (((u32)tmp_addrlen)<<14) | 2;
cmdbuf[6] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
SOCU_errno = ret;
if(ret<0)return -1;
return 0;
}

View File

@ -0,0 +1,50 @@
#include "soc_common.h"
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
int fcntl(int fd, int cmd, ...)
{
int ret=0;
int arg=0;
u32 *cmdbuf = getThreadCommandBuffer();
va_list args;
if(cmd!=F_GETFL && cmd!=F_SETFL)
{
SOCU_errno = -EINVAL;
return -1;
}
va_start(args, cmd);
if(cmd==F_SETFL)
{
arg = va_arg(args, int);
if(arg && arg!=O_NONBLOCK)
{
SOCU_errno = -EINVAL;
va_end(args);
return -1;
}
if(arg==O_NONBLOCK)arg = 0x4;
}
va_end(args);
cmdbuf[0] = 0x001300C2;
cmdbuf[1] = (u32)fd;
cmdbuf[2] = (u32)cmd;
cmdbuf[3] = (u32)arg;
cmdbuf[4] = 0x20;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret<0)return -1;
return ret;
}

View File

@ -0,0 +1,60 @@
#include "soc_common.h"
#include <netdb.h>
#define MAX_HOSTENT_RESULTS 16
static struct hostent SOC_hostent;
static char *SOC_hostent_results[MAX_HOSTENT_RESULTS+1];
static char *SOC_hostent_alias = NULL;
int h_errno = 0;
struct hostent* gethostbyname(const char *name)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
static u8 outbuf[0x1A88];
cmdbuf[0] = 0x000D0082;
cmdbuf[1] = strlen(name)+1;
cmdbuf[2] = sizeof(outbuf);
cmdbuf[3] = ((strlen(name)+1) << 14) | 0xC02;
cmdbuf[4] = (u32)name;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = (sizeof(outbuf) << 14) | 2;
cmdbuf[0x104>>2] = (u32)outbuf;
if(( ret = svcSendSyncRequest(SOCU_handle))!=0)return NULL;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
/* TODO: set h_errno based on SOCU_errno */
if(ret<0)return NULL;
u32 num_results, i;
memcpy(&num_results, (char*)outbuf+4, sizeof(num_results));
if(num_results > MAX_HOSTENT_RESULTS)
num_results = MAX_HOSTENT_RESULTS;
SOC_hostent.h_name = (char*)outbuf + 8;
SOC_hostent.h_aliases = &SOC_hostent_alias;
SOC_hostent.h_addrtype = AF_INET;
SOC_hostent.h_length = 4;
SOC_hostent.h_addr_list = SOC_hostent_results;
SOC_hostent_alias = NULL;
for(i = 0; i < num_results; ++i)
SOC_hostent_results[i] = (char*)outbuf + 0x1908 + i*0x10;
SOC_hostent_results[num_results] = NULL;
return &SOC_hostent;
}

View File

@ -0,0 +1,16 @@
#include "soc_common.h"
long gethostid(void)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00160000;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = cmdbuf[2];
return ret;
}

View File

@ -0,0 +1,41 @@
#include "soc_common.h"
#include <sys/socket.h>
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
u8 tmpaddr[0x1c];
cmdbuf[0] = 0x00180082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x1c;
cmdbuf[3] = 0x20;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = (0x1c<<14) | 2;
cmdbuf[0x104>>2] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret==0)
{
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
memset(addr, 0, sizeof(struct sockaddr));
addr->sa_family = tmpaddr[1];
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
}
if(ret<0)return -1;
return ret;
}

View File

@ -0,0 +1,41 @@
#include "soc_common.h"
#include <sys/socket.h>
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
u8 tmpaddr[0x1c];
cmdbuf[0] = 0x00170082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x1c;
cmdbuf[3] = 0x20;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = (0x1c<<14) | 2;
cmdbuf[0x104>>2] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret==0)
{
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
memset(addr, 0, sizeof(struct sockaddr));
addr->sa_family = tmpaddr[1];
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
}
if(ret<0)return -1;
return ret;
}

View File

@ -0,0 +1,36 @@
#include "soc_common.h"
#include <sys/socket.h>
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
cmdbuf[0] = 0x00110102;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)level;
cmdbuf[3] = (u32)optname;
cmdbuf[4] = (u32)*optlen;
cmdbuf[5] = 0x20;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = ((*optlen)<<14) | 2;
cmdbuf[0x104>>2] = (u32)optval;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret==0)*optlen = cmdbuf[3];
if(ret<0)return -1;
return ret;
}

View File

@ -0,0 +1,9 @@
#include "soc_common.h"
#include <arpa/inet.h>
in_addr_t inet_addr(const char *cp)
{
struct in_addr addr = { .s_addr = INADDR_BROADCAST };
inet_aton(cp, &addr);
return addr.s_addr;
}

View File

@ -0,0 +1,85 @@
#include "soc_common.h"
#include <arpa/inet.h>
#include <ctype.h>
#include <stdint.h>
int inet_aton(const char *cp, struct in_addr *inp)
{
int base;
uint32_t val;
int c;
char bytes[4];
size_t num_bytes = 0;
c = *cp;
for(;;) {
if(!isdigit(c)) return 0;
val = 0;
base = 10;
if(c == '0') {
c = *++cp;
if(c == 'x' || c == 'X') {
base = 16;
c = *++cp;
}
else base = 8;
}
for(;;) {
if(isdigit(c)) {
if(base == 8 && c >= '8') return 0;
val *= base;
val += c - '0';
c = *++cp;
}
else if(base == 16 && isxdigit(c)) {
val *= base;
val += c + 10 - (islower(c) ? 'a' : 'A');
c = *++cp;
}
else break;
}
if(c == '.') {
if(num_bytes > 3) return 0;
if(val > 0xFF) return 0;
bytes[num_bytes++] = val;
c = *++cp;
}
else break;
}
if(c != 0) return 0;
switch(num_bytes) {
case 0:
return 0;
case 1:
break;
case 2:
if(val > 0xFFFFFF) return 0;
val |= bytes[0] << 24;
break;
case 3:
if(val > 0xFFFF) return 0;
val |= bytes[0] << 24;
val |= bytes[1] << 16;
break;
case 4:
if(val > 0xFF) return 0;
val |= bytes[0] << 24;
val |= bytes[1] << 16;
val |= bytes[2] << 8;
break;
}
if(inp)
inp->s_addr = htonl(val);
return 1;
}

View File

@ -0,0 +1,32 @@
#include "soc_common.h"
#include <arpa/inet.h>
#include <netinet/in.h>
static char buffer[INET_ADDRSTRLEN];
char* inet_ntoa(struct in_addr in)
{
unsigned char *addrbuf = (unsigned char*)&in;
char *p;
size_t i;
unsigned int n;
memset(buffer, 0, sizeof(buffer));
for(p = buffer, i = 0; i < 4; ++i) {
if(i > 0) *p++ = '.';
n = addrbuf[i];
if(n >= 100) {
*p++ = n/100 + '0';
n %= 100;
}
if(n >= 10 || addrbuf[i] >= 100) {
*p++ = n/10 + '0';
n %= 10;
}
*p++ = n + '0';
}
*p = 0;
return buffer;
}

View File

@ -0,0 +1,44 @@
#include "soc_common.h"
static Result socu_cmd1(Handle memhandle, u32 memsize)
{
Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00010044;
cmdbuf[1] = memsize;
cmdbuf[2] = 0x20;
cmdbuf[4] = 0;
cmdbuf[5] = memhandle;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
return cmdbuf[1];
}
Result SOC_Initialize(u32 *context_addr, u32 context_size)
{
Result ret=0;
ret = svcCreateMemoryBlock(&socMemhandle, (u32)context_addr, context_size, 0, 3);
if(ret!=0)return ret;
if((ret = srvGetServiceHandle(&SOCU_handle, "soc:U"))!=0)return ret;
return socu_cmd1(socMemhandle, context_size);
}
Result SOC_Shutdown(void)
{
Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00190000;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
svcCloseHandle(SOCU_handle);
svcCloseHandle(socMemhandle);
return cmdbuf[1];
}

View File

@ -0,0 +1,37 @@
#include "soc_common.h"
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sys/ioctl.h>
int ioctl(int fd, int request, ...)
{
int ret;
int flags;
int *value;
va_list ap;
va_start(ap, request);
switch(request) {
case FIONBIO:
value = va_arg(ap, int*);
if(value == NULL) ret = -1;
else if(*value) {
flags = fcntl(fd, F_GETFL, 0);
ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
else {
flags = fcntl(fd, F_GETFL, 0);
ret = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
}
break;
default:
errno = ENOTTY;
ret = -1;
break;
}
return ret;
}

View File

@ -0,0 +1,22 @@
#include "soc_common.h"
#include <sys/socket.h>
int listen(int sockfd, int max_connections)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00030082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)max_connections;
cmdbuf[3] = 0x20;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
SOCU_errno = ret;
if(ret!=0)return -1;
return 0;
}

View File

@ -0,0 +1,35 @@
#include "soc_common.h"
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfsd, int timeout)
{
int ret = 0;
u32 size = sizeof(struct pollfd)*nfsd;
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
cmdbuf[0] = 0x00140084;
cmdbuf[1] = (u32)nfsd;
cmdbuf[2] = (u32)timeout;
cmdbuf[3] = 0x20;
cmdbuf[5] = (size<<14) | 0x2802;
cmdbuf[6] = (u32)fds;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = (size<<14) | 2;
cmdbuf[0x104>>2] = (u32)fds;
if((ret = svcSendSyncRequest(SOCU_handle)) != 0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret<0)return -1;
return ret;
}

View File

@ -0,0 +1,7 @@
#include "soc_common.h"
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags)
{
return recvfrom(sockfd, buf, len, flags, NULL, 0);
}

View File

@ -0,0 +1,107 @@
#include "soc_common.h"
#include <sys/socket.h>
ssize_t socuipc_cmd7(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 tmp_addrlen=0;
u8 tmpaddr[0x1c];
u32 saved_threadstorage[2];
memset(tmpaddr, 0, 0x1c);
if(src_addr)tmp_addrlen = 0x1c;
cmdbuf[0] = 0x00070104;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)len;
cmdbuf[3] = (u32)flags;
cmdbuf[4] = (u32)tmp_addrlen;
cmdbuf[5] = 0x20;
cmdbuf[7] = (((u32)len)<<4) | 12;
cmdbuf[8] = (u32)buf;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = (tmp_addrlen<<14) | 2;
cmdbuf[0x104>>2] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret>0 && src_addr!=NULL)
{
src_addr->sa_family = tmpaddr[1];
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
}
if(ret<0)return -1;
return ret;
}
ssize_t socuipc_cmd8(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 tmp_addrlen=0;
u8 tmpaddr[0x1c];
u32 saved_threadstorage[4];
if(src_addr)tmp_addrlen = 0x1c;
memset(tmpaddr, 0, 0x1c);
cmdbuf[0] = 0x00080102;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)len;
cmdbuf[3] = (u32)flags;
cmdbuf[4] = (u32)tmp_addrlen;
cmdbuf[5] = 0x20;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
saved_threadstorage[2] = cmdbuf[0x108>>2];
saved_threadstorage[3] = cmdbuf[0x10c>>2];
cmdbuf[0x100>>2] = (((u32)len)<<14) | 2;
cmdbuf[0x104>>2] = (u32)buf;
cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2;
cmdbuf[0x10c>>2] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
cmdbuf[0x108>>2] = saved_threadstorage[2];
cmdbuf[0x10c>>2] = saved_threadstorage[3];
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret>0 && src_addr!=NULL)
{
src_addr->sa_family = tmpaddr[1];
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
}
if(ret<0)return -1;
return ret;
}
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
{
if(len<0x2000)return socuipc_cmd8(sockfd, buf, len, flags, src_addr, addrlen);
return socuipc_cmd7(sockfd, buf, len, flags, src_addr, addrlen);
}

View File

@ -0,0 +1,90 @@
#include "soc_common.h"
#include <errno.h>
#include <poll.h>
#include <stdlib.h>
#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
{
struct pollfd *pollinfo;
nfds_t numfds = 0;
size_t i, j;
int rc, found;
for(i = 0; i < nfds; ++i) {
if((readfds && FD_ISSET(i, readfds))
|| (writefds && FD_ISSET(i, writefds))
|| (exceptfds && FD_ISSET(i, exceptfds)))
++numfds;
}
pollinfo = (struct pollfd*)calloc(numfds, sizeof(struct pollfd));
if(pollinfo == NULL) {
SOCU_errno = ENOMEM;
return -1;
}
for(i = 0, j = 0; i < nfds; ++i) {
if((readfds && FD_ISSET(i, readfds))
|| (writefds && FD_ISSET(i, writefds))
|| (exceptfds && FD_ISSET(i, exceptfds))) {
pollinfo[j].fd = i;
pollinfo[j].events = 0;
pollinfo[j].revents = 0;
if(readfds && FD_ISSET(i, readfds))
pollinfo[j].events |= POLLIN;
if(writefds && FD_ISSET(i, writefds))
pollinfo[j].events |= POLLOUT;
++j;
}
}
if(timeout)
rc = poll(pollinfo, numfds, timeout->tv_sec*1000 + timeout->tv_usec/1000);
else
rc = poll(pollinfo, numfds, -1);
if(rc < 0) {
free(pollinfo);
return rc;
}
for(i = 0, j = 0, rc = 0; i < nfds; ++i) {
found = 0;
if((readfds && FD_ISSET(i, readfds))
|| (writefds && FD_ISSET(i, writefds))
|| (exceptfds && FD_ISSET(i, exceptfds))) {
if(readfds && FD_ISSET(i, readfds)) {
if(pollinfo[j].events & (POLLIN|POLLHUP))
found = 1;
else
FD_CLR(i, readfds);
}
if(writefds && FD_ISSET(i, writefds)) {
if(pollinfo[j].events & (POLLOUT|POLLHUP))
found = 1;
else
FD_CLR(i, writefds);
}
if(exceptfds && FD_ISSET(i, exceptfds)) {
if(pollinfo[j].events & POLLERR)
found = 1;
else
FD_CLR(i, exceptfds);
}
if(found) ++rc;
++j;
}
}
free(pollinfo);
return rc;
}

View File

@ -0,0 +1,7 @@
#include "soc_common.h"
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags)
{
return sendto(sockfd, buf, len, flags, NULL, 0);
}

View File

@ -0,0 +1,113 @@
#include "soc_common.h"
#include <errno.h>
#include <sys/socket.h>
ssize_t socuipc_cmd9(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 tmp_addrlen=0;
u8 tmpaddr[0x1c];
memset(tmpaddr, 0, 0x1c);
if(dest_addr)
{
if(dest_addr->sa_family == AF_INET)
{
tmp_addrlen = 8;
}
else
{
tmp_addrlen = 0x1c;
}
if(addrlen < tmp_addrlen)
{
SOCU_errno = -EINVAL;
return -1;
}
tmpaddr[0] = tmp_addrlen;
tmpaddr[1] = dest_addr->sa_family;
memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2);
}
cmdbuf[0] = 0x00090106;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)len;
cmdbuf[3] = (u32)flags;
cmdbuf[4] = (u32)tmp_addrlen;
cmdbuf[5] = 0x20;
cmdbuf[7] = (tmp_addrlen<<14) | 0x402;
cmdbuf[8] = (u32)tmpaddr;
cmdbuf[9] = (((u32)len)<<4) | 10;
cmdbuf[10] = (u32)buf;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret<0)return -1;
return ret;
}
ssize_t socuipc_cmda(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 tmp_addrlen=0;
u8 tmpaddr[0x1c];
memset(tmpaddr, 0, 0x1c);
if(dest_addr)
{
if(dest_addr->sa_family == AF_INET)
{
tmp_addrlen = 8;
}
else
{
tmp_addrlen = 0x1c;
}
if(addrlen < tmp_addrlen)
{
SOCU_errno = -EINVAL;
return -1;
}
tmpaddr[0] = tmp_addrlen;
tmpaddr[1] = dest_addr->sa_family;
memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2);
}
cmdbuf[0] = 0x000A0106;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)len;
cmdbuf[3] = (u32)flags;
cmdbuf[4] = (u32)tmp_addrlen;
cmdbuf[5] = 0x20;
cmdbuf[7] = (((u32)len)<<14) | 0x802;
cmdbuf[8] = (u32)buf;
cmdbuf[9] = (tmp_addrlen<<14) | 0x402;
cmdbuf[10] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret<0)return -1;
return ret;
}
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
{
if(len<0x2000)return socuipc_cmda(sockfd, buf, len, flags, dest_addr, addrlen);
return socuipc_cmd9(sockfd, buf, len, flags, (struct sockaddr*)dest_addr, addrlen);
}

View File

@ -0,0 +1,26 @@
#include "soc_common.h"
#include <sys/socket.h>
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00120104;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)level;
cmdbuf[3] = (u32)optname;
cmdbuf[4] = (u32)optlen;
cmdbuf[5] = 0x20;
cmdbuf[7] = (optlen<<14) | 0x2402;
cmdbuf[8] = (u32)optval;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret<0)return -1;
return ret;
}

View File

@ -0,0 +1,22 @@
#include "soc_common.h"
#include <sys/socket.h>
int shutdown(int sockfd, int shutdown_type)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000C0082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)shutdown_type;
cmdbuf[3] = 0x20;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
SOCU_errno = ret;
if(ret!=0)return -1;
return 0;
}

View File

@ -0,0 +1,21 @@
#include "soc_common.h"
#include <sys/socket.h>
int sockatmark(int sockfd)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00150042;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x20;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret;
if(ret<0)return -1;
return ret;
}

View File

@ -0,0 +1,22 @@
#include "soc_common.h"
#include <sys/socket.h>
int socket(int domain, int type, int protocol)
{
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000200C2;
cmdbuf[1] = domain;
cmdbuf[2] = type;
cmdbuf[3] = protocol;
cmdbuf[4] = 0x20;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
ret = (int)cmdbuf[1];
SOCU_errno = ret;
if(ret!=0)return -1;
return _net_convert_error(cmdbuf[2]);
}