mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Make it a non-fatal error when one of two listeners can't be opened.
Unless given a specific listen address, we open two separate listening sockets, one for IPv4 and one for IPv6. It was previously a fatal error if we failed to create either socket. Now it is fatal only when all potential listening addresses fail. David Millis discovered that the IPv6 listener failed on Windows XP without IPv6 configured. Ncat: socket: An address incompatible with the requested protocol was used. QUITTING. http://seclists.org/nmap-dev/2013/q3/96
This commit is contained in:
@@ -233,6 +233,7 @@ static int ncat_listen_stream(int proto)
|
||||
fd_set listen_fds;
|
||||
struct timeval tv;
|
||||
struct timeval *tvp = NULL;
|
||||
unsigned int num_sockets;
|
||||
|
||||
/* clear out structs */
|
||||
FD_ZERO(&master_readfds);
|
||||
@@ -268,24 +269,36 @@ static int ncat_listen_stream(int proto)
|
||||
for (i = 0; i < NUM_LISTEN_ADDRS; i++)
|
||||
listen_socket[i] = -1;
|
||||
|
||||
num_sockets = 0;
|
||||
for (i = 0; i < num_listenaddrs; i++) {
|
||||
/* setup the main listening socket */
|
||||
listen_socket[i] = do_listen(SOCK_STREAM, proto, &listenaddrs[i]);
|
||||
if (listen_socket[i] == -1)
|
||||
bye("do_listen: %s", socket_strerror(socket_errno()));
|
||||
listen_socket[num_sockets] = do_listen(SOCK_STREAM, proto, &listenaddrs[i]);
|
||||
if (listen_socket[num_sockets] == -1) {
|
||||
logdebug("do_listen(\"%s\"): %s\n", inet_ntop_ez(&listenaddrs[i].storage, sizeof(listenaddrs[i].storage)), socket_strerror(socket_errno()));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Make our listening socket non-blocking because there are timing issues
|
||||
* which could cause us to block on accept() even though select() says it's
|
||||
* readable. See UNPv1 2nd ed, p422 for more.
|
||||
*/
|
||||
unblock_socket(listen_socket[i]);
|
||||
unblock_socket(listen_socket[num_sockets]);
|
||||
|
||||
/* setup select sets and max fd */
|
||||
FD_SET(listen_socket[i], &master_readfds);
|
||||
add_fd(&client_fdlist, listen_socket[i]);
|
||||
FD_SET(listen_socket[num_sockets], &master_readfds);
|
||||
add_fd(&client_fdlist, listen_socket[num_sockets]);
|
||||
|
||||
FD_SET(listen_socket[i], &listen_fds);
|
||||
FD_SET(listen_socket[num_sockets], &listen_fds);
|
||||
|
||||
num_sockets++;
|
||||
}
|
||||
if (num_sockets == 0) {
|
||||
if (num_listenaddrs == 1)
|
||||
bye("Unable to open listening socket on %s: %s", inet_ntop_ez(&listenaddrs[0].storage, sizeof(listenaddrs[0].storage)), socket_strerror(socket_errno()));
|
||||
else
|
||||
bye("Unable to open any listening sockets.");
|
||||
}
|
||||
|
||||
add_fd(&client_fdlist, STDIN_FILENO);
|
||||
|
||||
init_fdlist(&broadcast_fdlist, o.conn_limit);
|
||||
@@ -621,7 +634,10 @@ int read_socket(int recv_fd)
|
||||
*/
|
||||
static int ncat_listen_dgram(int proto)
|
||||
{
|
||||
int sockfd[NUM_LISTEN_ADDRS];
|
||||
struct {
|
||||
int fd;
|
||||
union sockaddr_u addr;
|
||||
} sockfd[NUM_LISTEN_ADDRS];
|
||||
int i, fdn = -1;
|
||||
int fdmax, nbytes, n, fds_ready;
|
||||
char buf[DEFAULT_UDP_BUF_LEN] = { 0 };
|
||||
@@ -631,9 +647,11 @@ static int ncat_listen_dgram(int proto)
|
||||
socklen_t sslen = sizeof(remotess.storage);
|
||||
struct timeval tv;
|
||||
struct timeval *tvp = NULL;
|
||||
unsigned int num_sockets;
|
||||
|
||||
for (i = 0; i < NUM_LISTEN_ADDRS; i++) {
|
||||
sockfd[i] = -1;
|
||||
sockfd[i].fd = -1;
|
||||
sockfd[i].addr.storage.ss_family = AF_UNSPEC;
|
||||
}
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
@@ -658,13 +676,24 @@ static int ncat_listen_dgram(int proto)
|
||||
FD_ZERO(&listen_fds);
|
||||
init_fdlist(&listen_fdlist, num_listenaddrs);
|
||||
|
||||
num_sockets = 0;
|
||||
for (i = 0; i < num_listenaddrs; i++) {
|
||||
/* create the UDP listen sockets */
|
||||
sockfd[i] = do_listen(SOCK_DGRAM, proto, &listenaddrs[i]);
|
||||
if (sockfd[i] == -1)
|
||||
bye("do_listen: %s", socket_strerror(socket_errno()));
|
||||
FD_SET(sockfd[i], &listen_fds);
|
||||
add_fd(&listen_fdlist, sockfd[i]);
|
||||
sockfd[num_sockets].fd = do_listen(SOCK_DGRAM, proto, &listenaddrs[i]);
|
||||
if (sockfd[num_sockets].fd == -1) {
|
||||
logdebug("do_listen(\"%s\"): %s\n", inet_ntop_ez(&listenaddrs[i].storage, sizeof(listenaddrs[i].storage)), socket_strerror(socket_errno()));
|
||||
continue;
|
||||
}
|
||||
FD_SET(sockfd[num_sockets].fd, &listen_fds);
|
||||
add_fd(&listen_fdlist, sockfd[num_sockets].fd);
|
||||
sockfd[num_sockets].addr = listenaddrs[i];
|
||||
num_sockets++;
|
||||
}
|
||||
if (num_sockets == 0) {
|
||||
if (num_listenaddrs == 1)
|
||||
bye("Unable to open listening socket on %s: %s", inet_ntop_ez(&listenaddrs[0].storage, sizeof(listenaddrs[0].storage)), socket_strerror(socket_errno()));
|
||||
else
|
||||
bye("Unable to open any listening sockets.");
|
||||
}
|
||||
|
||||
if (o.idletimeout > 0)
|
||||
@@ -675,15 +704,15 @@ static int ncat_listen_dgram(int proto)
|
||||
|
||||
if (fdn != -1) {
|
||||
/*remove socket descriptor which is burnt */
|
||||
FD_CLR(sockfd[fdn], &listen_fds);
|
||||
rm_fd(&listen_fdlist, sockfd[fdn]);
|
||||
FD_CLR(sockfd[fdn].fd, &listen_fds);
|
||||
rm_fd(&listen_fdlist, sockfd[fdn].fd);
|
||||
|
||||
/* Rebuild the udp socket which got burnt */
|
||||
sockfd[fdn] = do_listen(SOCK_DGRAM, proto, &listenaddrs[fdn]);
|
||||
if (sockfd[fdn] == -1)
|
||||
sockfd[fdn].fd = do_listen(SOCK_DGRAM, proto, &sockfd[fdn].addr);
|
||||
if (sockfd[fdn].fd == -1)
|
||||
bye("do_listen: %s", socket_strerror(socket_errno()));
|
||||
FD_SET(sockfd[fdn], &listen_fds);
|
||||
add_fd(&listen_fdlist, sockfd[fdn]);
|
||||
FD_SET(sockfd[fdn].fd, &listen_fds);
|
||||
add_fd(&listen_fdlist, sockfd[fdn].fd);
|
||||
|
||||
}
|
||||
fdn = -1;
|
||||
@@ -720,8 +749,8 @@ static int ncat_listen_dgram(int proto)
|
||||
continue;
|
||||
|
||||
/* Check each listening socket */
|
||||
for (j = 0; j < num_listenaddrs; j++) {
|
||||
if (i == sockfd[j]) {
|
||||
for (j = 0; j < num_sockets; j++) {
|
||||
if (i == sockfd[j].fd) {
|
||||
if (o.debug > 1)
|
||||
logdebug("Valid descriptor %d \n", i);
|
||||
fdn = j;
|
||||
|
||||
@@ -192,6 +192,7 @@ int ncat_http_server(void)
|
||||
union sockaddr_u conn;
|
||||
struct timeval tv;
|
||||
struct timeval *tvp = NULL;
|
||||
unsigned int num_sockets;
|
||||
|
||||
#ifndef WIN32
|
||||
Signal(SIGCHLD, proxyreaper);
|
||||
@@ -216,18 +217,28 @@ int ncat_http_server(void)
|
||||
init_fdlist(&listen_fdlist, num_listenaddrs);
|
||||
|
||||
/* Listen on each address, set up lists for select */
|
||||
num_sockets = 0;
|
||||
for (i = 0; i < num_listenaddrs; i++) {
|
||||
listen_socket[i] = do_listen(SOCK_STREAM, IPPROTO_TCP, &listenaddrs[i]);
|
||||
if (listen_socket[i] == -1)
|
||||
bye("do_listen: %s", socket_strerror(socket_errno()));
|
||||
listen_socket[num_sockets] = do_listen(SOCK_STREAM, IPPROTO_TCP, &listenaddrs[i]);
|
||||
if (listen_socket[num_sockets] == -1) {
|
||||
logdebug("do_listen(\"%s\"): %s\n", inet_ntop_ez(&listenaddrs[i].storage, sizeof(listenaddrs[i].storage)), socket_strerror(socket_errno()));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* make us not block on accepts in wierd cases. See ncat_listen.c:209 */
|
||||
unblock_socket(listen_socket[i]);
|
||||
unblock_socket(listen_socket[num_sockets]);
|
||||
|
||||
/* setup select sets and max fd */
|
||||
FD_SET(listen_socket[i], &listen_fds);
|
||||
add_fd(&listen_fdlist, listen_socket[i]);
|
||||
FD_SET(listen_socket[num_sockets], &listen_fds);
|
||||
add_fd(&listen_fdlist, listen_socket[num_sockets]);
|
||||
|
||||
num_sockets++;
|
||||
}
|
||||
if (num_sockets == 0) {
|
||||
if (num_listenaddrs == 1)
|
||||
bye("Unable to open listening socket on %s: %s", inet_ntop_ez(&listenaddrs[0].storage, sizeof(listenaddrs[0].storage)), socket_strerror(socket_errno()));
|
||||
else
|
||||
bye("Unable to open any listening sockets.");
|
||||
}
|
||||
|
||||
if (o.idletimeout > 0)
|
||||
@@ -261,7 +272,7 @@ int ncat_http_server(void)
|
||||
continue;
|
||||
|
||||
/* Check each listening socket */
|
||||
for (j = 0; j < num_listenaddrs; j++) {
|
||||
for (j = 0; j < num_sockets; j++) {
|
||||
if (i == listen_socket[j]) {
|
||||
fds_ready--;
|
||||
c = accept(i, &conn.sockaddr, &sslen);
|
||||
|
||||
Reference in New Issue
Block a user