[BACK]Return to netcat.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / nc

Annotation of src/usr.bin/nc/netcat.c, Revision 1.21

1.21    ! ericj       1: /* $OpenBSD$ */
        !             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.21    ! ericj      29: /*
        !            30:  * Re-written nc(1) for OpenBSD. Only code shared with previous version
        !            31:  * was the code for telnet emulation. Original implementation by
        !            32:  * *Hobbit* <hobbit@avian.org>.
        !            33:  */
1.1       deraadt    34:
1.7       deraadt    35: #include <sys/types.h>
1.21    ! ericj      36: #include <sys/socket.h>
1.7       deraadt    37: #include <sys/time.h>
1.21    ! ericj      38:
1.7       deraadt    39: #include <netinet/in.h>
1.21    ! ericj      40: #include <arpa/telnet.h>
1.11      ericj      41: #include <err.h>
1.7       deraadt    42: #include <errno.h>
1.21    ! ericj      43: #include <netdb.h>
        !            44: #include <poll.h>
1.13      ericj      45: #include <stdarg.h>
1.21    ! ericj      46: #include <stdio.h>
1.1       deraadt    47: #include <stdlib.h>
1.21    ! ericj      48: #include <string.h>
1.5       art        49: #include <unistd.h>
1.1       deraadt    50:
1.21    ! ericj      51: /* Command Line Options */
        !            52: int    iflag;                                  /* Interval Flag */
        !            53: int    kflag;                                  /* More than one connect */
        !            54: int    lflag;                                  /* Bind to local port */
        !            55: int    nflag;                                  /* Dont do name lookup */
        !            56: char   *pflag;                                 /* Localport flag */
        !            57: int    rflag;                                  /* Random ports flag */
        !            58: char   *sflag;                                 /* Source Address */
        !            59: int    tflag;                                  /* Telnet Emulation */
        !            60: int    uflag;                                  /* UDP - Default to TCP */
        !            61: int    vflag;                                  /* Verbosity */
        !            62: int    zflag;                                  /* Port Scan Flag */
        !            63:
        !            64: int timeout;
        !            65: int family = AF_UNSPEC;
        !            66: char *portlist[65535];
        !            67:
        !            68: void atelnet __P((int, unsigned char *, unsigned int));
        !            69: void build_ports __P((char *));
        !            70: void help __P((void));
        !            71: int local_listen __P((char *, char *, struct addrinfo));
        !            72: void readwrite __P((int));
        !            73: int remote_connect __P((char *, char *, struct addrinfo));
        !            74: int udptest __P((int));
        !            75: void usage __P((int));
