First attempt at hooking sockets into a devoptab.

This commit is contained in:
mtheall 2015-01-23 14:23:59 -06:00 committed by Dave Murphy
parent 9fec42f38f
commit 4fa477c039
19 changed files with 362 additions and 41 deletions

View File

@ -5,10 +5,37 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
int ret = 0;
int tmp_addrlen = 0x1c;
int fd, dev;
__handle *handle;
u32 *cmdbuf = getThreadCommandBuffer();
u8 tmpaddr[0x1c];
u32 saved_threadstorage[2];
sockfd = soc_get_fd(sockfd);
if(sockfd < 0)
{
SOCU_errno = sockfd;
return -1;
}
dev = FindDevice("soc:");
if(dev < 0)
{
SOCU_errno = -ENODEV;
return -1;
}
fd = __alloc_handle(sizeof(__handle) + sizeof(Handle));
if(fd < 0)
{
SOCU_errno = -ENOMEM;
return -1;
}
handle = __get_handle(fd);
handle->device = dev;
handle->fileStruct = ((void *)handle) + sizeof(__handle);
memset(tmpaddr, 0, 0x1c);
cmdbuf[0] = 0x00040082;
@ -22,22 +49,37 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
cmdbuf[0x100>>2] = (tmp_addrlen<<14) | 2;
cmdbuf[0x104>>2] = (u32)tmpaddr;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
if((ret = svcSendSyncRequest(SOCU_handle)) != 0)
{
__release_handle(fd);
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)
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];
if(*addrlen > tmpaddr[0])
*addrlen = tmpaddr[0];
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
}
if(ret<0)return -1;
return ret;
if(ret < 0)
{
__release_handle(fd);
return -1;
}
else
*(Handle*)handle->fileStruct = ret;
return fd;
}

View File

@ -9,6 +9,13 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
u32 *cmdbuf = getThreadCommandBuffer();
u8 tmpaddr[0x1c];
sockfd = soc_get_fd(sockfd);
if(sockfd < 0)
{
SOCU_errno = sockfd;
return -1;
}
memset(tmpaddr, 0, 0x1c);
if(addr->sa_family == AF_INET)

View File

@ -3,19 +3,12 @@
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 fd = soc_get_fd(sockfd);
if(fd < 0)
{
SOCU_errno = fd;
return -1;
}
return close(sockfd);
}

View File

@ -1,5 +1,6 @@
#include "soc_common.h"
#include <errno.h>
#include <sys/iosupport.h>
Handle SOCU_handle = 0;
int SOCU_errno = 0;

View File

@ -1,13 +1,30 @@
#pragma once
#include <errno.h>
#include <string.h>
#include <sys/iosupport.h>
#include <3ds/types.h>
#include <3ds/svc.h>
#include <3ds/srv.h>
#include <3ds/services/soc.h>
int __alloc_handle(int size);
__handle *__get_handle(int fd);
void __release_handle(int fd);
extern Handle SOCU_handle;
extern int SOCU_errno;
extern Handle socMemhandle;
static inline int
soc_get_fd(int fd)
{
__handle *handle = __get_handle(fd);
if(handle == NULL)
return -ENODEV;
if(strcmp(devoptab_list[handle->device]->name, "soc") != 0)
return -ENOTSOCK;
return *(Handle*)handle->fileStruct;
}
s32 _net_convert_error(s32 sock_retval);

View File

@ -9,6 +9,13 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
u32 *cmdbuf = getThreadCommandBuffer();
u8 tmpaddr[0x1c];
sockfd = soc_get_fd(sockfd);
if(sockfd < 0)
{
SOCU_errno = sockfd;
return -1;
}
memset(tmpaddr, 0, 0x1c);
if(addr->sa_family == AF_INET)

View File

@ -28,7 +28,7 @@ static int to_3ds(int flags)
return newflags;
}
int fcntl(int fd, int cmd, ...)
int fcntl(int sockfd, int cmd, ...)
{
int ret = 0;
int arg = 0;
@ -36,6 +36,13 @@ int fcntl(int fd, int cmd, ...)
va_list args;
sockfd = soc_get_fd(sockfd);
if(sockfd < 0)
{
SOCU_errno = sockfd;
return -1;
}
if(cmd != F_GETFL && cmd != F_SETFL)
{
SOCU_errno = -EINVAL;
@ -60,7 +67,7 @@ int fcntl(int fd, int cmd, ...)
va_end(args);
cmdbuf[0] = 0x001300C2;
cmdbuf[1] = (u32)fd;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)cmd;
cmdbuf[3] = (u32)arg;
cmdbuf[4] = 0x20;

View File

@ -8,6 +8,13 @@ int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
u32 saved_threadstorage[2];
u8 tmpaddr[0x1c];
sockfd = soc_get_fd(sockfd);
if(sockfd < 0)
{
SOCU_errno = sockfd;
return -1;
}
cmdbuf[0] = 0x00180082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x1c;

View File

@ -8,6 +8,13 @@ int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
u32 saved_threadstorage[2];
u8 tmpaddr[0x1c];
sockfd = soc_get_fd(sockfd);
if(sockfd < 0)
{
SOCU_errno = sockfd;
return -1;
}
cmdbuf[0] = 0x00170082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x1c;

View File

@ -7,6 +7,13 @@ int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optl
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
sockfd = soc_get_fd(sockfd);
if(sockfd < 0)
{
SOCU_errno = sockfd;
return -1;
}
cmdbuf[0] = 0x00110102;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)level;

