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