support TCP/IPv6 address and UNIX domain socket path as rfc2217 server
This commit is contained in:
committed by
Kim Woelders
parent
f41067c3be
commit
9739087594
+69
-15
@@ -7,6 +7,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
#include "nvt_log.h"
|
#include "nvt_log.h"
|
||||||
#include "nvt_socket.h"
|
#include "nvt_socket.h"
|
||||||
@@ -18,42 +19,95 @@ typedef struct {
|
|||||||
union {
|
union {
|
||||||
struct sockaddr gen;
|
struct sockaddr gen;
|
||||||
struct sockaddr_in ipv4;
|
struct sockaddr_in ipv4;
|
||||||
|
struct sockaddr_in6 ipv6;
|
||||||
|
struct sockaddr_un un;
|
||||||
};
|
};
|
||||||
} sa_t;
|
} sa_t;
|
||||||
|
|
||||||
|
|
||||||
static int _sa_host_lookup(sa_t * sa, const char *host)
|
static int _sa_host_lookup(sa_t * sa, const char *host, const char *port)
|
||||||
{
|
{
|
||||||
struct hostent *server;
|
struct addrinfo hint, *adrinf = NULL, *p;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
server = gethostbyname(host);
|
memset(&hint, 0, sizeof(struct addrinfo));
|
||||||
if (server == NULL)
|
|
||||||
{
|
if(getaddrinfo(host, port, &hint, &adrinf) != 0) {
|
||||||
nvt_log(LOG_ERR, "Cannot resolve host name: %m\n");
|
nvt_log(LOG_ERR, "Cannot resolve host name: %m\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Priority is given to the use of IPv4
|
||||||
|
// This code must be modified if the preffered protocol is changed or varied.
|
||||||
|
for(p = adrinf; p; p = p->ai_next) {
|
||||||
|
if(p->ai_family == AF_INET) {
|
||||||
sa->slen = sizeof(sa->ipv4);
|
sa->slen = sizeof(sa->ipv4);
|
||||||
|
memcpy(&sa->ipv4, p->ai_addr, sizeof(struct sockaddr_in));
|
||||||
sa->ipv4.sin_family = AF_INET;
|
ret = 0;
|
||||||
memcpy(&sa->ipv4.sin_addr.s_addr, server->h_addr, server->h_length);
|
goto exit_host_lookup;
|
||||||
|
}
|
||||||
return 0;
|
}
|
||||||
|
for(p = adrinf; p; p = p->ai_next) {
|
||||||
|
if(p->ai_family == AF_INET6) {
|
||||||
|
sa->slen = sizeof(sa->ipv6);
|
||||||
|
memcpy(&sa->ipv6, p->ai_addr, sizeof(struct sockaddr_in6));
|
||||||
|
ret = 0;
|
||||||
|
goto exit_host_lookup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit_host_lookup:
|
||||||
|
freeaddrinfo(adrinf);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sa_addr_parse(sa_t * sa, const char *addr)
|
static int _sa_addr_parse(sa_t * sa, const char *addr)
|
||||||
{
|
{
|
||||||
char host[64], port[64];
|
ssize_t host_len;
|
||||||
|
char host[64];
|
||||||
|
const char *port;
|
||||||
|
|
||||||
memset(sa, 0, sizeof(sa_t));
|
memset(sa, 0, sizeof(sa_t));
|
||||||
|
|
||||||
sscanf(addr, "%63[^:]:%63s", host, port);
|
if (strncmp(addr, "unix:", 5) == 0) { // case of unix domain sockets ...
|
||||||
|
addr += 5; // skip "unix:" prefix
|
||||||
|
if(strlen(addr) > sizeof(sa->un.sun_path) - 1) {
|
||||||
|
nvt_log(LOG_ERR, "UNIX domain socket path is too long.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
sa->slen = sizeof(sa->un);
|
||||||
|
sa->un.sun_family = AF_UNIX;
|
||||||
|
strcpy(sa->un.sun_path, addr);
|
||||||
|
sa->type = SOCK_STREAM;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (_sa_host_lookup(sa, host) != 0)
|
if(!(port = strrchr(addr, ':'))) {
|
||||||
|
nvt_log(LOG_ERR, "bad server address format.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
host_len = (port++) - addr;
|
||||||
|
// *port indicates the last ':', its next is 1st char of the port number
|
||||||
|
if(host_len >= 2 && addr[0] == '[' && addr[host_len-1] == ']') {
|
||||||
|
// IPv6 addresses are enclosed in pair of square brackets.
|
||||||
|
addr += 1;
|
||||||
|
host_len -= 2;
|
||||||
|
} else {
|
||||||
|
if(strchr(addr, ':') != port-1) {
|
||||||
|
nvt_log(LOG_ERR, "addresses containing colons must be enclosed in square brackets.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((ssize_t)sizeof(host) <= host_len) {
|
||||||
|
nvt_log(LOG_ERR, "host name is too long.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strncpy(host, addr, host_len);
|
||||||
|
host[host_len] = '\0'; // strncpy doesn't add null char
|
||||||
|
|
||||||
|
if (_sa_host_lookup(sa, host, port) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
sa->type = SOCK_STREAM;
|
sa->type = SOCK_STREAM;
|
||||||
sa->ipv4.sin_port = htons(atoi(port));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -103,7 +157,7 @@ int socket_create_server(const char *addr)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.gen.sa_family == AF_INET)
|
if (sa.gen.sa_family == AF_INET || sa.gen.sa_family == AF_INET6)
|
||||||
{
|
{
|
||||||
/* Avoid TIME_WAIT state on socket close */
|
/* Avoid TIME_WAIT state on socket close */
|
||||||
opt = 1;
|
opt = 1;
|
||||||
|
|||||||
+3
-1
@@ -1172,7 +1172,9 @@ static void print_help(void)
|
|||||||
"\t-q\t\tBe quiet (suppress informational messages)\n"
|
"\t-q\t\tBe quiet (suppress informational messages)\n"
|
||||||
"\t-r\t\tDisable telnet processing\n"
|
"\t-r\t\tDisable telnet processing\n"
|
||||||
"\t-s delay \t\tDelay at close in ms (use u suffix for us)\n"
|
"\t-s delay \t\tDelay at close in ms (use u suffix for us)\n"
|
||||||
"\t-S server, --server=host:port\n");
|
"\t-S server, --server=host:port\n"
|
||||||
|
"\t\t\t[ipv6addr]:port (connect via IPv6)\n"
|
||||||
|
"\t\t\tunix:/path/to.socket (connect via UNIX domain socket)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|||||||
Reference in New Issue
Block a user