A recently added -F option to the nc (netcat) command to pass a
connected file descriptor to stdout only works for the listen mode
when it passes the accepted descriptor.
The patch below makes -F universal. When given it makes nc to always
pass the socket to stdout rather than performing the copy loop. This
works both in the client and the server modes including -l -k when nc
continuesly passes to stdout all sockets it accepted when listening to
the connection.
The patch aslo updates nc.1 to show how to use nc -F together with
ProxyUseFdPass.
Index: nc.1
===================================================================
RCS file: /cvs/src/usr.bin/nc/nc.1,v
retrieving revision 1.67
diff -U3 -p -r1.67 nc.1
--- nc.1 26 Feb 2014 20:56:11 -0000 1.67
+++ nc.1 2 May 2014 18:18:10 -0000
@@ -103,9 +103,9 @@ Enable debugging on the socket.
.It Fl d
Do not attempt to read from stdin.
.It Fl F
-Pass the first connected socket using
+Pass the connected socket using
.Xr sendmsg 2
-to stdout and exit.
+to stdout and close own copy.
This is useful in conjunction with
.Fl X
to have
@@ -116,7 +116,14 @@ connection to another program (e.g.\&
using the
.Xr ssh_config 5
.Cm ProxyUseFdPass
-option).
+directive). When this option is specified together with
+.Fl l,
+.Nm
+sends a socket representing the connection it accepted from a client. If the
+.Fl k
+is also given,
+.Nm
+will continue to send all incomming connections indefinitely.
.It Fl h
Prints out
.Nm
@@ -445,16 +452,18 @@ stream socket:
.Dl $ nc -lU /var/tmp/dsocket
.Pp
Connect to port 42 of host.example.com via an HTTP proxy at 10.2.3.4,
-port 8080.
+port 8080, pass the connected socket to stdout and exit.
This example could also be used by
.Xr ssh 1 ;
see the
.Cm ProxyCommand
-directive in
+and
+.Cm ProxyUseFdPass
+directives in
.Xr ssh_config 5
for more information.
.Pp
-.Dl $ nc -x10.2.3.4:8080 -Xconnect host.example.com 42
+.Dl $ nc -F -x10.2.3.4:8080 -Xconnect host.example.com 42
.Pp
The same example again, this time enabling proxy authentication with username
.Dq ruser
Index: netcat.c
===================================================================
RCS file: /cvs/src/usr.bin/nc/netcat.c,v
retrieving revision 1.118
diff -U3 -p -r1.118 netcat.c
--- netcat.c 12 Mar 2014 10:19:40 -0000 1.118
+++ netcat.c 2 May 2014 18:18:10 -0000
@@ -99,7 +99,7 @@ void build_ports(char *);
void help(void);
int local_listen(char *, char *, struct addrinfo);
void readwrite(int);
-void fdpass(int nfd) __attribute__((noreturn));
+void fdpass(int nfd);
int remote_connect(const char *, const char *, struct addrinfo);
int timeout_connect(int, const struct sockaddr *, socklen_t);
int socks_connect(const char *, const char *, struct addrinfo,
@@ -286,6 +286,15 @@ main(int argc, char *argv[])
if (!lflag && kflag)
errx(1, "must use -l with -k");
+ if (Fflag && zflag) {
+ warnx(1, "ignoring -z flag as -F is given");
+ zflag = 0;
+ }
+ if (FFlag && uflag && kflag) {
+ warnx(1, "ignoring -k flag as -F is given together with -u");
+ kflag = 0;
+ }
+
/* Get name of temporary socket for unix datagram client */
if ((family == AF_UNIX) && uflag && !lflag) {
if (sflag) {
@@ -469,9 +478,7 @@ main(int argc, char *argv[])
uflag ? "udp" : "tcp",
sv ? sv->s_name : "*");
}
- if (Fflag)
- fdpass(s);
- else if (!zflag)
+ if (!zflag)
readwrite(s);
}
}
@@ -727,17 +734,25 @@ local_listen(char *host, char *port, str
/*
* readwrite()
- * Loop that polls on the network file descriptor and stdin.
+ * Loop that polls on the network file descriptor and stdin, or, when the
+ * FFlag is given, pass the descriptor to stdout.
*/
void
readwrite(int nfd)
{
struct pollfd pfd[2];
unsigned char buf[16384];
- int n, wfd = fileno(stdin);
- int lfd = fileno(stdout);
+ int n, wfd;
+ int lfd;
int plen;
+ if (Fflag) {
+ fdpass(nfd);
+ return;
+ }
+
+ lfd = fileno(stdout);
+ wfd = fileno(stdin);
plen = 2048;
/* Setup Network FD */
@@ -793,7 +808,7 @@ readwrite(int nfd)
/*
* fdpass()
- * Pass the connected file descriptor to stdout and exit.
+ * Pass the connected file descriptor to stdout.
*/
void
fdpass(int nfd)
@@ -848,7 +863,6 @@ fdpass(int nfd)
else
break;
}
- exit(0);
}
/* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */