From 4be1fd62131f7e186e6f92f1bb5a356dc1ac1951 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Mon, 25 Dec 2023 20:12:44 +0100 Subject: 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. --- src/cmd/netstack/util.c | 1 + src/libc/arpainet.c | 20 --------- src/libc/include/arpa/inet.h | 3 ++ src/libc/net/arpainet.c | 38 ++++++++++++++++++ src/libc/net/gethostbyname.c | 51 +++++++++++++++++++++++ src/libc/net/socket.c | 91 +++++++++++++++++++++++++++++++++++++++++ src/libc/socket.c | 96 -------------------------------------------- sysroot/usr/share/hosts | 8 ++++ 8 files changed, 192 insertions(+), 116 deletions(-) delete mode 100644 src/libc/arpainet.c create mode 100644 src/libc/net/arpainet.c create mode 100644 src/libc/net/gethostbyname.c create mode 100644 src/libc/net/socket.c delete mode 100644 src/libc/socket.c create mode 100644 sysroot/usr/share/hosts diff --git a/src/cmd/netstack/util.c b/src/cmd/netstack/util.c index 68092aa..093c5ac 100644 --- a/src/cmd/netstack/util.c +++ b/src/cmd/netstack/util.c @@ -43,6 +43,7 @@ uint16_t ip_checksumphdr( } int ip_parse(const char *s, uint32_t *dest) { + // TODO use inet_aton if (!s) return -1; uint32_t ip = strtol(s, (char**)&s, 0); diff --git a/src/libc/arpainet.c b/src/libc/arpainet.c deleted file mode 100644 index 125a855..0000000 --- a/src/libc/arpainet.c +++ /dev/null @@ -1,20 +0,0 @@ -#include - -uint32_t htonl(uint32_t n) { - return ((n & 0xFF000000) >> 24) - | ((n & 0x00FF0000) >> 8) - | ((n & 0x0000FF00) << 8) - | ((n & 0x000000FF) << 24); -} - -uint16_t htons(uint16_t n) { - return (n >> 8) | (n << 8); -} - -uint32_t ntohl(uint32_t n) { - return htonl(n); -} - -uint16_t ntohs(uint16_t n) { - return htons(n); -} diff --git a/src/libc/include/arpa/inet.h b/src/libc/include/arpa/inet.h index d372467..1e4f97e 100644 --- a/src/libc/include/arpa/inet.h +++ b/src/libc/include/arpa/inet.h @@ -1,4 +1,5 @@ #pragma once +#include #include uint32_t htonl(uint32_t n); @@ -6,3 +7,5 @@ uint16_t htons(uint16_t n); uint32_t ntohl(uint32_t n); uint16_t ntohs(uint16_t n); + +int inet_aton(const char *s, struct in_addr *dest); diff --git a/src/libc/net/arpainet.c b/src/libc/net/arpainet.c new file mode 100644 index 0000000..62efb62 --- /dev/null +++ b/src/libc/net/arpainet.c @@ -0,0 +1,38 @@ +#include +#include + +uint32_t htonl(uint32_t n) { + return ((n & 0xFF000000) >> 24) + | ((n & 0x00FF0000) >> 8) + | ((n & 0x0000FF00) << 8) + | ((n & 0x000000FF) << 24); +} + +uint16_t htons(uint16_t n) { + return (n >> 8) | (n << 8); +} + +uint32_t ntohl(uint32_t n) { + return htonl(n); +} + +uint16_t ntohs(uint16_t n) { + return htons(n); +} + +int inet_aton(const char *s, struct in_addr *dest) { + if (!s) return -1; + + uint32_t ip = strtol(s, (char**)&s, 0); + int parts = 1; + for (; parts < 4; parts++) { + if (!*s) break; + if (*s++ != '.') return 0; + ip <<= 8; + ip += strtol(s, (char**)&s, 0); + } + if (parts > 1) + ip = ((ip & 0xFFFFFF00) << 8 * (4 - parts)) | (ip & 0xFF); + dest->s_addr = htonl(ip); + return 1; +} diff --git a/src/libc/net/gethostbyname.c b/src/libc/net/gethostbyname.c new file mode 100644 index 0000000..f2b59c1 --- /dev/null +++ b/src/libc/net/gethostbyname.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct hostent *gethostbyname(const char *name) { + // TODO ipv4 addresses should just get copied + static struct hostent he; + static struct in_addr addr; + static void *addrs[2] = {NULL, NULL}; + bool found = false; + char buf[256]; + FILE *fp; + + if (he.h_name) { + free(he.h_name); + he.h_name = NULL; + } + + if ((fp = fopen("/usr/share/hosts", "r")) == NULL) { + return NULL; + } + while (!found && fgets(buf, sizeof buf, fp)) { + char *s; + if (!isdigit(buf[0])) continue; + s = strtok(buf, " \t\n"); + if (!inet_aton(s, &addr)) continue; + while ((s = strtok(NULL, " \t\n"))) { + if (strcmp(s, name) == 0) { + found = true; + break; + } + } + } + fclose(fp); + if (!found) { + return NULL; + } + + he.h_name = strdup(name); + he.h_aliases = NULL; + he.h_addrtype = AF_INET; + he.h_length = 4; + he.h_addr_list = (void*)&addrs; + addrs[0] = &addr.s_addr; + return &he; +} 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 +#include +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/src/libc/socket.c b/src/libc/socket.c deleted file mode 100644 index 5ea7266..0000000 --- a/src/libc/socket.c +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -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; -} - -struct hostent *gethostbyname(const char *name) { - (void)name; - return NULL; -} diff --git a/sysroot/usr/share/hosts b/sysroot/usr/share/hosts new file mode 100644 index 0000000..54710a0 --- /dev/null +++ b/sysroot/usr/share/hosts @@ -0,0 +1,8 @@ +127.0.0.1 localhost + +104.18.114.97 cloudflare.com icanhazip.com dzwdz.net + +# friends etc +104.248.107.166 tilde.town +88.99.244.36 sortix.org +88.99.244.4 irc.sortix.org -- cgit v1.2.3