View File

@ -1,4 +1,41 @@
#include "soc_common.h"
#include <sys/socket.h>
static int soc_open(struct _reent *r, void *fileStruct, const char *path, int flags, int mode);
static int soc_close(struct _reent *r, int fd);
static ssize_t soc_write(struct _reent *r, int fd, const char *ptr, size_t len);
static ssize_t soc_read(struct _reent *r, int fd, char *ptr, size_t len);
static devoptab_t
soc_devoptab =
{
.name = "soc",
.structSize = sizeof(Handle),
.open_r = soc_open,
.close_r = soc_close,
.write_r = soc_write,
.read_r = soc_read,
.seek_r = NULL,
.fstat_r = NULL,
.stat_r = NULL,
.link_r = NULL,
.unlink_r = NULL,
.chdir_r = NULL,
.rename_r = NULL,
.mkdir_r = NULL,
.dirStateSize = 0,
.diropen_r = NULL,
.dirreset_r = NULL,
.dirnext_r = NULL,
.dirclose_r = NULL,
.statvfs_r = NULL,
.ftruncate_r = NULL,
.fsync_r = NULL,
.deviceData = NULL,
.chmod_r = NULL,
.fchmod_r = NULL,
};
static Result socu_cmd1(Handle memhandle, u32 memsize)
{
@ -20,18 +57,43 @@ Result SOC_Initialize(u32 *context_addr, u32 context_size)
{
Result ret=0;
/* check that the "soc" device doesn't already exist */
int dev = FindDevice("soc:");
if(dev >= 0)
return -1;
/* add the "soc" device */
dev = AddDevice(&soc_devoptab);
if(dev < 0)
return dev;
ret = svcCreateMemoryBlock(&socMemhandle, (u32)context_addr, context_size, 0, 3);
if(ret!=0)return ret;
if(ret != 0)
{
RemoveDevice("soc");
return ret;
}
if((ret = srvGetServiceHandle(&SOCU_handle, "soc:U"))!=0)return ret;
if((ret = srvGetServiceHandle(&SOCU_handle, "soc:U")) != 0)
{
RemoveDevice("soc");
return ret;
}
return socu_cmd1(socMemhandle, context_size);
if((ret = socu_cmd1(socMemhandle, context_size)) != 0)
{
RemoveDevice("soc");
return ret;
}
return 0;
}
Result SOC_Shutdown(void)
{
Result ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
int dev;
cmdbuf[0] = 0x00190000;
@ -40,5 +102,62 @@ Result SOC_Shutdown(void)
svcCloseHandle(SOCU_handle);
svcCloseHandle(socMemhandle);
dev = FindDevice("soc:");
if(dev >= 0)
RemoveDevice("soc");
return cmdbuf[1];
}
static int
soc_open(struct _reent *r,
void *fileStruct,
const char *path,
int flags,
int mode)
{
return -1;
}
static int
soc_close(struct _reent *r,
int fd)
{
Handle sockfd = *(Handle*)fd;
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;
}
static ssize_t
soc_write(struct _reent *r,
int fd,
const char *ptr,
size_t len)
{
Handle sockfd = *(Handle*)fd;
return send(sockfd, ptr, len, 0);
}
static ssize_t
soc_read(struct _reent *r,
int fd,
char *ptr,
size_t len)
{
Handle sockfd = *(Handle*)fd;
return recv(sockfd, ptr, len, 0);
}

View File

@ -4,13 +4,20 @@
#include <stdarg.h>
#include <sys/ioctl.h>
int ioctl(int fd, int request, ...)
int ioctl(int sockfd, int request, ...)
{
int ret;
int flags;
int *value;
va_list ap;
sockfd = soc_get_fd(sockfd);
if(sockfd < 0)
{
SOCU_errno = sockfd;
return -1;
}
va_start(ap, request);
switch(request) {
@ -22,15 +29,15 @@ int ioctl(int fd, int request, ...)
return -1;
}
flags = fcntl(fd, F_GETFL, 0);
flags = fcntl(sockfd, F_GETFL, 0);
if(flags == -1) {
errno = SOC_GetErrno();
va_end(ap);
return -1;
}
if(*value) ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
else ret = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
if(*value) ret = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
else ret = fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK);
if(ret != 0)
errno = SOC_GetErrno();

View File

@ -6,6 +6,13 @@ int listen(int sockfd, int max_connections)
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
sockfd = soc_get_fd(sockfd);
if(sockfd < 0)
{
SOCU_errno = sockfd;
return -1;
}
cmdbuf[0] = 0x00030082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)max_connections;

