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