Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 May 2011 21:52:26 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r221793 - head/contrib/netcat
Message-ID:  <201105112152.p4BLqQuI007584@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Wed May 11 21:52:26 2011
New Revision: 221793
URL: http://svn.freebsd.org/changeset/base/221793

Log:
  MFV: nc(1) from OpenBSD 4.9.
  
  MFC after:	1 month
  Obtained from:	OpenBSD

Modified:
  head/contrib/netcat/atomicio.c
  head/contrib/netcat/nc.1
  head/contrib/netcat/netcat.c
  head/contrib/netcat/socks.c
Directory Properties:
  head/contrib/netcat/   (props changed)

Modified: head/contrib/netcat/atomicio.c
==============================================================================
--- head/contrib/netcat/atomicio.c	Wed May 11 21:47:30 2011	(r221792)
+++ head/contrib/netcat/atomicio.c	Wed May 11 21:52:26 2011	(r221793)
@@ -1,4 +1,4 @@
-/* $OpenBSD: atomicio.c,v 1.9 2007/09/07 14:50:44 tobias Exp $ */
+/* $OpenBSD: atomicio.c,v 1.10 2011/01/08 00:47:19 jeremy Exp $ */
 /*
  * Copyright (c) 2006 Damien Miller. All rights reserved.
  * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
@@ -53,7 +53,7 @@ atomicio(ssize_t (*f) (int, void *, size
 		case -1:
 			if (errno == EINTR)
 				continue;
-			if (errno == EAGAIN) {
+			if ((errno == EAGAIN) || (errno == ENOBUFS)) {
 				(void)poll(&pfd, 1, -1);
 				continue;
 			}

Modified: head/contrib/netcat/nc.1
==============================================================================
--- head/contrib/netcat/nc.1	Wed May 11 21:47:30 2011	(r221792)
+++ head/contrib/netcat/nc.1	Wed May 11 21:52:26 2011	(r221793)
@@ -1,4 +1,4 @@
-.\"     $OpenBSD: nc.1,v 1.55 2010/07/25 07:51:39 guenther Exp $
+.\"     $OpenBSD: nc.1,v 1.57 2011/01/09 22:16:46 jeremy Exp $
 .\"
 .\" Copyright (c) 1996 David Sacerdote
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 25, 2010
+.Dd January 8, 2011
 .Dt NC 1
 .Os
 .Sh NAME
@@ -44,7 +44,7 @@
 .Op Fl O Ar length
 .Op Fl P Ar proxy_username
 .Op Fl p Ar source_port
-.Op Fl s Ar source_ip_address
+.Op Fl s Ar source
 .Op Fl T Ar ToS
 .Op Fl V Ar rtable
 .Op Fl w Ar timeout
@@ -53,7 +53,7 @@
 .Fl x Ar proxy_address Ns Oo : Ns
 .Ar port Oc
 .Xc Oc
-.Op Ar hostname
+.Op Ar destination
 .Op Ar port
 .Ek
 .Sh DESCRIPTION
@@ -61,8 +61,10 @@ The
 .Nm
 (or
 .Nm netcat )
-utility is used for just about anything under the sun involving TCP
-or UDP.
+utility is used for just about anything under the sun involving TCP,
+UDP, or
+.Ux Ns -domain
+sockets.
 It can open TCP connections, send UDP packets, listen on arbitrary
 TCP and UDP ports, do port scanning, and deal with both IPv4 and
 IPv6.
@@ -175,8 +177,12 @@ instead of sequentially within a range o
 assigns them.
 .It Fl S
 Enables the RFC 2385 TCP MD5 signature option.
-.It Fl s Ar source_ip_address
+.It Fl s Ar source
 Specifies the IP of the interface which is used to send the packets.
+For
+.Ux Ns -domain
+datagram sockets, specifies the local temporary socket file
+to create and use so that datagrams can be received.
 It is an error to use this option in conjunction with the
 .Fl l
 option.
@@ -201,6 +207,16 @@ Specifies to use
 sockets.
 .It Fl u
 Use UDP instead of the default option of TCP.
+For
+.Ux Ns -domain
+sockets, use a datagram socket instead of a stream socket.
+If a
+.Ux Ns -domain
+socket is used, a temporary receiving socket is created in
+.Pa /tmp
+unless the
+.Fl s
+flag is given.
 .It Fl V Ar rtable
 Set the routing table
 .Pq Dq FIB
@@ -244,7 +260,7 @@ If the protocol is not specified, SOCKS 
 Requests that
 .Nm
 should connect to
-.Ar hostname
+.Ar destination
 using a proxy at
 .Ar proxy_address
 and
@@ -262,16 +278,22 @@ It is an error to use this option in con
 option.
 .El
 .Pp
-.Ar hostname
+.Ar destination
 can be a numerical IP address or a symbolic hostname
 (unless the
 .Fl n
 option is given).
-In general, a hostname must be specified,
+In general, a destination must be specified,
 unless the
 .Fl l
 option is given
 (in which case the local host is used).
+For
+.Ux Ns -domain
+sockets, a destination is required and is the socket path to connect to
+(or listen on if the
+.Fl l
+option is given).
 .Pp
 .Ar port
 can be a single integer or a range of ports.
@@ -280,8 +302,7 @@ In general,
 a destination port must be specified,
 unless the
 .Fl U
-option is given
-(in which case a socket must be specified).
+option is given.
 .Sh CLIENT/SERVER MODEL
 It is quite simple to build a very basic client/server model using
 .Nm .
@@ -424,7 +445,7 @@ outgoing traffic only.
 .Pp
 Create and listen on a
 .Ux Ns -domain
-socket:
+stream socket:
 .Pp
 .Dl $ nc -lU /var/tmp/dsocket
 .Pp

Modified: head/contrib/netcat/netcat.c
==============================================================================
--- head/contrib/netcat/netcat.c	Wed May 11 21:47:30 2011	(r221792)
+++ head/contrib/netcat/netcat.c	Wed May 11 21:52:26 2011	(r221793)
@@ -1,4 +1,4 @@
-/* $OpenBSD: netcat.c,v 1.98 2010/07/03 04:44:51 guenther Exp $ */
+/* $OpenBSD: netcat.c,v 1.100 2011/01/09 22:16:46 jeremy Exp $ */
 /*
  * Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
  *
@@ -70,6 +70,7 @@
 
 #define PORT_MAX	65535
 #define PORT_MAX_LEN	6
+#define UNIX_DG_TMP_SOCKET_SIZE	19
 
 /* Command Line Options */
 int	dflag;					/* detached, no stdin */