View File

@ -1,19 +1,47 @@
#include "soc_common.h"
#include <poll.h>
#include <stdlib.h>
int poll(struct pollfd *fds, nfds_t nfsd, int timeout)
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
int ret = 0;
u32 size = sizeof(struct pollfd)*nfsd;
nfds_t i;
u32 size = sizeof(struct pollfd)*nfds;
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
if(nfds == 0)
{
SOCU_errno = -EINVAL;
return -1;
}
struct pollfd *tmp_fds = (struct pollfd*)malloc(sizeof(struct pollfd) * nfds);
if(tmp_fds == NULL)
{
SOCU_errno = -ENOMEM;
return -1;
}
memcpy(tmp_fds, fds, sizeof(struct pollfd) * nfds);
for(i = 0; i < nfds; ++i)
{
tmp_fds[i].fd = soc_get_fd(fds[i].fd);
if(tmp_fds[i].fd < 0)
{
SOCU_errno = tmp_fds[i].fd;
free(tmp_fds);
return -1;
}
}
cmdbuf[0] = 0x00140084;
cmdbuf[1] = (u32)nfsd;
cmdbuf[1] = (u32)nfds;
cmdbuf[2] = (u32)timeout;
cmdbuf[3] = 0x20;
cmdbuf[5] = (size<<14) | 0x2802;
cmdbuf[6] = (u32)fds;
cmdbuf[6] = (u32)tmp_fds;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
@ -21,7 +49,13 @@ int poll(struct pollfd *fds, nfds_t nfsd, int timeout)
cmdbuf[0x100>>2] = (size<<14) | 2;
cmdbuf[0x104>>2] = (u32)fds;
if((ret = svcSendSyncRequest(SOCU_handle)) != 0)return ret;
if((ret = svcSendSyncRequest(SOCU_handle)) != 0)
{
free(tmp_fds);
return ret;
}
free(tmp_fds);
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];

View File

@ -102,6 +102,13 @@ ssize_t socuipc_cmd8(int sockfd, void *buf, size_t len, int flags, struct sockad
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
{
sockfd = soc_get_fd(sockfd);
if(sockfd < 0)
{
SOCU_errno = sockfd;
return -1;
}
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

@ -108,6 +108,13 @@ ssize_t socuipc_cmda(int sockfd, const void *buf, size_t len, int flags, const s
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
{
sockfd = soc_get_fd(sockfd);
if(sockfd < 0)
{
SOCU_errno = sockfd;
return -1;
}
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

@ -6,6 +6,13 @@ int shutdown(int sockfd, int shutdown_type)
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
sockfd = soc_get_fd(sockfd);
if(sockfd < 0)
{
SOCU_errno = sockfd;
return -1;
}
cmdbuf[0] = 0x000C0082;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = (u32)shutdown_type;

View File

@ -6,6 +6,13 @@ int sockatmark(int sockfd)
int ret=0;
u32 *cmdbuf = getThreadCommandBuffer();
sockfd = soc_get_fd(sockfd);
if(sockfd < 0)
{
SOCU_errno = sockfd;
return -1;
}
cmdbuf[0] = 0x00150042;
cmdbuf[1] = (u32)sockfd;
cmdbuf[2] = 0x20;

View File

@ -1,9 +1,13 @@
#include "soc_common.h"
#include <errno.h>
#include <sys/iosupport.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol)
{
int ret=0;
int fd, dev;
__handle *handle;
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000200C2;
@ -12,11 +16,38 @@ int socket(int domain, int type, int protocol)
cmdbuf[3] = protocol;
cmdbuf[4] = 0x20;
if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;
dev = FindDevice("soc:");
if(dev < 0)
{
SOCU_errno = -ENODEV;
return -1;
}
fd = __alloc_handle(sizeof(__handle) + sizeof(Handle));
if(fd < 0)
{
SOCU_errno = -ENOMEM;
return -1;
}
handle = __get_handle(fd);
handle->device = dev;
handle->fileStruct = ((void *)handle) + sizeof(__handle);
if((ret = svcSendSyncRequest(SOCU_handle)) != 0)
{
__release_handle(fd);
return ret;
}
ret = (int)cmdbuf[1];
SOCU_errno = ret;
if(ret!=0)return -1;
return _net_convert_error(cmdbuf[2]);
if(ret != 0)
{
SOCU_errno = _net_convert_error(cmdbuf[2]);
__release_handle(fd);
return -1;
}
*(Handle*)handle->fileStruct = cmdbuf[2];
return fd;
}