From 8b599e8c8d32bdbbfe5a5ca696d4d9cdff5d5350 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Mon, 28 Jul 2025 03:06:19 -0400 Subject: kernel: net: Add socket syscalls Introduce the following syscalls: - SYS_socket - SYS_bind - SYS_recv - SYS_send Signed-off-by: Ian Moffett --- sys/include/sys/socket.h | 5 +++ sys/include/sys/syscall.h | 4 ++ sys/kern/kern_socket.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++ sys/kern/kern_syscall.c | 5 +++ 4 files changed, 116 insertions(+) diff --git a/sys/include/sys/socket.h b/sys/include/sys/socket.h index 7175da5..f01e2bf 100644 --- a/sys/include/sys/socket.h +++ b/sys/include/sys/socket.h @@ -81,6 +81,11 @@ struct ksocket { struct sockbuf buf; struct mutex *mtx; }; + +scret_t sys_socket(struct syscall_args *scargs); +scret_t sys_bind(struct syscall_args *scargs); +scret_t sys_recv(struct syscall_args *scargs); +scret_t sys_send(struct syscall_args *scargs); #endif /* _KERNEL */ int socket(int domain, int type, int protocol); diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h index 02629a9..51a1016 100644 --- a/sys/include/sys/syscall.h +++ b/sys/include/sys/syscall.h @@ -59,6 +59,10 @@ #define SYS_setuid 18 #define SYS_getuid 19 #define SYS_waitpid 20 +#define SYS_socket 21 +#define SYS_bind 22 +#define SYS_recv 23 +#define SYS_send 24 #if defined(_KERNEL) /* Syscall return value and arg type */ diff --git a/sys/kern/kern_socket.c b/sys/kern/kern_socket.c index 7f58921..a6cc8d2 100644 --- a/sys/kern/kern_socket.c +++ b/sys/kern/kern_socket.c @@ -338,6 +338,108 @@ bind(int sockfd, const struct sockaddr *addr, socklen_t len) return 0; } +/* + * socket(7) syscall + * + * arg0: domain + * arg1: type + * arg2: protocol + */ +scret_t +sys_socket(struct syscall_args *scargs) +{ + int domain = scargs->arg0; + int type = scargs->arg1; + int protocol = scargs->arg2; + + return socket(domain, type, protocol); +} + +/* + * bind(2) syscall + * + * arg0: sockfd + * arg1: addr + * arg2: len + */ +scret_t +sys_bind(struct syscall_args *scargs) +{ + const struct sockaddr *u_addr = (void *)scargs->arg1; + struct sockaddr addr_copy; + int sockfd = scargs->arg0; + int len = scargs->arg2; + int error; + + error = copyin(u_addr, &addr_copy, sizeof(addr_copy)); + if (error < 0) { + return error; + } + + return bind(sockfd, &addr_copy, len); +} + +/* + * recv(2) syscall + * + * arg0: sockfd + * arg1: buf + * arg2: size + * arg3: flags + */ +scret_t +sys_recv(struct syscall_args *scargs) +{ + char buf[NETBUF_LEN]; + void *u_buf = (void *)scargs->arg1; + int sockfd = scargs->arg0; + size_t len = scargs->arg2; + int error, flags = scargs->arg3; + + if (len > sizeof(buf)) { + return -ENOBUFS; + } + + error = recv(sockfd, buf, len, flags); + if (error < 0) { + pr_error("sys_recv: recv() fail (fd=%d)\n", sockfd); + return error; + } + + error = copyout(buf, u_buf, len); + return (error == 0) ? len : error; +} + +/* + * send(2) syscall + * + * arg0: sockfd + * arg1: buf + * arg2: size + * arg3: flags + */ +scret_t +sys_send(struct syscall_args *scargs) +{ + char buf[NETBUF_LEN]; + const void *u_buf = (void *)scargs->arg1; + int sockfd = scargs->arg0; + size_t len = scargs->arg2; + int error, flags = scargs->arg3; + + if (len > sizeof(buf)) { + return -ENOBUFS; + } + + error = copyin(u_buf, buf, len); + if (error < 0) { + pr_error("sys_send: copyin() failure (fd=%d)\n", sockfd); + return error; + } + + return send(sockfd, buf, len, flags); +} + static struct vops socket_vops = { .read = NULL, .write = NULL, diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c index cb7e1d2..dd3de4f 100644 --- a/sys/kern/kern_syscall.c +++ b/sys/kern/kern_syscall.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -60,6 +61,10 @@ scret_t(*g_sctab[])(struct syscall_args *) = { sys_setuid, /* SYS_setuid */ sys_getuid, /* SYS_getuid */ sys_waitpid, /* SYS_waitpid */ + sys_socket, /* SYS_socket */ + sys_bind, /* SYS_bind */ + sys_recv, /* SYS_recv */ + sys_send, /* SYS_send */ }; const size_t MAX_SYSCALLS = NELEM(g_sctab); -- cgit v1.2.3