@@ -98,6 +99,7 @@ u_int	rtableid;
 int timeout = -1;
 int family = AF_UNSPEC;
 char *portlist[PORT_MAX+1];
+char *unix_dg_tmp_socket;
 
 void	atelnet(int, unsigned char *, unsigned int);
 void	build_ports(char *);
@@ -108,6 +110,7 @@ int	remote_connect(const char *, const c
 int	socks_connect(const char *, const char *, struct addrinfo,
 	    const char *, const char *, struct addrinfo, int, const char *);
 int	udptest(int);
+int	unix_bind(char *);
 int	unix_connect(char *);
 int	unix_listen(char *);
 void	set_common_sockopts(int);
@@ -134,6 +137,7 @@ main(int argc, char *argv[])
 	char *proxy;
 	const char *errstr, *proxyhost = "", *proxyport = NULL;
 	struct addrinfo proxyhints;
+	char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE];
 	struct option longopts[] = {
 		{ "no-tcpopt",	no_argument,	&FreeBSD_Oflag,	1 },
 		{ NULL,		0,		NULL,		0 }
@@ -288,8 +292,6 @@ main(int argc, char *argv[])
 
 	/* Cruft to make sure options are clean, and used properly. */
 	if (argv[0] && !argv[1] && family == AF_UNIX) {
-		if (uflag)
-			errx(1, "cannot use -u and -U");
 		host = argv[0];
 		uport = NULL;
 	} else if (argv[0] && !argv[1]) {
@@ -312,6 +314,19 @@ main(int argc, char *argv[])
 	if (!lflag && kflag)
 		errx(1, "must use -l with -k");
 
+	/* Get name of temporary socket for unix datagram client */
+	if ((family == AF_UNIX) && uflag && !lflag) {
+		if (sflag) {
+			unix_dg_tmp_socket = sflag;
+		} else {
+			strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX",
+				UNIX_DG_TMP_SOCKET_SIZE);
+			if (mktemp(unix_dg_tmp_socket_buf) == NULL)
+				err(1, "mktemp");
+			unix_dg_tmp_socket = unix_dg_tmp_socket_buf;
+		}
+	}
+
 	/* Initialize addrinfo structure. */
 	if (family != AF_UNIX) {
 		memset(&hints, 0, sizeof(struct addrinfo));
@@ -354,8 +369,12 @@ main(int argc, char *argv[])
 		int connfd;
 		ret = 0;
 
-		if (family == AF_UNIX)
-			s = unix_listen(host);
+		if (family == AF_UNIX) {
+			if (uflag)
+				s = unix_bind(host);
+			else
+				s = unix_listen(host);
+		}
 
 		/* Allow only one connection at a time, but stay alive. */
 		for (;;) {
@@ -384,17 +403,21 @@ main(int argc, char *argv[])
 				if (rv < 0)
 					err(1, "connect");
 
-				connfd = s;
+				readwrite(s);
 			} else {
 				len = sizeof(cliaddr);
 				connfd = accept(s, (struct sockaddr *)&cliaddr,
 				    &len);
+				readwrite(connfd);
+				close(connfd);
 			}
 
-			readwrite(connfd);
-			close(connfd);
 			if (family != AF_UNIX)
 				close(s);
+			else if (uflag) {
+				if (connect(s, NULL, 0) < 0)
+					err(1, "connect");
+			}
 
 			if (!kflag)
 				break;
@@ -408,6 +431,8 @@ main(int argc, char *argv[])
 		} else
 			ret = 1;
 
+		if (uflag)
+			unlink(unix_dg_tmp_socket);
 		exit(ret);
 
 	} else {
@@ -468,18 +493,19 @@ main(int argc, char *argv[])
 }
 
 /*
- * unix_connect()
- * Returns a socket connected to a local unix socket. Returns -1 on failure.
+ * unix_bind()
+ * Returns a unix socket bound to the given path
  */
 int
