Vendor import of netcat as of OPENBSD_5_1.

This commit is contained in:
Xin LI 2012-05-04 18:29:32 +00:00
parent b4a93b50d6
commit 4e1e6f2641
2 changed files with 129 additions and 39 deletions

48
nc.1
View File

@ -1,4 +1,4 @@
.\" $OpenBSD: nc.1,v 1.57 2011/01/09 22:16:46 jeremy Exp $
.\" $OpenBSD: nc.1,v 1.60 2012/02/07 12:11:43 lum Exp $
.\"
.\" Copyright (c) 1996 David Sacerdote
.\" All rights reserved.
@ -25,7 +25,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd $Mdocdate: January 8 2011 $
.Dd $Mdocdate: October 4 2011 $
.Dt NC 1
.Os
.Sh NAME
@ -41,7 +41,7 @@
.Op Fl P Ar proxy_username
.Op Fl p Ar source_port
.Op Fl s Ar source
.Op Fl T Ar ToS
.Op Fl T Ar toskeyword
.Op Fl V Ar rtable
.Op Fl w Ar timeout
.Op Fl X Ar proxy_protocol
@ -164,14 +164,21 @@ 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.
.It Fl T Ar ToS
Specifies IP Type of Service (ToS) for the connection.
Valid values are the tokens
.Dq lowdelay ,
.Dq throughput ,
.Dq reliability ,
or an 8-bit hexadecimal value preceded by
.Dq 0x .
.It Fl T Ar toskeyword
Change IPv4 TOS value.
.Ar toskeyword
may be one of
.Ar critical ,
.Ar inetcontrol ,
.Ar lowdelay ,
.Ar netcontrol ,
.Ar throughput ,
.Ar reliability ,
or one of the DiffServ Code Points:
.Ar ef ,
.Ar af11 ... af43 ,
.Ar cs0 ... cs7 ;
or a number in either hex or decimal.
.It Fl t
Causes
.Nm
@ -203,9 +210,9 @@ Have
.Nm
give more verbose output.
.It Fl w Ar timeout
If a connection and stdin are idle for more than
Connections which cannot be established or are idle timeout after
.Ar timeout
seconds, then the connection is silently closed.
seconds.
The
.Fl w
flag has no effect on the
@ -442,8 +449,15 @@ Original implementation by *Hobbit*
Rewritten with IPv6 support by
.An Eric Jackson Aq ericj@monkey.org .
.Sh CAVEATS
UDP port scans will always succeed
(i.e. report the port as open),
rendering the
UDP port scans using the
.Fl uz
combination of flags relatively useless.
combination of flags will always report success irrespective of
the target machine's state.
However,
in conjunction with a traffic sniffer either on the target machine
or an intermediary device,
the
.Fl uz
combination could be useful for communications diagnostics.
Note that the amount of UDP traffic generated may be limited either
due to hardware resources and/or configuration settings.

