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