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