summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/include/sys/socket.h5
-rw-r--r--sys/include/sys/syscall.h4
-rw-r--r--sys/kern/kern_socket.c102
-rw-r--r--sys/kern/kern_syscall.c5
4 files changed, 116 insertions, 0 deletions
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 <sys/syscall.h>
#include <sys/sysctl.h>
+#include <sys/socket.h>
#include <sys/reboot.h>
#include <sys/types.h>
#include <sys/ucred.h>
@@ -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);