1*03100a63Svk199839 /* $OpenBSD: netcat.c,v 1.89 2007/02/20 14:11:17 jmc Exp $ */ 2*03100a63Svk199839 /* 3*03100a63Svk199839 * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> 4*03100a63Svk199839 * 5*03100a63Svk199839 * Redistribution and use in source and binary forms, with or without 6*03100a63Svk199839 * modification, are permitted provided that the following conditions 7*03100a63Svk199839 * are met: 8*03100a63Svk199839 * 9*03100a63Svk199839 * 1. Redistributions of source code must retain the above copyright 10*03100a63Svk199839 * notice, this list of conditions and the following disclaimer. 11*03100a63Svk199839 * 2. Redistributions in binary form must reproduce the above copyright 12*03100a63Svk199839 * notice, this list of conditions and the following disclaimer in the 13*03100a63Svk199839 * documentation and/or other materials provided with the distribution. 14*03100a63Svk199839 * 3. The name of the author may not be used to endorse or promote products 15*03100a63Svk199839 * derived from this software without specific prior written permission. 16*03100a63Svk199839 * 17*03100a63Svk199839 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18*03100a63Svk199839 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19*03100a63Svk199839 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20*03100a63Svk199839 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21*03100a63Svk199839 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22*03100a63Svk199839 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23*03100a63Svk199839 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24*03100a63Svk199839 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25*03100a63Svk199839 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26*03100a63Svk199839 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27*03100a63Svk199839 */ 28*03100a63Svk199839 29*03100a63Svk199839 /* 30*03100a63Svk199839 * Re-written nc(1) for OpenBSD. Original implementation by 31*03100a63Svk199839 * *Hobbit* <hobbit@avian.org>. 32*03100a63Svk199839 */ 33*03100a63Svk199839 34*03100a63Svk199839 #pragma ident "%Z%%M% %I% %E% SMI" 35*03100a63Svk199839 36*03100a63Svk199839 #include <sys/types.h> 37*03100a63Svk199839 #include <sys/socket.h> 38*03100a63Svk199839 #include <sys/time.h> 39*03100a63Svk199839 #include <sys/un.h> 40*03100a63Svk199839 41*03100a63Svk199839 #include <netinet/in.h> 42*03100a63Svk199839 #include <netinet/in_systm.h> 43*03100a63Svk199839 #include <netinet/tcp.h> 44*03100a63Svk199839 #include <netinet/ip.h> 45*03100a63Svk199839 #include <arpa/telnet.h> 46*03100a63Svk199839 47*03100a63Svk199839 #include <err.h> 48*03100a63Svk199839 #include <errno.h> 49*03100a63Svk199839 #include <netdb.h> 50*03100a63Svk199839 #include <poll.h> 51*03100a63Svk199839 #include <stdarg.h> 52*03100a63Svk199839 #include <stdio.h> 53*03100a63Svk199839 #include <stdlib.h> 54*03100a63Svk199839 #include <string.h> 55*03100a63Svk199839 #include <unistd.h> 56*03100a63Svk199839 #include <fcntl.h> 57*03100a63Svk199839 #include <limits.h> 58*03100a63Svk199839 #include <signal.h> 59*03100a63Svk199839 60*03100a63Svk199839 #include "atomicio.h" 61*03100a63Svk199839 #include "strtonum.h" 62*03100a63Svk199839 63*03100a63Svk199839 #ifndef SUN_LEN 64*03100a63Svk199839 #define SUN_LEN(su) \ 65*03100a63Svk199839 (sizeof (*(su)) - sizeof ((su)->sun_path) + strlen((su)->sun_path)) 66*03100a63Svk199839 #endif 67*03100a63Svk199839 68*03100a63Svk199839 #define PORT_MIN 1 69*03100a63Svk199839 #define PORT_MAX 65535 70*03100a63Svk199839 #define PORT_MAX_LEN 6 71*03100a63Svk199839 72*03100a63Svk199839 /* Command Line Options */ 73*03100a63Svk199839 int dflag; /* detached, no stdin */ 74*03100a63Svk199839 unsigned int iflag; /* Interval Flag */ 75*03100a63Svk199839 int kflag; /* More than one connect */ 76*03100a63Svk199839 int lflag; /* Bind to local port */ 77*03100a63Svk199839 int nflag; /* Don't do name lookup */ 78*03100a63Svk199839 char *Pflag; /* Proxy username */ 79*03100a63Svk199839 char *pflag; /* Localport flag */ 80*03100a63Svk199839 int rflag; /* Random ports flag */ 81*03100a63Svk199839 char *sflag; /* Source Address */ 82*03100a63Svk199839 int tflag; /* Telnet Emulation */ 83*03100a63Svk199839 int uflag; /* UDP - Default to TCP */ 84*03100a63Svk199839 int vflag; /* Verbosity */ 85*03100a63Svk199839 int xflag; /* Socks proxy */ 86*03100a63Svk199839 int Xflag; /* indicator of Socks version set */ 87*03100a63Svk199839 int zflag; /* Port Scan Flag */ 88*03100a63Svk199839 int Dflag; /* sodebug */ 89*03100a63Svk199839 int Tflag = -1; /* IP Type of Service */ 90*03100a63Svk199839 91*03100a63Svk199839 int timeout = -1; 92*03100a63Svk199839 int family = AF_UNSPEC; 93*03100a63Svk199839 char *portlist[PORT_MAX+1]; 94*03100a63Svk199839 95*03100a63Svk199839 void atelnet(int, unsigned char *, unsigned int); 96*03100a63Svk199839 void build_ports(char *); 97*03100a63Svk199839 void help(void); 98*03100a63Svk199839 int local_listen(char *, char *, struct addrinfo); 99*03100a63Svk199839 void readwrite(int); 100*03100a63Svk199839 int remote_connect(const char *, const char *, struct addrinfo); 101*03100a63Svk199839 int socks_connect(const char *, const char *, 102*03100a63Svk199839 const char *, const char *, struct addrinfo, int, const char *); 103*03100a63Svk199839 int udptest(int); 104*03100a63Svk199839 int unix_connect(char *); 105*03100a63Svk199839 int unix_listen(char *); 106*03100a63Svk199839 void set_common_sockopts(int); 107*03100a63Svk199839 int parse_iptos(char *); 108*03100a63Svk199839 void usage(int); 109*03100a63Svk199839 110*03100a63Svk199839 int 111*03100a63Svk199839 main(int argc, char *argv[]) 112*03100a63Svk199839 { 113*03100a63Svk199839 int ch, s, ret, socksv; 114*03100a63Svk199839 char *host, *uport, *proxy; 115*03100a63Svk199839 struct addrinfo hints; 116*03100a63Svk199839 struct servent *sv; 117*03100a63Svk199839 socklen_t len; 118*03100a63Svk199839 struct sockaddr_storage cliaddr; 119*03100a63Svk199839 const char *errstr, *proxyhost = "", *proxyport = NULL; 120*03100a63Svk199839 struct addrinfo proxyhints; 121*03100a63Svk199839 122*03100a63Svk199839 ret = 1; 123*03100a63Svk199839 s = 0; 124*03100a63Svk199839 socksv = 5; 125*03100a63Svk199839 host = NULL; 126*03100a63Svk199839 uport = NULL; 127*03100a63Svk199839 sv = NULL; 128*03100a63Svk199839 129*03100a63Svk199839 while ((ch = getopt(argc, argv, 130*03100a63Svk199839 "46Ddhi:klnP:p:rs:T:tUuvw:X:x:z")) != -1) { 131*03100a63Svk199839 switch (ch) { 132*03100a63Svk199839 case '4': 133*03100a63Svk199839 family = AF_INET; 134*03100a63Svk199839 break; 135*03100a63Svk199839 case '6': 136*03100a63Svk199839 family = AF_INET6; 137*03100a63Svk199839 break; 138*03100a63Svk199839 case 'U': 139*03100a63Svk199839 family = AF_UNIX; 140*03100a63Svk199839 break; 141*03100a63Svk199839 case 'X': 142*03100a63Svk199839 Xflag = 1; 143*03100a63Svk199839 if (strcasecmp(optarg, "connect") == 0) 144*03100a63Svk199839 socksv = -1; /* HTTP proxy CONNECT */ 145*03100a63Svk199839 else if (strcmp(optarg, "4") == 0) 146*03100a63Svk199839 socksv = 4; /* SOCKS v.4 */ 147*03100a63Svk199839 else if (strcmp(optarg, "5") == 0) 148*03100a63Svk199839 socksv = 5; /* SOCKS v.5 */ 149*03100a63Svk199839 else 150*03100a63Svk199839 errx(1, "unsupported proxy protocol"); 151*03100a63Svk199839 break; 152*03100a63Svk199839 case 'd': 153*03100a63Svk199839 dflag = 1; 154*03100a63Svk199839 break; 155*03100a63Svk199839 case 'h': 156*03100a63Svk199839 help(); 157*03100a63Svk199839 break; 158*03100a63Svk199839 case 'i': 159*03100a63Svk199839 iflag = strtonum(optarg, 0, UINT_MAX, &errstr); 160*03100a63Svk199839 if (errstr) 161*03100a63Svk199839 errx(1, "interval %s: %s", errstr, optarg); 162*03100a63Svk199839 break; 163*03100a63Svk199839 case 'k': 164*03100a63Svk199839 kflag = 1; 165*03100a63Svk199839 break; 166*03100a63Svk199839 case 'l': 167*03100a63Svk199839 lflag = 1; 168*03100a63Svk199839 break; 169*03100a63Svk199839 case 'n': 170*03100a63Svk199839 nflag = 1; 171*03100a63Svk199839 break; 172*03100a63Svk199839 case 'P': 173*03100a63Svk199839 Pflag = optarg; 174*03100a63Svk199839 break; 175*03100a63Svk199839 case 'p': 176*03100a63Svk199839 pflag = optarg; 177*03100a63Svk199839 break; 178*03100a63Svk199839 case 'r': 179*03100a63Svk199839 rflag = 1; 180*03100a63Svk199839 break; 181*03100a63Svk199839 case 's': 182*03100a63Svk199839 sflag = optarg; 183*03100a63Svk199839 break; 184*03100a63Svk199839 case 't': 185*03100a63Svk199839 tflag = 1; 186*03100a63Svk199839 break; 187*03100a63Svk199839 case 'u': 188*03100a63Svk199839 uflag = 1; 189*03100a63Svk199839 break; 190*03100a63Svk199839 case 'v': 191*03100a63Svk199839 vflag = 1; 192*03100a63Svk199839 break; 193*03100a63Svk199839 case 'w': 194*03100a63Svk199839 timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr); 195*03100a63Svk199839 if (errstr) 196*03100a63Svk199839 errx(1, "timeout %s: %s", errstr, optarg); 197*03100a63Svk199839 timeout *= 1000; 198*03100a63Svk199839 break; 199*03100a63Svk199839 case 'x': 200*03100a63Svk199839 xflag = 1; 201*03100a63Svk199839 if ((proxy = strdup(optarg)) == NULL) 202*03100a63Svk199839 err(1, NULL); 203*03100a63Svk199839 break; 204*03100a63Svk199839 case 'z': 205*03100a63Svk199839 zflag = 1; 206*03100a63Svk199839 break; 207*03100a63Svk199839 case 'D': 208*03100a63Svk199839 Dflag = 1; 209*03100a63Svk199839 break; 210*03100a63Svk199839 case 'T': 211*03100a63Svk199839 Tflag = parse_iptos(optarg); 212*03100a63Svk199839 break; 213*03100a63Svk199839 default: 214*03100a63Svk199839 usage(1); 215*03100a63Svk199839 } 216*03100a63Svk199839 } 217*03100a63Svk199839 argc -= optind; 218*03100a63Svk199839 argv += optind; 219*03100a63Svk199839 220*03100a63Svk199839 /* Cruft to make sure options are clean, and used properly. */ 221*03100a63Svk199839 if (argv[0] && !argv[1] && family == AF_UNIX) { 222*03100a63Svk199839 if (uflag) 223*03100a63Svk199839 errx(1, "cannot use -u and -U"); 224*03100a63Svk199839 host = argv[0]; 225*03100a63Svk199839 uport = NULL; 226*03100a63Svk199839 } else if (argv[0] && !argv[1]) { 227*03100a63Svk199839 if (!lflag) 228*03100a63Svk199839 usage(1); 229*03100a63Svk199839 uport = argv[0]; 230*03100a63Svk199839 host = NULL; 231*03100a63Svk199839 } else if (argv[0] && argv[1]) { 232*03100a63Svk199839 if (family == AF_UNIX) 233*03100a63Svk199839 usage(1); 234*03100a63Svk199839 host = argv[0]; 235*03100a63Svk199839 uport = argv[1]; 236*03100a63Svk199839 } else { 237*03100a63Svk199839 if (!(lflag && pflag)) 238*03100a63Svk199839 usage(1); 239*03100a63Svk199839 } 240*03100a63Svk199839 241*03100a63Svk199839 if (lflag && sflag) 242*03100a63Svk199839 errx(1, "cannot use -s and -l"); 243*03100a63Svk199839 if (lflag && rflag) 244*03100a63Svk199839 errx(1, "cannot use -r and -l"); 245*03100a63Svk199839 if (lflag && pflag) { 246*03100a63Svk199839 if (uport) 247*03100a63Svk199839 usage(1); 248*03100a63Svk199839 uport = pflag; 249*03100a63Svk199839 } 250*03100a63Svk199839 if (lflag && zflag) 251*03100a63Svk199839 errx(1, "cannot use -z and -l"); 252*03100a63Svk199839 if (!lflag && kflag) 253*03100a63Svk199839 errx(1, "must use -l with -k"); 254*03100a63Svk199839 if (lflag && (Pflag || xflag || Xflag)) 255*03100a63Svk199839 errx(1, "cannot use -l with -P, -X or -x"); 256*03100a63Svk199839 257*03100a63Svk199839 /* Initialize addrinfo structure. */ 258*03100a63Svk199839 if (family != AF_UNIX) { 259*03100a63Svk199839 (void) memset(&hints, 0, sizeof (struct addrinfo)); 260*03100a63Svk199839 hints.ai_family = family; 261*03100a63Svk199839 hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; 262*03100a63Svk199839 hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; 263*03100a63Svk199839 if (nflag) 264*03100a63Svk199839 hints.ai_flags |= AI_NUMERICHOST; 265*03100a63Svk199839 } 266*03100a63Svk199839 267*03100a63Svk199839 if (xflag) { 268*03100a63Svk199839 if (uflag) 269*03100a63Svk199839 errx(1, "no proxy support for UDP mode"); 270*03100a63Svk199839 271*03100a63Svk199839 if (lflag) 272*03100a63Svk199839 errx(1, "no proxy support for listen"); 273*03100a63Svk199839 274*03100a63Svk199839 if (family == AF_UNIX) 275*03100a63Svk199839 errx(1, "no proxy support for unix sockets"); 276*03100a63Svk199839 277*03100a63Svk199839 if (family == AF_INET6) 278*03100a63Svk199839 errx(1, "no proxy support for IPv6"); 279*03100a63Svk199839 280*03100a63Svk199839 if (sflag) 281*03100a63Svk199839 errx(1, "no proxy support for local source address"); 282*03100a63Svk199839 283*03100a63Svk199839 if ((proxyhost = strtok(proxy, ":")) == NULL) 284*03100a63Svk199839 errx(1, "missing port specification"); 285*03100a63Svk199839 proxyport = strtok(NULL, ":"); 286*03100a63Svk199839 287*03100a63Svk199839 (void) memset(&proxyhints, 0, sizeof (struct addrinfo)); 288*03100a63Svk199839 proxyhints.ai_family = family; 289*03100a63Svk199839 proxyhints.ai_socktype = SOCK_STREAM; 290*03100a63Svk199839 proxyhints.ai_protocol = IPPROTO_TCP; 291*03100a63Svk199839 if (nflag) 292*03100a63Svk199839 proxyhints.ai_flags |= AI_NUMERICHOST; 293*03100a63Svk199839 } 294*03100a63Svk199839 295*03100a63Svk199839 if (lflag) { 296*03100a63Svk199839 int connfd; 297*03100a63Svk199839 ret = 0; 298*03100a63Svk199839 299*03100a63Svk199839 if (family == AF_UNIX) 300*03100a63Svk199839 s = unix_listen(host); 301*03100a63Svk199839 302*03100a63Svk199839 /* Allow only one connection at a time, but stay alive. */ 303*03100a63Svk199839 for (;;) { 304*03100a63Svk199839 if (family != AF_UNIX) 305*03100a63Svk199839 s = local_listen(host, uport, hints); 306*03100a63Svk199839 if (s < 0) 307*03100a63Svk199839 err(1, NULL); 308*03100a63Svk199839 /* 309*03100a63Svk199839 * For UDP, we will use recvfrom() initially 310*03100a63Svk199839 * to wait for a caller, then use the regular 311*03100a63Svk199839 * functions to talk to the caller. 312*03100a63Svk199839 */ 313*03100a63Svk199839 if (uflag) { 314*03100a63Svk199839 int rv, plen; 315*03100a63Svk199839 char buf[8192]; 316*03100a63Svk199839 struct sockaddr_storage z; 317*03100a63Svk199839 318*03100a63Svk199839 len = sizeof (z); 319*03100a63Svk199839 plen = 1024; 320*03100a63Svk199839 rv = recvfrom(s, buf, plen, MSG_PEEK, 321*03100a63Svk199839 (struct sockaddr *)&z, &len); 322*03100a63Svk199839 if (rv < 0) 323*03100a63Svk199839 err(1, "recvfrom"); 324*03100a63Svk199839 325*03100a63Svk199839 rv = connect(s, (struct sockaddr *)&z, len); 326*03100a63Svk199839 if (rv < 0) 327*03100a63Svk199839 err(1, "connect"); 328*03100a63Svk199839 329*03100a63Svk199839 connfd = s; 330*03100a63Svk199839 } else { 331*03100a63Svk199839 len = sizeof (cliaddr); 332*03100a63Svk199839 connfd = accept(s, (struct sockaddr *)&cliaddr, 333*03100a63Svk199839 &len); 334*03100a63Svk199839 } 335*03100a63Svk199839 336*03100a63Svk199839 readwrite(connfd); 337*03100a63Svk199839 (void) close(connfd); 338*03100a63Svk199839 if (family != AF_UNIX) 339*03100a63Svk199839 (void) close(s); 340*03100a63Svk199839 341*03100a63Svk199839 if (!kflag) 342*03100a63Svk199839 break; 343*03100a63Svk199839 } 344*03100a63Svk199839 } else if (family == AF_UNIX) { 345*03100a63Svk199839 ret = 0; 346*03100a63Svk199839 347*03100a63Svk199839 if ((s = unix_connect(host)) > 0 && !zflag) { 348*03100a63Svk199839 readwrite(s); 349*03100a63Svk199839 (void) close(s); 350*03100a63Svk199839 } else 351*03100a63Svk199839 ret = 1; 352*03100a63Svk199839 353*03100a63Svk199839 exit(ret); 354*03100a63Svk199839 355*03100a63Svk199839 } else { /* AF_INET or AF_INET6 */ 356*03100a63Svk199839 int i = 0; 357*03100a63Svk199839 358*03100a63Svk199839 /* Construct the portlist[] array. */ 359*03100a63Svk199839 build_ports(uport); 360*03100a63Svk199839 361*03100a63Svk199839 /* Cycle through portlist, connecting to each port. */ 362*03100a63Svk199839 for (i = 0; portlist[i] != NULL; i++) { 363*03100a63Svk199839 if (s) 364*03100a63Svk199839 (void) close(s); 365*03100a63Svk199839 366*03100a63Svk199839 if (xflag) 367*03100a63Svk199839 s = socks_connect(host, portlist[i], 368*03100a63Svk199839 proxyhost, proxyport, proxyhints, socksv, 369*03100a63Svk199839 Pflag); 370*03100a63Svk199839 else 371*03100a63Svk199839 s = remote_connect(host, portlist[i], hints); 372*03100a63Svk199839 373*03100a63Svk199839 if (s < 0) 374*03100a63Svk199839 continue; 375*03100a63Svk199839 376*03100a63Svk199839 ret = 0; 377*03100a63Svk199839 if (vflag || zflag) { 378*03100a63Svk199839 /* For UDP, make sure we are connected. */ 379*03100a63Svk199839 if (uflag) { 380*03100a63Svk199839 if (udptest(s) == -1) { 381*03100a63Svk199839 ret = 1; 382*03100a63Svk199839 continue; 383*03100a63Svk199839 } 384*03100a63Svk199839 } 385*03100a63Svk199839 386*03100a63Svk199839 /* Don't look up port if -n. */ 387*03100a63Svk199839 if (nflag) 388*03100a63Svk199839 sv = NULL; 389*03100a63Svk199839 else { 390*03100a63Svk199839 sv = getservbyport( 391*03100a63Svk199839 ntohs(atoi(portlist[i])), 392*03100a63Svk199839 uflag ? "udp" : "tcp"); 393*03100a63Svk199839 } 394*03100a63Svk199839 395*03100a63Svk199839 (void) printf("Connection to %s %s " 396*03100a63Svk199839 "port [%s/%s] succeeded!\n", 397*03100a63Svk199839 host, portlist[i], uflag ? "udp" : "tcp", 398*03100a63Svk199839 sv ? sv->s_name : "*"); 399*03100a63Svk199839 } 400*03100a63Svk199839 if (!zflag) 401*03100a63Svk199839 readwrite(s); 402*03100a63Svk199839 } 403*03100a63Svk199839 } 404*03100a63Svk199839 405*03100a63Svk199839 if (s) 406*03100a63Svk199839 (void) close(s); 407*03100a63Svk199839 408*03100a63Svk199839 return (ret); 409*03100a63Svk199839 } 410*03100a63Svk199839 411*03100a63Svk199839 /* 412*03100a63Svk199839 * unix_connect() 413*03100a63Svk199839 * Returns a socket connected to a local unix socket. Returns -1 on failure. 414*03100a63Svk199839 */ 415*03100a63Svk199839 int 416*03100a63Svk199839 unix_connect(char *path) 417*03100a63Svk199839 { 418*03100a63Svk199839 struct sockaddr_un sunaddr; 419*03100a63Svk199839 int s; 420*03100a63Svk199839 421*03100a63Svk199839 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 422*03100a63Svk199839 return (-1); 423*03100a63Svk199839 424*03100a63Svk199839 (void) memset(&sunaddr, 0, sizeof (struct sockaddr_un)); 425*03100a63Svk199839 sunaddr.sun_family = AF_UNIX; 426*03100a63Svk199839 427*03100a63Svk199839 if (strlcpy(sunaddr.sun_path, path, sizeof (sunaddr.sun_path)) >= 428*03100a63Svk199839 sizeof (sunaddr.sun_path)) { 429*03100a63Svk199839 (void) close(s); 430*03100a63Svk199839 errno = ENAMETOOLONG; 431*03100a63Svk199839 return (-1); 432*03100a63Svk199839 } 433*03100a63Svk199839 if (connect(s, (struct sockaddr *)&sunaddr, SUN_LEN(&sunaddr)) < 0) { 434*03100a63Svk199839 (void) close(s); 435*03100a63Svk199839 return (-1); 436*03100a63Svk199839 } 437*03100a63Svk199839 return (s); 438*03100a63Svk199839 } 439*03100a63Svk199839 440*03100a63Svk199839 /* 441*03100a63Svk199839 * unix_listen() 442*03100a63Svk199839 * Create a unix domain socket, and listen on it. 443*03100a63Svk199839 */ 444*03100a63Svk199839 int 445*03100a63Svk199839 unix_listen(char *path) 446*03100a63Svk199839 { 447*03100a63Svk199839 struct sockaddr_un sunaddr; 448*03100a63Svk199839 int s; 449*03100a63Svk199839 450*03100a63Svk199839 /* Create unix domain socket. */ 451*03100a63Svk199839 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 452*03100a63Svk199839 return (-1); 453*03100a63Svk199839 454*03100a63Svk199839 (void) memset(&sunaddr, 0, sizeof (struct sockaddr_un)); 455*03100a63Svk199839 sunaddr.sun_family = AF_UNIX; 456*03100a63Svk199839 457*03100a63Svk199839 if (strlcpy(sunaddr.sun_path, path, sizeof (sunaddr.sun_path)) >= 458*03100a63Svk199839 sizeof (sunaddr.sun_path)) { 459*03100a63Svk199839 (void) close(s); 460*03100a63Svk199839 errno = ENAMETOOLONG; 461*03100a63Svk199839 return (-1); 462*03100a63Svk199839 } 463*03100a63Svk199839 464*03100a63Svk199839 if (bind(s, (struct sockaddr *)&sunaddr, SUN_LEN(&sunaddr)) < 0) { 465*03100a63Svk199839 (void) close(s); 466*03100a63Svk199839 return (-1); 467*03100a63Svk199839 } 468*03100a63Svk199839 469*03100a63Svk199839 if (listen(s, 5) < 0) { 470*03100a63Svk199839 (void) close(s); 471*03100a63Svk199839 return (-1); 472*03100a63Svk199839 } 473*03100a63Svk199839 return (s); 474*03100a63Svk199839 } 475*03100a63Svk199839 476*03100a63Svk199839 /* 477*03100a63Svk199839 * remote_connect() 478*03100a63Svk199839 * Returns a socket connected to a remote host. Properly binds to a local 479*03100a63Svk199839 * port or source address if needed. Returns -1 on failure. 480*03100a63Svk199839 */ 481*03100a63Svk199839 int 482*03100a63Svk199839 remote_connect(const char *host, const char *port, struct addrinfo hints) 483*03100a63Svk199839 { 484*03100a63Svk199839 struct addrinfo *res, *res0; 485*03100a63Svk199839 int s, error; 486*03100a63Svk199839 487*03100a63Svk199839 if ((error = getaddrinfo(host, port, &hints, &res))) 488*03100a63Svk199839 errx(1, "getaddrinfo: %s", gai_strerror(error)); 489*03100a63Svk199839 490*03100a63Svk199839 res0 = res; 491*03100a63Svk199839 do { 492*03100a63Svk199839 if ((s = socket(res0->ai_family, res0->ai_socktype, 493*03100a63Svk199839 res0->ai_protocol)) < 0) { 494*03100a63Svk199839 warn("failed to create socket"); 495*03100a63Svk199839 continue; 496*03100a63Svk199839 } 497*03100a63Svk199839 498*03100a63Svk199839 /* Bind to a local port or source address if specified. */ 499*03100a63Svk199839 if (sflag || pflag) { 500*03100a63Svk199839 struct addrinfo ahints, *ares; 501*03100a63Svk199839 502*03100a63Svk199839 (void) memset(&ahints, 0, sizeof (struct addrinfo)); 503*03100a63Svk199839 ahints.ai_family = res0->ai_family; 504*03100a63Svk199839 ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; 505*03100a63Svk199839 ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; 506*03100a63Svk199839 ahints.ai_flags = AI_PASSIVE; 507*03100a63Svk199839 if ((error = getaddrinfo(sflag, pflag, &ahints, &ares))) 508*03100a63Svk199839 errx(1, "getaddrinfo: %s", gai_strerror(error)); 509*03100a63Svk199839 510*03100a63Svk199839 if (bind(s, (struct sockaddr *)ares->ai_addr, 511*03100a63Svk199839 ares->ai_addrlen) < 0) 512*03100a63Svk199839 errx(1, "bind failed: %s", strerror(errno)); 513*03100a63Svk199839 freeaddrinfo(ares); 514*03100a63Svk199839 } 515*03100a63Svk199839 516*03100a63Svk199839 set_common_sockopts(s); 517*03100a63Svk199839 518*03100a63Svk199839 if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0) 519*03100a63Svk199839 break; 520*03100a63Svk199839 else if (vflag) 521*03100a63Svk199839 warn("connect to %s port %s (%s) failed", host, port, 522*03100a63Svk199839 uflag ? "udp" : "tcp"); 523*03100a63Svk199839 524*03100a63Svk199839 (void) close(s); 525*03100a63Svk199839 s = -1; 526*03100a63Svk199839 } while ((res0 = res0->ai_next) != NULL); 527*03100a63Svk199839 528*03100a63Svk199839 freeaddrinfo(res); 529*03100a63Svk199839 530*03100a63Svk199839 return (s); 531*03100a63Svk199839 } 532*03100a63Svk199839 533*03100a63Svk199839 /* 534*03100a63Svk199839 * local_listen() 535*03100a63Svk199839 * Returns a socket listening on a local port, binds to specified source 536*03100a63Svk199839 * address. Returns -1 on failure. 537*03100a63Svk199839 */ 538*03100a63Svk199839 int 539*03100a63Svk199839 local_listen(char *host, char *port, struct addrinfo hints) 540*03100a63Svk199839 { 541*03100a63Svk199839 struct addrinfo *res, *res0; 542*03100a63Svk199839 int s, ret, x = 1; 543*03100a63Svk199839 int error; 544*03100a63Svk199839 545*03100a63Svk199839 /* Allow nodename to be null. */ 546*03100a63Svk199839 hints.ai_flags |= AI_PASSIVE; 547*03100a63Svk199839 548*03100a63Svk199839 /* 549*03100a63Svk199839 * In the case of binding to a wildcard address 550*03100a63Svk199839 * default to binding to an ipv4 address. 551*03100a63Svk199839 */ 552*03100a63Svk199839 if (host == NULL && hints.ai_family == AF_UNSPEC) 553*03100a63Svk199839 hints.ai_family = AF_INET; 554*03100a63Svk199839 555*03100a63Svk199839 if ((error = getaddrinfo(host, port, &hints, &res))) 556*03100a63Svk199839 errx(1, "getaddrinfo: %s", gai_strerror(error)); 557*03100a63Svk199839 558*03100a63Svk199839 res0 = res; 559*03100a63Svk199839 do { 560*03100a63Svk199839 if ((s = socket(res0->ai_family, res0->ai_socktype, 561*03100a63Svk199839 res0->ai_protocol)) < 0) { 562*03100a63Svk199839 warn("failed to create socket"); 563*03100a63Svk199839 continue; 564*03100a63Svk199839 } 565*03100a63Svk199839 566*03100a63Svk199839 ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)); 567*03100a63Svk199839 if (ret == -1) 568*03100a63Svk199839 err(1, NULL); 569*03100a63Svk199839 570*03100a63Svk199839 set_common_sockopts(s); 571*03100a63Svk199839 572*03100a63Svk199839 if (bind(s, (struct sockaddr *)res0->ai_addr, 573*03100a63Svk199839 res0->ai_addrlen) == 0) 574*03100a63Svk199839 break; 575*03100a63Svk199839 576*03100a63Svk199839 (void) close(s); 577*03100a63Svk199839 s = -1; 578*03100a63Svk199839 } while ((res0 = res0->ai_next) != NULL); 579*03100a63Svk199839 580*03100a63Svk199839 if (!uflag && s != -1) { 581*03100a63Svk199839 if (listen(s, 1) < 0) 582*03100a63Svk199839 err(1, "listen"); 583*03100a63Svk199839 } 584*03100a63Svk199839 585*03100a63Svk199839 freeaddrinfo(res); 586*03100a63Svk199839 587*03100a63Svk199839 return (s); 588*03100a63Svk199839 } 589*03100a63Svk199839 590*03100a63Svk199839 /* 591*03100a63Svk199839 * readwrite() 592*03100a63Svk199839 * Loop that polls on the network file descriptor and stdin. 593*03100a63Svk199839 */ 594*03100a63Svk199839 void 595*03100a63Svk199839 readwrite(int nfd) 596*03100a63Svk199839 { 597*03100a63Svk199839 struct pollfd pfd[2]; 598*03100a63Svk199839 unsigned char buf[8192]; 599*03100a63Svk199839 int n, wfd = fileno(stdin); 600*03100a63Svk199839 int lfd = fileno(stdout); 601*03100a63Svk199839 int plen; 602*03100a63Svk199839 603*03100a63Svk199839 plen = 1024; 604*03100a63Svk199839 605*03100a63Svk199839 /* Setup Network FD */ 606*03100a63Svk199839 pfd[0].fd = nfd; 607*03100a63Svk199839 pfd[0].events = POLLIN; 608*03100a63Svk199839 609*03100a63Svk199839 /* Set up STDIN FD. */ 610*03100a63Svk199839 pfd[1].fd = wfd; 611*03100a63Svk199839 pfd[1].events = POLLIN; 612*03100a63Svk199839 613*03100a63Svk199839 while (pfd[0].fd != -1) { 614*03100a63Svk199839 if (iflag) 615*03100a63Svk199839 (void) sleep(iflag); 616*03100a63Svk199839 617*03100a63Svk199839 if ((n = poll(pfd, 2 - dflag, timeout)) < 0) { 618*03100a63Svk199839 (void) close(nfd); 619*03100a63Svk199839 err(1, "Polling Error"); 620*03100a63Svk199839 } 621*03100a63Svk199839 622*03100a63Svk199839 if (n == 0) 623*03100a63Svk199839 return; 624*03100a63Svk199839 625*03100a63Svk199839 if (pfd[0].revents & (POLLIN|POLLHUP)) { 626*03100a63Svk199839 if ((n = read(nfd, buf, plen)) < 0) 627*03100a63Svk199839 return; 628*03100a63Svk199839 else if (n == 0) { 629*03100a63Svk199839 (void) shutdown(nfd, SHUT_RD); 630*03100a63Svk199839 pfd[0].fd = -1; 631*03100a63Svk199839 pfd[0].events = 0; 632*03100a63Svk199839 } else { 633*03100a63Svk199839 if (tflag) 634*03100a63Svk199839 atelnet(nfd, buf, n); 635*03100a63Svk199839 if (atomicio(vwrite, lfd, buf, n) != n) 636*03100a63Svk199839 return; 637*03100a63Svk199839 } 638*03100a63Svk199839 } 639*03100a63Svk199839 640*03100a63Svk199839 /* 641*03100a63Svk199839 * handle the case of disconnected pipe: after pipe 642*03100a63Svk199839 * is closed (indicated by POLLHUP) there may still 643*03100a63Svk199839 * be some data lingering (POLLIN). After we read 644*03100a63Svk199839 * the data, only POLLHUP remains, read() returns 0 645*03100a63Svk199839 * and we are finished. 646*03100a63Svk199839 */ 647*03100a63Svk199839 if (!dflag && (pfd[1].revents & (POLLIN|POLLHUP))) { 648*03100a63Svk199839 if ((n = read(wfd, buf, plen)) < 0) 649*03100a63Svk199839 return; 650*03100a63Svk199839 else if (n == 0) { 651*03100a63Svk199839 (void) shutdown(nfd, SHUT_WR); 652*03100a63Svk199839 pfd[1].fd = -1; 653*03100a63Svk199839 pfd[1].events = 0; 654*03100a63Svk199839 } else { 655*03100a63Svk199839 if (atomicio(vwrite, nfd, buf, n) != n) 656*03100a63Svk199839 return; 657*03100a63Svk199839 } 658*03100a63Svk199839 } 659*03100a63Svk199839 } 660*03100a63Svk199839 } 661*03100a63Svk199839 662*03100a63Svk199839 /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */ 663*03100a63Svk199839 void 664*03100a63Svk199839 atelnet(int nfd, unsigned char *buf, unsigned int size) 665*03100a63Svk199839 { 666*03100a63Svk199839 unsigned char *p, *end; 667*03100a63Svk199839 unsigned char obuf[4]; 668*03100a63Svk199839 669*03100a63Svk199839 end = buf + size; 670*03100a63Svk199839 obuf[0] = '\0'; 671*03100a63Svk199839 672*03100a63Svk199839 for (p = buf; p < end; p++) { 673*03100a63Svk199839 if (*p != IAC) 674*03100a63Svk199839 break; 675*03100a63Svk199839 676*03100a63Svk199839 obuf[0] = IAC; 677*03100a63Svk199839 obuf[1] = 0; 678*03100a63Svk199839 p++; 679*03100a63Svk199839 /* refuse all options */ 680*03100a63Svk199839 if ((*p == WILL) || (*p == WONT)) 681*03100a63Svk199839 obuf[1] = DONT; 682*03100a63Svk199839 if ((*p == DO) || (*p == DONT)) 683*03100a63Svk199839 obuf[1] = WONT; 684*03100a63Svk199839 if (obuf[1]) { 685*03100a63Svk199839 p++; 686*03100a63Svk199839 obuf[2] = *p; 687*03100a63Svk199839 obuf[3] = '\0'; 688*03100a63Svk199839 if (atomicio(vwrite, nfd, obuf, 3) != 3) 689*03100a63Svk199839 warn("Write Error!"); 690*03100a63Svk199839 obuf[0] = '\0'; 691*03100a63Svk199839 } 692*03100a63Svk199839 } 693*03100a63Svk199839 } 694*03100a63Svk199839 695*03100a63Svk199839 /* 696*03100a63Svk199839 * build_ports() 697*03100a63Svk199839 * Build an array of ports in portlist[], listing each port 698*03100a63Svk199839 * that we should try to connect to. 699*03100a63Svk199839 */ 700*03100a63Svk199839 void 701*03100a63Svk199839 build_ports(char *p) 702*03100a63Svk199839 { 703*03100a63Svk199839 const char *errstr; 704*03100a63Svk199839 char *n; 705*03100a63Svk199839 int hi, lo, cp; 706*03100a63Svk199839 int x = 0; 707*03100a63Svk199839 708*03100a63Svk199839 if ((n = strchr(p, '-')) != NULL) { 709*03100a63Svk199839 if (lflag) 710*03100a63Svk199839 errx(1, "Cannot use -l with multiple ports!"); 711*03100a63Svk199839 712*03100a63Svk199839 *n = '\0'; 713*03100a63Svk199839 n++; 714*03100a63Svk199839 715*03100a63Svk199839 /* Make sure the ports are in order: lowest->highest. */ 716*03100a63Svk199839 hi = strtonum(n, PORT_MIN, PORT_MAX, &errstr); 717*03100a63Svk199839 if (errstr) 718*03100a63Svk199839 errx(1, "port number %s: %s", errstr, n); 719*03100a63Svk199839 lo = strtonum(p, PORT_MIN, PORT_MAX, &errstr); 720*03100a63Svk199839 if (errstr) 721*03100a63Svk199839 errx(1, "port number %s: %s", errstr, p); 722*03100a63Svk199839 723*03100a63Svk199839 if (lo > hi) { 724*03100a63Svk199839 cp = hi; 725*03100a63Svk199839 hi = lo; 726*03100a63Svk199839 lo = cp; 727*03100a63Svk199839 } 728*03100a63Svk199839 729*03100a63Svk199839 /* Load ports sequentially. */ 730*03100a63Svk199839 for (cp = lo; cp <= hi; cp++) { 731*03100a63Svk199839 portlist[x] = calloc(1, PORT_MAX_LEN); 732*03100a63Svk199839 if (portlist[x] == NULL) 733*03100a63Svk199839 err(1, NULL); 734*03100a63Svk199839 (void) snprintf(portlist[x], PORT_MAX_LEN, "%d", cp); 735*03100a63Svk199839 x++; 736*03100a63Svk199839 } 737*03100a63Svk199839 738*03100a63Svk199839 /* Randomly swap ports. */ 739*03100a63Svk199839 if (rflag) { 740*03100a63Svk199839 int y; 741*03100a63Svk199839 char *c; 742*03100a63Svk199839 743*03100a63Svk199839 srandom(time((time_t *)0)); 744*03100a63Svk199839 745*03100a63Svk199839 for (x = 0; x <= (hi - lo); x++) { 746*03100a63Svk199839 y = (random() & 0xFFFF) % (hi - lo); 747*03100a63Svk199839 c = portlist[x]; 748*03100a63Svk199839 portlist[x] = portlist[y]; 749*03100a63Svk199839 portlist[y] = c; 750*03100a63Svk199839 } 751*03100a63Svk199839 } 752*03100a63Svk199839 } else { 753*03100a63Svk199839 hi = strtonum(p, PORT_MIN, PORT_MAX, &errstr); 754*03100a63Svk199839 if (errstr) 755*03100a63Svk199839 errx(1, "port number %s: %s", errstr, p); 756*03100a63Svk199839 portlist[0] = calloc(1, PORT_MAX_LEN); 757*03100a63Svk199839 if (portlist[0] == NULL) 758*03100a63Svk199839 err(1, NULL); 759*03100a63Svk199839 portlist[0] = p; 760*03100a63Svk199839 } 761*03100a63Svk199839 } 762*03100a63Svk199839 763*03100a63Svk199839 /* 764*03100a63Svk199839 * udptest() 765*03100a63Svk199839 * Do a few writes to see if the UDP port is there. 766*03100a63Svk199839 * XXX - Better way of doing this? Doesn't work for IPv6. 767*03100a63Svk199839 * Also fails after around 100 ports checked. 768*03100a63Svk199839 */ 769*03100a63Svk199839 int 770*03100a63Svk199839 udptest(int s) 771*03100a63Svk199839 { 772*03100a63Svk199839 int i, ret; 773*03100a63Svk199839 774*03100a63Svk199839 for (i = 0; i <= 3; i++) { 775*03100a63Svk199839 if (write(s, "X", 1) == 1) 776*03100a63Svk199839 ret = 1; 777*03100a63Svk199839 else 778*03100a63Svk199839 ret = -1; 779*03100a63Svk199839 } 780*03100a63Svk199839 return (ret); 781*03100a63Svk199839 } 782*03100a63Svk199839 783*03100a63Svk199839 void 784*03100a63Svk199839 set_common_sockopts(int s) 785*03100a63Svk199839 { 786*03100a63Svk199839 int x = 1; 787*03100a63Svk199839 788*03100a63Svk199839 if (Dflag) { 789*03100a63Svk199839 if (setsockopt(s, SOL_SOCKET, SO_DEBUG, &x, sizeof (x)) == -1) 790*03100a63Svk199839 err(1, NULL); 791*03100a63Svk199839 } 792*03100a63Svk199839 if (Tflag != -1) { 793*03100a63Svk199839 if (setsockopt(s, IPPROTO_IP, IP_TOS, &Tflag, 794*03100a63Svk199839 sizeof (Tflag)) == -1) 795*03100a63Svk199839 err(1, "set IP ToS"); 796*03100a63Svk199839 } 797*03100a63Svk199839 } 798*03100a63Svk199839 799*03100a63Svk199839 int 800*03100a63Svk199839 parse_iptos(char *s) 801*03100a63Svk199839 { 802*03100a63Svk199839 int tos = -1; 803*03100a63Svk199839 804*03100a63Svk199839 if (strcmp(s, "lowdelay") == 0) 805*03100a63Svk199839 return (IPTOS_LOWDELAY); 806*03100a63Svk199839 if (strcmp(s, "throughput") == 0) 807*03100a63Svk199839 return (IPTOS_THROUGHPUT); 808*03100a63Svk199839 if (strcmp(s, "reliability") == 0) 809*03100a63Svk199839 return (IPTOS_RELIABILITY); 810*03100a63Svk199839 811*03100a63Svk199839 if (sscanf(s, "0x%x", (unsigned int *) &tos) != 1 || 812*03100a63Svk199839 tos < 0 || tos > 0xff) 813*03100a63Svk199839 errx(1, "invalid IP Type of Service"); 814*03100a63Svk199839 return (tos); 815*03100a63Svk199839 } 816*03100a63Svk199839 817*03100a63Svk199839 void 818*03100a63Svk199839 help(void) 819*03100a63Svk199839 { 820*03100a63Svk199839 usage(0); 821*03100a63Svk199839 (void) fprintf(stderr, "\tCommand Summary:\n\ 822*03100a63Svk199839 \t-4 Use IPv4\n\ 823*03100a63Svk199839 \t-6 Use IPv6\n\ 824*03100a63Svk199839 \t-D Enable the debug socket option\n\ 825*03100a63Svk199839 \t-d Detach from stdin\n\ 826*03100a63Svk199839 \t-h This help text\n\ 827*03100a63Svk199839 \t-i secs\t Delay interval for lines sent, ports scanned\n\ 828*03100a63Svk199839 \t-k Keep inbound sockets open for multiple connects\n\ 829*03100a63Svk199839 \t-l Listen mode, for inbound connects\n\ 830*03100a63Svk199839 \t-n Suppress name/port resolutions\n\ 831*03100a63Svk199839 \t-P proxyuser\tUsername for proxy authentication\n\ 832*03100a63Svk199839 \t-p port\t Specify local port or listen port\n\ 833*03100a63Svk199839 \t-r Randomize remote ports\n\ 834*03100a63Svk199839 \t-s addr\t Local source address\n\ 835*03100a63Svk199839 \t-T ToS\t Set IP Type of Service\n\ 836*03100a63Svk199839 \t-t Answer TELNET negotiation\n\ 837*03100a63Svk199839 \t-U Use UNIX domain socket\n\ 838*03100a63Svk199839 \t-u UDP mode\n\ 839*03100a63Svk199839 \t-v Verbose\n\ 840*03100a63Svk199839 \t-w secs\t Timeout for connects and final net reads\n\ 841*03100a63Svk199839 \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\ 842*03100a63Svk199839 \t-x addr[:port]\tSpecify proxy address and port\n\ 843*03100a63Svk199839 \t-z Zero-I/O mode [used for scanning]\n\ 844*03100a63Svk199839 Port numbers can be individual or ranges: lo-hi [inclusive]\n"); 845*03100a63Svk199839 exit(1); 846*03100a63Svk199839 } 847*03100a63Svk199839 848*03100a63Svk199839 void 849*03100a63Svk199839 usage(int ret) 850*03100a63Svk199839 { 851*03100a63Svk199839 (void) fprintf(stderr, 852*03100a63Svk199839 "usage: nc [-46DdhklnrtUuvz] [-i interval] [-P proxy_username]" 853*03100a63Svk199839 " [-p port]\n"); 854*03100a63Svk199839 (void) fprintf(stderr, 855*03100a63Svk199839 "\t [-s source_ip_address] [-T ToS] [-w timeout]" 856*03100a63Svk199839 " [-X proxy_protocol]\n"); 857*03100a63Svk199839 (void) fprintf(stderr, 858*03100a63Svk199839 "\t [-x proxy_address[:port]] [hostname]" 859*03100a63Svk199839 " [port[s]]\n"); 860*03100a63Svk199839 if (ret) 861*03100a63Svk199839 exit(1); 862*03100a63Svk199839 } 863