netcat.c revision e4e83f8147f92141cd02cc46cccca088c527ea2a
1ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt/* $OpenBSD: netcat.c,v 1.103 2011/10/04 08:34:34 fgsch Exp $ */ 2ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt/* 3032722b2d24138ee92e459c779ae4869f33b1f37Jan Engelhardt * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> 4032722b2d24138ee92e459c779ae4869f33b1f37Jan Engelhardt * 5ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * Redistribution and use in source and binary forms, with or without 6ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * modification, are permitted provided that the following conditions 7ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * are met: 8ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * 9ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * 1. Redistributions of source code must retain the above copyright 10ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * notice, this list of conditions and the following disclaimer. 11ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * 2. Redistributions in binary form must reproduce the above copyright 12ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * notice, this list of conditions and the following disclaimer in the 13ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * documentation and/or other materials provided with the distribution. 14ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * 3. The name of the author may not be used to endorse or promote products 15ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * derived from this software without specific prior written permission. 16b4af04be14560b3fcc6cf23200148d408014a2f5Jan Engelhardt * 17ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 258d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt */ 28d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt 29d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt/* 30db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardt * Re-written nc(1) for OpenBSD. Original implementation by 311201871343223d9781253283a64686be4e63ad52Jan Engelhardt * *Hobbit* <hobbit@avian.org>. 321201871343223d9781253283a64686be4e63ad52Jan Engelhardt */ 33db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardt 348d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal#include <sys/types.h> 35ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#include <sys/socket.h> 36ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#include <sys/time.h> 37ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#include <sys/un.h> 38ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 39ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#include <netinet/in.h> 40ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#include <netinet/in_systm.h> 41d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt#include <netinet/tcp.h> 42d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt#include <netinet/ip.h> 43d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt#include <arpa/telnet.h> 44d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt 45d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt#include <err.h> 468d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal#include <errno.h> 47d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt#include <netdb.h> 48d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt#include <poll.h> 49d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt#include <stdarg.h> 50d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt#include <stdio.h> 511201871343223d9781253283a64686be4e63ad52Jan Engelhardt#include <stdlib.h> 521201871343223d9781253283a64686be4e63ad52Jan Engelhardt#include <string.h> 531201871343223d9781253283a64686be4e63ad52Jan Engelhardt#include <unistd.h> 54db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardt#include <fcntl.h> 55db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardt#include <limits.h> 56db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardt#include "atomicio.h" 57d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt 58ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#ifndef SUN_LEN 59ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#define SUN_LEN(su) \ 60ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) 61ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#endif 62ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 638b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt#define PORT_MAX 65535 649b488b992872d4d2b7ebf7897d74d52f4fb59e1cJan Engelhardt#define PORT_MAX_LEN 6 659b488b992872d4d2b7ebf7897d74d52f4fb59e1cJan Engelhardt#define UNIX_DG_TMP_SOCKET_SIZE 19 669b488b992872d4d2b7ebf7897d74d52f4fb59e1cJan Engelhardt 679b488b992872d4d2b7ebf7897d74d52f4fb59e1cJan Engelhardt/* Command Line Options */ 689b488b992872d4d2b7ebf7897d74d52f4fb59e1cJan Engelhardtint dflag; /* detached, no stdin */ 699b488b992872d4d2b7ebf7897d74d52f4fb59e1cJan Engelhardtunsigned int iflag; /* Interval Flag */ 709b488b992872d4d2b7ebf7897d74d52f4fb59e1cJan Engelhardt#ifdef ANDROID 719b488b992872d4d2b7ebf7897d74d52f4fb59e1cJan Engelhardtint jflag = 0; 729b488b992872d4d2b7ebf7897d74d52f4fb59e1cJan Engelhardt#else 73db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardtint jflag; /* use jumbo frames if we can */ 74ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#endif /* !ANDROID */ 75ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint kflag; /* More than one connect */ 76ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint lflag; /* Bind to local port */ 77ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint nflag; /* Don't do name look up */ 78ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtchar *Pflag; /* Proxy username */ 79ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtchar *pflag; /* Localport flag */ 80ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint rflag; /* Random ports flag */ 81ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtchar *sflag; /* Source Address */ 82ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint tflag; /* Telnet Emulation */ 83ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint uflag; /* UDP - Default to TCP */ 84ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint vflag; /* Verbosity */ 85ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#ifndef ANDROID 86ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint xflag; /* Socks proxy */ 87ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#endif /* !ANDROID */ 88fceebd8a493a16a767cf1c8e890830c129218c8fPatrick McHardyint zflag; /* Port Scan Flag */ 89ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint Dflag; /* sodebug */ 90ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint Iflag; /* TCP receive buffer size */ 91ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint Oflag; /* TCP send buffer size */ 92ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#ifndef ANDROID 93ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint Sflag; /* TCP MD5 signature option */ 94ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint Tflag = -1; /* IP Type of Service */ 95ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtu_int rtableid; 96ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#endif /* !ANDROID */ 97ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 98ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint timeout = -1; 99ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint family = AF_UNSPEC; 100ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtchar *portlist[PORT_MAX+1]; 101ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtchar *unix_dg_tmp_socket; 102ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 103ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtvoid atelnet(int, unsigned char *, unsigned int); 104ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtvoid build_ports(char *); 105ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtvoid help(void); 106ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint local_listen(char *, char *, struct addrinfo); 107ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtvoid readwrite(int); 108ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint remote_connect(const char *, const char *, struct addrinfo); 109ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint timeout_connect(int, const struct sockaddr *, socklen_t); 110ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#ifndef ANDROID 111ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint socks_connect(const char *, const char *, struct addrinfo, 112ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt const char *, const char *, struct addrinfo, int, const char *); 113ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#endif /* !ANDROID */ 114ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint udptest(int); 115ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint unix_bind(char *); 116ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint unix_connect(char *); 117ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint unix_listen(char *); 118ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtvoid set_common_sockopts(int); 119ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint map_tos(char *, int *); 120ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtvoid usage(int); 121ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 122ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtint 123ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardtmain(int argc, char *argv[]) 124ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt{ 125ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt int ch, s, ret, socksv; 126ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt char *host, *uport; 127ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt struct addrinfo hints; 128ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt struct servent *sv; 129ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt socklen_t len; 130ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt struct sockaddr_storage cliaddr; 131ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt char *proxy; 132ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt const char *errstr, *proxyhost = "", *proxyport = NULL; 133ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt struct addrinfo proxyhints; 134ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; 135ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 136ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt ret = 1; 137ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt s = 0; 138ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt socksv = 5; 139ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt host = NULL; 140ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt uport = NULL; 141ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt sv = NULL; 142ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 143ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt while ((ch = getopt(argc, argv, 144ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt "46DdhI:i:jklnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) { 145ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt switch (ch) { 1468ad33a34a34ba2bcd360352ad3b7772916832702Florian Westphal case '4': 147b1319cc083de658c0007da93f25d19874f75d55fJan Engelhardt family = AF_INET; 148b1319cc083de658c0007da93f25d19874f75d55fJan Engelhardt break; 149b1319cc083de658c0007da93f25d19874f75d55fJan Engelhardt case '6': 150b1319cc083de658c0007da93f25d19874f75d55fJan Engelhardt family = AF_INET6; 151b1319cc083de658c0007da93f25d19874f75d55fJan Engelhardt break; 152b1319cc083de658c0007da93f25d19874f75d55fJan Engelhardt case 'U': 153ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt family = AF_UNIX; 154ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 155ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'X': 156ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (strcasecmp(optarg, "connect") == 0) 1571829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt socksv = -1; /* HTTP proxy CONNECT */ 158ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt else if (strcmp(optarg, "4") == 0) 159ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt socksv = 4; /* SOCKS v.4 */ 1601829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt else if (strcmp(optarg, "5") == 0) 161ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt socksv = 5; /* SOCKS v.5 */ 162ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt else 163ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "unsupported proxy protocol"); 164ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 165ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'd': 166ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt dflag = 1; 167ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 168ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'h': 169ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt help(); 170ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 171ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'i': 172ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#ifdef ANDROID 173ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt iflag = atoi(optarg); 174ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#else 175ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt iflag = strtonum(optarg, 0, UINT_MAX, &errstr); 176ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (errstr) 177ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "interval %s: %s", errstr, optarg); 178ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#endif /* ANDROID */ 179ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 180ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#ifndef ANDROID 181ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'j': 182ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt jflag = 1; 183ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 184ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#endif /* !ANDROID */ 185ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'k': 186ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt kflag = 1; 187ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 188ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'l': 189ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt lflag = 1; 1901829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt break; 191ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'n': 192ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt nflag = 1; 193ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 194ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'P': 195ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt Pflag = optarg; 196ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 197ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'p': 198ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt pflag = optarg; 199ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 200ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'r': 201ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt rflag = 1; 202ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 203ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 's': 204ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt sflag = optarg; 205ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 206ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 't': 207ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt tflag = 1; 208ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 209ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'u': 210ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt uflag = 1; 211ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 212ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#ifndef ANDROID 213ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'V': 214ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt rtableid = (unsigned int)strtonum(optarg, 0, 215ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt RT_TABLEID_MAX, &errstr); 216ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (errstr) 217ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "rtable %s: %s", errstr, optarg); 218ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 219ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#endif /* !ANDROID */ 220ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'v': 221ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt vflag = 1; 2221829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt break; 223ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'w': 224ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#ifdef ANDROID 225ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt timeout = atoi(optarg); 226ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#else 227ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr); 228ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (errstr) 229ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "timeout %s: %s", errstr, optarg); 230ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#endif 231ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt timeout *= 1000; 232ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 233ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#ifndef ANDROID 234ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'x': 235ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt xflag = 1; 236ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if ((proxy = strdup(optarg)) == NULL) 237ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt err(1, NULL); 238ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 239ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#endif /* !ANDROID */ 2401829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt case 'z': 241ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt zflag = 1; 242ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 243ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'D': 244ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt Dflag = 1; 245ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 246ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'I': 247ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#ifdef ANDROID 248ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt Iflag = atoi(optarg); 249ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#else 250ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt Iflag = strtonum(optarg, 1, 65536 << 14, &errstr); 251ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (errstr != NULL) 252ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "TCP receive window %s: %s", 253ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errstr, optarg); 2541829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt#endif 255ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt break; 256ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt case 'O': 257ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#ifdef ANDROID 258ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt Oflag = atoi(optarg); 259ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#else 260ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt Oflag = strtonum(optarg, 1, 65536 << 14, &errstr); 261d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt if (errstr != NULL) 262ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "TCP send window %s: %s", 263d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt errstr, optarg); 264d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt#endif 265d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt break; 266d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt#ifndef ANDROID 267d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt case 'S': 268d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt Sflag = 1; 269d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt break; 270d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt case 'T': 271d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt errstr = NULL; 272d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt errno = 0; 273d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt if (map_tos(optarg, &Tflag)) 274d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt break; 275d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt if (strlen(optarg) > 1 && optarg[0] == '0' && 276d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt optarg[1] == 'x') 277d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt Tflag = (int)strtol(optarg, NULL, 16); 278d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt else 2798d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal Tflag = (int)strtonum(optarg, 0, 255, 2808d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal &errstr); 2818d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal if (Tflag < 0 || Tflag > 255 || errstr || errno) 282d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt errx(1, "illegal tos value %s", optarg); 283db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardt break; 284db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardt#endif /* !ANDROID */ 285db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardt default: 286db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardt usage(1); 287db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardt } 288db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardt } 289ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt argc -= optind; 290d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt argv += optind; 291d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt 292d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt /* Cruft to make sure options are clean, and used properly. */ 293d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt if (argv[0] && !argv[1] && family == AF_UNIX) { 294ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt host = argv[0]; 295d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt uport = NULL; 296d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt } else if (argv[0] && !argv[1]) { 297d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt if (!lflag) 298d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt usage(1); 299ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt uport = argv[0]; 300d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt host = NULL; 301ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } else if (argv[0] && argv[1]) { 302ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt host = argv[0]; 303ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt uport = argv[1]; 304ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } else 305ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt usage(1); 306ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 307ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (lflag && sflag) 308ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "cannot use -s and -l"); 309ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (lflag && pflag) 310ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "cannot use -p and -l"); 311ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (lflag && zflag) 312b1319cc083de658c0007da93f25d19874f75d55fJan Engelhardt errx(1, "cannot use -z and -l"); 313ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (!lflag && kflag) 314ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "must use -l with -k"); 315ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 316ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt /* Get name of temporary socket for unix datagram client */ 317ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if ((family == AF_UNIX) && uflag && !lflag) { 31873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt if (sflag) { 319ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt unix_dg_tmp_socket = sflag; 320ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } else { 321ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX", 32273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt UNIX_DG_TMP_SOCKET_SIZE); 323ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (mktemp(unix_dg_tmp_socket_buf) == NULL) 324ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt err(1, "mktemp"); 325ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt unix_dg_tmp_socket = unix_dg_tmp_socket_buf; 326ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } 327ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } 328ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 329ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt /* Initialize addrinfo structure. */ 330ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (family != AF_UNIX) { 33173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt memset(&hints, 0, sizeof(struct addrinfo)); 332ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt hints.ai_family = family; 333ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; 334ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; 335ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (nflag) 336ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt hints.ai_flags |= AI_NUMERICHOST; 337ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } 338ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 339ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#ifndef ANDROID 340ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (xflag) { 341ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (uflag) 342ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "no proxy support for UDP mode"); 343ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 344ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (lflag) 345ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "no proxy support for listen"); 346ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 347ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (family == AF_UNIX) 348ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "no proxy support for unix sockets"); 349ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 350ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt /* XXX IPv6 transport to proxy would probably work */ 351ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (family == AF_INET6) 352ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "no proxy support for IPv6"); 353ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 354ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (sflag) 355ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt errx(1, "no proxy support for local source address"); 356ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 357ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt proxyhost = strsep(&proxy, ":"); 358ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt proxyport = proxy; 35973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt 360ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt memset(&proxyhints, 0, sizeof(struct addrinfo)); 361ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt proxyhints.ai_family = family; 362ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt proxyhints.ai_socktype = SOCK_STREAM; 363ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt proxyhints.ai_protocol = IPPROTO_TCP; 364ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (nflag) 365ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt proxyhints.ai_flags |= AI_NUMERICHOST; 366ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } 367ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt#endif /* !ANDROID */ 368ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 369ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (lflag) { 370ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt int connfd; 371ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt ret = 0; 372ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 373ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (family == AF_UNIX) { 374ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (uflag) 375ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt s = unix_bind(host); 376ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt else 377ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt s = unix_listen(host); 378ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } 379ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 380ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt /* Allow only one connection at a time, but stay alive. */ 381ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt for (;;) { 38269f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt if (family != AF_UNIX) 383ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt s = local_listen(host, uport, hints); 384ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (s < 0) 38573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt err(1, NULL); 386ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt /* 387ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * For UDP, we will use recvfrom() initially 388ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * to wait for a caller, then use the regular 389ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt * functions to talk to the caller. 39073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt */ 391ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (uflag) { 39273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt int rv, plen; 393ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt char buf[16384]; 394ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt struct sockaddr_storage z; 39573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt 396ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt len = sizeof(z); 397ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt plen = jflag ? 16384 : 2048; 398ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt rv = recvfrom(s, buf, plen, MSG_PEEK, 39973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt (struct sockaddr *)&z, &len); 400ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (rv < 0) 401ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt err(1, "recvfrom"); 402ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 40373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt rv = connect(s, (struct sockaddr *)&z, len); 404ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (rv < 0) 405ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt err(1, "connect"); 406fceebd8a493a16a767cf1c8e890830c129218c8fPatrick McHardy 40773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt readwrite(s); 408ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } else { 409ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt len = sizeof(cliaddr); 410ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt connfd = accept(s, (struct sockaddr *)&cliaddr, 41173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt &len); 4128d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal readwrite(connfd); 4138d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal close(connfd); 414ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } 415ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 416ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (family != AF_UNIX) 417ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt close(s); 418ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt else if (uflag) { 419ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (connect(s, NULL, 0) < 0) 420ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt err(1, "connect"); 421ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } 422ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 423ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (!kflag) 42473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt break; 425ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } 42673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt } else if (family == AF_UNIX) { 427ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt ret = 0; 428ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 42973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt if ((s = unix_connect(host)) > 0 && !zflag) { 430ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt readwrite(s); 431ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt close(s); 432ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } else 43373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt ret = 1; 434ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 435ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (uflag) 436ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt unlink(unix_dg_tmp_socket); 437ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt exit(ret); 438db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardt 439db50b83bc3cd634beb71f38978ad7d035c88ff11Jan Engelhardt } else { 4408d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal int i = 0; 4418d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal 4428d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal /* Construct the portlist[] array. */ 4438d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal build_ports(uport); 4448d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal 4458d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal /* Cycle through portlist, connecting to each port. */ 4468d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal for (i = 0; portlist[i] != NULL; i++) { 4478d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal if (s) 4488d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal close(s); 4498d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal 4508d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal#ifndef ANDROID 451ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (xflag) 452ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt s = socks_connect(host, portlist[i], hints, 453181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt proxyhost, proxyport, proxyhints, socksv, 454ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt Pflag); 45542979363f3958b4436c6d2503753c182c58e55eaJan Engelhardt else 4568b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt#endif /* !ANDROID */ 457ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt s = remote_connect(host, portlist[i], hints); 458ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 459ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (s < 0) 460ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt continue; 461ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 462ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt ret = 0; 463d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt if (vflag || zflag) { 4648d8896a3833292d091ee5a028f3461083bb956bdFlorian Westphal /* For UDP, make sure we are connected. */ 465d64d54777b4a9405a8229a533e44a2e80f000a9fJan Engelhardt if (uflag) { 466ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt if (udptest(s) == -1) { 467ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt ret = 1; 468ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt continue; 469ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt } 470181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt } 471ad326ef9f734ac30548de292c59fc0e2fd81ac2aJan Engelhardt 472 /* Don't look up port if -n. */ 473 if (nflag) 474 sv = NULL; 475 else { 476 sv = getservbyport( 477 ntohs(atoi(portlist[i])), 478 uflag ? "udp" : "tcp"); 479 } 480 481 fprintf(stderr, 482 "Connection to %s %s port [%s/%s] " 483 "succeeded!\n", host, portlist[i], 484 uflag ? "udp" : "tcp", 485 sv ? sv->s_name : "*"); 486 } 487 if (!zflag) 488 readwrite(s); 489 } 490 } 491 492 if (s) 493 close(s); 494 495 exit(ret); 496} 497 498/* 499 * unix_bind() 500 * Returns a unix socket bound to the given path 501 */ 502int 503unix_bind(char *path) 504{ 505 struct sockaddr_un sun; 506 int s; 507 508 /* Create unix domain socket. */ 509 if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM, 510 0)) < 0) 511 return (-1); 512 513 memset(&sun, 0, sizeof(struct sockaddr_un)); 514 sun.sun_family = AF_UNIX; 515 516 if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= 517 sizeof(sun.sun_path)) { 518 close(s); 519 errno = ENAMETOOLONG; 520 return (-1); 521 } 522 523 if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { 524 close(s); 525 return (-1); 526 } 527 return (s); 528} 529 530/* 531 * unix_connect() 532 * Returns a socket connected to a local unix socket. Returns -1 on failure. 533 */ 534int 535unix_connect(char *path) 536{ 537 struct sockaddr_un sun; 538 int s; 539 540 if (uflag) { 541 if ((s = unix_bind(unix_dg_tmp_socket)) < 0) 542 return (-1); 543 } else { 544 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 545 return (-1); 546 } 547 (void)fcntl(s, F_SETFD, 1); 548 549 memset(&sun, 0, sizeof(struct sockaddr_un)); 550 sun.sun_family = AF_UNIX; 551 552 if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= 553 sizeof(sun.sun_path)) { 554 close(s); 555 errno = ENAMETOOLONG; 556 return (-1); 557 } 558 if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { 559 close(s); 560 return (-1); 561 } 562 return (s); 563 564} 565 566/* 567 * unix_listen() 568 * Create a unix domain socket, and listen on it. 569 */ 570int 571unix_listen(char *path) 572{ 573 int s; 574 if ((s = unix_bind(path)) < 0) 575 return (-1); 576 577 if (listen(s, 5) < 0) { 578 close(s); 579 return (-1); 580 } 581 return (s); 582} 583 584/* 585 * remote_connect() 586 * Returns a socket connected to a remote host. Properly binds to a local 587 * port or source address if needed. Returns -1 on failure. 588 */ 589int 590remote_connect(const char *host, const char *port, struct addrinfo hints) 591{ 592 struct addrinfo *res, *res0; 593 int s, error, on = 1; 594 595 if ((error = getaddrinfo(host, port, &hints, &res))) 596 errx(1, "getaddrinfo: %s", gai_strerror(error)); 597 598 res0 = res; 599 do { 600 if ((s = socket(res0->ai_family, res0->ai_socktype, 601 res0->ai_protocol)) < 0) 602 continue; 603 604#ifndef ANDROID 605 if (rtableid) { 606 if (setsockopt(s, SOL_SOCKET, SO_RTABLE, &rtableid, 607 sizeof(rtableid)) == -1) 608 err(1, "setsockopt SO_RTABLE"); 609 } 610#endif /* !ANDROID */ 611 612 /* Bind to a local port or source address if specified. */ 613 if (sflag || pflag) { 614 struct addrinfo ahints, *ares; 615 616#ifndef ANDROID 617 /* try SO_BINDANY, but don't insist */ 618 setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on)); 619#endif /* !ANDROID */ 620 memset(&ahints, 0, sizeof(struct addrinfo)); 621 ahints.ai_family = res0->ai_family; 622 ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; 623 ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; 624 ahints.ai_flags = AI_PASSIVE; 625 if ((error = getaddrinfo(sflag, pflag, &ahints, &ares))) 626 errx(1, "getaddrinfo: %s", gai_strerror(error)); 627 628 if (bind(s, (struct sockaddr *)ares->ai_addr, 629 ares->ai_addrlen) < 0) 630 errx(1, "bind failed: %s", strerror(errno)); 631 freeaddrinfo(ares); 632 } 633 634 set_common_sockopts(s); 635 636 if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0) 637 break; 638 else if (vflag) 639 warn("connect to %s port %s (%s) failed", host, port, 640 uflag ? "udp" : "tcp"); 641 642 close(s); 643 s = -1; 644 } while ((res0 = res0->ai_next) != NULL); 645 646 freeaddrinfo(res); 647 648 return (s); 649} 650 651int 652timeout_connect(int s, const struct sockaddr *name, socklen_t namelen) 653{ 654 struct pollfd pfd; 655 socklen_t optlen; 656 int flags, optval; 657 int ret; 658 659 if (timeout != -1) { 660 flags = fcntl(s, F_GETFL, 0); 661 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) 662 err(1, "set non-blocking mode"); 663 } 664 665 if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) { 666 pfd.fd = s; 667 pfd.events = POLLOUT; 668 if ((ret = poll(&pfd, 1, timeout)) == 1) { 669 optlen = sizeof(optval); 670 if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR, 671 &optval, &optlen)) == 0) { 672 errno = optval; 673 ret = optval == 0 ? 0 : -1; 674 } 675 } else if (ret == 0) { 676 errno = ETIMEDOUT; 677 ret = -1; 678 } else 679 err(1, "poll failed"); 680 } 681 682 if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1) 683 err(1, "restoring flags"); 684 685 return (ret); 686} 687 688/* 689 * local_listen() 690 * Returns a socket listening on a local port, binds to specified source 691 * address. Returns -1 on failure. 692 */ 693int 694local_listen(char *host, char *port, struct addrinfo hints) 695{ 696 struct addrinfo *res, *res0; 697 int s, ret, x = 1; 698 int error; 699 700 /* Allow nodename to be null. */ 701 hints.ai_flags |= AI_PASSIVE; 702 703 /* 704 * In the case of binding to a wildcard address 705 * default to binding to an ipv4 address. 706 */ 707 if (host == NULL && hints.ai_family == AF_UNSPEC) 708 hints.ai_family = AF_INET; 709 710 if ((error = getaddrinfo(host, port, &hints, &res))) 711 errx(1, "getaddrinfo: %s", gai_strerror(error)); 712 713 res0 = res; 714 do { 715 if ((s = socket(res0->ai_family, res0->ai_socktype, 716 res0->ai_protocol)) < 0) 717 continue; 718 719#ifndef ANDROID 720 if (rtableid) { 721 if (setsockopt(s, IPPROTO_IP, SO_RTABLE, &rtableid, 722 sizeof(rtableid)) == -1) 723 err(1, "setsockopt SO_RTABLE"); 724 } 725#endif /* !ANDROID */ 726 727#ifdef ANDROID 728 ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); 729#else 730 ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); 731#endif 732 if (ret == -1) 733 err(1, NULL); 734 735 set_common_sockopts(s); 736 737 if (bind(s, (struct sockaddr *)res0->ai_addr, 738 res0->ai_addrlen) == 0) 739 break; 740 741 close(s); 742 s = -1; 743 } while ((res0 = res0->ai_next) != NULL); 744 745 if (!uflag && s != -1) { 746 if (listen(s, 1) < 0) 747 err(1, "listen"); 748 } 749 750 freeaddrinfo(res); 751 752 return (s); 753} 754 755/* 756 * readwrite() 757 * Loop that polls on the network file descriptor and stdin. 758 */ 759void 760readwrite(int nfd) 761{ 762 struct pollfd pfd[2]; 763 unsigned char buf[16384]; 764 int n, wfd = fileno(stdin); 765 int lfd = fileno(stdout); 766 int plen; 767 768 plen = jflag ? 16384 : 2048; 769 770 /* Setup Network FD */ 771 pfd[0].fd = nfd; 772 pfd[0].events = POLLIN; 773 774 /* Set up STDIN FD. */ 775 pfd[1].fd = wfd; 776 pfd[1].events = POLLIN; 777 778 while (pfd[0].fd != -1) { 779 if (iflag) 780 sleep(iflag); 781 782 if ((n = poll(pfd, 2 - dflag, timeout)) < 0) { 783 close(nfd); 784 err(1, "Polling Error"); 785 } 786 787 if (n == 0) 788 return; 789 790 if (pfd[0].revents & POLLIN) { 791 if ((n = read(nfd, buf, plen)) < 0) 792 return; 793 else if (n == 0) { 794 shutdown(nfd, SHUT_RD); 795 pfd[0].fd = -1; 796 pfd[0].events = 0; 797 } else { 798 if (tflag) 799 atelnet(nfd, buf, n); 800 if (atomicio(vwrite, lfd, buf, n) != n) 801 return; 802 } 803 } 804 805 if (!dflag && pfd[1].revents & POLLIN) { 806 if ((n = read(wfd, buf, plen)) < 0) 807 return; 808 else if (n == 0) { 809 shutdown(nfd, SHUT_WR); 810 pfd[1].fd = -1; 811 pfd[1].events = 0; 812 } else { 813 if (atomicio(vwrite, nfd, buf, n) != n) 814 return; 815 } 816 } 817 } 818} 819 820/* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */ 821void 822atelnet(int nfd, unsigned char *buf, unsigned int size) 823{ 824 unsigned char *p, *end; 825 unsigned char obuf[4]; 826 827 if (size < 3) 828 return; 829 end = buf + size - 2; 830 831 for (p = buf; p < end; p++) { 832 if (*p != IAC) 833 continue; 834 835 obuf[0] = IAC; 836 p++; 837 if ((*p == WILL) || (*p == WONT)) 838 obuf[1] = DONT; 839 else if ((*p == DO) || (*p == DONT)) 840 obuf[1] = WONT; 841 else 842 continue; 843 844 p++; 845 obuf[2] = *p; 846 if (atomicio(vwrite, nfd, obuf, 3) != 3) 847 warn("Write Error!"); 848 } 849} 850 851/* 852 * build_ports() 853 * Build an array or ports in portlist[], listing each port 854 * that we should try to connect to. 855 */ 856void 857build_ports(char *p) 858{ 859 const char *errstr; 860 char *n; 861 int hi, lo, cp; 862 int x = 0; 863 864 if ((n = strchr(p, '-')) != NULL) { 865 if (lflag) 866 errx(1, "Cannot use -l with multiple ports!"); 867 868 *n = '\0'; 869 n++; 870 871 /* Make sure the ports are in order: lowest->highest. */ 872#ifdef ANDROID 873 hi = atoi(n); 874#else 875 hi = strtonum(n, 1, PORT_MAX, &errstr); 876 if (errstr) 877 errx(1, "port number %s: %s", errstr, n); 878#endif 879#ifdef ANDROID 880 lo = atoi(p); 881#else 882 lo = strtonum(p, 1, PORT_MAX, &errstr); 883 if (errstr) 884 errx(1, "port number %s: %s", errstr, p); 885#endif 886 887 if (lo > hi) { 888 cp = hi; 889 hi = lo; 890 lo = cp; 891 } 892 893 /* Load ports sequentially. */ 894 for (cp = lo; cp <= hi; cp++) { 895 portlist[x] = calloc(1, PORT_MAX_LEN); 896 if (portlist[x] == NULL) 897 err(1, NULL); 898 snprintf(portlist[x], PORT_MAX_LEN, "%d", cp); 899 x++; 900 } 901 902 /* Randomly swap ports. */ 903 if (rflag) { 904 int y; 905 char *c; 906 907 for (x = 0; x <= (hi - lo); x++) { 908 y = (arc4random() & 0xFFFF) % (hi - lo); 909 c = portlist[x]; 910 portlist[x] = portlist[y]; 911 portlist[y] = c; 912 } 913 } 914 } else { 915#ifdef ANDROID 916 hi = atoi(p); 917#else 918 hi = strtonum(p, 1, PORT_MAX, &errstr); 919 if (errstr) 920 errx(1, "port number %s: %s", errstr, p); 921#endif 922 portlist[0] = strdup(p); 923 if (portlist[0] == NULL) 924 err(1, NULL); 925 } 926} 927 928/* 929 * udptest() 930 * Do a few writes to see if the UDP port is there. 931 * XXX - Better way of doing this? Doesn't work for IPv6. 932 * Also fails after around 100 ports checked. 933 */ 934int 935udptest(int s) 936{ 937 int i, ret; 938 939 for (i = 0; i <= 3; i++) { 940 if (write(s, "X", 1) == 1) 941 ret = 1; 942 else 943 ret = -1; 944 } 945 return (ret); 946} 947 948void 949set_common_sockopts(int s) 950{ 951 int x = 1; 952 953#ifndef ANDROID 954 if (Sflag) { 955 if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG, 956 &x, sizeof(x)) == -1) 957 err(1, NULL); 958 } 959#endif 960 if (Dflag) { 961 if (setsockopt(s, SOL_SOCKET, SO_DEBUG, 962 &x, sizeof(x)) == -1) 963 err(1, NULL); 964 } 965#ifndef ANDROID 966 if (jflag) { 967 if (setsockopt(s, SOL_SOCKET, SO_JUMBO, 968 &x, sizeof(x)) == -1) 969 err(1, NULL); 970 } 971 if (Tflag != -1) { 972 if (setsockopt(s, IPPROTO_IP, IP_TOS, 973 &Tflag, sizeof(Tflag)) == -1) 974 err(1, "set IP ToS"); 975 } 976#endif 977 if (Iflag) { 978 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, 979 &Iflag, sizeof(Iflag)) == -1) 980 err(1, "set TCP receive buffer size"); 981 } 982 if (Oflag) { 983 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, 984 &Oflag, sizeof(Oflag)) == -1) 985 err(1, "set TCP send buffer size"); 986 } 987} 988 989#ifndef ANDROID 990int 991map_tos(char *s, int *val) 992{ 993 /* DiffServ Codepoints and other TOS mappings */ 994 const struct toskeywords { 995 const char *keyword; 996 int val; 997 } *t, toskeywords[] = { 998 { "af11", IPTOS_DSCP_AF11 }, 999 { "af12", IPTOS_DSCP_AF12 }, 1000 { "af13", IPTOS_DSCP_AF13 }, 1001 { "af21", IPTOS_DSCP_AF21 }, 1002 { "af22", IPTOS_DSCP_AF22 }, 1003 { "af23", IPTOS_DSCP_AF23 }, 1004 { "af31", IPTOS_DSCP_AF31 }, 1005 { "af32", IPTOS_DSCP_AF32 }, 1006 { "af33", IPTOS_DSCP_AF33 }, 1007 { "af41", IPTOS_DSCP_AF41 }, 1008 { "af42", IPTOS_DSCP_AF42 }, 1009 { "af43", IPTOS_DSCP_AF43 }, 1010 { "critical", IPTOS_PREC_CRITIC_ECP }, 1011 { "cs0", IPTOS_DSCP_CS0 }, 1012 { "cs1", IPTOS_DSCP_CS1 }, 1013 { "cs2", IPTOS_DSCP_CS2 }, 1014 { "cs3", IPTOS_DSCP_CS3 }, 1015 { "cs4", IPTOS_DSCP_CS4 }, 1016 { "cs5", IPTOS_DSCP_CS5 }, 1017 { "cs6", IPTOS_DSCP_CS6 }, 1018 { "cs7", IPTOS_DSCP_CS7 }, 1019 { "ef", IPTOS_DSCP_EF }, 1020 { "inetcontrol", IPTOS_PREC_INTERNETCONTROL }, 1021 { "lowdelay", IPTOS_LOWDELAY }, 1022 { "netcontrol", IPTOS_PREC_NETCONTROL }, 1023 { "reliability", IPTOS_RELIABILITY }, 1024 { "throughput", IPTOS_THROUGHPUT }, 1025 { NULL, -1 }, 1026 }; 1027 1028 for (t = toskeywords; t->keyword != NULL; t++) { 1029 if (strcmp(s, t->keyword) == 0) { 1030 *val = t->val; 1031 return (1); 1032 } 1033 } 1034 1035 return (0); 1036} 1037#endif 1038 1039void 1040help(void) 1041{ 1042 usage(0); 1043 fprintf(stderr, "\tCommand Summary:\n\ 1044 \t-4 Use IPv4\n\ 1045 \t-6 Use IPv6\n\ 1046 \t-D Enable the debug socket option\n\ 1047 \t-d Detach from stdin\n\ 1048 \t-h This help text\n\ 1049 \t-I length TCP receive buffer length\n\ 1050 \t-i secs\t Delay interval for lines sent, ports scanned\n\ 1051 \t-k Keep inbound sockets open for multiple connects\n\ 1052 \t-l Listen mode, for inbound connects\n\ 1053 \t-n Suppress name/port resolutions\n\ 1054 \t-O length TCP send buffer length\n\ 1055 \t-P proxyuser\tUsername for proxy authentication\n\ 1056 \t-p port\t Specify local port for remote connects\n\ 1057 \t-r Randomize remote ports\n\ 1058 \t-S Enable the TCP MD5 signature option\n\ 1059 \t-s addr\t Local source address\n\ 1060 \t-T toskeyword\tSet IP Type of Service\n\ 1061 \t-t Answer TELNET negotiation\n\ 1062 \t-U Use UNIX domain socket\n\ 1063 \t-u UDP mode\n\ 1064 \t-V rtable Specify alternate routing table\n\ 1065 \t-v Verbose\n\ 1066 \t-w secs\t Timeout for connects and final net reads\n\ 1067 \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\ 1068 \t-x addr[:port]\tSpecify proxy address and port\n\ 1069 \t-z Zero-I/O mode [used for scanning]\n\ 1070 Port numbers can be individual or ranges: lo-hi [inclusive]\n"); 1071 exit(1); 1072} 1073 1074void 1075usage(int ret) 1076{ 1077 fprintf(stderr, 1078 "usage: nc [-46DdhklnrStUuvz] [-I length] [-i interval] [-O length]\n" 1079 "\t [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n" 1080 "\t [-V rtable] [-w timeout] [-X proxy_protocol]\n" 1081 "\t [-x proxy_address[:port]] [destination] [port]\n"); 1082 if (ret) 1083 exit(1); 1084} 1085