1 /* $OpenBSD: netcat.c,v 1.89 2007/02/20 14:11:17 jmc Exp $ */
2 /*
3 * Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
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.
16 *
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 */
28
29 /*
30 * Re-written nc(1) for OpenBSD. Original implementation by
31 * *Hobbit* <hobbit@avian.org>.
32 */
33
34 /*
35 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
36 * Use is subject to license terms.
37 */
38
39 /*
40 * Portions Copyright 2008 Erik Trauschke
41 * Copyright 2024 Oxide Computer Company
42 */
43
44 #include <sys/types.h>
45 #include <sys/socket.h>
46 #include <sys/time.h>
47 #include <sys/un.h>
48
49 #include <netinet/in.h>
50 #include <netinet/in_systm.h>
51 #include <netinet/tcp.h>
52 #include <netinet/ip.h>
53 #include <arpa/telnet.h>
54
55 #include <err.h>
56 #include <errno.h>
57 #include <netdb.h>
58 #include <poll.h>
59 #include <stdarg.h>
60 #include <stdio.h>
61 #include <stdlib.h>
62 #include <string.h>
63 #include <unistd.h>
64 #include <fcntl.h>
65 #include <limits.h>
66 #include <signal.h>
67
68 #include "atomicio.h"
69
70 #ifndef SUN_LEN
71 #define SUN_LEN(su) \
72 (sizeof (*(su)) - sizeof ((su)->sun_path) + strlen((su)->sun_path))
73 #endif
74
75 #define PORT_MIN 1
76 #define PORT_MAX 65535
77 #define PORT_MAX_LEN 6
78 #define PLIST_SZ 32 /* initial capacity of the portlist */
79
80 /* Command Line Options */
81 int dflag; /* detached, no stdin */
82 unsigned int iflag; /* Interval Flag */
83 int kflag; /* More than one connect */
84 int lflag; /* Bind to local port */
85 int nflag; /* Don't do name lookup */
86 const char *Pflag; /* Proxy username */
87 char *pflag; /* Localport flag */
88 int rflag; /* Random ports flag */
89 const char *sflag; /* Source Address */
90 int tflag; /* Telnet Emulation */
91 int uflag; /* UDP - Default to TCP */
92 int vflag; /* Verbosity */
93 int xflag; /* Socks proxy */
94 int Xflag; /* indicator of Socks version set */
95 int zflag; /* Port Scan Flag */
96 int Dflag; /* sodebug */
97 int Sflag; /* TCP MD5 signature option */
98 int Tflag = -1; /* IP Type of Service */
99
100 int timeout = -1;
101 int family = AF_UNSPEC;
102 int ttl = -1;
103 int minttl = -1;
104
105 /*
106 * portlist structure
107 * Used to store a list of ports given by the user and maintaining
108 * information about the number of ports stored.
109 */
110 struct {
111 uint16_t *list; /* list containing the ports */
112 uint_t listsize; /* capacity of the list (number of entries) */
113 uint_t numports; /* number of ports in the list */
114 } ports;
115
116 void atelnet(int, unsigned char *, unsigned int);
117 void build_ports(char *);
118 void help(void);
119 int local_listen(const char *, const char *, struct addrinfo);
120 void readwrite(int);
121 int remote_connect(const char *, const char *, struct addrinfo);
122 int socks_connect(const char *, const char *,
123 const char *, const char *, struct addrinfo, int, const char *);
124 int udptest(int);
125 int unix_connect(const char *);
126 int unix_listen(const char *);
127 void set_common_sockopts(int, int);
128 int parse_iptos(const char *);
129 void usage(int);
130 const char *print_addr(char *, size_t, struct sockaddr *, int, int);
131
132 int
main(int argc,char * argv[])133 main(int argc, char *argv[])
134 {
135 int ch, s, ret, socksv;
136 char *host, *uport, *proxy;
137 struct addrinfo hints;
138 struct servent *sv;
139 socklen_t len;
140 struct sockaddr_storage cliaddr;
141 const char *errstr, *proxyhost = "", *proxyport = NULL;
142 struct addrinfo proxyhints;
143 char port[PORT_MAX_LEN];
144
145 ret = 1;
146 s = -1;
147 socksv = 5;
148 host = NULL;
149 uport = NULL;
150 sv = NULL;
151
152 while ((ch = getopt(argc, argv,
153 "46Ddhi:klm:M:nP:p:rs:ST:tUuvw:X:x:z")) != -1) {
154 switch (ch) {
155 case '4':
156 family = AF_INET;
157 break;
158 case '6':
159 family = AF_INET6;
160 break;
161 case 'U':
162 family = AF_UNIX;
163 break;
164 case 'X':
165 Xflag = 1;
166 if (strcasecmp(optarg, "connect") == 0)
167 socksv = -1; /* HTTP proxy CONNECT */
168 else if (strcmp(optarg, "4") == 0)
169 socksv = 4; /* SOCKS v.4 */
170 else if (strcmp(optarg, "5") == 0)
171 socksv = 5; /* SOCKS v.5 */
172 else
173 errx(1, "unsupported proxy protocol");
174 break;
175 case 'd':
176 dflag = 1;
177 break;
178 case 'h':
179 help();
180 break;
181 case 'i':
182 iflag = strtonum(optarg, 0, UINT_MAX, &errstr);
183 if (errstr)
184 errx(1, "interval %s: %s", errstr, optarg);
185 break;
186 case 'k':
187 kflag = 1;
188 break;
189 case 'M':
190 ttl = strtonumx(optarg, 1, 255, &errstr, 0);
191 if (errstr != NULL) {
192 errx(1, "ttl is %s: %s, valid values are "
193 "between 1 and 255", errstr, optarg);
194 }
195 break;
196 case 'm':
197 minttl = strtonumx(optarg, 0, 255, &errstr, 0);
198 if (errstr != NULL) {
199 errx(1, "minimum ttl is %s: %s, valid values "
200 "are between 0 and 255", errstr, optarg);
201 }
202 break;
203 case 'l':
204 lflag = 1;
205 break;
206 case 'n':
207 nflag = 1;
208 break;
209 case 'P':
210 Pflag = optarg;
211 break;
212 case 'p':
213 pflag = optarg;
214 break;
215 case 'r':
216 rflag = 1;
217 break;
218 case 's':
219 sflag = optarg;
220 break;
221 case 't':
222 tflag = 1;
223 break;
224 case 'u':
225 uflag = 1;
226 break;
227 case 'v':
228 vflag = 1;
229 break;
230 case 'w':
231 timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr);
232 if (errstr)
233 errx(1, "timeout %s: %s", errstr, optarg);
234 timeout *= 1000;
235 break;
236 case 'x':
237 xflag = 1;
238 if ((proxy = strdup(optarg)) == NULL)
239 err(1, NULL);
240 break;
241 case 'z':
242 zflag = 1;
243 break;
244 case 'D':
245 Dflag = 1;
246 break;
247 case 'S':
248 Sflag = 1;
249 break;
250 case 'T':
251 Tflag = parse_iptos(optarg);
252 break;
253 default:
254 usage(1);
255 }
256 }
257 argc -= optind;
258 argv += optind;
259
260 /* Cruft to make sure options are clean, and used properly. */
261 if (argv[0] && !argv[1] && family == AF_UNIX) {
262 if (uflag)
263 errx(1, "cannot use -u and -U");
264 host = argv[0];
265 uport = NULL;
266 } else if (argv[0] && !argv[1]) {
267 if (!lflag)
268 usage(1);
269 uport = argv[0];
270 host = NULL;
271 } else if (argv[0] && argv[1]) {
272 if (family == AF_UNIX)
273 usage(1);
274 host = argv[0];
275 uport = argv[1];
276 } else {
277 if (!(lflag && pflag))
278 usage(1);
279 }
280
281 if (argc > 2)
282 usage(1);
283
284 if (lflag && sflag)
285 errx(1, "cannot use -s and -l");
286 if (lflag && rflag)
287 errx(1, "cannot use -r and -l");
288 if (lflag && (timeout >= 0))
289 warnx("-w has no effect with -l");
290 if (lflag && pflag) {
291 if (uport)
292 usage(1);
293 uport = pflag;
294 }
295 if (lflag && zflag)
296 errx(1, "cannot use -z and -l");
297 if (!lflag && kflag)
298 errx(1, "must use -l with -k");
299 if (lflag && (Pflag || xflag || Xflag))
300 errx(1, "cannot use -l with -P, -X or -x");
301
302 /* Initialize addrinfo structure. */
303 if (family != AF_UNIX) {
304 (void) memset(&hints, 0, sizeof (struct addrinfo));
305 hints.ai_family = family;
306 hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
307 hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
308 if (nflag)
309 hints.ai_flags |= AI_NUMERICHOST;
310 }
311
312 if (xflag) {
313 if (uflag)
314 errx(1, "no proxy support for UDP mode");
315
316 if (lflag)
317 errx(1, "no proxy support for listen");
318
319 if (family == AF_UNIX)
320 errx(1, "no proxy support for unix sockets");
321
322 if (family == AF_INET6)
323 errx(1, "no proxy support for IPv6");
324
325 if (sflag)
326 errx(1, "no proxy support for local source address");
327
328 if ((proxyhost = strtok(proxy, ":")) == NULL)
329 errx(1, "missing port specification");
330 proxyport = strtok(NULL, ":");
331
332 (void) memset(&proxyhints, 0, sizeof (struct addrinfo));
333 proxyhints.ai_family = family;
334 proxyhints.ai_socktype = SOCK_STREAM;
335 proxyhints.ai_protocol = IPPROTO_TCP;
336 if (nflag)
337 proxyhints.ai_flags |= AI_NUMERICHOST;
338 }
339
340 if (lflag) {
341 int connfd;
342 ret = 0;
343
344 if (family == AF_UNIX) {
345 if (host == NULL)
346 usage(1);
347 s = unix_listen(host);
348 }
349
350 /* Allow only one connection at a time, but stay alive. */
351 for (;;) {
352 if (family != AF_UNIX) {
353 /* check if uport is valid */
354 if (strtonum(uport, PORT_MIN, PORT_MAX,
355 &errstr) == 0)
356 errx(1, "port number %s: %s",
357 uport, errstr);
358 s = local_listen(host, uport, hints);
359 }
360 if (s < 0)
361 err(1, NULL);
362 /*
363 * For UDP, we will use recvfrom() initially
364 * to wait for a caller, then use the regular
365 * functions to talk to the caller.
366 */
367 if (uflag) {
368 int rv, plen;
369 char buf[8192];
370 struct sockaddr_storage z;
371
372 len = sizeof (z);
373 plen = 1024;
374 rv = recvfrom(s, buf, plen, MSG_PEEK,
375 (struct sockaddr *)&z, &len);
376 if (rv < 0)
377 err(1, "recvfrom");
378
379 rv = connect(s, (struct sockaddr *)&z, len);
380 if (rv < 0)
381 err(1, "connect");
382
383 connfd = s;
384 } else {
385 len = sizeof (cliaddr);
386 connfd = accept(s, (struct sockaddr *)&cliaddr,
387 &len);
388 if ((connfd != -1) && vflag) {
389 char ntop[NI_MAXHOST + NI_MAXSERV];
390 (void) fprintf(stderr,
391 "Received connection from %s\n",
392 print_addr(ntop, sizeof (ntop),
393 (struct sockaddr *)&cliaddr, len,
394 nflag ? NI_NUMERICHOST : 0));
395 }
396 }
397
398 readwrite(connfd);
399 (void) close(connfd);
400 if (family != AF_UNIX)
401 (void) close(s);
402
403 if (!kflag)
404 break;
405 }
406 } else if (family == AF_UNIX) {
407 ret = 0;
408
409 if ((s = unix_connect(host)) > 0 && !zflag) {
410 readwrite(s);
411 (void) close(s);
412 } else
413 ret = 1;
414
415 exit(ret);
416
417 } else { /* AF_INET or AF_INET6 */
418 int i;
419
420 /* Construct the portlist. */
421 build_ports(uport);
422
423 /* Cycle through portlist, connecting to each port. */
424 for (i = 0; i < ports.numports; i++) {
425 (void) snprintf(port, sizeof (port), "%u",
426 ports.list[i]);
427
428 if (s != -1)
429 (void) close(s);
430
431 if (xflag)
432 s = socks_connect(host, port,
433 proxyhost, proxyport, proxyhints, socksv,
434 Pflag);
435 else
436 s = remote_connect(host, port, hints);
437
438 if (s < 0)
439 continue;
440
441 ret = 0;
442 if (vflag || zflag) {
443 /* For UDP, make sure we are connected. */
444 if (uflag) {
445 if (udptest(s) == -1) {
446 ret = 1;
447 continue;
448 }
449 }
450
451 /* Don't look up port if -n. */
452 if (nflag)
453 sv = NULL;
454 else {
455 sv = getservbyport(
456 ntohs(ports.list[i]),
457 uflag ? "udp" : "tcp");
458 }
459
460 (void) fprintf(stderr, "Connection to %s %s "
461 "port [%s/%s] succeeded!\n",
462 host, port, uflag ? "udp" : "tcp",
463 sv ? sv->s_name : "*");
464 }
465 if (!zflag)
466 readwrite(s);
467 }
468 free(ports.list);
469 }
470
471 if (s != -1)
472 (void) close(s);
473
474 return (ret);
475 }
476
477 /*
478 * print IP address and (optionally) a port
479 */
480 const char *
print_addr(char * ntop,size_t ntlen,struct sockaddr * addr,int len,int flags)481 print_addr(char *ntop, size_t ntlen, struct sockaddr *addr, int len, int flags)
482 {
483 char port[NI_MAXSERV];
484 int e;
485
486 /* print port always as number */
487 if ((e = getnameinfo(addr, len, ntop, ntlen,
488 port, sizeof (port), flags|NI_NUMERICSERV)) != 0) {
489 return ((char *)gai_strerror(e));
490 }
491
492 (void) strlcat(ntop, " port ", ntlen);
493 (void) strlcat(ntop, port, ntlen);
494
495 return (ntop);
496 }
497
498 /*
499 * unix_connect()
500 * Returns a socket connected to a local unix socket. Returns -1 on failure.
501 */
502 int
unix_connect(const char * path)503 unix_connect(const char *path)
504 {
505 struct sockaddr_un sunaddr;
506 int s;
507
508 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
509 return (-1);
510
511 (void) memset(&sunaddr, 0, sizeof (struct sockaddr_un));
512 sunaddr.sun_family = AF_UNIX;
513
514 if (strlcpy(sunaddr.sun_path, path, sizeof (sunaddr.sun_path)) >=
515 sizeof (sunaddr.sun_path)) {
516 (void) close(s);
517 errno = ENAMETOOLONG;
518 return (-1);
519 }
520 if (connect(s, (struct sockaddr *)&sunaddr, SUN_LEN(&sunaddr)) < 0) {
521 (void) close(s);
522 return (-1);
523 }
524 return (s);
525 }
526
527 /*
528 * unix_listen()
529 * Create a unix domain socket, and listen on it.
530 */
531 int
unix_listen(const char * path)532 unix_listen(const char *path)
533 {
534 struct sockaddr_un sunaddr;
535 int s;
536
537 /* Create unix domain socket. */
538 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
539 return (-1);
540
541 (void) memset(&sunaddr, 0, sizeof (struct sockaddr_un));
542 sunaddr.sun_family = AF_UNIX;
543
544 if (strlcpy(sunaddr.sun_path, path, sizeof (sunaddr.sun_path)) >=
545 sizeof (sunaddr.sun_path)) {
546 (void) close(s);
547 errno = ENAMETOOLONG;
548 return (-1);
549 }
550
551 if (bind(s, (struct sockaddr *)&sunaddr, SUN_LEN(&sunaddr)) < 0) {
552 (void) close(s);
553 return (-1);
554 }
555
556 if (listen(s, 5) < 0) {
557 (void) close(s);
558 return (-1);
559 }
560 return (s);
561 }
562
563 /*
564 * remote_connect()
565 * Returns a socket connected to a remote host. Properly binds to a local
566 * port or source address if needed. Returns -1 on failure.
567 */
568 int
remote_connect(const char * host,const char * port,struct addrinfo hints)569 remote_connect(const char *host, const char *port, struct addrinfo hints)
570 {
571 struct addrinfo *res, *res0;
572 int s, error;
573
574 if ((error = getaddrinfo(host, port, &hints, &res)))
575 errx(1, "getaddrinfo: %s", gai_strerror(error));
576
577 res0 = res;
578 do {
579 if ((s = socket(res0->ai_family, res0->ai_socktype,
580 res0->ai_protocol)) < 0) {
581 warn("failed to create socket");
582 continue;
583 }
584
585 /* Bind to a local port or source address if specified. */
586 if (sflag || pflag) {
587 struct addrinfo ahints, *ares;
588
589 (void) memset(&ahints, 0, sizeof (struct addrinfo));
590 ahints.ai_family = res0->ai_family;
591 ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
592 ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
593 ahints.ai_flags = AI_PASSIVE;
594 if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
595 errx(1, "getaddrinfo: %s", gai_strerror(error));
596
597 if (bind(s, (struct sockaddr *)ares->ai_addr,
598 ares->ai_addrlen) < 0)
599 errx(1, "bind failed: %s", strerror(errno));
600 freeaddrinfo(ares);
601
602 if (vflag && !lflag) {
603 if (sflag != NULL)
604 (void) fprintf(stderr,
605 "Using source address: %s\n",
606 sflag);
607 if (pflag != NULL)
608 (void) fprintf(stderr,
609 "Using source port: %s\n", pflag);
610 }
611 }
612
613 set_common_sockopts(s, res0->ai_family);
614
615 if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
616 break;
617 else if (vflag) {
618 char ntop[NI_MAXHOST + NI_MAXSERV];
619 warn("connect to %s [host %s] (%s) failed",
620 print_addr(ntop, sizeof (ntop),
621 res0->ai_addr, res0->ai_addrlen, NI_NUMERICHOST),
622 host, uflag ? "udp" : "tcp");
623 }
624
625 (void) close(s);
626 s = -1;
627 } while ((res0 = res0->ai_next) != NULL);
628
629 freeaddrinfo(res);
630
631 return (s);
632 }
633
634 /*
635 * local_listen()
636 * Returns a socket listening on a local port, binds to specified source
637 * address. Returns -1 on failure.
638 */
639 int
local_listen(const char * host,const char * port,struct addrinfo hints)640 local_listen(const char *host, const char *port, struct addrinfo hints)
641 {
642 struct addrinfo *res, *res0;
643 int s, ret, x = 1;
644 int error;
645
646 /* Allow nodename to be null. */
647 hints.ai_flags |= AI_PASSIVE;
648
649 if ((error = getaddrinfo(host, port, &hints, &res)))
650 errx(1, "getaddrinfo: %s", gai_strerror(error));
651
652 res0 = res;
653 do {
654 if ((s = socket(res0->ai_family, res0->ai_socktype,
655 res0->ai_protocol)) < 0) {
656 warn("failed to create socket");
657 continue;
658 }
659
660 ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x));
661 if (ret == -1)
662 err(1, NULL);
663
664 set_common_sockopts(s, res0->ai_family);
665
666 if (bind(s, (struct sockaddr *)res0->ai_addr,
667 res0->ai_addrlen) == 0)
668 break;
669
670 (void) close(s);
671 s = -1;
672 } while ((res0 = res0->ai_next) != NULL);
673
674 if (!uflag && s != -1) {
675 if (listen(s, 1) < 0)
676 err(1, "listen");
677 }
678
679 freeaddrinfo(res);
680
681 return (s);
682 }
683
684 /*
685 * readwrite()
686 * Loop that polls on the network file descriptor and stdin.
687 */
688 void
readwrite(int nfd)689 readwrite(int nfd)
690 {
691 struct pollfd pfd[2];
692 unsigned char buf[8192];
693 int n, wfd = fileno(stdin);
694 int lfd = fileno(stdout);
695 int plen;
696
697 plen = 1024;
698
699 /* Setup Network FD */
700 pfd[0].fd = nfd;
701 pfd[0].events = POLLIN;
702
703 /* Set up STDIN FD. */
704 pfd[1].fd = wfd;
705 pfd[1].events = POLLIN;
706
707 while (pfd[0].fd != -1) {
708 if (iflag)
709 (void) sleep(iflag);
710
711 if ((n = poll(pfd, 2 - dflag, timeout)) < 0) {
712 (void) close(nfd);
713 err(1, "Polling Error");
714 }
715
716 if (n == 0)
717 return;
718
719 if (pfd[0].revents & (POLLIN|POLLHUP)) {
720 if ((n = read(nfd, buf, plen)) < 0)
721 return;
722 else if (n == 0) {
723 (void) shutdown(nfd, SHUT_RD);
724 pfd[0].fd = -1;
725 pfd[0].events = 0;
726 } else {
727 if (tflag)
728 atelnet(nfd, buf, n);
729 if (atomicio(vwrite, lfd, buf, n) != n)
730 return;
731 }
732 }
733
734 /*
735 * handle the case of disconnected pipe: after pipe
736 * is closed (indicated by POLLHUP) there may still
737 * be some data lingering (POLLIN). After we read
738 * the data, only POLLHUP remains, read() returns 0
739 * and we are finished.
740 */
741 if (!dflag && (pfd[1].revents & (POLLIN|POLLHUP))) {
742 if ((n = read(wfd, buf, plen)) < 0)
743 return;
744 else if (n == 0) {
745 (void) shutdown(nfd, SHUT_WR);
746 pfd[1].fd = -1;
747 pfd[1].events = 0;
748 } else {
749 if (atomicio(vwrite, nfd, buf, n) != n)
750 return;
751 }
752 }
753 }
754 }
755
756 /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */
757 void
atelnet(int nfd,unsigned char * buf,unsigned int size)758 atelnet(int nfd, unsigned char *buf, unsigned int size)
759 {
760 unsigned char *p, *end;
761 unsigned char obuf[4];
762
763 end = buf + size;
764 obuf[0] = '\0';
765
766 for (p = buf; p < end; p++) {
767 if (*p != IAC)
768 break;
769
770 obuf[0] = IAC;
771 obuf[1] = 0;
772 p++;
773 /* refuse all options */
774 if ((*p == WILL) || (*p == WONT))
775 obuf[1] = DONT;
776 if ((*p == DO) || (*p == DONT))
777 obuf[1] = WONT;
778 if (obuf[1]) {
779 p++;
780 obuf[2] = *p;
781 obuf[3] = '\0';
782 if (atomicio(vwrite, nfd, obuf, 3) != 3)
783 warn("Write Error!");
784 obuf[0] = '\0';
785 }
786 }
787 }
788
789 /*
790 * build_ports()
791 * Build an array of ports in ports.list[], listing each port
792 * that we should try to connect to.
793 */
794 void
build_ports(char * p)795 build_ports(char *p)
796 {
797 const char *errstr;
798 const char *token;
799 char *n;
800 int lo, hi, cp;
801 int i;
802
803 /* Set up initial portlist. */
804 ports.list = malloc(PLIST_SZ * sizeof (uint16_t));
805 if (ports.list == NULL)
806 err(1, NULL);
807 ports.listsize = PLIST_SZ;
808 ports.numports = 0;
809
810 /* Cycle through list of given ports sep. by "," */
811 while ((token = strsep(&p, ",")) != NULL) {
812 if (*token == '\0')
813 errx(1, "Invalid port/portlist format: "
814 "zero length port");
815
816 /* check if it is a range */
817 if ((n = strchr(token, '-')) != NULL)
818 *n++ = '\0';
819
820 lo = strtonum(token, PORT_MIN, PORT_MAX, &errstr);
821 if (errstr)
822 errx(1, "port number %s: %s", errstr, token);
823
824 if (n == NULL) {
825 hi = lo;
826 } else {
827 hi = strtonum(n, PORT_MIN, PORT_MAX, &errstr);
828 if (errstr)
829 errx(1, "port number %s: %s", errstr, n);
830 if (lo > hi) {
831 cp = hi;
832 hi = lo;
833 lo = cp;
834 }
835 }
836
837 /*
838 * Grow the portlist if needed.
839 * We double the size and add size of current range
840 * to make sure we don't have to resize that often.
841 */
842 if (hi - lo + ports.numports + 1 >= ports.listsize) {
843 ports.listsize = ports.listsize * 2 + hi - lo;
844 ports.list = realloc(ports.list,
845 ports.listsize * sizeof (uint16_t));
846 if (ports.list == NULL)
847 err(1, NULL);
848 }
849
850 /* Load ports sequentially. */
851 for (i = lo; i <= hi; i++)
852 ports.list[ports.numports++] = i;
853 }
854
855 /* Randomly swap ports. */
856 if (rflag) {
857 int y;
858 uint16_t u;
859
860 if (ports.numports < 2) {
861 warnx("can not swap %d port randomly",
862 ports.numports);
863 return;
864 }
865 srandom(time(NULL));
866 for (i = 0; i < ports.numports; i++) {
867 y = random() % (ports.numports - 1);
868 u = ports.list[i];
869 ports.list[i] = ports.list[y];
870 ports.list[y] = u;
871 }
872 }
873 }
874
875 /*
876 * udptest()
877 * Do a few writes to see if the UDP port is there.
878 * XXX - Better way of doing this? Doesn't work for IPv6.
879 * Also fails after around 100 ports checked.
880 */
881 int
udptest(int s)882 udptest(int s)
883 {
884 int i, ret;
885
886 for (i = 0; i <= 3; i++) {
887 if (write(s, "X", 1) == 1)
888 ret = 1;
889 else
890 ret = -1;
891 }
892 return (ret);
893 }
894
895 void
set_common_sockopts(int s,int af)896 set_common_sockopts(int s, int af)
897 {
898 int x = 1;
899
900 if (Sflag) {
901 if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
902 &x, sizeof (x)) == -1) {
903 err(1, NULL);
904 }
905 }
906
907 if (Dflag) {
908 if (setsockopt(s, SOL_SOCKET, SO_DEBUG, &x, sizeof (x)) == -1)
909 err(1, NULL);
910 }
911 if (Tflag != -1) {
912 switch (af) {
913 case AF_INET:
914 if (setsockopt(s, IPPROTO_IP, IP_TOS, &Tflag,
915 sizeof (Tflag)) == -1) {
916 err(1, "failed to set IP ToS socket option");
917 }
918 break;
919 case AF_INET6:
920 if (setsockopt(s, IPPROTO_IPV6, IPV6_TCLASS, &Tflag,
921 sizeof (Tflag)) == -1) {
922 err(1, "failed to set IPv6 traffic class "
923 "socket option");
924 }
925 break;
926 default:
927 err(1, "cannot set TTL/Hops on unsupported socket "
928 "family 0x%x", af);
929 }
930 }
931
932 if (ttl != -1) {
933 switch (af) {
934 case AF_INET:
935 if (setsockopt(s, IPPROTO_IP, IP_TTL, &ttl,
936 sizeof (ttl)) != 0) {
937 err(1, "failed to set IP TTL socket option");
938 }
939 break;
940 case AF_INET6:
941 if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl,
942 sizeof (ttl)) != 0) {
943 err(1, "failed to set IPv6 unicast hops socket "
944 "option");
945 }
946 break;
947 default:
948 err(1, "cannot set TTL/Hops on unsupported socket "
949 "family 0x%x", af);
950 }
951 }
952
953 if (minttl != -1) {
954 switch (af) {
955 case AF_INET:
956 if (setsockopt(s, IPPROTO_IP, IP_MINTTL, &minttl,
957 sizeof (minttl)) != 0) {
958 err(1, "failed to set IP minimum TTL socket "
959 "option");
960 }
961 break;
962 case AF_INET6:
963 if (setsockopt(s, IPPROTO_IPV6, IPV6_MINHOPCOUNT,
964 &minttl, sizeof (minttl)) != 0) {
965 err(1, "failed to set IPv6 minimum hop count "
966 "socket option");
967 }
968 break;
969 default:
970 err(1, "cannot set minimum TTL/Hops on unsupported "
971 "socket family 0x%x", af);
972 }
973 }
974
975 }
976
977 int
parse_iptos(const char * s)978 parse_iptos(const char *s)
979 {
980 int tos;
981 const char *errstr;
982
983 if (strcmp(s, "lowdelay") == 0)
984 return (IPTOS_LOWDELAY);
985 if (strcmp(s, "throughput") == 0)
986 return (IPTOS_THROUGHPUT);
987 if (strcmp(s, "reliability") == 0)
988 return (IPTOS_RELIABILITY);
989
990 tos = strtonumx(s, 0, 255, &errstr, 0);
991 if (errstr != NULL) {
992 errx(1, "IP ToS/IPv6 TC is %s: %s, valid values are "
993 "between 0 and 255", errstr, optarg);
994 }
995
996 return (tos);
997 }
998
999 void
help(void)1000 help(void)
1001 {
1002 usage(0);
1003 (void) fprintf(stderr, "\tCommand Summary:\n\
1004 \t-4 Use IPv4\n\
1005 \t-6 Use IPv6\n\
1006 \t-D Enable the debug socket option\n\
1007 \t-d Detach from stdin\n\
1008 \t-h This help text\n\
1009 \t-i secs\t Delay interval for lines sent, ports scanned\n\
1010 \t-k Keep inbound sockets open for multiple connects\n\
1011 \t-l Listen mode, for inbound connects\n\
1012 \t-l Listen mode, for inbound connects\n\
1013 \t-M ttl\t Set the outbound IPv4 TTL / IPv6 Hop Limit\n\
1014 \t-m minttl Set the inbound minimum IPv4 TTL / IPv6 Hop Limit\n\
1015 \t-n Suppress name/port resolutions\n\
1016 \t-P proxyuser\tUsername for proxy authentication\n\
1017 \t-p port\t Specify local port or listen port\n\
1018 \t-r Randomize remote ports\n\
1019 \t-S Enable TCP MD5 signature socket option\n\
1020 \t-s addr\t Local source address\n\
1021 \t-T ToS\t Set IP Type of Service\n\
1022 \t-t Answer TELNET negotiation\n\
1023 \t-U Use UNIX domain socket\n\
1024 \t-u UDP mode\n\
1025 \t-v Verbose\n\
1026 \t-w secs\t Timeout for connects and final net reads\n\
1027 \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\
1028 \t-x addr[:port]\tSpecify proxy address and port\n\
1029 \t-z Zero-I/O mode [used for scanning]\n\
1030 Port numbers can be individuals, ranges (lo-hi; inclusive) and\n\
1031 combinations of both separated by comma (e.g. 10,22-25,80)\n");
1032 exit(1);
1033 }
1034
1035 void
usage(int ret)1036 usage(int ret)
1037 {
1038 (void) fprintf(stderr,
1039 "usage: nc [-46DdhklnrStUuvz] [-i interval] [-M ttl] [-m minttl]\n"
1040 "\t [-P proxy_username] [-p port] [-s source_ip_address] "
1041 "[-T ToS]\n"
1042 "\t [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]]\n"
1043 "\t [hostname] [port[s]]\n");
1044 if (ret)
1045 exit(1);
1046 }
1047