/* * Socket interface API */ #include /* getaddrinfo() */ #include #include #include #include #include #include "nvt_log.h" #include "nvt_socket.h" typedef struct { unsigned short type; // socket type unsigned short slen; // sockaddr length union { struct sockaddr gen; struct sockaddr_in ipv4; }; } sa_t; static int _sa_host_lookup(sa_t * sa, const char *host) { struct hostent *server; server = gethostbyname(host); if (server == NULL) { nvt_log(LOG_ERR, "Cannot resolve host name: %m\n"); return -1; } 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, "%s: Could not find address: '%s'", __func__, addr); return fd; } err = connect(fd, &sa.gen, sa.slen); if (err < 0) { nvt_log(LOG_ERR, "Failed to connect to: %s: %m\n", addr); close(fd); return -1; } 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; }