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