MFV: nc(1) from OpenBSD 4.9.

MFC after:	1 month
Obtained from:	OpenBSD
This commit is contained in:
Xin LI 2011-05-11 21:52:26 +00:00
commit 59c7ad52aa
4 changed files with 129 additions and 50 deletions

View File

@ -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_t), int fd, void *_s, size_t n)
case -1:
if (errno == EINTR)
continue;
if (errno == EAGAIN) {
if ((errno == EAGAIN) || (errno == ENOBUFS)) {
(void)poll(&pfd, 1, -1);
continue;
}

View File

@ -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 or in the order that the system
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 version 5 is used.
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 conjunction with the
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

View File

@ -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 char *, struct addrinfo);
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 {
@ -467,6 +492,38 @@ main(int argc, char *argv[])
exit(ret);
}
/*
* unix_bind()
* Returns a unix socket bound to the given path
*/
int
unix_bind(char *path)
{
struct sockaddr_un sun;
int s;
/* Create unix domain socket. */
if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM,
0)) < 0)
return (-1);
memset(&sun, 0, sizeof(struct sockaddr_un));
sun.sun_family = AF_UNIX;
if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
sizeof(sun.sun_path)) {
close(s);
errno = ENAMETOOLONG;
return (-1);
}
if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
close(s);
return (-1);
}
return (s);
}
/*
* unix_connect()
* Returns a socket connected to a local unix socket. Returns -1 on failure.
@ -477,8 +534,13 @@ unix_connect(char *path)
struct sockaddr_un sun;
int s;
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));
@ -505,28 +567,10 @@ unix_connect(char *path)
int
unix_listen(char *path)
{
struct sockaddr_un sun;
int s;
/* Create unix domain socket. */
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
if ((s = unix_bind(path)) < 0)
return (-1);
memset(&sun, 0, sizeof(struct sockaddr_un));
sun.sun_family = AF_UNIX;
if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
sizeof(sun.sun_path)) {
close(s);
errno = ENAMETOOLONG;
return (-1);
}
if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
close(s);
return (-1);
}
if (listen(s, 5) < 0) {
close(s);
return (-1);
@ -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);
}

View File

@ -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 char *port,
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,