1.1       deraadt    76:
1.21    ! ericj      77: int
        !            78: main(argc, argv)
        !            79:        int argc;
        !            80:        char *argv[];
        !            81: {
        !            82:        int ch, s, ret = 1;
        !            83:        char *host, *uport;
        !            84:        struct addrinfo hints;
        !            85:        struct servent *sv = 0;
        !            86:        socklen_t len;
        !            87:        struct sockaddr *cliaddr;
1.11      ericj      88:
1.21    ! ericj      89:        while ((ch = getopt(argc, argv, "46hi:klnp:rs:tuvw:z")) != -1) {
        !            90:                switch (ch) {
        !            91:                case '4':
        !            92:                        family = AF_INET;
        !            93:                        break;
        !            94:                case '6':
        !            95:                        family = AF_INET6;
        !            96:                        break;
        !            97:                case 'h':
        !            98:                        help();
        !            99:                        break;
        !           100:                case 'i':
        !           101:                        iflag = atoi(optarg);
        !           102:                        break;
        !           103:                case 'k':
        !           104:                        kflag = 1;
        !           105:                        break;
        !           106:                case 'l':
        !           107:                        lflag = 1;
        !           108:                        break;
        !           109:                case 'n':
        !           110:                        nflag = 1;
        !           111:                        break;
        !           112:                case 'p':
        !           113:                        pflag = optarg;
        !           114:                        break;
        !           115:                case 'r':
        !           116:                        rflag = 1;
        !           117:                        break;
        !           118:                case 's':
        !           119:                        sflag = optarg;
        !           120:                        break;
        !           121:                case 't':
        !           122:                        tflag = 1;
        !           123:                        break;
        !           124:                case 'u':
        !           125:                        uflag = 1;
        !           126:                        break;
        !           127:                case 'v':
        !           128:                        vflag = 1;
        !           129:                        break;
        !           130:                case 'w':
        !           131:                        timeout = atoi(optarg);
        !           132:                        break;
        !           133:                case 'z':
        !           134:                        zflag = 1;
        !           135:                        break;
        !           136:                default:
        !           137:                        usage(1);
        !           138:                }
        !           139:        }
        !           140:        argc -= optind;
        !           141:        argv += optind;
1.11      ericj     142:
1.21    ! ericj     143:        /* Cruft to make sure options are clean, and used properly. */
        !           144:        if (argv[0] && !argv[1]) {
        !           145:                if  (!lflag)
        !           146:                        usage(1);
        !           147:                uport = argv[0];
        !           148:                host = NULL;
        !           149:        } else if (argv[0] && argv[1]) {
        !           150:                host = argv[0];
        !           151:                uport = argv[1];
        !           152:        } else
        !           153:                usage(1);
1.1       deraadt   154:
1.21    ! ericj     155:        if (lflag && sflag)
        !           156:                errx(1, "cannot use -s and -l");
        !           157:        if (lflag && pflag)
        !           158:                errx(1, "cannot use -p and -l");
        !           159:        if (lflag && zflag)
        !           160:                errx(1, "cannot use -p and -l");
        !           161:        if (!lflag && kflag)
        !           162:                errx(1, "must use -k with -l");
        !           163:
        !           164:        /* Initialize addrinfo structure */
        !           165:        memset(&hints, 0, sizeof(struct addrinfo));
        !           166:        hints.ai_family = family;
        !           167:        hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
        !           168:        hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
        !           169:        if (nflag)
        !           170:                hints.ai_flags |= AI_NUMERICHOST;
1.1       deraadt   171:
1.21    ! ericj     172:        if (lflag) {
        !           173:                int connfd;
        !           174:
        !           175:                if ((s = local_listen(host, uport, hints)) < 0)
        !           176:                        errx(1, NULL);
1.1       deraadt   177:
1.21    ! ericj     178:                ret = 0;
        !           179:                /* Allow only one connection at a time, but stay alive */
        !           180:                for (;;) {
        !           181:                        /*
        !           182:                         * For UDP, we will use recvfrom() initially
        !           183:                         * to wait for a caller, then use the regular
        !           184:                         * functions to talk to the caller.
        !           185:                         */
        !           186:                        if (uflag) {
        !           187:                                int ret;
        !           188:                                char buf[1024];
        !           189:                                char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
        !           190:                                struct sockaddr_storage z;
        !           191:
        !           192:                                len = sizeof(z);
        !           193:                                ret = recvfrom(s, buf, sizeof(buf), MSG_PEEK,
        !           194:                                        (struct sockaddr *)&z, &len);
        !           195:                                if (ret < 0)
        !           196:                                        errx(1, "%s", strerror(errno));
        !           197:
        !           198:                                ret = connect(s, (struct sockaddr *)&z,
        !           199:                                        len);
        !           200:                                if (ret < 0)
        !           201:                                        errx(1, "%s", strerror(errno));
1.1       deraadt   202:
1.21    ! ericj     203:                                connfd = s;
        !           204:                        } else {
        !           205:                                connfd = accept(s, (struct sockaddr *)&cliaddr,
        !           206:                                                                        &len);
        !           207:                        }
1.1       deraadt   208:
1.21    ! ericj     209:                        readwrite(connfd);
        !           210:                        close(connfd);
        !           211:                        if (!kflag)
        !           212:                                break;
1.11      ericj     213:                }
1.21    ! ericj     214:        } else {
        !           215:                int i = 0;
1.6       deraadt   216:
1.21    ! ericj     217:                /* construct the portlist[] array */
        !           218:                build_ports(uport);
1.1       deraadt   219:
1.21    ! ericj     220:                /* Cycle through portlist, connecting to each port */
        !           221:                for (i = 0; portlist[i] != NULL; i++) {
        !           222:
        !           223:                        if (s)
        !           224:                                close(s);
        !           225:
        !           226:                        if ((s = remote_connect(host, portlist[i], hints)) < 0)
        !           227:                                continue;
1.1       deraadt   228:
1.21    ! ericj     229:                        ret = 0;
        !           230:                        if (vflag || zflag) {
        !           231:                                /* For UDP, make sure we are connected */
        !           232:                                if (uflag) {
        !           233:                                        if ((udptest(s)) == -1) {
        !           234:                                                ret = 1;
        !           235:                                                continue;
        !           236:                                        }
        !           237:                                }
1.1       deraadt   238:
1.21    ! ericj     239:                                /* Don't lookup port if -n */
        !           240:                                if (nflag)
        !           241:                                        sv = NULL;
        !           242:                                else {
        !           243:                                        sv = getservbyport(
        !           244:                                                ntohs(atoi(portlist[i])),
        !           245:                                                uflag ? "udp" : "tcp");
        !           246:                                }
        !           247:
        !           248:                                printf("Connection to %s %s port [%s/%s] succeeded!\n",
        !           249:                                        host, portlist[i], uflag ? "udp" : "tcp",
        !           250:                                        sv ? sv->s_name : "*");
        !           251:                        }
        !           252:                        if (!zflag)
        !           253:                                readwrite(s);
1.7       deraadt   254:                }
1.11      ericj     255:        }
1.1       deraadt   256:
1.21    ! ericj     257:        if (s)
        !           258:                close(s);
        !           259:
        !           260:        exit(ret);
1.7       deraadt   261: }
1.1       deraadt   262:
1.11      ericj     263: /*
1.21    ! ericj     264:  * remote_connect()
        !           265:  * Return's a socket connected to a remote host. Properly bind's to a local
        !           266:  * port or source address if needed. Return's -1 on failure.
1.11      ericj     267:  */
1.21    ! ericj     268: int
        !           269: remote_connect(host, port, hints)
        !           270:        char *host, *port;
        !           271:        struct addrinfo hints;
        !           272: {
        !           273:        struct addrinfo *res, *res0;
        !           274:        int s, error;
        !           275:
        !           276:        if ((error = getaddrinfo(host, port, &hints, &res)))
        !           277:                errx(1, "%s", gai_strerror(error));
        !           278:
        !           279:        res0 = res;
        !           280:        do {
        !           281:                if ((s = socket(res0->ai_family, res0->ai_socktype,
        !           282:                                res0->ai_protocol)) < 0)
        !           283:                        continue;
        !           284:
        !           285:                /* Bind to a local port or source address if specified */
        !           286:                if (sflag || pflag) {
        !           287:                        struct addrinfo ahints, *ares;
        !           288:
        !           289:                        if (!(sflag && pflag)) {
        !           290:                                if (!sflag)
        !           291:                                        sflag = NULL;
        !           292:                                else
        !           293:                                        pflag = NULL;
        !           294:                        }
1.6       deraadt   295:
1.21    ! ericj     296:                        memset(&ahints, 0, sizeof(struct addrinfo));
        !           297:                        ahints.ai_family = res0->ai_family;
        !           298:                        ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
        !           299:                        ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
        !           300:                        if (getaddrinfo(sflag, pflag, &ahints, &ares))
        !           301:                                errx(1, "%s", gai_strerror(error));
        !           302:
        !           303:                        if (bind(s, (struct sockaddr *)ares->ai_addr,
        !           304:                                                        ares->ai_addrlen) < 0) {
        !           305:                                errx(1, "bind failed: %s", strerror(errno));
        !           306:                                freeaddrinfo(ares);
        !           307:                                continue;
        !           308:                        }
        !           309:                        freeaddrinfo(ares);
1.6       deraadt   310:                }
                    311:
1.21    ! ericj     312:                if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
1.6       deraadt   313:                        break;
1.21    ! ericj     314:
        !           315:                close(s);
        !           316:                s = -1;
        !           317:        } while ((res0 = res0->ai_next) != NULL);
        !           318:
        !           319:        freeaddrinfo(res);
1.1       deraadt   320:
1.21    ! ericj     321:        return (s);
1.7       deraadt   322: }
1.1       deraadt   323:
1.11      ericj     324: /*
1.21    ! ericj     325:  * local_listen()
        !           326:  * Return's a socket listening on a local port, binds to specified source
        !           327:  * address. Return's -1 on failure.
1.11      ericj     328:  */
1.21    ! ericj     329: int
        !           330: local_listen(host, port, hints)
        !           331:        char *host, *port;
        !           332:        struct addrinfo hints;
        !           333: {
        !           334:        struct addrinfo *res, *res0;
        !           335:        int s, ret, x = 1;
        !           336:        int error;
1.6       deraadt   337:
1.21    ! ericj     338:        /* Allow nodename to be null */
        !           339:        hints.ai_flags |= AI_PASSIVE;
1.7       deraadt   340:
1.21    ! ericj     341:        /*
        !           342:         * In the case of binding to a wildcard address
        !           343:         * default to binding to an ipv4 address.
        !           344:         */
        !           345:        if (host == NULL && hints.ai_family == AF_UNSPEC)
        !           346:                hints.ai_family = AF_INET;
1.1       deraadt   347:
1.21    ! ericj     348:        if ((error = getaddrinfo(host, port, &hints, &res)))
        !           349:                 errx(1, "%s", gai_strerror(error));
1.14      ericj     350:
1.21    ! ericj     351:        res0 = res;
        !           352:        do {
        !           353:                if ((s = socket(res0->ai_family, res0->ai_socktype,
        !           354:                                res0->ai_protocol)) == 0)
        !           355:                        continue;
1.1       deraadt   356:
1.21    ! ericj     357:                ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
        !           358:                if (ret == -1)
        !           359:                        errx(1, NULL);
1.1       deraadt   360:
1.21    ! ericj     361:                if (bind(s, (struct sockaddr *)res0->ai_addr,
        !           362:                                                res0->ai_addrlen) == 0)
        !           363:                        break;
1.1       deraadt   364:
1.21    ! ericj     365:                close(s);
        !           366:                s = -1;
        !           367:        } while ((res0 = res0->ai_next) != NULL);
1.1       deraadt   368:
1.21    ! ericj     369:        if (!uflag) {
        !           370:                if (listen(s, 1) < 0)
        !           371:                        errx(1, "%s", strerror(errno));
1.12      ericj     372:        }
1.1       deraadt   373:
1.21    ! ericj     374:        freeaddrinfo(res);
1.1       deraadt   375:
1.21    ! ericj     376:        return (s);
1.7       deraadt   377: }
                    378:
