diff options
author | dzwdz | 2023-12-25 20:12:44 +0100 |
---|---|---|
committer | dzwdz | 2023-12-25 20:12:44 +0100 |
commit | 4be1fd62131f7e186e6f92f1bb5a356dc1ac1951 (patch) | |
tree | 54de3a2d99fe9d6e93ad45c5107aff5420f9900d /src/libc/net/socket.c | |
parent | b9f5f92bff69059471a76e73539780eedb356455 (diff) |
user/libc: reorganize net stuff, basic hosts-only gethostbyname()
/usr/share/hosts because i don't have /etc/ yet and i don't feel like creating it.
Diffstat (limited to 'src/libc/net/socket.c')
-rw-r--r-- | src/libc/net/socket.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/libc/net/socket.c b/src/libc/net/socket.c new file mode 100644 index 0000000..9eacbe5 --- /dev/null +++ b/src/libc/net/socket.c @@ -0,0 +1,91 @@ +#include <arpa/inet.h> +#include <camellia.h> +#include <camellia/syscalls.h> +#include <errno.h> +#include <netdb.h> +#include <netinet/in.h> +#include <stdio.h> +#include <sys/socket.h> + +int socket(int domain, int type, int protocol) { + if (domain != AF_INET || type != SOCK_STREAM || protocol != IPPROTO_TCP) { + return errno = ENOSYS, -1; + } + int h = _sys_getnull(0); + if (h < 0) { + return errno = -h, -1; + } else { + return h; + } +} + +int bind(int, const struct sockaddr *, socklen_t) { + return errno = ENOSYS, -1; +} + +int accept(int, struct sockaddr *, socklen_t *) { + return errno = ENOSYS, -1; +} + +int listen(int, int) { + return errno = ENOSYS, -1; +} + +int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { + char buf[256]; + struct sockaddr_in *addr4 = (void*)addr; + uint32_t ip; + uint16_t port; + int newfd; + + if (addr->sa_family != AF_INET) { + return errno = ENOSYS, -1; + } + + if (addrlen < (ssize_t)sizeof(*addr4)) { + return errno = EINVAL, -1; + } + + ip = ntohl(addr4->sin_addr.s_addr); + port = ntohs(addr4->sin_port); + if (snprintf(buf, 256, "/net/connect/0/%ld/tcp/%d", ip, port) >= 256) { + return errno = EGENERIC, -1; + } + newfd = camellia_open(buf, OPEN_READ | OPEN_WRITE); + if (newfd < 0) { + return -1; + } + dup2(newfd, sockfd); + close(newfd); + return 0; +} + +ssize_t send(int sockfd, const void *buf, size_t len, int flags) { + if (flags != 0) { + return errno = ENOSYS, -1; + } + return write(sockfd, buf, len); +} + +ssize_t recv(int sockfd, void *buf, size_t len, int flags) { + if (flags != 0) { + return errno = ENOSYS, -1; + } + return read(sockfd, buf, len); +} + +int getsockopt(int, int, int, void *, socklen_t *) { + return errno = ENOSYS, -1; +} + +int setsockopt(int, int, int, const void *, socklen_t) { + return 0; +} + +int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { + // TODO /net/ should expose local address somehow + /* dummy output, just to satisfy curl */ + (void)sockfd; (void)addrlen; + addr->sa_family = AF_UNSPEC; + return 0; +} |