-unix_connect(char *path)
+unix_bind(char *path)
 {
 	struct sockaddr_un sun;
 	int s;
 
-	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+	/* Create unix domain socket. */
+	if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM,
+	     0)) < 0)
 		return (-1);
-	(void)fcntl(s, F_SETFD, 1);
 
 	memset(&sun, 0, sizeof(struct sockaddr_un));
 	sun.sun_family = AF_UNIX;
@@ -490,27 +516,32 @@ unix_connect(char *path)
 		errno = ENAMETOOLONG;
 		return (-1);
 	}
-	if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
+
+	if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
 		close(s);
 		return (-1);
 	}
 	return (s);
-
 }
 
 /*
- * unix_listen()
- * Create a unix domain socket, and listen on it.
+ * unix_connect()
+ * Returns a socket connected to a local unix socket. Returns -1 on failure.
  */
 int
-unix_listen(char *path)
+unix_connect(char *path)
 {
 	struct sockaddr_un sun;
 	int s;
 
-	/* Create unix domain socket. */
-	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
-		return (-1);
+	if (uflag) {
+		if ((s = unix_bind(unix_dg_tmp_socket)) < 0)
+			return (-1);
+	} else {
+		if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+			return (-1);
+	}
+	(void)fcntl(s, F_SETFD, 1);
 
 	memset(&sun, 0, sizeof(struct sockaddr_un));
 	sun.sun_family = AF_UNIX;
@@ -521,11 +552,24 @@ unix_listen(char *path)
 		errno = ENAMETOOLONG;
 		return (-1);
 	}
-
-	if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
+	if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
 		close(s);
 		return (-1);
 	}
+	return (s);
+
+}
+
+/*
+ * unix_listen()
+ * Create a unix domain socket, and listen on it.
+ */
+int
+unix_listen(char *path)
+{
+	int s;
+	if ((s = unix_bind(path)) < 0)
+		return (-1);
 
 	if (listen(s, 5) < 0) {
 		close(s);
@@ -989,9 +1033,9 @@ usage(int ret)
 #else
 	    "usage: nc [-46DdhklnrStUuvz] [-I length] [-i interval] [-O length]\n"
 #endif
-	    "\t  [-P proxy_username] [-p source_port] [-s source_ip_address] [-T ToS]\n"
+	    "\t  [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n"
 	    "\t  [-V rtable] [-w timeout] [-X proxy_protocol]\n"
-	    "\t  [-x proxy_address[:port]] [hostname] [port]\n");
+	    "\t  [-x proxy_address[:port]] [destination] [port]\n");
 	if (ret)
 		exit(1);
 }

Modified: head/contrib/netcat/socks.c
==============================================================================
--- head/contrib/netcat/socks.c	Wed May 11 21:47:30 2011	(r221792)
+++ head/contrib/netcat/socks.c	Wed May 11 21:52:26 2011	(r221793)
@@ -1,4 +1,4 @@
-/*	$OpenBSD: socks.c,v 1.18 2010/04/20 07:26:35 nicm Exp $	*/
+/*	$OpenBSD: socks.c,v 1.19 2011/02/12 15:54:18 okan Exp $	*/
 
 /*
  * Copyright (c) 1999 Niklas Hallqvist.  All rights reserved.
@@ -222,11 +222,25 @@ socks_connect(const char *host, const ch
 		if (cnt != wlen)
 			err(1, "write failed (%zu/%zu)", cnt, wlen);
 
-		cnt = atomicio(read, proxyfd, buf, 10);
-		if (cnt != 10)
-			err(1, "read failed (%zu/10)", cnt);
+		cnt = atomicio(read, proxyfd, buf, 4);
+		if (cnt != 4)
+			err(1, "read failed (%zu/4)", cnt);
 		if (buf[1] != 0)
 			errx(1, "connection failed, SOCKS error %d", buf[1]);
+		switch (buf[3]) {
+		case SOCKS_IPV4:
+			cnt = atomicio(read, proxyfd, buf + 4, 6);
+			if (cnt != 6)
+				err(1, "read failed (%zd/6)", cnt);
+			break;
+		case SOCKS_IPV6:
+			cnt = atomicio(read, proxyfd, buf + 4, 18);
+			if (cnt != 18)
+				err(1, "read failed (%zd/18)", cnt);
+			break;
+		default:
+			errx(1, "connection failed, unsupported address type");
+		}
 	} else if (socksv == 4) {
 		/* This will exit on lookup failure */
 		decode_addrport(host, port, (struct sockaddr *)&addr,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105112152.p4BLqQuI007584>