aboutsummaryrefslogtreecommitdiffstats
path: root/src/libopm/src/libopm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libopm/src/libopm.c')
-rw-r--r--src/libopm/src/libopm.c66
1 files changed, 46 insertions, 20 deletions
diff --git a/src/libopm/src/libopm.c b/src/libopm/src/libopm.c
index 89b376f..d6118ff 100644
--- a/src/libopm/src/libopm.c
+++ b/src/libopm/src/libopm.c
@@ -29,10 +29,14 @@
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
+#include <assert.h>
#include <poll.h>
#ifdef HAVE_LIBCRYPTO
#include <openssl/ssl.h>
#endif
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
#include "config.h"
#include "libopm.h"
@@ -392,24 +396,39 @@ libopm_protocol_config_free(OPM_PROTOCOL_CONFIG_T *protocol)
OPM_ERR_T
opm_scan(OPM_T *scanner, OPM_REMOTE_T *remote)
{
- OPM_SCAN_T *scan; /* New scan for OPM_T */
OPM_NODE_T *node; /* Node we'll add scan to when we link it to scans */
- struct in_addr in;
+ struct addrinfo hints, *res;
if (LIST_SIZE(&scanner->protocols) == 0 &&
LIST_SIZE(&remote->protocols) == 0)
return OPM_ERR_NOPROTOCOLS;
+ memset(&hints, 0, sizeof(hints));
+
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_NUMERICHOST;
+
/*
* XXX: libopm ideally shouldn't see an IP address in string representation.
* Could have been stuffed into the _OPM_REMOTE struct by the caller that
* already does getaddrinfo() anyway.
*/
- if (inet_pton(AF_INET, remote->ip, &in) <= 0)
+ if (getaddrinfo(remote->ip, NULL, &hints, &res) || res->ai_family != AF_INET) /* XXX: only do v4 for now */
+ {
+ if (res)
+ freeaddrinfo(res);
+
return OPM_ERR_BADADDR;
+ }
+
+ OPM_SCAN_T *scan = libopm_scan_create(scanner, remote);
- scan = libopm_scan_create(scanner, remote);
- memcpy(&scan->addr.sin_addr, &in, sizeof(scan->addr.sin_addr));
+ memcpy(&scan->addr, res->ai_addr, res->ai_addrlen);
+ scan->addr.ss_family = res->ai_family;
+ scan->addr_len = res->ai_addrlen;
+
+ freeaddrinfo(res);
node = libopm_node_create(scan);
libopm_list_add(&scanner->queue, node);
@@ -891,19 +910,16 @@ libopm_check_closed(OPM_T *scanner)
static void
libopm_do_connect(OPM_T * scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
{
- struct sockaddr_in *bind_ip;
- struct sockaddr_in *addr; /* Outgoing host */
- struct sockaddr_in local_addr; /* For binding */
-
- addr = &scan->addr; /* Already have the IP in byte format from opm_scan */
- addr->sin_family = AF_INET;
- addr->sin_port = htons(conn->port);
+ assert(scan->addr.ss_family == AF_INET);
- bind_ip = (struct sockaddr_in *)libopm_config(scanner->config, OPM_CONFIG_BIND_IP);
+ if (scan->addr.ss_family == AF_INET6)
+ ((struct sockaddr_in6 *)&scan->addr)->sin6_port = htons(conn->port);
+ else
+ ((struct sockaddr_in *)&scan->addr)->sin_port = htons(conn->port);
- conn->fd = socket(AF_INET, SOCK_STREAM, 0);
scanner->fd_use++; /* Increase file descriptor use */
+ conn->fd = socket(scan->addr.ss_family, SOCK_STREAM, 0);
if (conn->fd == -1)
{
libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_NOFD);
@@ -911,15 +927,25 @@ libopm_do_connect(OPM_T * scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
return;
}
+ struct sockaddr_storage *bind_ip = libopm_config(scanner->config, OPM_CONFIG_BIND_IP);
if (bind_ip)
{
- memset(&local_addr, 0, sizeof(local_addr));
+ size_t addr_len;
- local_addr.sin_addr.s_addr = bind_ip->sin_addr.s_addr;
- local_addr.sin_family = AF_INET;
- local_addr.sin_port = htons(0);
+ if (bind_ip->ss_family == AF_INET6)
+ {
+ struct sockaddr_in6 *in = (struct sockaddr_in6 *)bind_ip;
+ in->sin6_port = htons(0);
+ addr_len = sizeof(*in);
+ }
+ else
+ {
+ struct sockaddr_in *in = (struct sockaddr_in *)bind_ip;
+ in->sin_port = htons(0);
+ addr_len = sizeof(*in);
+ }
- if (bind(conn->fd, (struct sockaddr *)&local_addr, sizeof(local_addr)) == -1)
+ if (bind(conn->fd, (const struct sockaddr *)bind_ip, addr_len) == -1)
{
libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_BIND);
conn->state = OPM_STATE_CLOSED;
@@ -930,7 +956,7 @@ libopm_do_connect(OPM_T * scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
/* Set socket non blocking */
fcntl(conn->fd, F_SETFL, O_NONBLOCK);
- connect(conn->fd, (struct sockaddr *)addr, sizeof(*addr));
+ connect(conn->fd, (const struct sockaddr *)&scan->addr, scan->addr_len);
#ifdef HAVE_LIBCRYPTO
if (conn->protocol->use_tls)