Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/networking/nc_bloaty.c

    r1765 r2725  
    22 * Released into public domain by the author.
    33 *
    4  * Copyright (C) 2007 Denis Vlasenko.
     4 * Copyright (C) 2007 Denys Vlasenko.
    55 *
    6  * Licensed under GPLv2, see file LICENSE in this tarball for details.
     6 * Licensed under GPLv2, see file LICENSE in this source tree.
    77 */
    88
     
    3737 * - multiple DNS checks
    3838 * Functionalty which is different from nc 1.10:
    39  * - Prog in '-e prog' can have prog's parameters and options.
     39 * - PROG in '-e PROG' can have ARGS (and options).
    4040 *   Because of this -e option must be last.
    41  * - nc doesn't redirect stderr to the network socket for the -e prog.
     41//TODO: remove -e incompatibility?
     42 * - we don't redirect stderr to the network socket for the -e PROG.
     43 *   (PROG can do it itself if needed, but sometimes it is NOT wanted!)
    4244 * - numeric addresses are printed in (), not [] (IPv6 looks better),
    4345 *   port numbers are inside (): (1.2.3.4:5678)
     
    4648 * - TCP connects from wrong ip/ports (if peer ip:port is specified
    4749 *   on the command line, but accept() says that it came from different addr)
    48  *   are closed, but nc doesn't exit - continues to listen/accept.
     50 *   are closed, but we don't exit - we continue to listen/accept.
    4951 */
    5052
    5153/* done in nc.c: #include "libbb.h" */
     54
     55//usage:#if ENABLE_NC_110_COMPAT
     56//usage:
     57//usage:#define nc_trivial_usage
     58//usage:       "[OPTIONS] HOST PORT  - connect"
     59//usage:    IF_NC_SERVER("\n"
     60//usage:       "nc [OPTIONS] -l -p PORT [HOST] [PORT]  - listen"
     61//usage:    )
     62//usage:#define nc_full_usage "\n\n"
     63//usage:       "Options:"
     64//usage:     "\n    -e PROG Run PROG after connect (must be last)"
     65//usage:    IF_NC_SERVER(
     66//usage:     "\n    -l  Listen mode, for inbound connects"
     67//usage:    )
     68//usage:     "\n    -p PORT Local port"
     69//usage:     "\n    -s ADDR Local address"
     70//usage:     "\n    -w SEC  Timeout for connects and final net reads"
     71//usage:    IF_NC_EXTRA(
     72//usage:     "\n    -i SEC  Delay interval for lines sent" /* ", ports scanned" */
     73//usage:    )
     74//usage:     "\n    -n  Don't do DNS resolution"
     75//usage:     "\n    -u  UDP mode"
     76//usage:     "\n    -v  Verbose"
     77//usage:    IF_NC_EXTRA(
     78//usage:     "\n    -o FILE Hex dump traffic"
     79//usage:     "\n    -z  Zero-I/O mode (scanning)"
     80//usage:    )
     81//usage:#endif
     82
     83/*   "\n    -r      Randomize local and remote ports" */
     84/*   "\n    -g gateway  Source-routing hop point[s], up to 8" */
     85/*   "\n    -G num      Source-routing pointer: 4, 8, 12, ..." */
     86/*   "\nport numbers can be individual or ranges: lo-hi [inclusive]" */
     87
     88/* -e PROG can take ARGS too: "nc ... -e ls -l", but we don't document it
     89 * in help text: nc 1.10 does not allow that. We don't want to entice
     90 * users to use this incompatibility */
    5291
    5392enum {
     
    78117    unsigned wrote_net;          /* total net bytes */
    79118#endif
    80     /* ouraddr is never NULL and goes thru three states as we progress:
     119    /* ouraddr is never NULL and goes through three states as we progress:
    81120     1 - local address before bind (IP/port possibly zero)
    82121     2 - local address after bind (port is nonzero)
     
    98137
    99138#define G (*ptr_to_globals)
    100 
    101139#define wrote_out  (G.wrote_out )
    102140#define wrote_net  (G.wrote_net )
     
    116154#define o_interval 0
    117155#endif
     156#define INIT_G() do { \
     157    SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
     158} while (0)
     159
    118160
    119161/* Must match getopt32 call! */
     
    150192/* Beware: writes to stdOUT... */
    151193#if 0
    152 #define Debug(...) do { printf(__VA_ARGS__); printf("\n"); fflush(stdout); sleep(1); } while (0)
     194#define Debug(...) do { printf(__VA_ARGS__); printf("\n"); fflush_all(); sleep(1); } while (0)
    153195#else
    154196#define Debug(...) do { } while (0)
     
    164206        fprintf(stderr, SENT_N_RECV_M, wrote_net, wrote_out);
    165207    fprintf(stderr, "punt!\n");
    166     exit(1);
     208    kill_myself_with_sig(sig);
    167209}
    168210
     
    175217
    176218/* timeout and other signal handling cruft */
    177 static void tmtravel(int sig)
     219static void tmtravel(int sig UNUSED_PARAM)
    178220{
    179221    unarm();
     
    220262 Use at your own hairy risk; if you leave shells lying around behind open
    221263 listening ports you deserve to lose!! */
    222 static int doexec(char **proggie) ATTRIBUTE_NORETURN;
     264static int doexec(char **proggie) NORETURN;
    223265static int doexec(char **proggie)
    224266{
     
    228270     * exec'ed prog can do it yourself, if needed */
    229271    execvp(proggie[0], proggie);
    230     bb_perror_msg_and_die("exec");
     272    bb_perror_msg_and_die("can't execute '%s'", proggie[0]);
    231273}
    232274
     
    244286    arm(o_wait);
    245287    if (setjmp(jbuf) == 0) {
    246         rr = connect(fd, &themaddr->sa, themaddr->len);
     288        rr = connect(fd, &themaddr->u.sa, themaddr->len);
    247289        unarm();
    248290    } else { /* setjmp: connect failed... */
     
    276318    if (o_verbose) {
    277319        char *addr;
    278         rr = getsockname(netfd, &ouraddr->sa, &ouraddr->len);
    279         if (rr < 0)
    280             bb_perror_msg_and_die("getsockname after bind");
    281         addr = xmalloc_sockaddr2dotted(&ouraddr->sa);
     320        getsockname(netfd, &ouraddr->u.sa, &ouraddr->len);
     321        //if (rr < 0)
     322        //  bb_perror_msg_and_die("getsockname after bind");
     323        addr = xmalloc_sockaddr2dotted(&ouraddr->u.sa);
    282324        fprintf(stderr, "listening on %s ...\n", addr);
    283325        free(addr);
     
    307349        if (themaddr) {
    308350            remend = *themaddr;
    309             xconnect(netfd, &themaddr->sa, themaddr->len);
     351            xconnect(netfd, &themaddr->u.sa, themaddr->len);
    310352        }
    311353        /* peek first packet and remember peer addr */
     
    315357            /* and here we block... */
    316358            rr = recv_from_to(netfd, NULL, 0, MSG_PEEK, /*was bigbuf_net, BIGSIZ*/
    317                 &remend.sa, &ouraddr->sa, ouraddr->len);
     359                &remend.u.sa, &ouraddr->u.sa, ouraddr->len);
    318360            if (rr < 0)
    319361                bb_perror_msg_and_die("recvfrom");
     
    324366our socket on it, so that our outbound packets will have correct local IP.
    325367Unfortunately, bind() on already bound socket will fail now (EINVAL):
    326     xbind(netfd, &ouraddr->sa, ouraddr->len);
     368    xbind(netfd, &ouraddr->u.sa, ouraddr->len);
    327369Need to read the packet, save data, close this socket and
    328370create new one, and bind() it. TODO */
    329371        if (!themaddr)
    330             xconnect(netfd, &remend.sa, ouraddr->len);
     372            xconnect(netfd, &remend.u.sa, ouraddr->len);
    331373    } else {
    332374        /* TCP */
     
    335377 again:
    336378            remend.len = LSA_SIZEOF_SA;
    337             rr = accept(netfd, &remend.sa, &remend.len);
     379            rr = accept(netfd, &remend.u.sa, &remend.len);
    338380            if (rr < 0)
    339381                bb_perror_msg_and_die("accept");
    340             if (themaddr && memcmp(&remend.sa, &themaddr->sa, remend.len) != 0) {
    341                 /* nc 1.10 bails out instead, and its error message
    342                  * is not suppressed by o_verbose */
    343                 if (o_verbose) {
    344                     char *remaddr = xmalloc_sockaddr2dotted(&remend.sa);
    345                     bb_error_msg("connect from wrong ip/port %s ignored", remaddr);
    346                     free(remaddr);
     382            if (themaddr) {
     383                int sv_port, port, r;
     384
     385                sv_port = get_nport(&remend.u.sa); /* save */
     386                port = get_nport(&themaddr->u.sa);
     387                if (port == 0) {
     388                    /* "nc -nl -p LPORT RHOST" (w/o RPORT!):
     389                     * we should accept any remote port */
     390                    set_nport(&remend, 0); /* blot out remote port# */
    347391                }
    348                 close(rr);
    349                 goto again;
     392                r = memcmp(&remend.u.sa, &themaddr->u.sa, remend.len);
     393                set_nport(&remend, sv_port); /* restore */
     394                if (r != 0) {
     395                    /* nc 1.10 bails out instead, and its error message
     396                     * is not suppressed by o_verbose */
     397                    if (o_verbose) {
     398                        char *remaddr = xmalloc_sockaddr2dotted(&remend.u.sa);
     399                        bb_error_msg("connect from wrong ip/port %s ignored", remaddr);
     400                        free(remaddr);
     401                    }
     402                    close(rr);
     403                    goto again;
     404                }
    350405            }
    351406            unarm();
     
    357412         offer different services via different alias addresses, such as the
    358413         "virtual web site" hack. */
    359         rr = getsockname(netfd, &ouraddr->sa, &ouraddr->len);
    360         if (rr < 0)
    361             bb_perror_msg_and_die("getsockname after accept");
     414        getsockname(netfd, &ouraddr->u.sa, &ouraddr->len);
     415        //if (rr < 0)
     416        //  bb_perror_msg_and_die("getsockname after accept");
    362417    }
    363418
     
    372427     any machines I've tested, but feel free to surprise me. */
    373428        char optbuf[40];
    374         int x = sizeof(optbuf);
     429        socklen_t x = sizeof(optbuf);
    375430
    376431        rr = getsockopt(netfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x);
    377         if (rr < 0)
    378             bb_perror_msg("getsockopt failed");
    379         else if (x) {    /* we've got options, lessee em... */
     432        if (rr >= 0 && x) {    /* we've got options, lessee em... */
    380433            bin2hex(bigbuf_net, optbuf, x);
    381434            bigbuf_net[2*x] = '\0';
     
    394447     In other words, we need a TCP MSG_PEEK. */
    395448    /* bbox: removed most of it */
    396         lcladdr = xmalloc_sockaddr2dotted(&ouraddr->sa);
    397         remaddr = xmalloc_sockaddr2dotted(&remend.sa);
    398         remhostname = o_nflag ? remaddr : xmalloc_sockaddr2host(&remend.sa);
     449        lcladdr = xmalloc_sockaddr2dotted(&ouraddr->u.sa);
     450        remaddr = xmalloc_sockaddr2dotted(&remend.u.sa);
     451        remhostname = o_nflag ? remaddr : xmalloc_sockaddr2host(&remend.u.sa);
    399452        fprintf(stderr, "connect to %s from %s (%s)\n",
    400453                lcladdr, remhostname, remaddr);
     
    434487     us to hang forever, and hit it */
    435488        o_wait = 5;                     /* enough that we'll notice?? */
    436         rr = xsocket(ouraddr->sa.sa_family, SOCK_STREAM, 0);
     489        rr = xsocket(ouraddr->u.sa.sa_family, SOCK_STREAM, 0);
    437490        set_nport(themaddr, htons(SLEAZE_PORT));
    438491        connect_w_timeout(rr);
     
    485538            x = bc;
    486539        }
    487         sprintf(&stage[1], " %8.8x ", obc);  /* xxx: still slow? */
     540        sprintf((char *)&stage[1], " %8.8x ", obc);  /* xxx: still slow? */
    488541        bc -= x;          /* fix current count */
    489542        obc += x;         /* fix current offset */
     
    560613     from the net during that time, assume it's dead and close it too. */
    561614        if (rr == 0) {
    562             if (!FD_ISSET(0, &ding1))
     615            if (!FD_ISSET(STDIN_FILENO, &ding1))
    563616                netretry--;                        /* we actually try a coupla times. */
    564617            if (!netretry) {
     
    595648
    596649    /* okay, suck more stdin */
    597         if (FD_ISSET(0, &ding2)) {                /* stdin: ding! */
    598             rr = read(0, bigbuf_in, BIGSIZ);
     650        if (FD_ISSET(STDIN_FILENO, &ding2)) {                /* stdin: ding! */
     651            rr = read(STDIN_FILENO, bigbuf_in, BIGSIZ);
    599652    /* Considered making reads here smaller for UDP mode, but 8192-byte
    600653     mobygrams are kinda fun and exercise the reassembler. */
    601654            if (rr <= 0) {                        /* at end, or fukt, or ... */
    602                 FD_CLR(0, &ding1);                /* disable and close stdin */
    603                 close(0);
     655                FD_CLR(STDIN_FILENO, &ding1);                /* disable and close stdin */
     656                close(STDIN_FILENO);
     657// Does it make sense to shutdown(net_fd, SHUT_WR)
     658// to let other side know that we won't write anything anymore?
     659// (and what about keeping compat if we do that?)
    604660            } else {
    605661                rzleft = rr;
     
    623679        }
    624680        if (rnleft) {
    625             rr = write(1, np, rnleft);
     681            rr = write(STDOUT_FILENO, np, rnleft);
    626682            if (rr > 0) {
    627                 if (o_ofile)
    628                     oprint('<', np, rr);                /* log the stdout */
     683                if (o_ofile) /* log the stdout */
     684                    oprint('<', (unsigned char *)np, rr);
    629685                np += rr;                        /* fix up ptrs and whatnot */
    630686                rnleft -= rr;                        /* will get sanity-checked above */
     
    640696            rr = write(netfd, zp, rr);        /* one line, or the whole buffer */
    641697            if (rr > 0) {
    642                 if (o_ofile)
    643                     oprint('>', zp, rr);                /* log what got sent */
     698                if (o_ofile) /* log what got sent */
     699                    oprint('>', (unsigned char *)zp, rr);
    644700                zp += rr;
    645701                rzleft -= rr;
     
    669725
    670726/* main: now we pull it all together... */
    671 int nc_main(int argc, char **argv);
    672 int nc_main(int argc, char **argv)
    673 {
    674     char *str_p, *str_s, *str_w;
    675     USE_NC_EXTRA(char *str_i, *str_o;)
     727int nc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     728int nc_main(int argc UNUSED_PARAM, char **argv)
     729{
     730    char *str_p, *str_s;
     731    IF_NC_EXTRA(char *str_i, *str_o;)
    676732    char *themdotted = themdotted; /* gcc */
    677733    char **proggie;
     
    679735    unsigned o_lport = 0;
    680736
    681     /* I was in this barbershop quartet in Skokie IL ... */
    682     /* round up the usual suspects, i.e. malloc up all the stuff we need */
    683     PTR_TO_GLOBALS = xzalloc(sizeof(G));
     737    INIT_G();
    684738
    685739    /* catch a signal or two for cleanup */
    686     signal(SIGINT, catch);
    687     signal(SIGQUIT, catch);
    688     signal(SIGTERM, catch);
     740    bb_signals(0
     741        + (1 << SIGINT)
     742        + (1 << SIGQUIT)
     743        + (1 << SIGTERM)
     744        , catch);
    689745    /* and suppress others... */
     746    bb_signals(0
    690747#ifdef SIGURG
    691     signal(SIGURG, SIG_IGN);
    692 #endif
    693     signal(SIGPIPE, SIG_IGN); /* important! */
     748        + (1 << SIGURG)
     749#endif
     750        + (1 << SIGPIPE) /* important! */
     751        , SIG_IGN);
    694752
    695753    proggie = argv;
     
    697755        if (strcmp(*proggie, "-e") == 0) {
    698756            *proggie = NULL;
    699             argc = proggie - argv;
    700757            proggie++;
    701758            goto e_found;
     
    706763
    707764    // -g -G -t -r deleted, unimplemented -a deleted too
    708     opt_complementary = "?2:vv"; /* max 2 params, -v is a counter */
    709     getopt32(argv, "hnp:s:uvw:" USE_NC_SERVER("l")
    710             USE_NC_EXTRA("i:o:z"),
    711             &str_p, &str_s, &str_w
    712             USE_NC_EXTRA(, &str_i, &str_o, &o_verbose));
     765    opt_complementary = "?2:vv:w+"; /* max 2 params; -v is a counter; -w N */
     766    getopt32(argv, "hnp:s:uvw:" IF_NC_SERVER("l")
     767            IF_NC_EXTRA("i:o:z"),
     768            &str_p, &str_s, &o_wait
     769            IF_NC_EXTRA(, &str_i, &str_o), &o_verbose);
    713770    argv += optind;
    714771#if ENABLE_NC_EXTRA
     
    727784    //if (option_mask32 & OPT_u) /* use UDP */
    728785    //if (option_mask32 & OPT_v) /* verbose */
    729     if (option_mask32 & OPT_w) { /* wait time */
    730         o_wait = xatoi_u(str_w);
    731     }
     786    //if (option_mask32 & OPT_w) /* wait time */
    732787    //if (option_mask32 & OPT_z) /* little or no data xfer */
    733788
     
    747802        /* if o_lport is still 0, then we will use random port */
    748803        ouraddr = xhost2sockaddr(str_s, o_lport);
    749         x = xsocket(ouraddr->sa.sa_family, x, 0);
     804#ifdef BLOAT
     805        /* prevent spurious "UDP listen needs !0 port" */
     806        o_lport = get_nport(ouraddr);
     807        o_lport = ntohs(o_lport);
     808#endif
     809        x = xsocket(ouraddr->u.sa.sa_family, x, 0);
    750810    } else {
    751811        /* We try IPv6, then IPv4, unless addr family is
    752812         * implicitly set by way of remote addr/port spec */
    753813        x = xsocket_type(&ouraddr,
    754                 USE_FEATURE_IPV6((themaddr ? themaddr->sa.sa_family : AF_UNSPEC),)
     814                (themaddr ? themaddr->u.sa.sa_family : AF_UNSPEC),
    755815                x);
    756816        if (o_lport)
     
    761821    if (o_udpmode)
    762822        socket_want_pktinfo(netfd);
    763     xbind(netfd, &ouraddr->sa, ouraddr->len);
     823    if (!ENABLE_FEATURE_UNIX_LOCAL
     824     || o_listen
     825     || ouraddr->u.sa.sa_family != AF_UNIX
     826    ) {
     827        xbind(netfd, &ouraddr->u.sa, ouraddr->len);
     828    }
    764829#if 0
    765830    setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf);
     
    767832#endif
    768833
     834#ifdef BLOAT
    769835    if (OPT_l && (option_mask32 & (OPT_u|OPT_l)) == (OPT_u|OPT_l)) {
    770836        /* apparently UDP can listen ON "port 0",
     
    773839            bb_error_msg_and_die("UDP listen needs nonzero -p port");
    774840    }
    775 
    776     FD_SET(0, &ding1);                        /* stdin *is* initially open */
     841#endif
     842
     843    FD_SET(STDIN_FILENO, &ding1);                        /* stdin *is* initially open */
    777844    if (proggie) {
    778845        close(0); /* won't need stdin */
     
    793860        /* Outbound connects.  Now we're more picky about args... */
    794861        if (!themaddr)
    795             bb_error_msg_and_die("no destination");
     862            bb_show_usage();
    796863
    797864        remend = *themaddr;
    798865        if (o_verbose)
    799             themdotted = xmalloc_sockaddr2dotted(&themaddr->sa);
     866            themdotted = xmalloc_sockaddr2dotted(&themaddr->u.sa);
    800867
    801868        x = connect_w_timeout(netfd);
Note: See TracChangeset for help on using the changeset viewer.