Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/networking/nc_bloaty.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/networking/nc_bloaty.c
r1765 r2725 2 2 * Released into public domain by the author. 3 3 * 4 * Copyright (C) 2007 Den is Vlasenko.4 * Copyright (C) 2007 Denys Vlasenko. 5 5 * 6 * Licensed under GPLv2, see file LICENSE in this tarball for details.6 * Licensed under GPLv2, see file LICENSE in this source tree. 7 7 */ 8 8 … … 37 37 * - multiple DNS checks 38 38 * Functionalty which is different from nc 1.10: 39 * - P rog in '-e prog' can have prog's parameters and options.39 * - PROG in '-e PROG' can have ARGS (and options). 40 40 * 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!) 42 44 * - numeric addresses are printed in (), not [] (IPv6 looks better), 43 45 * port numbers are inside (): (1.2.3.4:5678) … … 46 48 * - TCP connects from wrong ip/ports (if peer ip:port is specified 47 49 * on the command line, but accept() says that it came from different addr) 48 * are closed, but nc doesn't exit - continuesto listen/accept.50 * are closed, but we don't exit - we continue to listen/accept. 49 51 */ 50 52 51 53 /* 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 */ 52 91 53 92 enum { … … 78 117 unsigned wrote_net; /* total net bytes */ 79 118 #endif 80 /* ouraddr is never NULL and goes thr uthree states as we progress:119 /* ouraddr is never NULL and goes through three states as we progress: 81 120 1 - local address before bind (IP/port possibly zero) 82 121 2 - local address after bind (port is nonzero) … … 98 137 99 138 #define G (*ptr_to_globals) 100 101 139 #define wrote_out (G.wrote_out ) 102 140 #define wrote_net (G.wrote_net ) … … 116 154 #define o_interval 0 117 155 #endif 156 #define INIT_G() do { \ 157 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 158 } while (0) 159 118 160 119 161 /* Must match getopt32 call! */ … … 150 192 /* Beware: writes to stdOUT... */ 151 193 #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) 153 195 #else 154 196 #define Debug(...) do { } while (0) … … 164 206 fprintf(stderr, SENT_N_RECV_M, wrote_net, wrote_out); 165 207 fprintf(stderr, "punt!\n"); 166 exit(1);208 kill_myself_with_sig(sig); 167 209 } 168 210 … … 175 217 176 218 /* timeout and other signal handling cruft */ 177 static void tmtravel(int sig )219 static void tmtravel(int sig UNUSED_PARAM) 178 220 { 179 221 unarm(); … … 220 262 Use at your own hairy risk; if you leave shells lying around behind open 221 263 listening ports you deserve to lose!! */ 222 static int doexec(char **proggie) ATTRIBUTE_NORETURN;264 static int doexec(char **proggie) NORETURN; 223 265 static int doexec(char **proggie) 224 266 { … … 228 270 * exec'ed prog can do it yourself, if needed */ 229 271 execvp(proggie[0], proggie); 230 bb_perror_msg_and_die(" exec");272 bb_perror_msg_and_die("can't execute '%s'", proggie[0]); 231 273 } 232 274 … … 244 286 arm(o_wait); 245 287 if (setjmp(jbuf) == 0) { 246 rr = connect(fd, &themaddr-> sa, themaddr->len);288 rr = connect(fd, &themaddr->u.sa, themaddr->len); 247 289 unarm(); 248 290 } else { /* setjmp: connect failed... */ … … 276 318 if (o_verbose) { 277 319 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); 282 324 fprintf(stderr, "listening on %s ...\n", addr); 283 325 free(addr); … … 307 349 if (themaddr) { 308 350 remend = *themaddr; 309 xconnect(netfd, &themaddr-> sa, themaddr->len);351 xconnect(netfd, &themaddr->u.sa, themaddr->len); 310 352 } 311 353 /* peek first packet and remember peer addr */ … … 315 357 /* and here we block... */ 316 358 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); 318 360 if (rr < 0) 319 361 bb_perror_msg_and_die("recvfrom"); … … 324 366 our socket on it, so that our outbound packets will have correct local IP. 325 367 Unfortunately, bind() on already bound socket will fail now (EINVAL): 326 xbind(netfd, &ouraddr-> sa, ouraddr->len);368 xbind(netfd, &ouraddr->u.sa, ouraddr->len); 327 369 Need to read the packet, save data, close this socket and 328 370 create new one, and bind() it. TODO */ 329 371 if (!themaddr) 330 xconnect(netfd, &remend. sa, ouraddr->len);372 xconnect(netfd, &remend.u.sa, ouraddr->len); 331 373 } else { 332 374 /* TCP */ … … 335 377 again: 336 378 remend.len = LSA_SIZEOF_SA; 337 rr = accept(netfd, &remend. sa, &remend.len);379 rr = accept(netfd, &remend.u.sa, &remend.len); 338 380 if (rr < 0) 339 381 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# */ 347 391 } 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 } 350 405 } 351 406 unarm(); … … 357 412 offer different services via different alias addresses, such as the 358 413 "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"); 362 417 } 363 418 … … 372 427 any machines I've tested, but feel free to surprise me. */ 373 428 char optbuf[40]; 374 int x = sizeof(optbuf);429 socklen_t x = sizeof(optbuf); 375 430 376 431 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... */ 380 433 bin2hex(bigbuf_net, optbuf, x); 381 434 bigbuf_net[2*x] = '\0'; … … 394 447 In other words, we need a TCP MSG_PEEK. */ 395 448 /* 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); 399 452 fprintf(stderr, "connect to %s from %s (%s)\n", 400 453 lcladdr, remhostname, remaddr); … … 434 487 us to hang forever, and hit it */ 435 488 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); 437 490 set_nport(themaddr, htons(SLEAZE_PORT)); 438 491 connect_w_timeout(rr); … … 485 538 x = bc; 486 539 } 487 sprintf( &stage[1], " %8.8x ", obc); /* xxx: still slow? */540 sprintf((char *)&stage[1], " %8.8x ", obc); /* xxx: still slow? */ 488 541 bc -= x; /* fix current count */ 489 542 obc += x; /* fix current offset */ … … 560 613 from the net during that time, assume it's dead and close it too. */ 561 614 if (rr == 0) { 562 if (!FD_ISSET( 0, &ding1))615 if (!FD_ISSET(STDIN_FILENO, &ding1)) 563 616 netretry--; /* we actually try a coupla times. */ 564 617 if (!netretry) { … … 595 648 596 649 /* 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); 599 652 /* Considered making reads here smaller for UDP mode, but 8192-byte 600 653 mobygrams are kinda fun and exercise the reassembler. */ 601 654 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?) 604 660 } else { 605 661 rzleft = rr; … … 623 679 } 624 680 if (rnleft) { 625 rr = write( 1, np, rnleft);681 rr = write(STDOUT_FILENO, np, rnleft); 626 682 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); 629 685 np += rr; /* fix up ptrs and whatnot */ 630 686 rnleft -= rr; /* will get sanity-checked above */ … … 640 696 rr = write(netfd, zp, rr); /* one line, or the whole buffer */ 641 697 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); 644 700 zp += rr; 645 701 rzleft -= rr; … … 669 725 670 726 /* 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;)727 int nc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 728 int nc_main(int argc UNUSED_PARAM, char **argv) 729 { 730 char *str_p, *str_s; 731 IF_NC_EXTRA(char *str_i, *str_o;) 676 732 char *themdotted = themdotted; /* gcc */ 677 733 char **proggie; … … 679 735 unsigned o_lport = 0; 680 736 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(); 684 738 685 739 /* 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); 689 745 /* and suppress others... */ 746 bb_signals(0 690 747 #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); 694 752 695 753 proggie = argv; … … 697 755 if (strcmp(*proggie, "-e") == 0) { 698 756 *proggie = NULL; 699 argc = proggie - argv;700 757 proggie++; 701 758 goto e_found; … … 706 763 707 764 // -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_w712 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); 713 770 argv += optind; 714 771 #if ENABLE_NC_EXTRA … … 727 784 //if (option_mask32 & OPT_u) /* use UDP */ 728 785 //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 */ 732 787 //if (option_mask32 & OPT_z) /* little or no data xfer */ 733 788 … … 747 802 /* if o_lport is still 0, then we will use random port */ 748 803 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); 750 810 } else { 751 811 /* We try IPv6, then IPv4, unless addr family is 752 812 * implicitly set by way of remote addr/port spec */ 753 813 x = xsocket_type(&ouraddr, 754 USE_FEATURE_IPV6((themaddr ? themaddr->sa.sa_family : AF_UNSPEC),)814 (themaddr ? themaddr->u.sa.sa_family : AF_UNSPEC), 755 815 x); 756 816 if (o_lport) … … 761 821 if (o_udpmode) 762 822 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 } 764 829 #if 0 765 830 setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf); … … 767 832 #endif 768 833 834 #ifdef BLOAT 769 835 if (OPT_l && (option_mask32 & (OPT_u|OPT_l)) == (OPT_u|OPT_l)) { 770 836 /* apparently UDP can listen ON "port 0", … … 773 839 bb_error_msg_and_die("UDP listen needs nonzero -p port"); 774 840 } 775 776 FD_SET(0, &ding1); /* stdin *is* initially open */ 841 #endif 842 843 FD_SET(STDIN_FILENO, &ding1); /* stdin *is* initially open */ 777 844 if (proggie) { 778 845 close(0); /* won't need stdin */ … … 793 860 /* Outbound connects. Now we're more picky about args... */ 794 861 if (!themaddr) 795 bb_ error_msg_and_die("no destination");862 bb_show_usage(); 796 863 797 864 remend = *themaddr; 798 865 if (o_verbose) 799 themdotted = xmalloc_sockaddr2dotted(&themaddr-> sa);866 themdotted = xmalloc_sockaddr2dotted(&themaddr->u.sa); 800 867 801 868 x = connect_w_timeout(netfd);
Note:
See TracChangeset
for help on using the changeset viewer.