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