1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-21 06:59:01 +00:00

AF_VSOCK support. Closes #1075

This commit is contained in:
dmiller
2019-05-20 16:21:41 +00:00
parent 61e2976e95
commit 21f51ff822
20 changed files with 423 additions and 18 deletions

View File

@@ -1,5 +1,9 @@
#Nmap Changelog ($Id$); -*-text-*- #Nmap Changelog ($Id$); -*-text-*-
o [Nsock][Ncat][GH#1075] Add AF_VSOCK (Linux VM sockets) functionality to Nsock
and Ncat. VM sockets are used for communication between virtual machines and
the hypervisor. [Stefan Hajnoczi]
o [NSE][GH#1467] Avoid clobbering the "severity" and "ignore_404" values of o [NSE][GH#1467] Avoid clobbering the "severity" and "ignore_404" values of
fingerprints in http-enum. None of the standard fingerprints uses these fingerprints in http-enum. None of the standard fingerprints uses these
fields. [Kostas Milonas] fields. [Kostas Milonas]

View File

@@ -125,6 +125,9 @@
/* Define to 1 if you have the <sys/un.h> header file. */ /* Define to 1 if you have the <sys/un.h> header file. */
#undef HAVE_SYS_UN_H #undef HAVE_SYS_UN_H
/* Define to 1 if you have the <linux/vm_sockets.h> header file. */
#undef HAVE_LINUX_VM_SOCKETS_H
/* Define to 1 if you have the `vprintf' function. */ /* Define to 1 if you have the `vprintf' function. */
#undef HAVE_VPRINTF #undef HAVE_VPRINTF

13
ncat/configure vendored
View File

@@ -3813,6 +3813,19 @@ fi
done done
for ac_header in linux/vm_sockets.h
do :
ac_fn_c_check_header_compile "$LINENO" "linux/vm_sockets.h" "ac_cv_header_linux_vm_sockets_h" "#include <sys/socket.h>
"
if test "x$ac_cv_header_linux_vm_sockets_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LINUX_VM_SOCKETS_H 1
_ACEOF
fi
done
# Checks for typedefs, structures, and compiler characteristics. # Checks for typedefs, structures, and compiler characteristics.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat file-mode macros are broken" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat file-mode macros are broken" >&5

View File

@@ -40,6 +40,7 @@ AC_PATH_TOOL([STRIP], [strip], [/bin/true])
AC_HEADER_STDC AC_HEADER_STDC
AC_HEADER_SYS_WAIT AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([fcntl.h limits.h netdb.h netinet/in.h stdlib.h string.h strings.h sys/param.h sys/socket.h sys/time.h sys/timeb.h unistd.h sys/un.h]) AC_CHECK_HEADERS([fcntl.h limits.h netdb.h netinet/in.h stdlib.h string.h strings.h sys/param.h sys/socket.h sys/time.h sys/timeb.h unistd.h sys/un.h])
AC_CHECK_HEADERS([linux/vm_sockets.h], , , [#include <sys/socket.h>])
# Checks for typedefs, structures, and compiler characteristics. # Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STAT AC_HEADER_STAT

View File

@@ -2,12 +2,12 @@
.\" Title: Ncat .\" Title: Ncat
.\" Author: [see the "Authors" section] .\" Author: [see the "Authors" section]
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/> .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
.\" Date: 09/28/2018 .\" Date: 05/20/2019
.\" Manual: Ncat Reference Guide .\" Manual: Ncat Reference Guide
.\" Source: Ncat .\" Source: Ncat
.\" Language: English .\" Language: English
.\" .\"
.TH "NCAT" "1" "09/28/2018" "Ncat" "Ncat Reference Guide" .TH "NCAT" "1" "05/20/2019" "Ncat" "Ncat Reference Guide"
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
.\" * Define some portability stuff .\" * Define some portability stuff
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
@@ -51,6 +51,7 @@ Options taking a time assume seconds\&. Append \*(Aqms\*(Aq for milliseconds,
\-4 Use IPv4 only \-4 Use IPv4 only
\-6 Use IPv6 only \-6 Use IPv6 only
\-U, \-\-unixsock Use Unix domain sockets only \-U, \-\-unixsock Use Unix domain sockets only
\-\-vsock Use vsock sockets only
\-C, \-\-crlf Use CRLF for EOL sequence \-C, \-\-crlf Use CRLF for EOL sequence
\-c, \-\-sh\-exec <command> Executes the given command via /bin/sh \-c, \-\-sh\-exec <command> Executes the given command via /bin/sh
\-e, \-\-exec <command> Executes the given command \-e, \-\-exec <command> Executes the given command
@@ -85,8 +86,9 @@ Options taking a time assume seconds\&. Append \*(Aqms\*(Aq for milliseconds,
\-\-broker Enable Ncat\*(Aqs connection brokering mode \-\-broker Enable Ncat\*(Aqs connection brokering mode
\-\-chat Start a simple Ncat chat server \-\-chat Start a simple Ncat chat server
\-\-proxy <addr[:port]> Specify address of host to proxy through \-\-proxy <addr[:port]> Specify address of host to proxy through
\-\-proxy\-type <type> Specify proxy type ("http" or "socks4" or "socks5") \-\-proxy\-type <type> Specify proxy type ("http", "socks4", "socks5")
\-\-proxy\-auth <auth> Authenticate with HTTP or SOCKS proxy server \-\-proxy\-auth <auth> Authenticate with HTTP or SOCKS proxy server
\-\-proxy\-dns <type> Specify where to resolve proxy destination
\-\-ssl Connect or listen with SSL \-\-ssl Connect or listen with SSL
\-\-ssl\-cert Specify SSL certificate file (PEM) for listening \-\-ssl\-cert Specify SSL certificate file (PEM) for listening
\-\-ssl\-key Specify SSL private key (PEM) for listening \-\-ssl\-key Specify SSL private key (PEM) for listening
@@ -156,6 +158,16 @@ Use UDP for the connection (the default is TCP)\&.
.RS 4 .RS 4
Use SCTP for the connection (the default is TCP)\&. SCTP support is implemented in TCP\-compatible mode\&. Use SCTP for the connection (the default is TCP)\&. SCTP support is implemented in TCP\-compatible mode\&.
.RE .RE
.PP
\fB\-\-vsock\fR (Use AF_VSOCK sockets)
.RS 4
Use AF_VSOCK sockets rather than the default TCP sockets (Linux only)\&. This option may be used on its own for stream sockets or combined with
\fB\-\-udp\fR
for datagram sockets\&. A description of
\fB\-\-vsock\fR
mode is in
the section called \(lqAF_VSOCK SOCKETS\(rq\&.
.RE
.SH "CONNECT MODE OPTIONS" .SH "CONNECT MODE OPTIONS"
.PP .PP
\fB\-g \fR\fB\fIhop1\fR\fR\fB[,\fIhop2\fR,\&.\&.\&.]\fR (Loose source routing) \fB\-g \fR\fB\fIhop1\fR\fR\fB[,\fIhop2\fR,\&.\&.\&.]\fR (Loose source routing)
@@ -280,13 +292,13 @@ This option allows you to specify a comma\-separated list of protocols to send v
.RE .RE
.SH "PROXY OPTIONS" .SH "PROXY OPTIONS"
.PP .PP
\fB\-\-proxy \fR\fB\fIhost\fR\fR\fB[:\fR\fB\fIport\fR\fR\fB]\fR (Specify proxy address) \fB\-\-proxy \fR\fB\fIhost\fR\fR\fB[:\fIport\fR]\fR (Specify proxy address)
.RS 4 .RS 4
Requests proxying through Requests proxying through
\fIhost\fR:\fIport\fR, using the protocol specified by \fIhost\fR:\fIport\fR, using the protocol specified by
\fB\-\-proxy\-type\fR\&. \fB\-\-proxy\-type\fR\&.
.sp .sp
If no port is specified, the proxy protocol\*(Aqs well\-known port is used (1080 for SOCKS and 3128 for HTTP)\&. However, when specifying an IPv6 HTTP proxy server using the IP address rather than the hostname, the port number MUST be specified as well\&. If the proxy requires authentication, use If no port is specified, the proxy protocol\*(Aqs well\-known port is used (1080 for SOCKS and 3128 for HTTP)\&. When specifying an IPv6 HTTP proxy server using the IP address rather than the hostname, the square\-bracket notation (for example [2001:db8::1]:8080) MUST be used to separate the port from the IPv6 address\&. If the proxy requires authentication, use
\fB\-\-proxy\-auth\fR\&. \fB\-\-proxy\-auth\fR\&.
.RE .RE
.PP .PP
@@ -316,6 +328,30 @@ or
\fB\-\-proxy\-type socks5\fR, the form should be username:password\&. For \fB\-\-proxy\-type socks5\fR, the form should be username:password\&. For
\fB\-\-proxy\-type socks4\fR, it should be a username only\&. \fB\-\-proxy\-type socks4\fR, it should be a username only\&.
.RE .RE
.PP
\fB\-\-proxy\-dns \fR\fB\fItype\fR\fR (Specify where to resolve proxy destination)
.RS 4
In connect mode, it provides control over whether proxy destination hostnames are resolved by the remote proxy server or locally, by Ncat itself\&. Possible values for
\fItype\fR
are:
.sp
local
\- Hostnames are resolved locally on the Ncat host\&. Ncat exits with error if the hostname cannot be resolved\&.
.sp
remote
\- Hostnames are passed directly onto the remote proxy server\&. This is the default behavior\&.
.sp
both
\- Hostname resolution is first attempted on the Ncat host\&. Unresolvable hostnames are passed onto the remote proxy server\&.
.sp
none
\- Hostname resolution is completely disabled\&. Only a literal IPv4 or IPv6 address can be used as the proxy destination\&.
.sp
Local hostname resolution generally respects IP version specified with options
\fB\-4\fR
or
\fB\-6\fR, except for SOCKS4, which is incompatible with IPv6\&.
.RE
.SH "COMMAND EXECUTION OPTIONS" .SH "COMMAND EXECUTION OPTIONS"
.PP .PP
\fB\-e \fR\fB\fIcommand\fR\fR, \fB\-\-exec \fR\fB\fIcommand\fR\fR (Execute command) \fB\-e \fR\fB\fIcommand\fR\fR, \fB\-\-exec \fR\fB\fIcommand\fR\fR (Execute command)
@@ -477,6 +513,12 @@ If this option is passed, then Ncat will only send data and will ignore anything
If this option is passed, Ncat will not invoke shutdown on a socket after seeing EOF on stdin\&. This is provided for backward\-compatibility with OpenBSD netcat, which exhibits this behavior when executed with its \*(Aq\-d\*(Aq option\&. If this option is passed, Ncat will not invoke shutdown on a socket after seeing EOF on stdin\&. This is provided for backward\-compatibility with OpenBSD netcat, which exhibits this behavior when executed with its \*(Aq\-d\*(Aq option\&.
.RE .RE
.PP .PP
\fB\-n\fR, \fB\-\-nodns\fR (Do not resolve hostnames)
.RS 4
Completely disable hostname resolution across all Ncat options, such as the destination, source address, source routing hops, and the proxy\&. All addresses must be specified numerically\&. (Note that resolution of proxy destinations is controlled separately via option
\fB\-\-proxy\-dns\fR\&.)
.RE
.PP
\fB\-t\fR, \fB\-\-telnet\fR (Answer Telnet negotiations) \fB\-t\fR, \fB\-\-telnet\fR (Answer Telnet negotiations)
.RS 4 .RS 4
Handle DO/DONT WILL/WONT Telnet negotiations\&. This makes it possible to script Telnet sessions with Ncat\&. Handle DO/DONT WILL/WONT Telnet negotiations\&. This makes it possible to script Telnet sessions with Ncat\&.
@@ -508,6 +550,23 @@ on its own for stream sockets, or combine it with
for datagram sockets\&. Datagram sockets require a source socket to connect from\&. By default, a source socket with a random filename will be created as needed, and deleted when the program ends\&. Use the for datagram sockets\&. Datagram sockets require a source socket to connect from\&. By default, a source socket with a random filename will be created as needed, and deleted when the program ends\&. Use the
\fB\-\-source\fR \fB\-\-source\fR
with a path to use a source socket with a specific name\&. with a path to use a source socket with a specific name\&.
.SH "AF_VSOCK SOCKETS"
.PP
The
\fB\-\-vsock\fR
option causes Ncat to use AF_VSOCK sockets rather than network sockets\&. A CID must be given instead of a hostname or IP address\&. For example, to make a connection to the host,
.PP
\fBncat \-\-vsock 2 1234\fR
.PP
To listen on a socket:
.PP
\fBncat \-l \-\-vsock 1234\fR
.PP
Both stream and datagram domain sockets are supported, but socket type availability depends on the hypervisor\&. Use
\fB\-\-vsock\fR
on its own for stream sockets, or combine it with
\fB\-\-udp\fR
for datagram sockets\&.
.SH "EXAMPLES" .SH "EXAMPLES"
.PP .PP
Connect to example\&.org on TCP port 8080\&. Connect to example\&.org on TCP port 8080\&.
@@ -646,13 +705,13 @@ Netcat (or any other implementation), Ncat is most definitely based on Netcat in
.SH "LEGAL NOTICES" .SH "LEGAL NOTICES"
.SS "Ncat Copyright and Licensing" .SS "Ncat Copyright and Licensing"
.PP .PP
Ncat is (C) 2005\(en2012 Insecure\&.Com LLC\&. It is distributed as free and open source software under the same license terms as our Nmap software\&. Precise terms and further details are available Ncat is (C) 2005\(en2018 Insecure\&.Com LLC\&. It is distributed as free and open source software under the same license terms as our Nmap software\&. Precise terms and further details are available
from \m[blue]\fB\%https://nmap.org/man/man-legal.html\fR\m[]\&. from \m[blue]\fB\%https://nmap.org/man/man-legal.html\fR\m[]\&.
.SS "Creative Commons License for this Ncat Guide" .SS "Creative Commons License for this Ncat Guide"
.PP .PP
This This
Ncat Reference Guide Ncat Reference Guide
is (C) 2005\(en2012 Insecure\&.Com LLC\&. It is hereby placed under version 3\&.0 of the is (C) 2005\(en2018 Insecure\&.Com LLC\&. It is hereby placed under version 3\&.0 of the
\m[blue]\fBCreative Commons Attribution License\fR\m[]\&\s-2\u[1]\d\s+2\&. This allows you redistribute and modify the work as you desire, as long as you credit the original source\&. Alternatively, you may choose to treat this document as falling under the same license as Ncap itself (discussed previously)\&. \m[blue]\fBCreative Commons Attribution License\fR\m[]\&\s-2\u[1]\d\s+2\&. This allows you redistribute and modify the work as you desire, as long as you credit the original source\&. Alternatively, you may choose to treat this document as falling under the same license as Ncap itself (discussed previously)\&.
.SS "Source Code Availability and Community Contributions" .SS "Source Code Availability and Community Contributions"
.PP .PP

View File

@@ -6,6 +6,7 @@ Options taking a time assume seconds. Append 'ms' for milliseconds,
-4 Use IPv4 only -4 Use IPv4 only
-6 Use IPv6 only -6 Use IPv6 only
-U, --unixsock Use Unix domain sockets only -U, --unixsock Use Unix domain sockets only
--vsock Use vsock sockets only
-C, --crlf Use CRLF for EOL sequence -C, --crlf Use CRLF for EOL sequence
-c, --sh-exec <command> Executes the given command via /bin/sh -c, --sh-exec <command> Executes the given command via /bin/sh
-e, --exec <command> Executes the given command -e, --exec <command> Executes the given command

View File

@@ -153,6 +153,19 @@
SCTP support is implemented in TCP-compatible mode.</para> SCTP support is implemented in TCP-compatible mode.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>--vsock</option> (Use AF_VSOCK sockets)
<indexterm><primary><option>--vsock</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>Use AF_VSOCK sockets rather than the default TCP sockets (Linux only).
This option may be used on its own for stream sockets or combined with <option>--udp</option> for datagram sockets.
A description of <option>--vsock</option> mode is in
<xref linkend="ncat-man-vsock"/>.</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
@@ -916,6 +929,26 @@
</refsect1> </refsect1>
<refsect1 id="ncat-man-vsock">
<title>AF_VSOCK Sockets</title>
<para>
The <option>--vsock</option> option causes Ncat to use AF_VSOCK
sockets rather than network sockets. A CID must be given instead of a
hostname or IP address. For example, to make a connection to the host,
</para>
<para><command>ncat --vsock 2 1234</command></para>
<para>
To listen on a socket:
</para>
<para><command>ncat -l --vsock 1234</command></para>
<para>
Both stream and datagram domain sockets are supported, but socket type
availability depends on the hypervisor. Use
<option>--vsock</option> on its own for stream sockets, or
combine it with <option>--udp</option> for datagram sockets.
</para>
</refsect1>
<refsect1 id="ncat-man-examples"> <refsect1 id="ncat-man-examples">
<title>Examples</title> <title>Examples</title>

View File

@@ -1163,6 +1163,21 @@ static void try_nsock_connect(nsock_pool nsp, struct sockaddr_list *conn_addr)
NULL); NULL);
} }
else else
#endif
#ifdef HAVE_LINUX_VM_SOCKETS_H
if (o.af == AF_VSOCK) {
if (o.proto == IPPROTO_UDP) {
nsock_connect_vsock_datagram(nsp, cs.sock_nsi, connect_handler,
(void *)conn_addr->next, &conn_addr->addr.sockaddr,
conn_addr->addrlen, conn_addr->addr.vm.svm_port);
} else {
nsock_connect_vsock_stream(nsp, cs.sock_nsi, connect_handler,
o.conntimeout, (void *)conn_addr->next,
&conn_addr->addr.sockaddr, conn_addr->addrlen,
conn_addr->addr.vm.svm_port);
}
}
else
#endif #endif
if (o.proto == IPPROTO_UDP) { if (o.proto == IPPROTO_UDP) {
nsock_connect_udp(nsp, cs.sock_nsi, connect_handler, (void *)conn_addr->next, nsock_connect_udp(nsp, cs.sock_nsi, connect_handler, (void *)conn_addr->next,

View File

@@ -685,6 +685,17 @@ void setup_environment(struct fdinfo *info)
setenv_portable("NCAT_REMOTE_ADDR", "localhost"); setenv_portable("NCAT_REMOTE_ADDR", "localhost");
setenv_portable("NCAT_REMOTE_PORT", ""); setenv_portable("NCAT_REMOTE_PORT", "");
} else } else
#endif
#ifdef HAVE_LINUX_VM_SOCKETS_H
if (su.sockaddr.sa_family == AF_VSOCK) {
char char_u32[11];
snprintf(char_u32, sizeof(char_u32), "%u", su.vm.svm_cid);
setenv_portable("NCAT_REMOTE_ADDR", char_u32);
snprintf(char_u32, sizeof(char_u32), "%u", su.vm.svm_port);
setenv_portable("NCAT_REMOTE_PORT", char_u32);
} else
#endif #endif
if (getnameinfo((struct sockaddr *)&su, alen, ip, sizeof(ip), if (getnameinfo((struct sockaddr *)&su, alen, ip, sizeof(ip),
port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) == 0) { port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
@@ -703,6 +714,17 @@ void setup_environment(struct fdinfo *info)
setenv_portable("NCAT_LOCAL_ADDR", "localhost"); setenv_portable("NCAT_LOCAL_ADDR", "localhost");
setenv_portable("NCAT_LOCAL_PORT", ""); setenv_portable("NCAT_LOCAL_PORT", "");
} else } else
#endif
#ifdef HAVE_LINUX_VM_SOCKETS_H
if (su.sockaddr.sa_family == AF_VSOCK) {
char char_u32[11];
snprintf(char_u32, sizeof(char_u32), "%u", su.vm.svm_cid);
setenv_portable("NCAT_LOCAL_ADDR", char_u32);
snprintf(char_u32, sizeof(char_u32), "%u", su.vm.svm_port);
setenv_portable("NCAT_LOCAL_PORT", char_u32);
} else
#endif #endif
if (getnameinfo((struct sockaddr *)&su, alen, ip, sizeof(ip), if (getnameinfo((struct sockaddr *)&su, alen, ip, sizeof(ip),
port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) == 0) { port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {

View File

@@ -165,7 +165,7 @@ enum exec_mode {
#define PROXYDNS_REMOTE 2 #define PROXYDNS_REMOTE 2
struct options { struct options {
unsigned short portno; unsigned int portno;
int verbose; int verbose;
int debug; int debug;

View File

@@ -992,6 +992,14 @@ int ncat_listen()
else else
return ncat_listen_stream(0); return ncat_listen_stream(0);
else else
#endif
#if HAVE_LINUX_VM_SOCKETS_H
if (o.af == AF_VSOCK) {
if (o.proto == IPPROTO_UDP)
return ncat_listen_dgram(0);
else
return ncat_listen_stream(0);
} else
#endif #endif
if (o.httpserver) if (o.httpserver)
return ncat_http_server(); return ncat_http_server();

View File

@@ -287,7 +287,8 @@ int main(int argc, char *argv[])
struct host_list_node *deny_host_list = NULL; struct host_list_node *deny_host_list = NULL;
unsigned short proxyport; unsigned short proxyport;
int srcport = -1; long max_port = 65535;
long srcport = -1;
char *source = NULL; char *source = NULL;
struct option long_options[] = { struct option long_options[] = {
@@ -295,6 +296,9 @@ int main(int argc, char *argv[])
{"6", no_argument, NULL, '6'}, {"6", no_argument, NULL, '6'},
#if HAVE_SYS_UN_H #if HAVE_SYS_UN_H
{"unixsock", no_argument, NULL, 'U'}, {"unixsock", no_argument, NULL, 'U'},
#endif
#if HAVE_LINUX_VM_SOCKETS_H
{"vsock", no_argument, NULL, 0},
#endif #endif
{"crlf", no_argument, NULL, 'C'}, {"crlf", no_argument, NULL, 'C'},
{"g", required_argument, NULL, 'g'}, {"g", required_argument, NULL, 'g'},
@@ -449,9 +453,10 @@ int main(int argc, char *argv[])
o.hexlog = optarg; o.hexlog = optarg;
break; break;
case 'p': case 'p':
srcport = atoi(optarg); errno = 0;
if (srcport < 0 || srcport > 0xffff) srcport = strtol(optarg, NULL, 10);
bye("Invalid source port %d.", srcport); if (errno != 0 || srcport < 0)
bye("Invalid source port %ld.", srcport);
break; break;
case 'i': case 'i':
o.idletimeout = parse_timespec(optarg, "-i timeout"); o.idletimeout = parse_timespec(optarg, "-i timeout");
@@ -616,6 +621,11 @@ int main(int argc, char *argv[])
lua_setup(); lua_setup();
lua_run(); lua_run();
} }
#endif
#if HAVE_LINUX_VM_SOCKETS_H
else if (strcmp(long_options[option_index].name, "vsock") == 0) {
o.af = AF_VSOCK;
}
#endif #endif
break; break;
case 'h': case 'h':
@@ -630,6 +640,9 @@ int main(int argc, char *argv[])
#if HAVE_SYS_UN_H #if HAVE_SYS_UN_H
" -U, --unixsock Use Unix domain sockets only\n" " -U, --unixsock Use Unix domain sockets only\n"
#endif #endif
#if HAVE_LINUX_VM_SOCKETS_H
" --vsock Use vsock sockets only\n"
#endif
" -C, --crlf Use CRLF for EOL sequence\n" " -C, --crlf Use CRLF for EOL sequence\n"
" -c, --sh-exec <command> Executes the given command via /bin/sh\n" " -c, --sh-exec <command> Executes the given command via /bin/sh\n"
" -e, --exec <command> Executes the given command\n" " -e, --exec <command> Executes the given command\n"
@@ -693,6 +706,14 @@ int main(int argc, char *argv[])
} }
} }
#if HAVE_LINUX_VM_SOCKETS_H
if (o.af == AF_VSOCK)
max_port = UINT32_MAX;
#endif
if (srcport > max_port)
bye("Invalid source port %ld.", srcport);
#ifndef HAVE_OPENSSL #ifndef HAVE_OPENSSL
if (o.ssl) if (o.ssl)
bye("OpenSSL isn't compiled in. The --ssl option cannot be chosen."); bye("OpenSSL isn't compiled in. The --ssl option cannot be chosen.");
@@ -729,6 +750,21 @@ int main(int argc, char *argv[])
} }
#endif /* HAVE_SYS_UN_H */ #endif /* HAVE_SYS_UN_H */
#if HAVE_LINUX_VM_SOCKETS_H
if (o.af == AF_VSOCK) {
if (o.proxyaddr || o.proxytype)
bye("Proxy option not supported when using vsock sockets.");
#ifdef HAVE_OPENSSL
if (o.ssl)
bye("SSL option not supported when using vsock sockets.");
#endif
if (o.broker)
bye("Connection brokering not supported when using vsock sockets.");
if (o.numsrcrtes > 0)
bye("Loose source routing not allowed when using vsock sockets.");
}
#endif /* HAVE_LINUX_VM_SOCKETS_H */
/* Create a static target address, because at least one target address must be always allocated */ /* Create a static target address, because at least one target address must be always allocated */
targetaddrs = (struct sockaddr_list *)safe_zalloc(sizeof(struct sockaddr_list)); targetaddrs = (struct sockaddr_list *)safe_zalloc(sizeof(struct sockaddr_list));
@@ -818,6 +854,21 @@ int main(int argc, char *argv[])
if (o.verbose) if (o.verbose)
loguser("Specifying source socket for other than DATAGRAM Unix domain sockets have no effect.\n"); loguser("Specifying source socket for other than DATAGRAM Unix domain sockets have no effect.\n");
} else } else
#endif
#if HAVE_LINUX_VM_SOCKETS_H
if (o.af == AF_VSOCK) {
long long_cid;
srcaddr.vm.svm_family = AF_VSOCK;
errno = 0;
long_cid = strtol(source, NULL, 10);
if (errno != 0 || long_cid <= 0 || long_cid > UINT32_MAX)
bye("Invalid source address CID \"%s\".", source);
srcaddr.vm.svm_cid = long_cid;
srcaddrlen = sizeof(srcaddr.vm);
} else
#endif #endif
rc = resolve(source, 0, &srcaddr.storage, &srcaddrlen, o.af); rc = resolve(source, 0, &srcaddr.storage, &srcaddrlen, o.af);
if (rc != 0) if (rc != 0)
@@ -851,6 +902,26 @@ int main(int argc, char *argv[])
o.target = argv[optind]; o.target = argv[optind];
optind++; optind++;
} else } else
#endif
#if HAVE_LINUX_VM_SOCKETS_H
if (o.af == AF_VSOCK) {
if (!o.listen || optind + 1 < argc) {
long long_cid;
memset(&targetaddrs->addr.storage, 0, sizeof(struct sockaddr_vm));
targetaddrs->addr.vm.svm_family = AF_VSOCK;
errno = 0;
long_cid = strtol(argv[optind], NULL, 10);
if (errno != 0 || long_cid <= 0 || long_cid > UINT32_MAX)
bye("Invalid CID \"%s\".", argv[optind]);
targetaddrs->addr.vm.svm_cid = long_cid;
targetaddrs->addrlen = sizeof(targetaddrs->addr.vm);
o.target = argv[optind];
optind++;
}
} else
#endif #endif
/* Resolve hostname if we're given one */ /* Resolve hostname if we're given one */
if (strspn(argv[optind], "0123456789") != strlen(argv[optind])) { if (strspn(argv[optind], "0123456789") != strlen(argv[optind])) {
@@ -881,7 +952,7 @@ int main(int argc, char *argv[])
if (optind + 1 < argc || (o.listen && srcport != -1 && optind + 1 == argc)) { if (optind + 1 < argc || (o.listen && srcport != -1 && optind + 1 == argc)) {
loguser("Got more than one port specification:"); loguser("Got more than one port specification:");
if (o.listen && srcport != -1) if (o.listen && srcport != -1)
loguser_noprefix(" %d", srcport); loguser_noprefix(" %ld", srcport);
for (; optind < argc; optind++) for (; optind < argc; optind++)
loguser_noprefix(" %s", argv[optind]); loguser_noprefix(" %s", argv[optind]);
loguser_noprefix(". QUITTING.\n"); loguser_noprefix(". QUITTING.\n");
@@ -891,10 +962,10 @@ int main(int argc, char *argv[])
errno = 0; errno = 0;
long_port = strtol(argv[optind], NULL, 10); long_port = strtol(argv[optind], NULL, 10);
if (errno != 0 || long_port < 0 || long_port > 65535) if (errno != 0 || long_port < 0 || long_port > max_port)
bye("Invalid port number \"%s\".", argv[optind]); bye("Invalid port number \"%s\".", argv[optind]);
o.portno = (unsigned short) long_port; o.portno = (unsigned int) long_port;
} }
if (o.proxytype && !o.listen) if (o.proxytype && !o.listen)
@@ -913,6 +984,10 @@ int main(int argc, char *argv[])
/* If we use Unix domain sockets, we have to count with them. */ /* If we use Unix domain sockets, we have to count with them. */
else if (targetaddrs_item->addr.storage.ss_family == AF_UNIX) else if (targetaddrs_item->addr.storage.ss_family == AF_UNIX)
; /* Do nothing. */ ; /* Do nothing. */
#endif
#if HAVE_LINUX_VM_SOCKETS_H
else if (targetaddrs_item->addr.storage.ss_family == AF_VSOCK)
targetaddrs_item->addr.vm.svm_port = o.portno;
#endif #endif
else if (targetaddrs_item->addr.storage.ss_family == AF_UNSPEC) else if (targetaddrs_item->addr.storage.ss_family == AF_UNSPEC)
; /* Leave unspecified. */ ; /* Leave unspecified. */
@@ -941,8 +1016,12 @@ int main(int argc, char *argv[])
if (srcaddr.storage.ss_family == AF_INET) if (srcaddr.storage.ss_family == AF_INET)
srcaddr.in.sin_port = htons(srcport); srcaddr.in.sin_port = htons(srcport);
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
else else if (srcaddr.storage.ss_family == AF_INET6)
srcaddr.in6.sin6_port = htons(srcport); srcaddr.in6.sin6_port = htons(srcport);
#endif
#ifdef HAVE_LINUX_VM_SOCKETS_H
else if (srcaddr.storage.ss_family == AF_VSOCK)
srcaddr.vm.svm_port = srcport;
#endif #endif
} }
} }
@@ -1052,6 +1131,14 @@ static int ncat_listen_mode(void)
bye("Failed to resolve default IPv4 address: %s.", gai_strerror(rc)); bye("Failed to resolve default IPv4 address: %s.", gai_strerror(rc));
num_listenaddrs++; num_listenaddrs++;
} }
#ifdef HAVE_LINUX_VM_SOCKETS_H
if (o.af == AF_VSOCK) {
listenaddrs[num_listenaddrs].vm.svm_family = AF_VSOCK;
listenaddrs[num_listenaddrs].vm.svm_cid = VMADDR_CID_ANY;
listenaddrs[num_listenaddrs].vm.svm_port = o.portno;
num_listenaddrs++;
}
#endif
} }
if (o.proxytype) { if (o.proxytype) {

View File

@@ -133,10 +133,17 @@
#ifndef SOCKADDR_U_H_ #ifndef SOCKADDR_U_H_
#define SOCKADDR_U_H_ #define SOCKADDR_U_H_
#if HAVE_LINUX_VM_SOCKETS_H
#include <linux/vm_sockets.h>
#endif
union sockaddr_u { union sockaddr_u {
struct sockaddr_storage storage; struct sockaddr_storage storage;
#ifdef HAVE_SYS_UN_H #ifdef HAVE_SYS_UN_H
struct sockaddr_un un; struct sockaddr_un un;
#endif
#ifdef HAVE_LINUX_VM_SOCKETS_H
struct sockaddr_vm vm;
#endif #endif
struct sockaddr_in in; struct sockaddr_in in;
struct sockaddr_in6 in6; struct sockaddr_in6 in6;

View File

@@ -151,6 +151,10 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#if HAVE_LINUX_VM_SOCKETS_H
#include <linux/vm_sockets.h>
#endif
/* safely add 2 size_t */ /* safely add 2 size_t */
size_t sadd(size_t l, size_t r) size_t sadd(size_t l, size_t r)
{ {
@@ -464,6 +468,11 @@ int do_listen(int type, int proto, const union sockaddr_u *srcaddr_u)
sa_len = SUN_LEN(&srcaddr_u->un); sa_len = SUN_LEN(&srcaddr_u->un);
break; break;
#endif #endif
#ifdef HAVE_LINUX_VM_SOCKETS_H
case AF_VSOCK:
sa_len = sizeof (struct sockaddr_vm);
break;
#endif
#ifdef HAVE_SOCKADDR_SA_LEN #ifdef HAVE_SOCKADDR_SA_LEN
default: default:
sa_len = srcaddr_u->sockaddr.sa_len; sa_len = srcaddr_u->sockaddr.sa_len;
@@ -489,6 +498,14 @@ int do_listen(int type, int proto, const union sockaddr_u *srcaddr_u)
bye("bind to %s: %s.", srcaddr_u->un.sun_path, bye("bind to %s: %s.", srcaddr_u->un.sun_path,
socket_strerror(socket_errno())); socket_strerror(socket_errno()));
else else
#endif
#ifdef HAVE_LINUX_VM_SOCKETS_H
if (srcaddr_u->storage.ss_family == AF_VSOCK)
bye("bind to %u:%u: %s.",
srcaddr_u->vm.svm_cid,
srcaddr_u->vm.svm_port,
socket_strerror(socket_errno()));
else
#endif #endif
bye("bind to %s:%hu: %s.", inet_socktop(srcaddr_u), bye("bind to %s:%hu: %s.", inet_socktop(srcaddr_u),
inet_port(srcaddr_u), socket_strerror(socket_errno())); inet_port(srcaddr_u), socket_strerror(socket_errno()));
@@ -502,6 +519,13 @@ int do_listen(int type, int proto, const union sockaddr_u *srcaddr_u)
if (srcaddr_u->storage.ss_family == AF_UNIX) if (srcaddr_u->storage.ss_family == AF_UNIX)
loguser("Listening on %s\n", srcaddr_u->un.sun_path); loguser("Listening on %s\n", srcaddr_u->un.sun_path);
else else
#endif
#ifdef HAVE_LINUX_VM_SOCKETS_H
if (srcaddr_u->storage.ss_family == AF_VSOCK)
loguser("Listening on %u:%u\n",
srcaddr_u->vm.svm_cid,
srcaddr_u->vm.svm_port);
else
#endif #endif
loguser("Listening on %s:%hu\n", inet_socktop(srcaddr_u), inet_port(srcaddr_u)); loguser("Listening on %s:%hu\n", inet_socktop(srcaddr_u), inet_port(srcaddr_u));
} }

View File

@@ -88,6 +88,10 @@
#endif #endif
#endif /* HAVE_SYS_UN_H */ #endif /* HAVE_SYS_UN_H */
#if HAVE_LINUX_VM_SOCKETS_H
#include <linux/vm_sockets.h>
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@@ -530,6 +534,37 @@ nsock_event_id nsock_connect_unixsock_datagram(nsock_pool nsp, nsock_iod nsiod,
void *userdata, struct sockaddr *ss, size_t sslen); void *userdata, struct sockaddr *ss, size_t sslen);
#endif /* HAVE_SYS_UN_H */ #endif /* HAVE_SYS_UN_H */
#if HAVE_LINUX_VM_SOCKETS_H
/* Request a vsock stream connection to another system. ss should be a
* sockaddr_storage or sockaddr_vm, as appropriate (just like what you would
* pass to connect). sslen should be the sizeof the structure you are passing
* in. */
nsock_event_id nsock_connect_vsock_stream(nsock_pool nsp, nsock_iod ms_iod,
nsock_ev_handler handler,
int timeout_msecs, void *userdata,
struct sockaddr *saddr, size_t sslen,
unsigned int port);
/* Request a vsock datagram "connection" to another system. Since this is a
* datagram socket, no packets are actually sent. The destination CID and port
* are just associated with the nsiod (an actual OS connect() call is made).
* You can then use the normal nsock write calls on the socket. There is no
* timeout since this call always calls your callback at the next opportunity.
* The advantages to having a connected datagram socket (as opposed to just
* specifying an address with sendto() are that we can now use a consistent set
* of write/read calls for stream and datagram sockets, received packets from
* the non-partner are automatically dropped by the OS, and the OS can provide
* asynchronous errors (see Unix Network Programming pp224). ss should be a
* sockaddr_storage or sockaddr_vm, as appropriate (just like what you would
* pass to connect). sslen should be the sizeof the structure you are passing
* in. */
nsock_event_id nsock_connect_vsock_datagram(nsock_pool nsp, nsock_iod nsiod,
nsock_ev_handler handler,
void *userdata,
struct sockaddr *saddr,
size_t sslen, unsigned int port);
#endif /* HAVE_LINUX_VM_SOCKETS_H */
/* Request a TCP connection to another system (by IP address). The in_addr is /* Request a TCP connection to another system (by IP address). The in_addr is
* normal network byte order, but the port number should be given in HOST BYTE * normal network byte order, but the port number should be given in HOST BYTE
* ORDER. ss should be a sockaddr_storage, sockaddr_in6, or sockaddr_in as * ORDER. ss should be a sockaddr_storage, sockaddr_in6, or sockaddr_in as

View File

@@ -78,6 +78,8 @@
/* Define to 1 if you have the <sys/un.h> header file. */ /* Define to 1 if you have the <sys/un.h> header file. */
#undef HAVE_SYS_UN_H #undef HAVE_SYS_UN_H
#undef HAVE_LINUX_VM_SOCKETS_H
#undef HAVE_NETDB_H #undef HAVE_NETDB_H
#undef HAVE_OPENSSL #undef HAVE_OPENSSL

13
nsock/src/configure vendored
View File

@@ -4694,6 +4694,19 @@ fi
done done
for ac_header in linux/vm_sockets.h
do :
ac_fn_c_check_header_compile "$LINENO" "linux/vm_sockets.h" "ac_cv_header_linux_vm_sockets_h" "#include <sys/socket.h>
"
if test "x$ac_cv_header_linux_vm_sockets_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LINUX_VM_SOCKETS_H 1
_ACEOF
fi
done
# We test whether they specified openssl desires explicitly # We test whether they specified openssl desires explicitly
use_openssl="yes" use_openssl="yes"

View File

@@ -206,6 +206,7 @@ AC_CHECK_FUNC(nanosleep, , AC_CHECK_LIB(posix4, nanosleep))
dnl Checks for header files. dnl Checks for header files.
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS(net/bpf.h sys/ioctl.h sys/un.h netdb.h) AC_CHECK_HEADERS(net/bpf.h sys/ioctl.h sys/un.h netdb.h)
AC_CHECK_HEADERS([linux/vm_sockets.h], , , [#include <sys/socket.h>])
# We test whether they specified openssl desires explicitly # We test whether they specified openssl desires explicitly
use_openssl="yes" use_openssl="yes"

View File

@@ -187,7 +187,7 @@ int nsock_setup_udp(nsock_pool nsp, nsock_iod ms_iod, int af) {
/* This does the actual logistics of requesting a connection. It is shared /* This does the actual logistics of requesting a connection. It is shared
* by nsock_connect_tcp and nsock_connect_ssl, among others */ * by nsock_connect_tcp and nsock_connect_ssl, among others */
void nsock_connect_internal(struct npool *ms, struct nevent *nse, int type, int proto, struct sockaddr_storage *ss, size_t sslen, void nsock_connect_internal(struct npool *ms, struct nevent *nse, int type, int proto, struct sockaddr_storage *ss, size_t sslen,
unsigned short port) { unsigned int port) {
struct sockaddr_in *sin; struct sockaddr_in *sin;
#if HAVE_IPV6 #if HAVE_IPV6
@@ -243,6 +243,13 @@ void nsock_connect_internal(struct npool *ms, struct nevent *nse, int type, int
#if HAVE_SYS_UN_H #if HAVE_SYS_UN_H
else if (ss->ss_family == AF_UNIX) { else if (ss->ss_family == AF_UNIX) {
} }
#endif
#if HAVE_LINUX_VM_SOCKETS_H
else if (ss->ss_family == AF_VSOCK) {
struct sockaddr_vm *svm = (struct sockaddr_vm *)ss;
svm->svm_port = port;
}
#endif #endif
else { else {
fatal("Unknown address family %d\n", ss->ss_family); fatal("Unknown address family %d\n", ss->ss_family);
@@ -321,6 +328,76 @@ nsock_event_id nsock_connect_unixsock_datagram(nsock_pool nsp, nsock_iod nsiod,
#endif /* HAVE_SYS_UN_H */ #endif /* HAVE_SYS_UN_H */
#if HAVE_LINUX_VM_SOCKETS_H
/* Request a vsock stream connection to another system. ss should be a
* sockaddr_storage or sockaddr_vm, as appropriate (just like what you would
* pass to connect). sslen should be the sizeof the structure you are passing
* in. */
nsock_event_id nsock_connect_vsock_stream(nsock_pool nsp, nsock_iod ms_iod,
nsock_ev_handler handler,
int timeout_msecs, void *userdata,
struct sockaddr *saddr, size_t sslen,
unsigned int port) {
struct niod *nsi = (struct niod *)ms_iod;
struct npool *ms = (struct npool *)nsp;
struct nevent *nse;
struct sockaddr_storage *ss = (struct sockaddr_storage *)saddr;
struct sockaddr_vm *svm = (struct sockaddr_vm *)saddr;
assert(nsi->state == NSIOD_STATE_INITIAL || nsi->state == NSIOD_STATE_UNKNOWN);
nse = event_new(ms, NSE_TYPE_CONNECT, nsi, timeout_msecs, handler, userdata);
assert(nse);
nsock_log_info("vsock stream connection requested to %u:%u (IOD #%li) EID %li",
svm->svm_cid, port, nsi->id, nse->id);
/* Do the actual connect() */
nsock_connect_internal(ms, nse, SOCK_STREAM, 0, ss, sslen, port);
nsock_pool_add_event(ms, nse);
return nse->id;
}
/* Request a vsock datagram "connection" to another system. Since this is a
* datagram socket, no packets are actually sent. The destination CID and port
* are just associated with the nsiod (an actual OS connect() call is made).
* You can then use the normal nsock write calls on the socket. There is no
* timeout since this call always calls your callback at the next opportunity.
* The advantages to having a connected datagram socket (as opposed to just
* specifying an address with sendto() are that we can now use a consistent set
* of write/read calls for stream and datagram sockets, received packets from
* the non-partner are automatically dropped by the OS, and the OS can provide
* asynchronous errors (see Unix Network Programming pp224). ss should be a
* sockaddr_storage or sockaddr_vm, as appropriate (just like what you would
* pass to connect). sslen should be the sizeof the structure you are passing
* in. */
nsock_event_id nsock_connect_vsock_datagram(nsock_pool nsp, nsock_iod nsiod,
nsock_ev_handler handler,
void *userdata,
struct sockaddr *saddr,
size_t sslen, unsigned int port) {
struct niod *nsi = (struct niod *)nsiod;
struct npool *ms = (struct npool *)nsp;
struct nevent *nse;
struct sockaddr_storage *ss = (struct sockaddr_storage *)saddr;
struct sockaddr_vm *svm = (struct sockaddr_vm *)saddr;
assert(nsi->state == NSIOD_STATE_INITIAL || nsi->state == NSIOD_STATE_UNKNOWN);
nse = event_new(ms, NSE_TYPE_CONNECT, nsi, -1, handler, userdata);
assert(nse);
nsock_log_info("vsock dgram connection requested to %u:%u (IOD #%li) EID %li",
svm->svm_cid, port, nsi->id, nse->id);
nsock_connect_internal(ms, nse, SOCK_DGRAM, 0, ss, sslen, port);
nsock_pool_add_event(ms, nse);
return nse->id;
}
#endif /* HAVE_LINUX_VM_SOCKETS_H */
/* Request a TCP connection to another system (by IP address). The in_addr is /* Request a TCP connection to another system (by IP address). The in_addr is
* normal network byte order, but the port number should be given in HOST BYTE * normal network byte order, but the port number should be given in HOST BYTE
* ORDER. ss should be a sockaddr_storage, sockaddr_in6, or sockaddr_in as * ORDER. ss should be a sockaddr_storage, sockaddr_in6, or sockaddr_in as

View File

@@ -473,7 +473,7 @@ void event_delete(struct npool *nsp, struct nevent *nse);
* etc. */ * etc. */
void nsock_pool_add_event(struct npool *nsp, struct nevent *nse); void nsock_pool_add_event(struct npool *nsp, struct nevent *nse);
void nsock_connect_internal(struct npool *ms, struct nevent *nse, int type, int proto, struct sockaddr_storage *ss, size_t sslen, unsigned short port); void nsock_connect_internal(struct npool *ms, struct nevent *nse, int type, int proto, struct sockaddr_storage *ss, size_t sslen, unsigned int port);
/* Comments on using the following handle_*_result functions are available in nsock_core.c */ /* Comments on using the following handle_*_result functions are available in nsock_core.c */