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