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-*-
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
fingerprints in http-enum. None of the standard fingerprints uses these
fields. [Kostas Milonas]

View File

@@ -125,6 +125,9 @@
/* Define to 1 if you have the <sys/un.h> header file. */
#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. */
#undef HAVE_VPRINTF

13
ncat/configure vendored
View File

@@ -3813,6 +3813,19 @@ fi
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.
{ $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_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([linux/vm_sockets.h], , , [#include <sys/socket.h>])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STAT

View File

@@ -2,12 +2,12 @@
.\" Title: Ncat
.\" Author: [see the "Authors" section]
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
.\" Date: 09/28/2018
.\" Date: 05/20/2019
.\" Manual: Ncat Reference Guide
.\" Source: Ncat
.\" 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
.\" -----------------------------------------------------------------
@@ -51,6 +51,7 @@ Options taking a time assume seconds\&. Append \*(Aqms\*(Aq for milliseconds,
\-4 Use IPv4 only
\-6 Use IPv6 only
\-U, \-\-unixsock Use Unix domain sockets only
\-\-vsock Use vsock sockets only
\-C, \-\-crlf Use CRLF for EOL sequence
\-c, \-\-sh\-exec <command> Executes the given command via /bin/sh
\-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
\-\-chat Start a simple Ncat chat server
\-\-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\-dns <type> Specify where to resolve proxy destination
\-\-ssl Connect or listen with SSL
\-\-ssl\-cert Specify SSL certificate file (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
Use SCTP for the connection (the default is TCP)\&. SCTP support is implemented in TCP\-compatible mode\&.
.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"
.PP
\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
.SH "PROXY OPTIONS"
.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
Requests proxying through
\fIhost\fR:\fIport\fR, using the protocol specified by
\fB\-\-proxy\-type\fR\&.
.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\&.
.RE
.PP
@@ -316,6 +328,30 @@ or
\fB\-\-proxy\-type socks5\fR, the form should be username:password\&. For
\fB\-\-proxy\-type socks4\fR, it should be a username only\&.
.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"
.PP
\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\&.
.RE
.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)
.RS 4
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
\fB\-\-source\fR
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"
.PP
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"
.SS "Ncat Copyright and Licensing"
.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[]\&.
.SS "Creative Commons License for this Ncat Guide"
.PP
This
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)\&.
.SS "Source Code Availability and Community Contributions"
.PP

View File

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

View File

@@ -153,6 +153,19 @@
SCTP support is implemented in TCP-compatible mode.</para>
</listitem>
</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>
</refsect1>
@@ -916,6 +929,26 @@
</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">
<title>Examples</title>

View File

@@ -1163,6 +1163,21 @@ static void try_nsock_connect(nsock_pool nsp, struct sockaddr_list *conn_addr)
NULL);
}
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
if (o.proto == IPPROTO_UDP) {
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_PORT", "");
} 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
if (getnameinfo((struct sockaddr *)&su, alen, ip, sizeof(ip),
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_PORT", "");
} 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
if (getnameinfo((struct sockaddr *)&su, alen, ip, sizeof(ip),
port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {

View File

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

View File

@@ -992,6 +992,14 @@ int ncat_listen()
else
return ncat_listen_stream(0);
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
if (o.httpserver)
return ncat_http_server();

View File

@@ -287,7 +287,8 @@ int main(int argc, char *argv[])
struct host_list_node *deny_host_list = NULL;
unsigned short proxyport;
int srcport = -1;
long max_port = 65535;
long srcport = -1;
char *source = NULL;
struct option long_options[] = {
@@ -295,6 +296,9 @@ int main(int argc, char *argv[])
{"6", no_argument, NULL, '6'},
#if HAVE_SYS_UN_H
{"unixsock", no_argument, NULL, 'U'},
#endif
#if HAVE_LINUX_VM_SOCKETS_H
{"vsock", no_argument, NULL, 0},
#endif
{"crlf", no_argument, NULL, 'C'},
{"g", required_argument, NULL, 'g'},
@@ -449,9 +453,10 @@ int main(int argc, char *argv[])
o.hexlog = optarg;
break;
case 'p':
srcport = atoi(optarg);
if (srcport < 0 || srcport > 0xffff)
bye("Invalid source port %d.", srcport);
errno = 0;
srcport = strtol(optarg, NULL, 10);
if (errno != 0 || srcport < 0)
bye("Invalid source port %ld.", srcport);
break;
case 'i':
o.idletimeout = parse_timespec(optarg, "-i timeout");
@@ -616,6 +621,11 @@ int main(int argc, char *argv[])
lua_setup();
lua_run();
}
#endif
#if HAVE_LINUX_VM_SOCKETS_H
else if (strcmp(long_options[option_index].name, "vsock") == 0) {
o.af = AF_VSOCK;
}
#endif
break;
case 'h':
@@ -630,6 +640,9 @@ int main(int argc, char *argv[])
#if HAVE_SYS_UN_H
" -U, --unixsock Use Unix domain sockets only\n"
#endif
#if HAVE_LINUX_VM_SOCKETS_H
" --vsock Use vsock sockets only\n"
#endif
" -C, --crlf Use CRLF for EOL sequence\n"
" -c, --sh-exec <command> Executes the given command via /bin/sh\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
if (o.ssl)
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 */
#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 */
targetaddrs = (struct sockaddr_list *)safe_zalloc(sizeof(struct sockaddr_list));
@@ -818,6 +854,21 @@ int main(int argc, char *argv[])
if (o.verbose)
loguser("Specifying source socket for other than DATAGRAM Unix domain sockets have no effect.\n");
} 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
rc = resolve(source, 0, &srcaddr.storage, &srcaddrlen, o.af);
if (rc != 0)
@@ -851,6 +902,26 @@ int main(int argc, char *argv[])
o.target = argv[optind];
optind++;
} 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
/* Resolve hostname if we're given one */
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)) {
loguser("Got more than one port specification:");
if (o.listen && srcport != -1)
loguser_noprefix(" %d", srcport);
loguser_noprefix(" %ld", srcport);
for (; optind < argc; optind++)
loguser_noprefix(" %s", argv[optind]);
loguser_noprefix(". QUITTING.\n");
@@ -891,10 +962,10 @@ int main(int argc, char *argv[])
errno = 0;
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]);
o.portno = (unsigned short) long_port;
o.portno = (unsigned int) long_port;
}
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. */
else if (targetaddrs_item->addr.storage.ss_family == AF_UNIX)
; /* 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
else if (targetaddrs_item->addr.storage.ss_family == AF_UNSPEC)
; /* Leave unspecified. */
@@ -941,8 +1016,12 @@ int main(int argc, char *argv[])
if (srcaddr.storage.ss_family == AF_INET)
srcaddr.in.sin_port = htons(srcport);
#ifdef HAVE_IPV6
else
else if (srcaddr.storage.ss_family == AF_INET6)
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
}
}
@@ -1052,6 +1131,14 @@ static int ncat_listen_mode(void)
bye("Failed to resolve default IPv4 address: %s.", gai_strerror(rc));
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) {

View File

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

View File

@@ -151,6 +151,10 @@
#include <unistd.h>
#endif
#if HAVE_LINUX_VM_SOCKETS_H
#include <linux/vm_sockets.h>
#endif
/* safely add 2 size_t */
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);
break;
#endif
#ifdef HAVE_LINUX_VM_SOCKETS_H
case AF_VSOCK:
sa_len = sizeof (struct sockaddr_vm);
break;
#endif
#ifdef HAVE_SOCKADDR_SA_LEN
default:
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,
socket_strerror(socket_errno()));
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
bye("bind to %s:%hu: %s.", inet_socktop(srcaddr_u),
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)
loguser("Listening on %s\n", srcaddr_u->un.sun_path);
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
loguser("Listening on %s:%hu\n", inet_socktop(srcaddr_u), inet_port(srcaddr_u));
}

View File

@@ -88,6 +88,10 @@
#endif
#endif /* HAVE_SYS_UN_H */
#if HAVE_LINUX_VM_SOCKETS_H
#include <linux/vm_sockets.h>
#endif
#ifdef __cplusplus
extern "C" {
#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);
#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
* 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

View File

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

13
nsock/src/configure vendored
View File

@@ -4694,6 +4694,19 @@ fi
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
use_openssl="yes"

View File

@@ -206,6 +206,7 @@ AC_CHECK_FUNC(nanosleep, , AC_CHECK_LIB(posix4, nanosleep))
dnl Checks for header files.
AC_HEADER_STDC
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
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
* 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,
unsigned short port) {
unsigned int port) {
struct sockaddr_in *sin;
#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
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
else {
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 */
#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
* 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

View File

@@ -473,7 +473,7 @@ void event_delete(struct npool *nsp, struct nevent *nse);
* etc. */
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 */