120
netcat.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: netcat.c,v 1.101 2011/06/21 17:31:07 mikeb Exp $ */
/* $OpenBSD: netcat.c,v 1.105 2012/02/09 06:25:35 lum Exp $ */
/*
* Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
*
@ -98,6 +98,7 @@ void help(void);
int local_listen(char *, char *, struct addrinfo);
void readwrite(int);
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,
const char *, const char *, struct addrinfo, int, const char *);
int udptest(int);
@ -105,7 +106,7 @@ int unix_bind(char *);
int unix_connect(char *);
int unix_listen(char *);
void set_common_sockopts(int);
int parse_iptos(char *);
int map_tos(char *, int *);
void usage(int);
int
@ -234,7 +235,18 @@ main(int argc, char *argv[])
Sflag = 1;
break;
case 'T':
Tflag = parse_iptos(optarg);
errstr = NULL;
errno = 0;
if (map_tos(optarg, &Tflag))
break;
if (strlen(optarg) > 1 && optarg[0] == '0' &&
optarg[1] == 'x')
Tflag = (int)strtol(optarg, NULL, 16);
else
Tflag = (int)strtonum(optarg, 0, 255,
&errstr);
if (Tflag < 0 || Tflag > 255 || errstr || errno)
errx(1, "illegal tos value %s", optarg);
break;
default:
usage(1);
@ -579,7 +591,7 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
set_common_sockopts(s);
if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
break;
else if (vflag)
warn("connect to %s port %s (%s) failed", host, port,
@ -594,6 +606,43 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
return (s);
}
int
timeout_connect(int s, const struct sockaddr *name, socklen_t namelen)
{
struct pollfd pfd;
socklen_t optlen;
int flags, optval;
int ret;
if (timeout != -1) {
flags = fcntl(s, F_GETFL, 0);
if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1)
err(1, "set non-blocking mode");
}
if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) {
pfd.fd = s;
pfd.events = POLLOUT;
if ((ret = poll(&pfd, 1, timeout)) == 1) {
optlen = sizeof(optval);
if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR,
&optval, &optlen)) == 0) {
errno = optval;
ret = optval == 0 ? 0 : -1;
}
} else if (ret == 0) {
errno = ETIMEDOUT;
ret = -1;
} else
err(1, "poll failed");
}
if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1)
err(1, "restoring flags");
return (ret);
}
/*
* local_listen()
* Returns a socket listening on a local port, binds to specified source
@ -753,7 +802,7 @@ atelnet(int nfd, unsigned char *buf, unsigned int size)
/*
* build_ports()
* Build an array or ports in portlist[], listing each port
* Build an array of ports in portlist[], listing each port
* that we should try to connect to.
*/
void
@ -765,9 +814,6 @@ build_ports(char *p)
int x = 0;
if ((n = strchr(p, '-')) != NULL) {
if (lflag)
errx(1, "Cannot use -l with multiple ports!");
*n = '\0';
n++;
@ -819,8 +865,7 @@ build_ports(char *p)
/*
* udptest()
* Do a few writes to see if the UDP port is there.
* XXX - Better way of doing this? Doesn't work for IPv6.
* Also fails after around 100 ports checked.
* Fails once PF state table is full.
*/
int
udptest(int s)
@ -874,20 +919,51 @@ set_common_sockopts(int s)
}
int
parse_iptos(char *s)
map_tos(char *s, int *val)
{
int tos = -1;
/* DiffServ Codepoints and other TOS mappings */
const struct toskeywords {
const char *keyword;
int val;
} *t, toskeywords[] = {
{ "af11", IPTOS_DSCP_AF11 },
{ "af12", IPTOS_DSCP_AF12 },
{ "af13", IPTOS_DSCP_AF13 },
{ "af21", IPTOS_DSCP_AF21 },
{ "af22", IPTOS_DSCP_AF22 },
{ "af23", IPTOS_DSCP_AF23 },
{ "af31", IPTOS_DSCP_AF31 },
{ "af32", IPTOS_DSCP_AF32 },
{ "af33", IPTOS_DSCP_AF33 },
{ "af41", IPTOS_DSCP_AF41 },
{ "af42", IPTOS_DSCP_AF42 },
{ "af43", IPTOS_DSCP_AF43 },
{ "critical", IPTOS_PREC_CRITIC_ECP },
{ "cs0", IPTOS_DSCP_CS0 },
{ "cs1", IPTOS_DSCP_CS1 },
{ "cs2", IPTOS_DSCP_CS2 },
{ "cs3", IPTOS_DSCP_CS3 },
{ "cs4", IPTOS_DSCP_CS4 },
{ "cs5", IPTOS_DSCP_CS5 },
{ "cs6", IPTOS_DSCP_CS6 },
{ "cs7", IPTOS_DSCP_CS7 },
{ "ef", IPTOS_DSCP_EF },
{ "inetcontrol", IPTOS_PREC_INTERNETCONTROL },
{ "lowdelay", IPTOS_LOWDELAY },
{ "netcontrol", IPTOS_PREC_NETCONTROL },
{ "reliability", IPTOS_RELIABILITY },
{ "throughput", IPTOS_THROUGHPUT },
{ NULL, -1 },
};
if (strcmp(s, "lowdelay") == 0)
return (IPTOS_LOWDELAY);
if (strcmp(s, "throughput") == 0)
return (IPTOS_THROUGHPUT);
if (strcmp(s, "reliability") == 0)
return (IPTOS_RELIABILITY);
for (t = toskeywords; t->keyword != NULL; t++) {
if (strcmp(s, t->keyword) == 0) {
*val = t->val;
return (1);
}
}
if (sscanf(s, "0x%x", &tos) != 1 || tos < 0 || tos > 0xff)
errx(1, "invalid IP Type of Service");
return (tos);
return (0);
}
void
@ -911,7 +987,7 @@ help(void)
\t-r Randomize remote ports\n\
\t-S Enable the TCP MD5 signature option\n\
\t-s addr\t Local source address\n\
\t-T ToS\t Set IP Type of Service\n\
\t-T toskeyword\tSet IP Type of Service\n\
\t-t Answer TELNET negotiation\n\
\t-U Use UNIX domain socket\n\
\t-u UDP mode\n\