From 84c54c550481d8b38514b1165f6403e2e5c251db Mon Sep 17 00:00:00 2001 From: Kim Woelders Date: Sun, 12 Feb 2023 22:15:26 +0100 Subject: [PATCH] socket: Add server socket fucntions About to be used in test code. --- lib/nvt_socket.c | 136 ++++++++++++++++++++++++++++++++++++++++------- lib/nvt_socket.h | 3 ++ 2 files changed, 119 insertions(+), 20 deletions(-) diff --git a/lib/nvt_socket.c b/lib/nvt_socket.c index 783dcca..2ab2e32 100644 --- a/lib/nvt_socket.c +++ b/lib/nvt_socket.c @@ -12,14 +12,19 @@ #include "nvt_socket.h" -int socket_create_client(const char *addr) -{ - char host[64], port[64]; - struct hostent *server; - struct sockaddr_in serveraddr; - int sockfd, err; +typedef struct { + unsigned short type; // socket type + unsigned short slen; // sockaddr length + union { + struct sockaddr gen; + struct sockaddr_in ipv4; + }; +} sa_t; - sscanf(addr, "%63[^:]:%63s", host, port); + +static int _sa_host_lookup(sa_t * sa, const char *host) +{ + struct hostent *server; server = gethostbyname(host); if (server == NULL) @@ -28,26 +33,117 @@ int socket_create_client(const char *addr) return -1; } - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd < 0) + sa->slen = sizeof(sa->ipv4); + + sa->ipv4.sin_family = AF_INET; + memcpy(&sa->ipv4.sin_addr.s_addr, server->h_addr, server->h_length); + + return 0; +} + +static int _sa_addr_parse(sa_t * sa, const char *addr) +{ + char host[64], port[64]; + + memset(sa, 0, sizeof(sa_t)); + + sscanf(addr, "%63[^:]:%63s", host, port); + + if (_sa_host_lookup(sa, host) != 0) + return -1; + + sa->type = SOCK_STREAM; + sa->ipv4.sin_port = htons(atoi(port)); + + return 0; +} + +int socket_create_client(const char *addr) +{ + sa_t sa; + int fd, err; + + if (_sa_addr_parse(&sa, addr) != 0) + return -1; + + fd = socket(sa.gen.sa_family, sa.type, 0); + if (fd < 0) { - nvt_log(LOG_ERR, "Socket open failed: %m\n"); - return sockfd; + nvt_log(LOG_ERR, "%s: Could not find address: '%s'", __func__, addr); + return fd; } - bzero((char *)&serveraddr, sizeof(serveraddr)); - serveraddr.sin_family = AF_INET; - bcopy((char *)server->h_addr, (char *)&serveraddr.sin_addr.s_addr, - server->h_length); - serveraddr.sin_port = htons(atoi(port)); - - err = connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)); + err = connect(fd, &sa.gen, sa.slen); if (err < 0) { nvt_log(LOG_ERR, "Failed to connect to: %s: %m\n", addr); - close(sockfd); + close(fd); return -1; } - return sockfd; + return fd; +} + +int socket_create_server(const char *addr) +{ + sa_t sa; + int err, fd, opt; + + err = _sa_addr_parse(&sa, addr); + if (err != 0) + { + nvt_log(LOG_ERR, "%s: Could not find address: '%s'", __func__, addr); + return -1; + } + + fd = socket(sa.gen.sa_family, sa.type, 0); + if (fd < 0) + { + nvt_log(LOG_ERR, "%s: *** socket(%s): %m", __func__, addr); + return -1; + } + + if (sa.gen.sa_family == AF_INET) + { + /* Avoid TIME_WAIT state on socket close */ + opt = 1; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + } + + err = bind(fd, &sa.gen, sa.slen); + if (err != 0) + { + nvt_log(LOG_ERR, "%s: *** bind(%s): %m", __func__, addr); + close(fd); + return -1; + } + + if (sa.type == SOCK_STREAM) + { + err = listen(fd, 5); + if (err != 0) + { + nvt_log(LOG_ERR, "%s: *** listen(%s): %m", __func__, addr); + close(fd); + return -1; + } + } + + return fd; +} + +int socket_create_server_client(int sfd) +{ + int cfd; + socklen_t slen; + + slen = 0; + cfd = accept(sfd, NULL, &slen); + if (cfd < 0) + { + nvt_log(LOG_ERR, "%s: *** accept(): %m", __func__); + return -1; + } + + return cfd; } diff --git a/lib/nvt_socket.h b/lib/nvt_socket.h index 30ecc0e..cb4b4ff 100644 --- a/lib/nvt_socket.h +++ b/lib/nvt_socket.h @@ -6,4 +6,7 @@ int socket_create_client(const char *addr); +int socket_create_server(const char *addr); +int socket_create_server_client(int sfd); + #endif /* NVT_SOCKET_H */