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