1.11      ericj     379: /*
1.21    ! ericj     380:  * readwrite()
        !           381:  * Loop that polls on the network file descriptor and stdin.
1.11      ericj     382:  */
1.21    ! ericj     383: void
        !           384: readwrite(nfd)
        !           385:        int nfd;
1.6       deraadt   386: {
1.21    ! ericj     387:        struct pollfd *pfd;
        !           388:        char buf[BUFSIZ];
        !           389:        int wfd = fileno(stdin), n, ret;
        !           390:        int lfd = fileno(stdout);
        !           391:
        !           392:        pfd = malloc(2 * sizeof(struct pollfd));
        !           393:
        !           394:        /* Setup Network FD */
        !           395:        pfd[0].fd = nfd;
        !           396:        pfd[0].events = POLLIN;
        !           397:
        !           398:        /* Setup STDIN FD */
        !           399:        pfd[1].fd = wfd;
        !           400:        pfd[1].events = POLLIN;
        !           401:
        !           402:        for (;;) {
        !           403:                if (iflag)
        !           404:                        sleep(iflag);
        !           405:
        !           406:                if (poll(pfd, 2, timeout) < 0) {
        !           407:                        close(nfd);
        !           408:                        close(wfd);
        !           409:                        free(pfd);
        !           410:                        errx(1, "Polling Error");
        !           411:                }
        !           412:
        !           413:                if (pfd[0].revents & POLLIN) {
        !           414:                        if ((n = read(nfd, buf, sizeof(buf))) <= 0) {
        !           415:                                return;
        !           416:                        } else {
        !           417:                                if (tflag)
        !           418:                                        atelnet(nfd, buf, n);
        !           419:                                if ((ret = atomicio(write, lfd, buf, n)) != n)
        !           420:                                        return;
1.6       deraadt   421:                        }
1.21    ! ericj     422:                }
        !           423:
        !           424:                if (pfd[1].revents & POLLIN) {
        !           425:                        if ((n = read(wfd, buf, sizeof(buf))) <= 0) {
        !           426:                                return;
        !           427:                        } else
        !           428:                                if((ret = atomicio(write, nfd, buf, n)) != n)
        !           429:                                        return;
        !           430:                }
1.11      ericj     431:        }
1.7       deraadt   432: }
                    433:
