]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/netcat/netcat.c
Document freebsd extensions to netcat a bit better:
[FreeBSD/FreeBSD.git] / contrib / netcat / netcat.c
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  * $FreeBSD$
29  */
30
31 /*
32  * Re-written nc(1) for OpenBSD. Original implementation by
33  * *Hobbit* <hobbit@avian.org>.
34  */
35
36 #include <sys/limits.h>
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <sys/time.h>
40 #include <sys/un.h>
41
42 #include <netinet/in.h>
43 #include <netinet/in_systm.h>
44 #ifdef IPSEC
45 #include <netipsec/ipsec.h>
46 #endif
47 #include <netinet/tcp.h>
48 #include <netinet/ip.h>
49 #include <arpa/telnet.h>
50
51 #include <err.h>
52 #include <errno.h>
53 #include <netdb.h>
54 #include <poll.h>
55 #include <stdarg.h>
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <string.h>
59 #include <unistd.h>
60 #include <fcntl.h>
61 #include <limits.h>
62 #include "atomicio.h"
63
64 #ifndef SUN_LEN
65 #define SUN_LEN(su) \
66         (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
67 #endif
68
69 #define PORT_MAX        65535
70 #define PORT_MAX_LEN    6
71
72 /* Command Line Options */
73 int     Eflag;                                  /* Use IPsec ESP */
74 int     dflag;                                  /* detached, no stdin */
75 unsigned int iflag;                             /* Interval Flag */
76 int     jflag;                                  /* use jumbo frames if we can */
77 int     kflag;                                  /* More than one connect */
78 int     lflag;                                  /* Bind to local port */
79 int     nflag;                                  /* Don't do name look up */
80 int     oflag;                                  /* Once only: stop on EOF */
81 int     Oflag;                                  /* Do not use TCP options */
82 char   *Pflag;                                  /* Proxy username */
83 char   *pflag;                                  /* Localport flag */
84 int     rflag;                                  /* Random ports flag */
85 char   *sflag;                                  /* Source Address */
86 int     tflag;                                  /* Telnet Emulation */
87 int     uflag;                                  /* UDP - Default to TCP */
88 int     vflag;                                  /* Verbosity */
89 int     xflag;                                  /* Socks proxy */
90 int     zflag;                                  /* Port Scan Flag */
91 int     Dflag;                                  /* sodebug */
92 int     Sflag;                                  /* TCP MD5 signature option */
93 int     Tflag = -1;                             /* IP Type of Service */
94
95 int timeout = -1;
96 int family = AF_UNSPEC;
97 char *portlist[PORT_MAX+1];
98
99 void    atelnet(int, unsigned char *, unsigned int);
100 void    build_ports(char *);
101 void    help(void);
102 int     local_listen(char *, char *, struct addrinfo);
103 void    readwrite(int);
104 int     remote_connect(const char *, const char *, struct addrinfo);
105 int     socks_connect(const char *, const char *, struct addrinfo,
106             const char *, const char *, struct addrinfo, int, const char *);
107 int     udptest(int);
108 int     unix_connect(char *);
109 int     unix_listen(char *);
110 void    set_common_sockopts(int);
111 int     parse_iptos(char *);
112 void    usage(int);
113
114 #ifdef IPSEC
115 void    add_ipsec_policy(int, char *);
116
117 char    *ipsec_policy[2];
118 #endif
119
120 int
121 main(int argc, char *argv[])
122 {
123         int ch, s, ret, socksv, ipsec_count;
124         char *host, *uport;
125         struct addrinfo hints;
126         struct servent *sv;
127         socklen_t len;
128         struct sockaddr_storage cliaddr;
129         char *proxy;
130         const char *errstr, *proxyhost = "", *proxyport = NULL;
131         struct addrinfo proxyhints;
132
133         ret = 1;
134         ipsec_count = 0;
135         s = 0;
136         socksv = 5;
137         host = NULL;
138         uport = NULL;
139         sv = NULL;
140
141         while ((ch = getopt(argc, argv,
142             "46e:DEdhi:jklnoOP:p:rSs:tT:Uuvw:X:x:z")) != -1) {
143                 switch (ch) {
144                 case '4':
145                         family = AF_INET;
146                         break;
147                 case '6':
148                         family = AF_INET6;
149                         break;
150                 case 'U':
151                         family = AF_UNIX;
152                         break;
153                 case 'X':
154                         if (strcasecmp(optarg, "connect") == 0)
155                                 socksv = -1; /* HTTP proxy CONNECT */
156                         else if (strcmp(optarg, "4") == 0)
157                                 socksv = 4; /* SOCKS v.4 */
158                         else if (strcmp(optarg, "5") == 0)
159                                 socksv = 5; /* SOCKS v.5 */
160                         else
161                                 errx(1, "unsupported proxy protocol");
162                         break;
163                 case 'd':
164                         dflag = 1;
165                         break;
166                 case 'e':
167 #ifdef IPSEC
168                         ipsec_policy[ipsec_count++ % 2] = optarg;
169 #else
170                         errx(1, "IPsec support unavailable.");
171 #endif
172                         break;
173                 case 'E':
174 #ifdef IPSEC
175                         ipsec_policy[0] = "in  ipsec esp/transport//require";
176                         ipsec_policy[1] = "out ipsec esp/transport//require";
177 #else
178                         errx(1, "IPsec support unavailable.");
179 #endif
180                         break;
181                 case 'h':
182                         help();
183                         break;
184                 case 'i':
185                         iflag = strtonum(optarg, 0, UINT_MAX, &errstr);
186                         if (errstr)
187                                 errx(1, "interval %s: %s", errstr, optarg);
188                         break;
189 #ifdef SO_JUMBO
190                 case 'j':
191                         jflag = 1;
192                         break;
193 #endif
194                 case 'k':
195                         kflag = 1;
196                         break;
197                 case 'l':
198                         lflag = 1;
199                         break;
200                 case 'n':
201                         nflag = 1;
202                         break;
203                 case 'o':
204                         oflag = 1;
205                         break;
206                 case 'O':
207                         Oflag = 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                 host = argv[0];
273                 uport = argv[1];
274         } else
275                 usage(1);
276
277         if (lflag && sflag)
278                 errx(1, "cannot use -s and -l");
279         if (lflag && pflag)
280                 errx(1, "cannot use -p and -l");
281         if (lflag && zflag)
282                 errx(1, "cannot use -z and -l");
283         if (!lflag && kflag)
284                 errx(1, "must use -l with -k");
285
286         /* Initialize addrinfo structure. */
287         if (family != AF_UNIX) {
288                 memset(&hints, 0, sizeof(struct addrinfo));
289                 hints.ai_family = family;
290                 hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
291                 hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
292                 if (nflag)
293                         hints.ai_flags |= AI_NUMERICHOST;
294         }
295
296         if (xflag) {
297                 if (uflag)
298                         errx(1, "no proxy support for UDP mode");
299
300                 if (lflag)
301                         errx(1, "no proxy support for listen");
302
303                 if (family == AF_UNIX)
304                         errx(1, "no proxy support for unix sockets");
305
306                 /* XXX IPv6 transport to proxy would probably work */
307                 if (family == AF_INET6)
308                         errx(1, "no proxy support for IPv6");
309
310                 if (sflag)
311                         errx(1, "no proxy support for local source address");
312
313                 proxyhost = strsep(&proxy, ":");
314                 proxyport = proxy;
315
316                 memset(&proxyhints, 0, sizeof(struct addrinfo));
317                 proxyhints.ai_family = family;
318                 proxyhints.ai_socktype = SOCK_STREAM;
319                 proxyhints.ai_protocol = IPPROTO_TCP;
320                 if (nflag)
321                         proxyhints.ai_flags |= AI_NUMERICHOST;
322         }
323
324         if (lflag) {
325                 int connfd;
326                 ret = 0;
327
328                 if (family == AF_UNIX)
329                         s = unix_listen(host);
330
331                 /* Allow only one connection at a time, but stay alive. */
332                 for (;;) {
333                         if (family != AF_UNIX)
334                                 s = local_listen(host, uport, hints);
335                         if (s < 0)
336                                 err(1, NULL);
337                         /*
338                          * For UDP, we will use recvfrom() initially
339                          * to wait for a caller, then use the regular
340                          * functions to talk to the caller.
341                          */
342                         if (uflag) {
343                                 int rv, plen;
344                                 char buf[8192];
345                                 struct sockaddr_storage z;
346
347                                 len = sizeof(z);
348                                 plen = jflag ? 8192 : 1024;
349                                 rv = recvfrom(s, buf, plen, MSG_PEEK,
350                                     (struct sockaddr *)&z, &len);
351                                 if (rv < 0)
352                                         err(1, "recvfrom");
353
354                                 rv = connect(s, (struct sockaddr *)&z, len);
355                                 if (rv < 0)
356                                         err(1, "connect");
357
358                                 connfd = s;
359                         } else {
360                                 len = sizeof(cliaddr);
361                                 connfd = accept(s, (struct sockaddr *)&cliaddr,
362                                     &len);
363                         }
364
365                         readwrite(connfd);
366                         close(connfd);
367                         if (family != AF_UNIX)
368                                 close(s);
369
370                         if (!kflag)
371                                 break;
372                 }
373         } else if (family == AF_UNIX) {
374                 ret = 0;
375
376                 if ((s = unix_connect(host)) > 0 && !zflag) {
377                         readwrite(s);
378                         close(s);
379                 } else
380                         ret = 1;
381
382                 exit(ret);
383
384         } else {
385                 int i = 0;
386
387                 /* Construct the portlist[] array. */
388                 build_ports(uport);
389
390                 /* Cycle through portlist, connecting to each port. */
391                 for (i = 0; portlist[i] != NULL; i++) {
392                         if (s)
393                                 close(s);
394
395                         if (xflag)
396                                 s = socks_connect(host, portlist[i], hints,
397                                     proxyhost, proxyport, proxyhints, socksv,
398                                     Pflag);
399                         else
400                                 s = remote_connect(host, portlist[i], hints);
401
402                         if (s < 0)
403                                 continue;
404
405                         ret = 0;
406                         if (vflag || zflag) {
407                                 /* For UDP, make sure we are connected. */
408                                 if (uflag) {
409                                         if (udptest(s) == -1) {
410                                                 ret = 1;
411                                                 continue;
412                                         }
413                                 }
414
415                                 /* Don't look up port if -n. */
416                                 if (nflag)
417                                         sv = NULL;
418                                 else {
419                                         sv = getservbyport(
420                                             ntohs(atoi(portlist[i])),
421                                             uflag ? "udp" : "tcp");
422                                 }
423
424                                 printf("Connection to %s %s port [%s/%s] succeeded!\n",
425                                     host, portlist[i], uflag ? "udp" : "tcp",
426                                     sv ? sv->s_name : "*");
427                         }
428                         if (!zflag)
429                                 readwrite(s);
430                 }
431         }
432
433         if (s)
434                 close(s);
435
436         exit(ret);
437 }
438
439 /*
440  * unix_connect()
441  * Returns a socket connected to a local unix socket. Returns -1 on failure.
442  */
443 int
444 unix_connect(char *path)
445 {
446         struct sockaddr_un sun;
447         int s;
448
449         if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
450                 return (-1);
451         (void)fcntl(s, F_SETFD, 1);
452
453         memset(&sun, 0, sizeof(struct sockaddr_un));
454         sun.sun_family = AF_UNIX;
455
456         if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
457             sizeof(sun.sun_path)) {
458                 close(s);
459                 errno = ENAMETOOLONG;
460                 return (-1);
461         }
462         if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
463                 close(s);
464                 return (-1);
465         }
466         return (s);
467
468 }
469
470 /*
471  * unix_listen()
472  * Create a unix domain socket, and listen on it.
473  */
474 int
475 unix_listen(char *path)
476 {
477         struct sockaddr_un sun;
478         int s;
479
480         /* Create unix domain socket. */
481         if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
482                 return (-1);
483
484         memset(&sun, 0, sizeof(struct sockaddr_un));
485         sun.sun_family = AF_UNIX;
486
487         if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
488             sizeof(sun.sun_path)) {
489                 close(s);
490                 errno = ENAMETOOLONG;
491                 return (-1);
492         }
493
494         if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
495                 close(s);
496                 return (-1);
497         }
498
499         if (listen(s, 5) < 0) {
500                 close(s);
501                 return (-1);
502         }
503         return (s);
504 }
505
506 /*
507  * remote_connect()
508  * Returns a socket connected to a remote host. Properly binds to a local
509  * port or source address if needed. Returns -1 on failure.
510  */
511 int
512 remote_connect(const char *host, const char *port, struct addrinfo hints)
513 {
514         struct addrinfo *res, *res0;
515         int s, error;
516
517         if ((error = getaddrinfo(host, port, &hints, &res)))
518                 errx(1, "getaddrinfo: %s", gai_strerror(error));
519
520         res0 = res;
521         do {
522                 if ((s = socket(res0->ai_family, res0->ai_socktype,
523                     res0->ai_protocol)) < 0)
524                         continue;
525 #ifdef IPSEC
526                 if (ipsec_policy[0] != NULL)
527                         add_ipsec_policy(s, ipsec_policy[0]);
528                 if (ipsec_policy[1] != NULL)
529                         add_ipsec_policy(s, ipsec_policy[1]);
530 #endif
531
532                 /* Bind to a local port or source address if specified. */
533                 if (sflag || pflag) {
534                         struct addrinfo ahints, *ares;
535
536                         memset(&ahints, 0, sizeof(struct addrinfo));
537                         ahints.ai_family = res0->ai_family;
538                         ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
539                         ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
540                         ahints.ai_flags = AI_PASSIVE;
541                         if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
542                                 errx(1, "getaddrinfo: %s", gai_strerror(error));
543
544                         if (bind(s, (struct sockaddr *)ares->ai_addr,
545                             ares->ai_addrlen) < 0)
546                                 errx(1, "bind failed: %s", strerror(errno));
547                         freeaddrinfo(ares);
548                 }
549
550                 set_common_sockopts(s);
551
552                 if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
553                         break;
554                 else if (vflag)
555                         warn("connect to %s port %s (%s) failed", host, port,
556                             uflag ? "udp" : "tcp");
557
558                 close(s);
559                 s = -1;
560         } while ((res0 = res0->ai_next) != NULL);
561
562         freeaddrinfo(res);
563
564         return (s);
565 }
566
567 /*
568  * local_listen()
569  * Returns a socket listening on a local port, binds to specified source
570  * address. Returns -1 on failure.
571  */
572 int
573 local_listen(char *host, char *port, struct addrinfo hints)
574 {
575         struct addrinfo *res, *res0;
576         int s, ret, x = 1;
577         int error;
578
579         /* Allow nodename to be null. */
580         hints.ai_flags |= AI_PASSIVE;
581
582         /*
583          * In the case of binding to a wildcard address
584          * default to binding to an ipv4 address.
585          */
586         if (host == NULL && hints.ai_family == AF_UNSPEC)
587                 hints.ai_family = AF_INET;
588
589         if ((error = getaddrinfo(host, port, &hints, &res)))
590                 errx(1, "getaddrinfo: %s", gai_strerror(error));
591
592         res0 = res;
593         do {
594                 if ((s = socket(res0->ai_family, res0->ai_socktype,
595                     res0->ai_protocol)) < 0)
596                         continue;
597
598                 ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
599                 if (ret == -1)
600                         err(1, NULL);
601 #ifdef IPSEC
602                 if (ipsec_policy[0] != NULL)
603                         add_ipsec_policy(s, ipsec_policy[0]);
604                 if (ipsec_policy[1] != NULL)
605                         add_ipsec_policy(s, ipsec_policy[1]);
606 #endif
607                 if (Oflag) {
608                         if (setsockopt(s, IPPROTO_TCP, TCP_NOOPT,
609                             &Oflag, sizeof(Oflag)) == -1)
610                                 err(1, "disable TCP options");
611                 }
612
613                 if (bind(s, (struct sockaddr *)res0->ai_addr,
614                     res0->ai_addrlen) == 0)
615                         break;
616
617                 close(s);
618                 s = -1;
619         } while ((res0 = res0->ai_next) != NULL);
620
621         if (!uflag && s != -1) {
622                 if (listen(s, 1) < 0)
623                         err(1, "listen");
624         }
625
626         freeaddrinfo(res);
627
628         return (s);
629 }
630
631 /*
632  * readwrite()
633  * Loop that polls on the network file descriptor and stdin.
634  */
635 void
636 readwrite(int nfd)
637 {
638         struct pollfd pfd[2];
639         unsigned char buf[8192];
640         int n, wfd = fileno(stdin);
641         int lfd = fileno(stdout);
642         int plen;
643
644         plen = jflag ? 8192 : 1024;
645
646         /* Setup Network FD */
647         pfd[0].fd = nfd;
648         pfd[0].events = POLLIN;
649
650         /* Set up STDIN FD. */
651         pfd[1].fd = wfd;
652         pfd[1].events = POLLIN;
653
654         while (pfd[0].fd != -1) {
655                 if (iflag)
656                         sleep(iflag);
657
658                 if ((n = poll(pfd, 2 - dflag, timeout)) < 0) {
659                         close(nfd);
660                         err(1, "Polling Error");
661                 }
662
663                 if (n == 0)
664                         return;
665
666                 if (pfd[0].revents & POLLIN) {
667                         if ((n = read(nfd, buf, plen)) < 0)
668                                 return;
669                         else if (n == 0) {
670                                 shutdown(nfd, SHUT_RD);
671                                 pfd[0].fd = -1;
672                                 pfd[0].events = 0;
673                         } else {
674                                 if (tflag)
675                                         atelnet(nfd, buf, n);
676                                 if (atomicio(vwrite, lfd, buf, n) != n)
677                                         return;
678                         }
679                 }
680
681                 if (!dflag && pfd[1].revents & POLLIN) {
682                         if ((n = read(wfd, buf, plen)) < 0 ||
683                             (oflag && n == 0)) {
684                                 return;
685                         } else if (n == 0) {
686                                 shutdown(nfd, SHUT_WR);
687                                 pfd[1].fd = -1;
688                                 pfd[1].events = 0;
689                         } else {
690                                 if (atomicio(vwrite, nfd, buf, n) != n)
691                                         return;
692                         }
693                 }
694         }
695 }
696
697 /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */
698 void
699 atelnet(int nfd, unsigned char *buf, unsigned int size)
700 {
701         unsigned char *p, *end;
702         unsigned char obuf[4];
703
704         end = buf + size;
705         obuf[0] = '\0';
706
707         for (p = buf; p < end; p++) {
708                 if (*p != IAC)
709                         break;
710
711                 obuf[0] = IAC;
712                 p++;
713                 if ((*p == WILL) || (*p == WONT))
714                         obuf[1] = DONT;
715                 if ((*p == DO) || (*p == DONT))
716                         obuf[1] = WONT;
717                 if (obuf) {
718                         p++;
719                         obuf[2] = *p;
720                         obuf[3] = '\0';
721                         if (atomicio(vwrite, nfd, obuf, 3) != 3)
722                                 warn("Write Error!");
723                         obuf[0] = '\0';
724                 }
725         }
726 }
727
728 /*
729  * build_ports()
730  * Build an array or ports in portlist[], listing each port
731  * that we should try to connect to.
732  */
733 void
734 build_ports(char *p)
735 {
736         const char *errstr;
737         char *n;
738         int hi, lo, cp;
739         int x = 0;
740
741         if ((n = strchr(p, '-')) != NULL) {
742                 if (lflag)
743                         errx(1, "Cannot use -l with multiple ports!");
744
745                 *n = '\0';
746                 n++;
747
748                 /* Make sure the ports are in order: lowest->highest. */
749                 hi = strtonum(n, 1, PORT_MAX, &errstr);
750                 if (errstr)
751                         errx(1, "port number %s: %s", errstr, n);
752                 lo = strtonum(p, 1, PORT_MAX, &errstr);
753                 if (errstr)
754                         errx(1, "port number %s: %s", errstr, p);
755
756                 if (lo > hi) {
757                         cp = hi;
758                         hi = lo;
759                         lo = cp;
760                 }
761
762                 /* Load ports sequentially. */
763                 for (cp = lo; cp <= hi; cp++) {
764                         portlist[x] = calloc(1, PORT_MAX_LEN);
765                         if (portlist[x] == NULL)
766                                 err(1, NULL);
767                         snprintf(portlist[x], PORT_MAX_LEN, "%d", cp);
768                         x++;
769                 }
770
771                 /* Randomly swap ports. */
772                 if (rflag) {
773                         int y;
774                         char *c;
775
776                         for (x = 0; x <= (hi - lo); x++) {
777                                 y = (arc4random() & 0xFFFF) % (hi - lo);
778                                 c = portlist[x];
779                                 portlist[x] = portlist[y];
780                                 portlist[y] = c;
781                         }
782                 }
783         } else {
784                 hi = strtonum(p, 1, PORT_MAX, &errstr);
785                 if (errstr)
786                         errx(1, "port number %s: %s", errstr, p);
787                 portlist[0] = calloc(1, PORT_MAX_LEN);
788                 if (portlist[0] == NULL)
789                         err(1, NULL);
790                 portlist[0] = p;
791         }
792 }
793
794 /*
795  * udptest()
796  * Do a few writes to see if the UDP port is there.
797  * XXX - Better way of doing this? Doesn't work for IPv6.
798  * Also fails after around 100 ports checked.
799  */
800 int
801 udptest(int s)
802 {
803         int i, ret;
804
805         for (i = 0; i <= 3; i++) {
806                 if (write(s, "X", 1) == 1)
807                         ret = 1;
808                 else
809                         ret = -1;
810         }
811         return (ret);
812 }
813
814 void
815 set_common_sockopts(int s)
816 {
817         int x = 1;
818
819         if (Sflag) {
820                 if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
821                         &x, sizeof(x)) == -1)
822                         err(1, NULL);
823         }
824         if (Dflag) {
825                 if (setsockopt(s, SOL_SOCKET, SO_DEBUG,
826                         &x, sizeof(x)) == -1)
827                         err(1, NULL);
828         }
829 #ifdef SO_JUMBO
830         if (jflag) {
831                 if (setsockopt(s, SOL_SOCKET, SO_JUMBO,
832                         &x, sizeof(x)) == -1)
833                         err(1, NULL);
834         }
835 #endif
836         if (Tflag != -1) {
837                 if (setsockopt(s, IPPROTO_IP, IP_TOS,
838                     &Tflag, sizeof(Tflag)) == -1)
839                         err(1, "set IP ToS");
840         }
841         if (Oflag) {
842                 if (setsockopt(s, IPPROTO_TCP, TCP_NOOPT,
843                     &Oflag, sizeof(Oflag)) == -1)
844                         err(1, "disable TCP options");
845         }
846 }
847
848 int
849 parse_iptos(char *s)
850 {
851         int tos = -1;
852
853         if (strcmp(s, "lowdelay") == 0)
854                 return (IPTOS_LOWDELAY);
855         if (strcmp(s, "throughput") == 0)
856                 return (IPTOS_THROUGHPUT);
857         if (strcmp(s, "reliability") == 0)
858                 return (IPTOS_RELIABILITY);
859
860         if (sscanf(s, "0x%x", &tos) != 1 || tos < 0 || tos > 0xff)
861                 errx(1, "invalid IP Type of Service");
862         return (tos);
863 }
864
865 void
866 help(void)
867 {
868         usage(0);
869         fprintf(stderr, "\tCommand Summary:\n\
870         \t-4            Use IPv4\n\
871         \t-6            Use IPv6\n\
872         \t-D            Enable the debug socket option\n\
873         \t-d            Detach from stdin\n");
874 #ifdef IPSEC
875         fprintf(stderr, "\
876         \t-E            Use IPsec ESP\n\
877         \t-e policy     Use specified IPsec policy\n");
878 #endif
879         fprintf(stderr, "\
880         \t-h            This help text\n\
881         \t-i secs\t     Delay interval for lines sent, ports scanned\n\
882         \t-k            Keep inbound sockets open for multiple connects\n\
883         \t-l            Listen mode, for inbound connects\n\
884         \t-n            Suppress name/port resolutions\n\
885         \t-O            Disable TCP options\n\
886         \t-o            Terminate on EOF on input\n\
887         \t-P proxyuser\tUsername for proxy authentication\n\
888         \t-p port\t     Specify local port for remote connects\n\
889         \t-r            Randomize remote ports\n\
890         \t-S            Enable the TCP MD5 signature option\n\
891         \t-s addr\t     Local source address\n\
892         \t-T ToS\t      Set IP Type of Service\n\
893         \t-t            Answer TELNET negotiation\n\
894         \t-U            Use UNIX domain socket\n\
895         \t-u            UDP mode\n\
896         \t-v            Verbose\n\
897         \t-w secs\t     Timeout for connects and final net reads\n\
898         \t-X proto      Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\
899         \t-x addr[:port]\tSpecify proxy address and port\n\
900         \t-z            Zero-I/O mode [used for scanning]\n\
901         Port numbers can be individual or ranges: lo-hi [inclusive]\n");
902 #ifdef IPSEC
903         fprintf(stderr, "See ipsec_set_policy(3) for -e argument format\n");
904 #endif
905         exit(1);
906 }
907
908 #ifdef IPSEC
909 void
910 add_ipsec_policy(int s, char *policy)
911 {
912         char *raw;
913         int e;
914
915         raw = ipsec_set_policy(policy, strlen(policy));
916         if (raw == NULL)
917                 errx(1, "ipsec_set_policy `%s': %s", policy,
918                      ipsec_strerror());
919         e = setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY, raw,
920                         ipsec_get_policylen(raw));
921         if (e < 0)
922                 err(1, "ipsec policy cannot be configured");
923         free(raw);
924         if (vflag)
925                 fprintf(stderr, "ipsec policy configured: `%s'\n", policy);
926         return;
927 }
928 #endif /* IPSEC */
929
930 void
931 usage(int ret)
932 {
933 #ifdef IPSEC
934         fprintf(stderr, "usage: nc [-46DdEhklnOorStUuvz] [-e policy] [-i interval] [-P proxy_username] [-p source_port]\n");
935 #else
936         fprintf(stderr, "usage: nc [-46DdhklnOorStUuvz] [-i interval] [-P proxy_username] [-p source_port]\n");
937 #endif
938         fprintf(stderr, "\t  [-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_protocol]\n");
939         fprintf(stderr, "\t  [-x proxy_address[:port]] [hostname] [port[s]]\n");
940         if (ret)
941                 exit(1);
942 }