chroot: add DragonFly BSD support
[girocco.git] / src / dragonfly / netcat.c
blob3d5cf0abfcda3a2836ebc5744c290a99a421f45a
1 /* $OpenBSD: netcat.c,v 1.82 2005/07/24 09:33:56 marius Exp $ */
2 /*
3 * Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
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.
30 * Re-written nc(1) for OpenBSD. Original implementation by
31 * *Hobbit* <hobbit@avian.org>.
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <sys/time.h>
37 #include <sys/un.h>
39 #include <netinet/in.h>
40 #include <netinet/tcp.h>
41 #include <arpa/telnet.h>
43 #include <err.h>
44 #include <errno.h>
45 #ifdef __DragonFly__
46 #include <limits.h>
47 #endif /* __DragonFly__ */
48 #include <netdb.h>
49 #include <poll.h>
50 #include <stdarg.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <unistd.h>
55 #include <fcntl.h>
56 #include "atomicio.h"
58 #ifndef SUN_LEN
59 #define SUN_LEN(su) \
60 (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
61 #endif
63 #define PORT_MAX 65535
64 #define PORT_MAX_LEN 6
66 /* Command Line Options */
67 int dflag; /* detached, no stdin */
68 int iflag; /* Interval Flag */
69 #ifndef __DragonFly__
70 int jflag; /* use jumbo frames if we can */
71 #endif /* !__DragonFly__ */
72 int kflag; /* More than one connect */
73 int lflag; /* Bind to local port */
74 int nflag; /* Don't do name look up */
75 char *pflag; /* Localport flag */
76 int rflag; /* Random ports flag */
77 char *sflag; /* Source Address */
78 int tflag; /* Telnet Emulation */
79 int uflag; /* UDP - Default to TCP */
80 int vflag; /* Verbosity */
81 int xflag; /* Socks proxy */
82 int zflag; /* Port Scan Flag */
83 int Dflag; /* sodebug */
84 #ifndef __DragonFly__
85 int Sflag; /* TCP MD5 signature option */
86 #endif /* !__DragonFly__ */
88 int timeout = -1;
89 int family = AF_UNSPEC;
90 char *portlist[PORT_MAX+1];
92 void atelnet(int, unsigned char *, unsigned int);
93 void build_ports(char *);
94 void help(void);
95 int local_listen(char *, char *, struct addrinfo);
96 void readwrite(int);
97 int remote_connect(const char *, const char *, struct addrinfo);
98 int socks_connect(const char *, const char *, struct addrinfo, const char *, const char *,
99 struct addrinfo, int);
100 int udptest(int);
101 int unix_connect(char *);
102 int unix_listen(char *);
103 int set_common_sockopts(int);
104 void usage(int);
107 main(int argc, char *argv[])
109 int ch, s, ret, socksv;
110 char *host, *uport, *endp;
111 struct addrinfo hints;
112 struct servent *sv;
113 socklen_t len;
114 struct sockaddr_storage cliaddr;
115 char *proxy;
116 const char *proxyhost = "", *proxyport = NULL;
117 struct addrinfo proxyhints;
119 ret = 1;
120 s = 0;
121 socksv = 5;
122 host = NULL;
123 uport = NULL;
124 endp = NULL;
125 sv = NULL;
127 while ((ch = getopt(argc, argv,
128 "46Ddhi:jklnp:rSs:tUuvw:X:x:z")) != -1) {
129 switch (ch) {
130 case '4':
131 family = AF_INET;
132 break;
133 case '6':
134 family = AF_INET6;
135 break;
136 case 'U':
137 family = AF_UNIX;
138 break;
139 case 'X':
140 if (strcasecmp(optarg, "connect") == 0)
141 socksv = -1; /* HTTP proxy CONNECT */
142 else if (strcmp(optarg, "4") == 0)
143 socksv = 4; /* SOCKS v.4 */
144 else if (strcmp(optarg, "5") == 0)
145 socksv = 5; /* SOCKS v.5 */
146 else
147 errx(1, "unsupported proxy protocol");
148 break;
149 case 'd':
150 dflag = 1;
151 break;
152 case 'h':
153 help();
154 break;
155 case 'i':
156 iflag = (int)strtoul(optarg, &endp, 10);
157 if (iflag < 0 || *endp != '\0')
158 errx(1, "interval cannot be negative");
159 break;
160 #ifndef __DragonFly__
161 case 'j':
162 jflag = 1;
163 break;
164 #endif /* !__DragonFly__ */
165 case 'k':
166 kflag = 1;
167 break;
168 case 'l':
169 lflag = 1;
170 break;
171 case 'n':
172 nflag = 1;
173 break;
174 case 'p':
175 pflag = optarg;
176 break;
177 case 'r':
178 rflag = 1;
179 break;
180 case 's':
181 sflag = optarg;
182 break;
183 case 't':
184 tflag = 1;
185 break;
186 case 'u':
187 uflag = 1;
188 break;
189 case 'v':
190 vflag = 1;
191 break;
192 case 'w':
193 timeout = (int)strtoul(optarg, &endp, 10);
194 if (timeout < 0 || *endp != '\0')
195 errx(1, "timeout cannot be negative");
196 if (timeout >= (INT_MAX / 1000))
197 errx(1, "timeout too large");
198 #ifndef USE_SELECT
199 timeout *= 1000;
200 #endif
201 break;
202 case 'x':
203 xflag = 1;
204 if ((proxy = strdup(optarg)) == NULL)
205 err(1, NULL);
206 break;
207 case 'z':
208 zflag = 1;
209 break;
210 case 'D':
211 Dflag = 1;
212 break;
213 #ifndef __DragonFly__
214 case 'S':
215 Sflag = 1;
216 break;
217 #endif /* !__DragonFly__ */
218 default:
219 usage(1);
222 argc -= optind;
223 argv += optind;
225 /* Cruft to make sure options are clean, and used properly. */
226 if (argv[0] && !argv[1] && family == AF_UNIX) {
227 if (uflag)
228 errx(1, "cannot use -u and -U");
229 host = argv[0];
230 uport = NULL;
231 } else if (argv[0] && !argv[1]) {
232 if (!lflag)
233 usage(1);
234 uport = argv[0];
235 host = NULL;
236 } else if (argv[0] && argv[1]) {
237 host = argv[0];
238 uport = argv[1];
239 } else
240 usage(1);
242 if (lflag && sflag)
243 errx(1, "cannot use -s and -l");
244 if (lflag && pflag)
245 errx(1, "cannot use -p and -l");
246 if (lflag && zflag)
247 errx(1, "cannot use -z and -l");
248 if (!lflag && kflag)
249 errx(1, "must use -l with -k");
251 /* Initialize addrinfo structure. */
252 if (family != AF_UNIX) {
253 memset(&hints, 0, sizeof(struct addrinfo));
254 hints.ai_family = family;
255 hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
256 hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
257 if (nflag)
258 hints.ai_flags |= AI_NUMERICHOST;
261 if (xflag) {
262 if (uflag)
263 errx(1, "no proxy support for UDP mode");
265 if (lflag)
266 errx(1, "no proxy support for listen");
268 if (family == AF_UNIX)
269 errx(1, "no proxy support for unix sockets");
271 /* XXX IPv6 transport to proxy would probably work */
272 if (family == AF_INET6)
273 errx(1, "no proxy support for IPv6");
275 if (sflag)
276 errx(1, "no proxy support for local source address");
278 proxyhost = strsep(&proxy, ":");
279 proxyport = proxy;
281 memset(&proxyhints, 0, sizeof(struct addrinfo));
282 proxyhints.ai_family = family;
283 proxyhints.ai_socktype = SOCK_STREAM;
284 proxyhints.ai_protocol = IPPROTO_TCP;
285 if (nflag)
286 proxyhints.ai_flags |= AI_NUMERICHOST;
289 if (lflag) {
290 int connfd;
291 ret = 0;
293 if (family == AF_UNIX)
294 s = unix_listen(host);
296 /* Allow only one connection at a time, but stay alive. */
297 for (;;) {
298 if (family != AF_UNIX)
299 s = local_listen(host, uport, hints);
300 if (s < 0)
301 err(1, NULL);
303 * For UDP, we will use recvfrom() initially
304 * to wait for a caller, then use the regular
305 * functions to talk to the caller.
307 if (uflag) {
308 int rv, plen;
309 char buf[8192];
310 struct sockaddr_storage z;
312 len = sizeof(z);
313 #ifndef __DragonFly__
314 plen = jflag ? 8192 : 1024;
315 #else /* __DragonFly__ */
316 plen = 1024;
317 #endif /* !__DragonFly__ */
318 rv = recvfrom(s, buf, plen, MSG_PEEK,
319 (struct sockaddr *)&z, &len);
320 if (rv < 0)
321 err(1, "recvfrom");
323 rv = connect(s, (struct sockaddr *)&z, len);
324 if (rv < 0)
325 err(1, "connect");
327 connfd = s;
328 } else {
329 len = sizeof(cliaddr);
330 connfd = accept(s, (struct sockaddr *)&cliaddr,
331 &len);
334 readwrite(connfd);
335 close(connfd);
336 if (family != AF_UNIX)
337 close(s);
339 if (!kflag)
340 break;
342 } else if (family == AF_UNIX) {
343 ret = 0;
345 if ((s = unix_connect(host)) > 0 && !zflag) {
346 readwrite(s);
347 close(s);
348 } else
349 ret = 1;
351 exit(ret);
353 } else {
354 int i = 0;
356 /* Construct the portlist[] array. */
357 build_ports(uport);
359 /* Cycle through portlist, connecting to each port. */
360 for (i = 0; portlist[i] != NULL; i++) {
361 if (s)
362 close(s);
364 if (xflag)
365 s = socks_connect(host, portlist[i], hints,
366 proxyhost, proxyport, proxyhints, socksv);
367 else
368 s = remote_connect(host, portlist[i], hints);
370 if (s < 0)
371 continue;
373 ret = 0;
374 if (vflag || zflag) {
375 /* For UDP, make sure we are connected. */
376 if (uflag) {
377 if (udptest(s) == -1) {
378 ret = 1;
379 continue;
383 /* Don't look up port if -n. */
384 if (nflag)
385 sv = NULL;
386 else {
387 sv = getservbyport(
388 ntohs(atoi(portlist[i])),
389 uflag ? "udp" : "tcp");
392 printf("Connection to %s %s port [%s/%s] succeeded!\n",
393 host, portlist[i], uflag ? "udp" : "tcp",
394 sv ? sv->s_name : "*");
396 if (!zflag)
397 readwrite(s);
401 if (s)
402 close(s);
404 exit(ret);
408 * unix_connect()
409 * Returns a socket connected to a local unix socket. Returns -1 on failure.
412 unix_connect(char *path)
414 struct sockaddr_un sun;
415 int s;
417 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
418 return (-1);
419 (void)fcntl(s, F_SETFD, 1);
421 memset(&sun, 0, sizeof(struct sockaddr_un));
422 sun.sun_family = AF_UNIX;
424 if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
425 sizeof(sun.sun_path)) {
426 close(s);
427 errno = ENAMETOOLONG;
428 return (-1);
430 if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
431 close(s);
432 return (-1);
434 return (s);
439 * unix_listen()
440 * Create a unix domain socket, and listen on it.
443 unix_listen(char *path)
445 struct sockaddr_un sun;
446 int s;
448 /* Create unix domain socket. */
449 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
450 return (-1);
452 memset(&sun, 0, sizeof(struct sockaddr_un));
453 sun.sun_family = AF_UNIX;
455 if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
456 sizeof(sun.sun_path)) {
457 close(s);
458 errno = ENAMETOOLONG;
459 return (-1);
462 if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
463 close(s);
464 return (-1);
467 if (listen(s, 5) < 0) {
468 close(s);
469 return (-1);
471 return (s);
475 * remote_connect()
476 * Returns a socket connected to a remote host. Properly binds to a local
477 * port or source address if needed. Returns -1 on failure.
480 remote_connect(const char *host, const char *port, struct addrinfo hints)
482 struct addrinfo *res, *res0;
483 int s, error;
485 if ((error = getaddrinfo(host, port, &hints, &res)))
486 errx(1, "getaddrinfo: %s", gai_strerror(error));
488 res0 = res;
489 do {
490 if ((s = socket(res0->ai_family, res0->ai_socktype,
491 res0->ai_protocol)) < 0)
492 continue;
494 /* Bind to a local port or source address if specified. */
495 if (sflag || pflag) {
496 struct addrinfo ahints, *ares;
498 if (!(sflag && pflag)) {
499 if (!sflag)
500 sflag = NULL;
501 else
502 pflag = NULL;
505 memset(&ahints, 0, sizeof(struct addrinfo));
506 ahints.ai_family = res0->ai_family;
507 ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
508 ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
509 ahints.ai_flags = AI_PASSIVE;
510 if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
511 errx(1, "getaddrinfo: %s", gai_strerror(error));
513 if (bind(s, (struct sockaddr *)ares->ai_addr,
514 ares->ai_addrlen) < 0)
515 errx(1, "bind failed: %s", strerror(errno));
516 freeaddrinfo(ares);
519 set_common_sockopts(s);
521 if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
522 break;
523 else if (vflag)
524 warn("connect to %s port %s (%s) failed", host, port,
525 uflag ? "udp" : "tcp");
527 close(s);
528 s = -1;
529 } while ((res0 = res0->ai_next) != NULL);
531 freeaddrinfo(res);
533 return (s);
537 * local_listen()
538 * Returns a socket listening on a local port, binds to specified source
539 * address. Returns -1 on failure.
542 local_listen(char *host, char *port, struct addrinfo hints)
544 struct addrinfo *res, *res0;
545 int s, ret, x = 1;
546 int error;
548 /* Allow nodename to be null. */
549 hints.ai_flags |= AI_PASSIVE;
552 * In the case of binding to a wildcard address
553 * default to binding to an ipv4 address.
555 if (host == NULL && hints.ai_family == AF_UNSPEC)
556 hints.ai_family = AF_INET;
558 if ((error = getaddrinfo(host, port, &hints, &res)))
559 errx(1, "getaddrinfo: %s", gai_strerror(error));
561 res0 = res;
562 do {
563 if ((s = socket(res0->ai_family, res0->ai_socktype,
564 res0->ai_protocol)) < 0)
565 continue;
567 ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
568 if (ret == -1)
569 err(1, NULL);
571 set_common_sockopts(s);
573 if (bind(s, (struct sockaddr *)res0->ai_addr,
574 res0->ai_addrlen) == 0)
575 break;
577 close(s);
578 s = -1;
579 } while ((res0 = res0->ai_next) != NULL);
581 if (!uflag && s != -1) {
582 if (listen(s, 1) < 0)
583 err(1, "listen");
586 freeaddrinfo(res);
588 return (s);
592 * readwrite()
593 * Loop that polls on the network file descriptor and stdin.
595 void
596 readwrite(int nfd)
598 #ifdef USE_SELECT
599 fd_set readfds;
600 struct timeval tv;
601 int nfd_open = 1, wfd_open = 1;
602 #else
603 struct pollfd pfd[2];
604 #endif
605 unsigned char buf[8192];
606 int n, wfd = fileno(stdin);
607 int lfd = fileno(stdout);
608 int plen;
610 #ifndef __DragonFly__
611 plen = jflag ? 8192 : 1024;
612 #else /* __DragonFly__ */
613 plen = 1024;
614 #endif /* !__DragonFly__ */
616 #ifndef USE_SELECT
617 /* Setup Network FD */
618 pfd[0].fd = nfd;
619 pfd[0].events = POLLIN;
621 /* Set up STDIN FD. */
622 pfd[1].fd = wfd;
623 pfd[1].events = POLLIN;
624 #endif
626 #ifdef USE_SELECT
627 while (nfd_open) {
628 #else
629 while (pfd[0].fd != -1) {
630 #endif
631 if (iflag)
632 sleep(iflag);
634 #ifdef USE_SELECT
635 FD_ZERO(&readfds);
636 if (nfd_open)
637 FD_SET(nfd, &readfds);
638 if (wfd_open)
639 FD_SET(wfd, &readfds);
641 tv.tv_sec = timeout;
642 tv.tv_usec = 0;
644 if ((n = select(nfd + 1, &readfds, NULL, NULL, (timeout == -1) ? NULL : &tv)) < 0) {
645 #else
646 if ((n = poll(pfd, 2 - dflag, timeout)) < 0) {
647 #endif
648 close(nfd);
649 err(1, "Polling Error");
652 if (n == 0)
653 return;
655 #ifdef USE_SELECT
656 if (FD_ISSET(nfd, &readfds)) {
657 #else
658 if (pfd[0].revents & POLLIN) {
659 #endif
660 if ((n = read(nfd, buf, plen)) < 0)
661 return;
662 else if (n == 0) {
663 shutdown(nfd, SHUT_RD);
664 #ifdef USE_SELECT
665 nfd_open = 0;
666 #else
667 pfd[0].fd = -1;
668 pfd[0].events = 0;
669 #endif
670 } else {
671 if (tflag)
672 atelnet(nfd, buf, n);
673 if (atomicio(vwrite, lfd, buf, n) != n)
674 return;
678 #ifdef USE_SELECT
679 if (!dflag && FD_ISSET(wfd, &readfds)) {
680 #else
681 if (!dflag && pfd[1].revents & POLLIN) {
682 #endif
683 if ((n = read(wfd, buf, plen)) < 0)
684 return;
685 else if (n == 0) {
686 shutdown(nfd, SHUT_WR);
687 #ifdef USE_SELECT
688 wfd_open = 0;
689 #else
690 pfd[1].fd = -1;
691 pfd[1].events = 0;
692 #endif
693 } else {
694 if (atomicio(vwrite, nfd, buf, n) != n)
695 return;
701 /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */
702 void
703 atelnet(int nfd, unsigned char *buf, unsigned int size)
705 unsigned char *p, *end;
706 unsigned char obuf[4];
708 end = buf + size;
709 obuf[0] = '\0';
711 for (p = buf; p < end; p++) {
712 if (*p != IAC)
713 break;
715 obuf[0] = IAC;
716 p++;
717 if ((*p == WILL) || (*p == WONT))
718 obuf[1] = DONT;
719 if ((*p == DO) || (*p == DONT))
720 obuf[1] = WONT;
721 if (obuf) {
722 p++;
723 obuf[2] = *p;
724 obuf[3] = '\0';
725 if (atomicio(vwrite, nfd, obuf, 3) != 3)
726 warn("Write Error!");
727 obuf[0] = '\0';
733 * build_ports()
734 * Build an array or ports in portlist[], listing each port
735 * that we should try to connect to.
737 void
738 build_ports(char *p)
740 char *n, *endp;
741 int hi, lo, cp;
742 int x = 0;
744 if ((n = strchr(p, '-')) != NULL) {
745 if (lflag)
746 errx(1, "Cannot use -l with multiple ports!");
748 *n = '\0';
749 n++;
751 /* Make sure the ports are in order: lowest->highest. */
752 hi = (int)strtoul(n, &endp, 10);
753 if (hi <= 0 || hi > PORT_MAX || *endp != '\0')
754 errx(1, "port range not valid");
755 lo = (int)strtoul(p, &endp, 10);
756 if (lo <= 0 || lo > PORT_MAX || *endp != '\0')
757 errx(1, "port range not valid");
759 if (lo > hi) {
760 cp = hi;
761 hi = lo;
762 lo = cp;
765 /* Load ports sequentially. */
766 for (cp = lo; cp <= hi; cp++) {
767 portlist[x] = calloc(1, PORT_MAX_LEN);
768 if (portlist[x] == NULL)
769 err(1, NULL);
770 snprintf(portlist[x], PORT_MAX_LEN, "%d", cp);
771 x++;
774 /* Randomly swap ports. */
775 if (rflag) {
776 int y;
777 char *c;
779 for (x = 0; x <= (hi - lo); x++) {
780 y = (arc4random() & 0xFFFF) % (hi - lo);
781 c = portlist[x];
782 portlist[x] = portlist[y];
783 portlist[y] = c;
786 } else {
787 hi = (int)strtoul(p, &endp, 10);
788 if (hi <= 0 || hi > PORT_MAX || *endp != '\0')
789 errx(1, "port range not valid");
790 portlist[0] = calloc(1, PORT_MAX_LEN);
791 if (portlist[0] == NULL)
792 err(1, NULL);
793 portlist[0] = p;
798 * udptest()
799 * Do a few writes to see if the UDP port is there.
800 * XXX - Better way of doing this? Doesn't work for IPv6.
801 * Also fails after around 100 ports checked.
804 udptest(int s)
806 int i, ret;
808 for (i = 0; i <= 3; i++) {
809 if (write(s, "X", 1) == 1)
810 ret = 1;
811 else
812 ret = -1;
814 return (ret);
818 set_common_sockopts(int s)
820 int x = 1;
822 #ifndef __DragonFly__
823 if (Sflag) {
824 if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
825 &x, sizeof(x)) == -1)
826 err(1, NULL);
828 #endif /* !__DragonFly__ */
829 if (Dflag) {
830 if (setsockopt(s, SOL_SOCKET, SO_DEBUG,
831 &x, sizeof(x)) == -1)
832 err(1, NULL);
834 #ifndef __DragonFly__
835 if (jflag) {
836 if (setsockopt(s, SOL_SOCKET, SO_JUMBO,
837 &x, sizeof(x)) == -1)
838 err(1, NULL);
840 #endif /* !__DragonFly__ */
843 void
844 help(void)
846 usage(0);
847 fprintf(stderr, "\tCommand Summary:\n\
848 \t-4 Use IPv4\n\
849 \t-6 Use IPv6\n\
850 \t-D Enable the debug socket option\n\
851 \t-d Detach from stdin\n\
852 \t-h This help text\n\
853 \t-i secs\t Delay interval for lines sent, ports scanned\n\
854 \t-k Keep inbound sockets open for multiple connects\n\
855 \t-l Listen mode, for inbound connects\n\
856 \t-n Suppress name/port resolutions\n\
857 \t-p port\t Specify local port for remote connects\n\
858 \t-r Randomize remote ports\n\
860 \t-s addr\t Local source address\n\
861 \t-t Answer TELNET negotiation\n\
862 \t-U Use UNIX domain socket\n\
863 \t-u UDP mode\n\
864 \t-v Verbose\n\
865 \t-w secs\t Timeout for connects and final net reads\n\
866 \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\
867 \t-x addr[:port]\tSpecify proxy address and port\n\
868 \t-z Zero-I/O mode [used for scanning]\n\
869 Port numbers can be individual or ranges: lo-hi [inclusive]\n",
870 #ifndef __DragonFly__
871 " \t-S Enable the TCP MD5 signature option\n"
872 #else /* __DragonFly__ */
874 #endif /* !__DragonFly__ */
876 exit(1);
879 void
880 usage(int ret)
882 #ifndef __DragonFly__
883 fprintf(stderr, "usage: nc [-46DdhklnrStUuvz] [-i interval] [-p source_port]\n");
884 #else /* __DragonFly__ */
885 fprintf(stderr, "usage: nc [-46DdhklnrtUuvz] [-i interval] [-p source_port]\n");
886 #endif /* !__DragonFly__ */
887 fprintf(stderr, "\t [-s source_ip_address] [-w timeout] [-X proxy_version]\n");
888 fprintf(stderr, "\t [-x proxy_address[:port]] [hostname] [port[s]]\n");
889 if (ret)
890 exit(1);