MFV: nc(1) from OpenBSD 4.9.
MFC after: 1 month Obtained from: OpenBSD
This commit is contained in:
commit
59c7ad52aa
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user