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