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