]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/netcat/netcat.c
MFC r273619: MFV r273617: netcat from OpenBSD 5.6.
[FreeBSD/stable/10.git] / contrib / netcat / netcat.c
1 /* $OpenBSD: netcat.c,v 1.122 2014/07/20 01:38:40 guenther 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/uio.h>
42 #include <sys/un.h>
43
44 #include <netinet/in.h>
45 #include <netinet/in_systm.h>
46 #ifdef IPSEC
47 #include <netipsec/ipsec.h>
48 #endif
49 #include <netinet/tcp.h>
50 #include <netinet/ip.h>
51 #include <arpa/telnet.h>
52
53 #include <err.h>
54 #include <errno.h>
55 #include <getopt.h>
56 #include <netdb.h>
57 #include <poll.h>
58 #include <stdarg.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <unistd.h>
63 #include <fcntl.h>
64 #include <limits.h>
65 #include "atomicio.h"
66
67 #ifndef SUN_LEN
68 #define SUN_LEN(su) \
69         (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
70 #endif
71
72 #define PORT_MAX        65535
73 #define PORT_MAX_LEN    6
74 #define UNIX_DG_TMP_SOCKET_SIZE 19
75
76 /* Command Line Options */
77 int     dflag;                                  /* detached, no stdin */
78 int     Fflag;                                  /* fdpass sock to stdout */
79 unsigned int iflag;                             /* Interval Flag */
80 int     kflag;                                  /* More than one connect */
81 int     lflag;                                  /* Bind to local port */
82 int     Nflag;                                  /* shutdown() network socket */
83 int     nflag;                                  /* Don't do name look up */
84 int     FreeBSD_Oflag;                          /* Do not use TCP options */
85 char   *Pflag;                                  /* Proxy username */
86 char   *pflag;                                  /* Localport flag */
87 int     rflag;                                  /* Random ports flag */
88 char   *sflag;                                  /* Source Address */
89 int     tflag;                                  /* Telnet Emulation */
90 int     uflag;                                  /* UDP - Default to TCP */
91 int     vflag;                                  /* Verbosity */
92 int     xflag;                                  /* Socks proxy */
93 int     zflag;                                  /* Port Scan Flag */
94 int     Dflag;                                  /* sodebug */
95 int     Iflag;                                  /* TCP receive buffer size */
96 int     Oflag;                                  /* TCP send buffer size */
97 int     Sflag;                                  /* TCP MD5 signature option */
98 int     Tflag = -1;                             /* IP Type of Service */
99 int     rtableid = -1;
100
101 int timeout = -1;
102 int family = AF_UNSPEC;
103 char *portlist[PORT_MAX+1];
104 char *unix_dg_tmp_socket;
105
106 void    atelnet(int, unsigned char *, unsigned int);
107 void    build_ports(char *);
108 void    help(void);
109 int     local_listen(char *, char *, struct addrinfo);
110 void    readwrite(int);
111 void    fdpass(int nfd) __attribute__((noreturn));
112 int     remote_connect(const char *, const char *, struct addrinfo);
113 int     timeout_connect(int, const struct sockaddr *, socklen_t);
114 int     socks_connect(const char *, const char *, struct addrinfo,
115             const char *, const char *, struct addrinfo, int, const char *);
116 int     udptest(int);
117 int     unix_bind(char *);
118 int     unix_connect(char *);
119 int     unix_listen(char *);
120 void    set_common_sockopts(int);
121 int     map_tos(char *, int *);
122 void    report_connect(const struct sockaddr *, socklen_t);
123 void    usage(int);
124
125 #ifdef IPSEC
126 void    add_ipsec_policy(int, char *);
127
128 char    *ipsec_policy[2];
129 #endif
130
131 int
132 main(int argc, char *argv[])
133 {
134         int ch, s, ret, socksv, ipsec_count;
135         int numfibs;
136         size_t intsize = sizeof(int);
137         char *host, *uport;
138         struct addrinfo hints;
139         struct servent *sv;
140         socklen_t len;
141         struct sockaddr_storage cliaddr;
142         char *proxy;
143         const char *errstr, *proxyhost = "", *proxyport = NULL;
144         struct addrinfo proxyhints;
145         char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE];
146         struct option longopts[] = {
147                 { "no-tcpopt",  no_argument,    &FreeBSD_Oflag, 1 },
148                 { NULL,         0,              NULL,           0 }
149         };
150
151         ret = 1;
152         ipsec_count = 0;
153         s = 0;
154         socksv = 5;
155         host = NULL;
156         uport = NULL;
157         sv = NULL;
158
159         while ((ch = getopt_long(argc, argv,
160             "46DdEe:FhI:i:klNnoO:P:p:rSs:tT:UuV:vw:X:x:z",
161             longopts, NULL)) != -1) {
162                 switch (ch) {
163                 case '4':
164                         family = AF_INET;
165                         break;
166                 case '6':
167                         family = AF_INET6;
168                         break;
169                 case 'U':
170                         family = AF_UNIX;
171                         break;
172                 case 'X':
173                         if (strcasecmp(optarg, "connect") == 0)
174                                 socksv = -1; /* HTTP proxy CONNECT */
175                         else if (strcmp(optarg, "4") == 0)
176                                 socksv = 4; /* SOCKS v.4 */
177                         else if (strcmp(optarg, "5") == 0)
178                                 socksv = 5; /* SOCKS v.5 */
179                         else
180                                 errx(1, "unsupported proxy protocol");
181                         break;
182                 case 'd':
183                         dflag = 1;
184                         break;
185                 case 'e':
186 #ifdef IPSEC
187                         ipsec_policy[ipsec_count++ % 2] = optarg;
188 #else
189                         errx(1, "IPsec support unavailable.");
190 #endif
191                         break;
192                 case 'E':
193 #ifdef IPSEC
194                         ipsec_policy[0] = "in  ipsec esp/transport//require";
195                         ipsec_policy[1] = "out ipsec esp/transport//require";
196 #else
197                         errx(1, "IPsec support unavailable.");
198 #endif
199                         break;
200                 case 'F':
201                         Fflag = 1;
202                         break;
203                 case 'h':
204                         help();
205                         break;
206                 case 'i':
207                         iflag = strtonum(optarg, 0, UINT_MAX, &errstr);
208                         if (errstr)
209                                 errx(1, "interval %s: %s", errstr, optarg);
210                         break;
211                 case 'k':
212                         kflag = 1;
213                         break;
214                 case 'l':
215                         lflag = 1;
216                         break;
217                 case 'N':
218                         Nflag = 1;
219                         break;
220                 case 'n':
221                         nflag = 1;
222                         break;
223                 case 'o':
224                         fprintf(stderr, "option -o is deprecated.\n");
225                         break;
226                 case 'P':
227                         Pflag = optarg;
228                         break;
229                 case 'p':
230                         pflag = optarg;
231                         break;
232                 case 'r':
233                         rflag = 1;
234                         break;
235                 case 's':
236                         sflag = optarg;
237                         break;
238                 case 't':
239                         tflag = 1;
240                         break;
241                 case 'u':
242                         uflag = 1;
243                         break;
244                 case 'V':
245                         if (sysctlbyname("net.fibs", &numfibs, &intsize, NULL, 0) == -1)
246                                 errx(1, "Multiple FIBS not supported");
247                         rtableid = (int)strtonum(optarg, 0,
248                             numfibs - 1, &errstr);
249                         if (errstr)
250                                 errx(1, "rtable %s: %s", errstr, optarg);
251                         break;
252                 case 'v':
253                         vflag = 1;
254                         break;
255                 case 'w':
256                         timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr);
257                         if (errstr)
258                                 errx(1, "timeout %s: %s", errstr, optarg);
259                         timeout *= 1000;
260                         break;
261                 case 'x':
262                         xflag = 1;
263                         if ((proxy = strdup(optarg)) == NULL)
264                                 err(1, NULL);
265                         break;
266                 case 'z':
267                         zflag = 1;
268                         break;
269                 case 'D':
270                         Dflag = 1;
271                         break;
272                 case 'I':
273                         Iflag = strtonum(optarg, 1, 65536 << 14, &errstr);
274                         if (errstr != NULL)
275                                 errx(1, "TCP receive window %s: %s",
276                                     errstr, optarg);
277                         break;
278                 case 'O':
279                         Oflag = strtonum(optarg, 1, 65536 << 14, &errstr);
280                         if (errstr != NULL) {
281                             if (strcmp(errstr, "invalid") != 0)
282                                 errx(1, "TCP send window %s: %s",
283                                     errstr, optarg);
284                         }
285                         break;
286                 case 'S':
287                         Sflag = 1;
288                         break;
289                 case 'T':
290                         errstr = NULL;
291                         errno = 0;
292                         if (map_tos(optarg, &Tflag))
293                                 break;
294                         if (strlen(optarg) > 1 && optarg[0] == '0' &&
295                             optarg[1] == 'x')
296                                 Tflag = (int)strtol(optarg, NULL, 16);
297                         else
298                                 Tflag = (int)strtonum(optarg, 0, 255,
299                                     &errstr);
300                         if (Tflag < 0 || Tflag > 255 || errstr || errno)
301                                 errx(1, "illegal tos value %s", optarg);
302                         break;
303                 default:
304                         usage(1);
305                 }
306         }
307         argc -= optind;
308         argv += optind;
309
310         /* Cruft to make sure options are clean, and used properly. */
311         if (argv[0] && !argv[1] && family == AF_UNIX) {
312                 host = argv[0];
313                 uport = NULL;
314         } else if (argv[0] && !argv[1]) {
315                 if  (!lflag)
316                         usage(1);
317                 uport = argv[0];
318                 host = NULL;
319         } else if (argv[0] && argv[1]) {
320                 host = argv[0];
321                 uport = argv[1];
322         } else
323                 usage(1);
324
325         if (lflag && sflag)
326                 errx(1, "cannot use -s and -l");
327         if (lflag && pflag)
328                 errx(1, "cannot use -p and -l");
329         if (lflag && zflag)
330                 errx(1, "cannot use -z and -l");
331         if (!lflag && kflag)
332                 errx(1, "must use -l with -k");
333
334         /* Get name of temporary socket for unix datagram client */
335         if ((family == AF_UNIX) && uflag && !lflag) {
336                 if (sflag) {
337                         unix_dg_tmp_socket = sflag;
338                 } else {
339                         strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX",
340                                 UNIX_DG_TMP_SOCKET_SIZE);
341                         if (mktemp(unix_dg_tmp_socket_buf) == NULL)
342                                 err(1, "mktemp");
343                         unix_dg_tmp_socket = unix_dg_tmp_socket_buf;
344                 }
345         }
346
347         /* Initialize addrinfo structure. */
348         if (family != AF_UNIX) {
349                 memset(&hints, 0, sizeof(struct addrinfo));
350                 hints.ai_family = family;
351                 hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
352                 hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
353                 if (nflag)
354                         hints.ai_flags |= AI_NUMERICHOST;
355         }
356
357         if (xflag) {
358                 if (uflag)
359                         errx(1, "no proxy support for UDP mode");
360
361                 if (lflag)
362                         errx(1, "no proxy support for listen");
363
364                 if (family == AF_UNIX)
365                         errx(1, "no proxy support for unix sockets");
366
367                 /* XXX IPv6 transport to proxy would probably work */
368                 if (family == AF_INET6)
369                         errx(1, "no proxy support for IPv6");
370
371                 if (sflag)
372                         errx(1, "no proxy support for local source address");
373
374                 proxyhost = strsep(&proxy, ":");
375                 proxyport = proxy;
376
377                 memset(&proxyhints, 0, sizeof(struct addrinfo));
378                 proxyhints.ai_family = family;
379                 proxyhints.ai_socktype = SOCK_STREAM;
380                 proxyhints.ai_protocol = IPPROTO_TCP;
381                 if (nflag)
382                         proxyhints.ai_flags |= AI_NUMERICHOST;
383         }
384
385         if (lflag) {
386                 int connfd;
387                 ret = 0;
388
389                 if (family == AF_UNIX) {
390                         if (uflag)
391                                 s = unix_bind(host);
392                         else
393                                 s = unix_listen(host);
394                 }
395
396                 /* Allow only one connection at a time, but stay alive. */
397                 for (;;) {
398                         if (family != AF_UNIX)
399                                 s = local_listen(host, uport, hints);
400                         if (s < 0)
401                                 err(1, NULL);
402                         /*
403                          * For UDP and -k, don't connect the socket, let it
404                          * receive datagrams from multiple socket pairs.
405                          */
406                         if (uflag && kflag)
407                                 readwrite(s);
408                         /*
409                          * For UDP and not -k, we will use recvfrom() initially
410                          * to wait for a caller, then use the regular functions
411                          * to talk to the caller.
412                          */
413                         else if (uflag && !kflag) {
414                                 int rv, plen;
415                                 char buf[16384];
416                                 struct sockaddr_storage z;
417
418                                 len = sizeof(z);
419                                 plen = 2048;
420                                 rv = recvfrom(s, buf, plen, MSG_PEEK,
421                                     (struct sockaddr *)&z, &len);
422                                 if (rv < 0)
423                                         err(1, "recvfrom");
424
425                                 rv = connect(s, (struct sockaddr *)&z, len);
426                                 if (rv < 0)
427                                         err(1, "connect");
428
429                                 if (vflag)
430                                         report_connect((struct sockaddr *)&z, len);
431
432                                 readwrite(s);
433                         } else {
434                                 len = sizeof(cliaddr);
435                                 connfd = accept(s, (struct sockaddr *)&cliaddr,
436                                     &len);
437                                 if (connfd == -1) {
438                                         /* For now, all errnos are fatal */
439                                         err(1, "accept");
440                                 }
441                                 if (vflag)
442                                         report_connect((struct sockaddr *)&cliaddr, len);
443
444                                 readwrite(connfd);
445                                 close(connfd);
446                         }
447
448                         if (family != AF_UNIX)
449                                 close(s);
450                         else if (uflag) {
451                                 if (connect(s, NULL, 0) < 0)
452                                         err(1, "connect");
453                         }
454
455                         if (!kflag)
456                                 break;
457                 }
458         } else if (family == AF_UNIX) {
459                 ret = 0;
460
461                 if ((s = unix_connect(host)) > 0 && !zflag) {
462                         readwrite(s);
463                         close(s);
464                 } else
465                         ret = 1;
466
467                 if (uflag)
468                         unlink(unix_dg_tmp_socket);
469                 exit(ret);
470
471         } else {
472                 int i = 0;
473
474                 /* Construct the portlist[] array. */
475                 build_ports(uport);
476
477                 /* Cycle through portlist, connecting to each port. */
478                 for (i = 0; portlist[i] != NULL; i++) {
479                         if (s)
480                                 close(s);
481
482                         if (xflag)
483                                 s = socks_connect(host, portlist[i], hints,
484                                     proxyhost, proxyport, proxyhints, socksv,
485                                     Pflag);
486                         else
487                                 s = remote_connect(host, portlist[i], hints);
488
489                         if (s < 0)
490                                 continue;
491
492                         ret = 0;
493                         if (vflag || zflag) {
494                                 /* For UDP, make sure we are connected. */
495                                 if (uflag) {
496                                         if (udptest(s) == -1) {
497                                                 ret = 1;
498                                                 continue;
499                                         }
500                                 }
501
502                                 /* Don't look up port if -n. */
503                                 if (nflag)
504                                         sv = NULL;
505                                 else {
506                                         sv = getservbyport(
507                                             ntohs(atoi(portlist[i])),
508                                             uflag ? "udp" : "tcp");
509                                 }
510
511                                 fprintf(stderr,
512                                     "Connection to %s %s port [%s/%s] "
513                                     "succeeded!\n", host, portlist[i],
514                                     uflag ? "udp" : "tcp",
515                                     sv ? sv->s_name : "*");
516                         }
517                         if (Fflag)
518                                 fdpass(s);
519                         else if (!zflag)
520                                 readwrite(s);
521                 }
522         }
523
524         if (s)
525                 close(s);
526
527         exit(ret);
528 }
529
530 /*
531  * unix_bind()
532  * Returns a unix socket bound to the given path
533  */
534 int
535 unix_bind(char *path)
536 {
537         struct sockaddr_un sun;
538         int s;
539
540         /* Create unix domain socket. */
541         if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM,
542              0)) < 0)
543                 return (-1);
544
545         memset(&sun, 0, sizeof(struct sockaddr_un));
546         sun.sun_family = AF_UNIX;
547
548         if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
549             sizeof(sun.sun_path)) {
550                 close(s);
551                 errno = ENAMETOOLONG;
552                 return (-1);
553         }
554
555         if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
556                 close(s);
557                 return (-1);
558         }
559         return (s);
560 }
561
562 /*
563  * unix_connect()
564  * Returns a socket connected to a local unix socket. Returns -1 on failure.
565  */
566 int
567 unix_connect(char *path)
568 {
569         struct sockaddr_un sun;
570         int s;
571
572         if (uflag) {
573                 if ((s = unix_bind(unix_dg_tmp_socket)) < 0)
574                         return (-1);
575         } else {
576                 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
577                         return (-1);
578         }
579         (void)fcntl(s, F_SETFD, FD_CLOEXEC);
580
581         memset(&sun, 0, sizeof(struct sockaddr_un));
582         sun.sun_family = AF_UNIX;
583
584         if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
585             sizeof(sun.sun_path)) {
586                 close(s);
587                 errno = ENAMETOOLONG;
588                 return (-1);
589         }
590         if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
591                 close(s);
592                 return (-1);
593         }
594         return (s);
595
596 }
597
598 /*
599  * unix_listen()
600  * Create a unix domain socket, and listen on it.
601  */
602 int
603 unix_listen(char *path)
604 {
605         int s;
606         if ((s = unix_bind(path)) < 0)
607                 return (-1);
608
609         if (listen(s, 5) < 0) {
610                 close(s);
611                 return (-1);
612         }
613         return (s);
614 }
615
616 /*
617  * remote_connect()
618  * Returns a socket connected to a remote host. Properly binds to a local
619  * port or source address if needed. Returns -1 on failure.
620  */
621 int
622 remote_connect(const char *host, const char *port, struct addrinfo hints)
623 {
624         struct addrinfo *res, *res0;
625         int s, error, on = 1;
626
627         if ((error = getaddrinfo(host, port, &hints, &res)))
628                 errx(1, "getaddrinfo: %s", gai_strerror(error));
629
630         res0 = res;
631         do {
632                 if ((s = socket(res0->ai_family, res0->ai_socktype,
633                     res0->ai_protocol)) < 0)
634                         continue;
635 #ifdef IPSEC
636                 if (ipsec_policy[0] != NULL)
637                         add_ipsec_policy(s, ipsec_policy[0]);
638                 if (ipsec_policy[1] != NULL)
639                         add_ipsec_policy(s, ipsec_policy[1]);
640 #endif
641
642                 if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_SETFIB,
643                     &rtableid, sizeof(rtableid)) == -1))
644                         err(1, "setsockopt SO_SETFIB");
645
646                 /* Bind to a local port or source address if specified. */
647                 if (sflag || pflag) {
648                         struct addrinfo ahints, *ares;
649
650                         /* try IP_BINDANY, but don't insist */
651                         setsockopt(s, IPPROTO_IP, IP_BINDANY, &on, sizeof(on));
652                         memset(&ahints, 0, sizeof(struct addrinfo));
653                         ahints.ai_family = res0->ai_family;
654                         ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
655                         ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
656                         ahints.ai_flags = AI_PASSIVE;
657                         if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
658                                 errx(1, "getaddrinfo: %s", gai_strerror(error));
659
660                         if (bind(s, (struct sockaddr *)ares->ai_addr,
661                             ares->ai_addrlen) < 0)
662                                 err(1, "bind failed");
663                         freeaddrinfo(ares);
664                 }
665
666                 set_common_sockopts(s);
667
668                 if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
669                         break;
670                 else if (vflag)
671                         warn("connect to %s port %s (%s) failed", host, port,
672                             uflag ? "udp" : "tcp");
673
674                 close(s);
675                 s = -1;
676         } while ((res0 = res0->ai_next) != NULL);
677
678         freeaddrinfo(res);
679
680         return (s);
681 }
682
683 int
684 timeout_connect(int s, const struct sockaddr *name, socklen_t namelen)
685 {
686         struct pollfd pfd;
687         socklen_t optlen;
688         int flags, optval;
689         int ret;
690
691         if (timeout != -1) {
692                 flags = fcntl(s, F_GETFL, 0);
693                 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1)
694                         err(1, "set non-blocking mode");
695         }
696
697         if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) {
698                 pfd.fd = s;
699                 pfd.events = POLLOUT;
700                 if ((ret = poll(&pfd, 1, timeout)) == 1) {
701                         optlen = sizeof(optval);
702                         if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR,
703                             &optval, &optlen)) == 0) {
704                                 errno = optval;
705                                 ret = optval == 0 ? 0 : -1;
706                         }
707                 } else if (ret == 0) {
708                         errno = ETIMEDOUT;
709                         ret = -1;
710                 } else
711                         err(1, "poll failed");
712         }
713
714         if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1)
715                 err(1, "restoring flags");
716
717         return (ret);
718 }
719
720 /*
721  * local_listen()
722  * Returns a socket listening on a local port, binds to specified source
723  * address. Returns -1 on failure.
724  */
725 int
726 local_listen(char *host, char *port, struct addrinfo hints)
727 {
728         struct addrinfo *res, *res0;
729         int s, ret, x = 1;
730         int error;
731
732         /* Allow nodename to be null. */
733         hints.ai_flags |= AI_PASSIVE;
734
735         /*
736          * In the case of binding to a wildcard address
737          * default to binding to an ipv4 address.
738          */
739         if (host == NULL && hints.ai_family == AF_UNSPEC)
740                 hints.ai_family = AF_INET;
741
742         if ((error = getaddrinfo(host, port, &hints, &res)))
743                 errx(1, "getaddrinfo: %s", gai_strerror(error));
744
745         res0 = res;
746         do {
747                 if ((s = socket(res0->ai_family, res0->ai_socktype,
748                     res0->ai_protocol)) < 0)
749                         continue;
750
751                 if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_SETFIB,
752                     &rtableid, sizeof(rtableid)) == -1))
753                         err(1, "setsockopt SO_SETFIB");
754
755                 ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
756                 if (ret == -1)
757                         err(1, NULL);
758 #ifdef IPSEC
759                 if (ipsec_policy[0] != NULL)
760                         add_ipsec_policy(s, ipsec_policy[0]);
761                 if (ipsec_policy[1] != NULL)
762                         add_ipsec_policy(s, ipsec_policy[1]);
763 #endif
764                 if (FreeBSD_Oflag) {
765                         if (setsockopt(s, IPPROTO_TCP, TCP_NOOPT,
766                             &FreeBSD_Oflag, sizeof(FreeBSD_Oflag)) == -1)
767                                 err(1, "disable TCP options");
768                 }
769
770                 if (bind(s, (struct sockaddr *)res0->ai_addr,
771                     res0->ai_addrlen) == 0)
772                         break;
773
774                 close(s);
775                 s = -1;
776         } while ((res0 = res0->ai_next) != NULL);
777
778         if (!uflag && s != -1) {
779                 if (listen(s, 1) < 0)
780                         err(1, "listen");
781         }
782
783         freeaddrinfo(res);
784
785         return (s);
786 }
787
788 /*
789  * readwrite()
790  * Loop that polls on the network file descriptor and stdin.
791  */
792 void
793 readwrite(int nfd)
794 {
795         struct pollfd pfd[2];
796         unsigned char buf[16 * 1024];
797         int n, wfd = fileno(stdin);
798         int lfd = fileno(stdout);
799         int plen;
800
801         plen = sizeof(buf);
802
803         /* Setup Network FD */
804         pfd[0].fd = nfd;
805         pfd[0].events = POLLIN;
806
807         /* Set up STDIN FD. */
808         pfd[1].fd = wfd;
809         pfd[1].events = POLLIN;
810
811         while (pfd[0].fd != -1) {
812                 if (iflag)
813                         sleep(iflag);
814
815                 if ((n = poll(pfd, 2 - dflag, timeout)) < 0) {
816                         int saved_errno = errno;
817                         close(nfd);
818                         errc(1, saved_errno, "Polling Error");
819                 }
820
821                 if (n == 0)
822                         return;
823
824                 if (pfd[0].revents & POLLIN) {
825                         if ((n = read(nfd, buf, plen)) < 0)
826                                 return;
827                         else if (n == 0) {
828                                 shutdown(nfd, SHUT_RD);
829                                 pfd[0].fd = -1;
830                                 pfd[0].events = 0;
831                         } else {
832                                 if (tflag)
833                                         atelnet(nfd, buf, n);
834                                 if (atomicio(vwrite, lfd, buf, n) != n)
835                                         return;
836                         }
837                 }
838
839                 if (!dflag && pfd[1].revents & POLLIN) {
840                         if ((n = read(wfd, buf, plen)) < 0)
841                                 return;
842                         else if (n == 0) {
843                                 if (Nflag)
844                                         shutdown(nfd, SHUT_WR);
845                                 pfd[1].fd = -1;
846                                 pfd[1].events = 0;
847                         } else {
848                                 if (atomicio(vwrite, nfd, buf, n) != n)
849                                         return;
850                         }
851                 }
852         }
853 }
854
855 /*
856  * fdpass()
857  * Pass the connected file descriptor to stdout and exit.
858  */
859 void
860 fdpass(int nfd)
861 {
862         struct msghdr mh;
863         union {
864                 struct cmsghdr hdr;
865                 char buf[CMSG_SPACE(sizeof(int))];
866         } cmsgbuf;
867         struct cmsghdr *cmsg;
868         struct iovec iov;
869         char c = '\0';
870         ssize_t r;
871         struct pollfd pfd;
872
873         /* Avoid obvious stupidity */
874         if (isatty(STDOUT_FILENO))
875                 errx(1, "Cannot pass file descriptor to tty");
876
877         bzero(&mh, sizeof(mh));
878         bzero(&cmsgbuf, sizeof(cmsgbuf));
879         bzero(&iov, sizeof(iov));
880         bzero(&pfd, sizeof(pfd));
881
882         mh.msg_control = (caddr_t)&cmsgbuf.buf;
883         mh.msg_controllen = sizeof(cmsgbuf.buf);
884         cmsg = CMSG_FIRSTHDR(&mh);
885         cmsg->cmsg_len = CMSG_LEN(sizeof(int));
886         cmsg->cmsg_level = SOL_SOCKET;
887         cmsg->cmsg_type = SCM_RIGHTS;
888         *(int *)CMSG_DATA(cmsg) = nfd;
889
890         iov.iov_base = &c;
891         iov.iov_len = 1;
892         mh.msg_iov = &iov;
893         mh.msg_iovlen = 1;
894
895         bzero(&pfd, sizeof(pfd));
896         pfd.fd = STDOUT_FILENO;
897         for (;;) {
898                 r = sendmsg(STDOUT_FILENO, &mh, 0);
899                 if (r == -1) {
900                         if (errno == EAGAIN || errno == EINTR) {
901                                 pfd.events = POLLOUT;
902                                 if (poll(&pfd, 1, -1) == -1)
903                                         err(1, "poll");
904                                 continue;
905                         }
906                         err(1, "sendmsg");
907                 } else if (r == -1)
908                         errx(1, "sendmsg: unexpected return value %zd", r);
909                 else
910                         break;
911         }
912         exit(0);
913 }
914
915 /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */
916 void
917 atelnet(int nfd, unsigned char *buf, unsigned int size)
918 {
919         unsigned char *p, *end;
920         unsigned char obuf[4];
921
922         if (size < 3)
923                 return;
924         end = buf + size - 2;
925
926         for (p = buf; p < end; p++) {
927                 if (*p != IAC)
928                         continue;
929
930                 obuf[0] = IAC;
931                 p++;
932                 if ((*p == WILL) || (*p == WONT))
933                         obuf[1] = DONT;
934                 else if ((*p == DO) || (*p == DONT))
935                         obuf[1] = WONT;
936                 else
937                         continue;
938
939                 p++;
940                 obuf[2] = *p;
941                 if (atomicio(vwrite, nfd, obuf, 3) != 3)
942                         warn("Write Error!");
943         }
944 }
945
946 /*
947  * build_ports()
948  * Build an array of ports in portlist[], listing each port
949  * that we should try to connect to.
950  */
951 void
952 build_ports(char *p)
953 {
954         const char *errstr;
955         char *n;
956         int hi, lo, cp;
957         int x = 0;
958
959         if ((n = strchr(p, '-')) != NULL) {
960                 *n = '\0';
961                 n++;
962
963                 /* Make sure the ports are in order: lowest->highest. */
964                 hi = strtonum(n, 1, PORT_MAX, &errstr);
965                 if (errstr)
966                         errx(1, "port number %s: %s", errstr, n);
967                 lo = strtonum(p, 1, PORT_MAX, &errstr);
968                 if (errstr)
969                         errx(1, "port number %s: %s", errstr, p);
970
971                 if (lo > hi) {
972                         cp = hi;
973                         hi = lo;
974                         lo = cp;
975                 }
976
977                 /* Load ports sequentially. */
978                 for (cp = lo; cp <= hi; cp++) {
979                         portlist[x] = calloc(1, PORT_MAX_LEN);
980                         if (portlist[x] == NULL)
981                                 err(1, NULL);
982                         snprintf(portlist[x], PORT_MAX_LEN, "%d", cp);
983                         x++;
984                 }
985
986                 /* Randomly swap ports. */
987                 if (rflag) {
988                         int y;
989                         char *c;
990
991                         for (x = 0; x <= (hi - lo); x++) {
992                                 y = (arc4random() & 0xFFFF) % (hi - lo);
993                                 c = portlist[x];
994                                 portlist[x] = portlist[y];
995                                 portlist[y] = c;
996                         }
997                 }
998         } else {
999                 hi = strtonum(p, 1, PORT_MAX, &errstr);
1000                 if (errstr)
1001                         errx(1, "port number %s: %s", errstr, p);
1002                 portlist[0] = strdup(p);
1003                 if (portlist[0] == NULL)
1004                         err(1, NULL);
1005         }
1006 }
1007
1008 /*
1009  * udptest()
1010  * Do a few writes to see if the UDP port is there.
1011  * Fails once PF state table is full.
1012  */
1013 int
1014 udptest(int s)
1015 {
1016         int i, ret;
1017
1018         for (i = 0; i <= 3; i++) {
1019                 if (write(s, "X", 1) == 1)
1020                         ret = 1;
1021                 else
1022                         ret = -1;
1023         }
1024         return (ret);
1025 }
1026
1027 void
1028 set_common_sockopts(int s)
1029 {
1030         int x = 1;
1031
1032         if (Sflag) {
1033                 if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
1034                         &x, sizeof(x)) == -1)
1035                         err(1, NULL);
1036         }
1037         if (Dflag) {
1038                 if (setsockopt(s, SOL_SOCKET, SO_DEBUG,
1039                         &x, sizeof(x)) == -1)
1040                         err(1, NULL);
1041         }
1042         if (Tflag != -1) {
1043                 if (setsockopt(s, IPPROTO_IP, IP_TOS,
1044                     &Tflag, sizeof(Tflag)) == -1)
1045                         err(1, "set IP ToS");
1046         }
1047         if (Iflag) {
1048                 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
1049                     &Iflag, sizeof(Iflag)) == -1)
1050                         err(1, "set TCP receive buffer size");
1051         }
1052         if (Oflag) {
1053                 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
1054                     &Oflag, sizeof(Oflag)) == -1)
1055                         err(1, "set TCP send buffer size");
1056         }
1057         if (FreeBSD_Oflag) {
1058                 if (setsockopt(s, IPPROTO_TCP, TCP_NOOPT,
1059                     &FreeBSD_Oflag, sizeof(FreeBSD_Oflag)) == -1)
1060                         err(1, "disable TCP options");
1061         }
1062 }
1063
1064 int
1065 map_tos(char *s, int *val)
1066 {
1067         /* DiffServ Codepoints and other TOS mappings */
1068         const struct toskeywords {
1069                 const char      *keyword;
1070                 int              val;
1071         } *t, toskeywords[] = {
1072                 { "af11",               IPTOS_DSCP_AF11 },
1073                 { "af12",               IPTOS_DSCP_AF12 },
1074                 { "af13",               IPTOS_DSCP_AF13 },
1075                 { "af21",               IPTOS_DSCP_AF21 },
1076                 { "af22",               IPTOS_DSCP_AF22 },
1077                 { "af23",               IPTOS_DSCP_AF23 },
1078                 { "af31",               IPTOS_DSCP_AF31 },
1079                 { "af32",               IPTOS_DSCP_AF32 },
1080                 { "af33",               IPTOS_DSCP_AF33 },
1081                 { "af41",               IPTOS_DSCP_AF41 },
1082                 { "af42",               IPTOS_DSCP_AF42 },
1083                 { "af43",               IPTOS_DSCP_AF43 },
1084                 { "critical",           IPTOS_PREC_CRITIC_ECP },
1085                 { "cs0",                IPTOS_DSCP_CS0 },
1086                 { "cs1",                IPTOS_DSCP_CS1 },
1087                 { "cs2",                IPTOS_DSCP_CS2 },
1088                 { "cs3",                IPTOS_DSCP_CS3 },
1089                 { "cs4",                IPTOS_DSCP_CS4 },
1090                 { "cs5",                IPTOS_DSCP_CS5 },
1091                 { "cs6",                IPTOS_DSCP_CS6 },
1092                 { "cs7",                IPTOS_DSCP_CS7 },
1093                 { "ef",                 IPTOS_DSCP_EF },
1094                 { "inetcontrol",        IPTOS_PREC_INTERNETCONTROL },
1095                 { "lowdelay",           IPTOS_LOWDELAY },
1096                 { "netcontrol",         IPTOS_PREC_NETCONTROL },
1097                 { "reliability",        IPTOS_RELIABILITY },
1098                 { "throughput",         IPTOS_THROUGHPUT },
1099                 { NULL,                 -1 },
1100         };
1101
1102         for (t = toskeywords; t->keyword != NULL; t++) {
1103                 if (strcmp(s, t->keyword) == 0) {
1104                         *val = t->val;
1105                         return (1);
1106                 }
1107         }
1108
1109         return (0);
1110 }
1111
1112 void
1113 report_connect(const struct sockaddr *sa, socklen_t salen)
1114 {
1115         char remote_host[NI_MAXHOST];
1116         char remote_port[NI_MAXSERV];
1117         int herr;
1118         int flags = NI_NUMERICSERV;
1119         
1120         if (nflag)
1121                 flags |= NI_NUMERICHOST;
1122         
1123         if ((herr = getnameinfo(sa, salen,
1124             remote_host, sizeof(remote_host),
1125             remote_port, sizeof(remote_port),
1126             flags)) != 0) {
1127                 if (herr == EAI_SYSTEM)
1128                         err(1, "getnameinfo");
1129                 else
1130                         errx(1, "getnameinfo: %s", gai_strerror(herr));
1131         }
1132         
1133         fprintf(stderr,
1134             "Connection from %s %s "
1135             "received!\n", remote_host, remote_port);
1136 }
1137
1138 void
1139 help(void)
1140 {
1141         usage(0);
1142         fprintf(stderr, "\tCommand Summary:\n\
1143         \t-4            Use IPv4\n\
1144         \t-6            Use IPv6\n\
1145         \t-D            Enable the debug socket option\n\
1146         \t-d            Detach from stdin\n");
1147 #ifdef IPSEC
1148         fprintf(stderr, "\
1149         \t-E            Use IPsec ESP\n\
1150         \t-e policy     Use specified IPsec policy\n");
1151 #endif
1152         fprintf(stderr, "\
1153         \t-F            Pass socket fd\n\
1154         \t-h            This help text\n\
1155         \t-I length     TCP receive buffer length\n\
1156         \t-i secs\t     Delay interval for lines sent, ports scanned\n\
1157         \t-k            Keep inbound sockets open for multiple connects\n\
1158         \t-l            Listen mode, for inbound connects\n\
1159         \t-N            Shutdown the network socket after EOF on stdin\n\
1160         \t-n            Suppress name/port resolutions\n\
1161         \t--no-tcpopt   Disable TCP options\n\
1162         \t-O length     TCP send buffer length\n\
1163         \t-P proxyuser\tUsername for proxy authentication\n\
1164         \t-p port\t     Specify local port for remote connects\n\
1165         \t-r            Randomize remote ports\n\
1166         \t-S            Enable the TCP MD5 signature option\n\
1167         \t-s addr\t     Local source address\n\
1168         \t-T toskeyword\tSet IP Type of Service\n\
1169         \t-t            Answer TELNET negotiation\n\
1170         \t-U            Use UNIX domain socket\n\
1171         \t-u            UDP mode\n\
1172         \t-V rtable     Specify alternate routing table\n\
1173         \t-v            Verbose\n\
1174         \t-w secs\t     Timeout for connects and final net reads\n\
1175         \t-X proto      Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\
1176         \t-x addr[:port]\tSpecify proxy address and port\n\
1177         \t-z            Zero-I/O mode [used for scanning]\n\
1178         Port numbers can be individual or ranges: lo-hi [inclusive]\n");
1179 #ifdef IPSEC
1180         fprintf(stderr, "See ipsec_set_policy(3) for -e argument format\n");
1181 #endif
1182         exit(1);
1183 }
1184
1185 #ifdef IPSEC
1186 void
1187 add_ipsec_policy(int s, char *policy)
1188 {
1189         char *raw;
1190         int e;
1191
1192         raw = ipsec_set_policy(policy, strlen(policy));
1193         if (raw == NULL)
1194                 errx(1, "ipsec_set_policy `%s': %s", policy,
1195                      ipsec_strerror());
1196         e = setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY, raw,
1197                         ipsec_get_policylen(raw));
1198         if (e < 0)
1199                 err(1, "ipsec policy cannot be configured");
1200         free(raw);
1201         if (vflag)
1202                 fprintf(stderr, "ipsec policy configured: `%s'\n", policy);
1203         return;
1204 }
1205 #endif /* IPSEC */
1206
1207 void
1208 usage(int ret)
1209 {
1210         fprintf(stderr,
1211 #ifdef IPSEC
1212             "usage: nc [-46DdEFhklNnrStUuvz] [-e policy] [-I length] [-i interval] [-O length]\n"
1213 #else
1214             "usage: nc [-46DdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n"
1215 #endif
1216             "\t  [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n"
1217             "\t  [-V rtable] [-w timeout] [-X proxy_protocol]\n"
1218             "\t  [-x proxy_address[:port]] [destination] [port]\n");
1219         if (ret)
1220                 exit(1);
1221 }