1.11      ericj     434: /*
                    435:  * Answer anything that looks like telnet negotiation with don't/won't.
                    436:  * This doesn't modify any data buffers, update the global output count,
                    437:  * or show up in a hexdump -- it just shits into the outgoing stream.
                    438:  * Idea and codebase from Mudge@l0pht.com.
                    439:  */
1.21    ! ericj     440: void
        !           441: atelnet(nfd, buf, size)
        !           442:        int nfd;
        !           443:        unsigned char *buf;
1.6       deraadt   444:        unsigned int size;
                    445: {
1.21    ! ericj     446:        static unsigned char obuf[4];
        !           447:        int x, ret;
1.11      ericj     448:        unsigned char y;
                    449:        unsigned char *p;
1.6       deraadt   450:
                    451:        y = 0;
                    452:        p = buf;
                    453:        x = size;
                    454:        while (x > 0) {
1.21    ! ericj     455:                if (*p != IAC)
1.6       deraadt   456:                        goto notiac;
1.21    ! ericj     457:                obuf[0] = IAC;
        !           458:                p++; x--;
        !           459:                if ((*p == WILL) || (*p == WONT))
        !           460:                        y = DONT;
        !           461:                if ((*p == DO) || (*p == DONT))
        !           462:                        y = WONT;
1.6       deraadt   463:                if (y) {
                    464:                        obuf[1] = y;
1.21    ! ericj     465:                        p++; x--;
1.11      ericj     466:                        obuf[2] = *p;
1.21    ! ericj     467:                        if ((ret = atomicio(write , nfd, obuf, 3)) != 3)
        !           468:                                warnx("Write Error!");
1.6       deraadt   469:                        y = 0;
1.11      ericj     470:                }
1.1       deraadt   471: notiac:
1.21    ! ericj     472:                p++; x--;
1.11      ericj     473:        }
1.7       deraadt   474: }
                    475:
1.11      ericj     476: /*
1.21    ! ericj     477:  * build_ports()
        !           478:  * Build an array or ports in portlist[], listing each port
        !           479:  * that we should try to connect too.
1.11      ericj     480:  */
1.21    ! ericj     481: void
        !           482: build_ports(p)
        !           483:        char *p;
1.6       deraadt   484: {
1.21    ! ericj     485:        char *n;
        !           486:        int hi, lo, cp;
        !           487:        int x = 0;
        !           488:
        !           489:        if ((n = strchr(p, '-')) != NULL) {
        !           490:                if (lflag)
        !           491:                        errx(1, "Cannot use -l with multiple ports!");
        !           492:
        !           493:                *n = '\0';
        !           494:                n++;
        !           495:
        !           496:                /* Make sure the ports are in order: lowest->highest */
        !           497:                hi = atoi(n);
        !           498:                lo = atoi(p);
        !           499:
        !           500:                if (lo > hi) {
        !           501:                        cp = hi;
        !           502:                        hi = lo;
        !           503:                        lo = cp;
        !           504:                }
        !           505:
        !           506:                /* Load ports sequentially */
        !           507:                for (cp = lo; cp <= hi; cp++) {
        !           508:                        portlist[x] = malloc(sizeof(65535));
        !           509:                        sprintf(portlist[x], "%d", cp);
        !           510:                        x++;
        !           511:                }
        !           512:
        !           513:                /* Randomly swap ports */
        !           514:                if (rflag) {
        !           515:                        int y;
        !           516:                        char *c;
        !           517:
        !           518:                        for (x = 0; x <= (hi - lo); x++) {
        !           519:                                y = (arc4random() & 0xFFFF) % (hi - lo);
        !           520:                                c = portlist[x];
        !           521:                                portlist[x] = portlist[y];
        !           522:                                portlist[y] = c;
1.6       deraadt   523:                        }
1.11      ericj     524:                }
1.21    ! ericj     525:        } else {
        !           526:                portlist[0] = malloc(sizeof(65535));
        !           527:                portlist[0] = p;
1.11      ericj     528:        }
1.13      ericj     529: }
                    530:
                    531: /*
1.21    ! ericj     532:  * udptest()
        !           533:  * Do a few writes to see if the UDP port is there.
        !           534:  * XXX - Better way of doing this? Doesn't work for IPv6
        !           535:  * Also fails after around 100 ports checked.
1.13      ericj     536:  */
1.21    ! ericj     537: int
        !           538: udptest(s)
        !           539:         int s;
1.13      ericj     540: {
1.21    ! ericj     541:        int i, rv, ret;
1.13      ericj     542:
1.21    ! ericj     543:        for (i=0; i <= 3; i++) {
        !           544:                if ((rv = write(s, "X", 1)) == 1)
        !           545:                        ret = 1;
1.14      ericj     546:                else
1.21    ! ericj     547:                        ret = -1;
1.14      ericj     548:        }
1.21    ! ericj     549:        return (ret);
1.7       deraadt   550: }
1.1       deraadt   551:
1.11      ericj     552: void
1.21    ! ericj     553: help()
1.1       deraadt   554: {
1.21    ! ericj     555:        usage(0);
        !           556:        fprintf(stderr, "\tCommand Summary:\n\
        !           557:        \t-4            Use IPv4\n\
        !           558:        \t-6            Use IPv6\n\
        !           559:        \t-h            This help text\n\
        !           560:        \t-i secs\t     Delay interval for lines sent, ports scanned\n\
        !           561:        \t-k            Keep inbound sockets open for multiple connects\n\
        !           562:        \t-l            Listen mode, for inbound connects\n\
        !           563:        \t-n            Surpress name/port resolutions\n\
        !           564:        \t-p            Specify local port for remote connects\n\
        !           565:        \t-r            Randomize remote ports\n\
        !           566:        \t-s addr\t     Local source address\n\
        !           567:        \t-t            Answer TELNET negotiation\n\
        !           568:        \t-u            UDP mode\n\
        !           569:        \t-v            Verbose\n\
        !           570:        \t-w secs\t     Timeout for connects and final net reads\n\
        !           571:        \t-z            Zero-I/O mode [used for scanning]\n\
        !           572:        Port numbers can be individual or ranges: lo-hi [inclusive]\n");
        !           573:        exit(1);
1.11      ericj     574: }
                    575:
                    576: void
1.21    ! ericj     577: usage(ret)
        !           578:        int ret;
1.11      ericj     579: {
1.21    ! ericj     580:        fprintf(stderr, "usage: nc [-46hklnrtuvz] [-i interval] [-p source port]\n");
        !           581:        fprintf(stderr, "\t  [-s ip address] [-w timeout] [hostname] [port[s...]]\n");
        !           582:        if (ret)
        !           583:                exit(1);
1.7       deraadt   584: }