start_stop_daemon: NOMMU fixes, round 2 by Alex Landau <landau_alex@yahoo.com>
[oweals/busybox.git] / networking / pscan.c
index 10bf3b606f78883f736deac91d3ab2650073924a..9eda16865bc3858d2d51478dbab7e8e19ae2d84e 100644 (file)
 #define DERR(...) ((void)0)
 #endif
 
-/* return time in usec */
-// TODO: move to libbb and use in traceroute, zcip, arping etc
-// (maybe also use absolute monotonic clock - no time warps
-// due to admin resetting date/time?)
-static unsigned gettimeofday_us(void)
-{
-       struct timeval now;
-       
-       if (gettimeofday(&now, NULL))
-               return 0;
-       return (now.tv_sec * 1000000 + now.tv_usec);
-}
-
 static const char *port_name(unsigned port)
 {
        struct servent *server;
@@ -40,18 +27,21 @@ static const char *port_name(unsigned port)
        return "unknown";
 }
 
+/* We don't expect to see 1000+ seconds delay, unsigned is enough */
+#define MONOTONIC_US() ((unsigned)monotonic_us())
+
 int pscan_main(int argc, char **argv);
 int pscan_main(int argc, char **argv)
 {
        const char *opt_max_port = "1024";      /* -P: default max port */
        const char *opt_min_port = "1";         /* -p: default min port */
-       const char *opt_timeout = "5000";       /* -t: default timeout */
-       /* We estimate rtt and wait rtt*4 before concluding that port is 
+       const char *opt_timeout = "5000";       /* -t: default timeout in msec */
+       /* We estimate rtt and wait rtt*4 before concluding that port is
         * totally blocked. min rtt of 5 ms may be too low if you are
         * scanning an Internet host behind saturated/traffic shaped link.
         * Rule of thumb: with min_rtt of N msec, scanning 1000 ports
         * will take N seconds at absolute minimum */
-       const char *opt_min_rtt = "5";          /* -T: default min rtt */
+       const char *opt_min_rtt = "5";          /* -T: default min rtt in msec */
        len_and_sockaddr *lsap;
        int s;
        unsigned port, max_port, nports;
@@ -67,10 +57,8 @@ int pscan_main(int argc, char **argv)
        getopt32(argc, argv, "p:P:t:T:", &opt_min_port, &opt_max_port, &opt_timeout, &opt_min_rtt);
        argv += optind;
        max_port = xatou_range(opt_max_port, 1, 65535);
-       port = xatou_range(opt_min_port, 1, 65535);
+       port = xatou_range(opt_min_port, 1, max_port);
        nports = max_port - port + 1;
-       if ((int)nports <= 0)
-               bb_show_usage();
        rtt_4 = timeout = xatou_range(opt_timeout, 1, INT_MAX/1000 / 4) * 1000;
        min_rtt = xatou_range(opt_min_rtt, 1, INT_MAX/1000 / 4) * 1000;
 
@@ -91,7 +79,7 @@ int pscan_main(int argc, char **argv)
                /* Nonblocking connect typically "fails" with errno == EINPROGRESS */
                ndelay_on(s);
                DMSG("connect to port %u", port);
-               start = gettimeofday_us();
+               start = MONOTONIC_US();
                if (connect(s, &lsap->sa, lsap->len) == 0) {
                        /* Unlikely, for me even localhost fails :) */
                        DMSG("connect succeeded");
@@ -110,15 +98,15 @@ int pscan_main(int argc, char **argv)
                                closed_ports++;
                                break;
                        }
-                       DERR("port %u errno %d @%u", port, errno, gettimeofday_us() - start);
-                       if ((gettimeofday_us() - start) > rtt_4)
+                       DERR("port %u errno %d @%u", port, errno, MONOTONIC_US() - start);
+                       if ((MONOTONIC_US() - start) > rtt_4)
                                break;
                        /* Can sleep (much) longer than specified delay.
                         * We check rtt BEFORE we usleep, otherwise
                         * on localhost we'll do zero writes done (!)
                         * before we exceed (rather small) rtt */
                        usleep(rtt_4/8);
-                       DMSG("write to port %u @%u", port, gettimeofday_us() - start);
+                       DMSG("write to port %u @%u", port, MONOTONIC_US() - start);
                        if (write(s, " ", 1) >= 0) { /* We were able to write to the socket */
  open:
                                open_ports++;
@@ -126,13 +114,13 @@ int pscan_main(int argc, char **argv)
                                break;
                        }
                }
-               DMSG("out of loop @%u", gettimeofday_us() - start);
+               DMSG("out of loop @%u", MONOTONIC_US() - start);
 
                /* Estimate new rtt - we don't want to wait entire timeout
                 * for each port. *4 allows for rise in net delay.
                 * We increase rtt quickly (*4), decrease slowly (4/8 == 1/2)
                 * because we don't want to accidentally miss ports. */
-               rtt_4 = (gettimeofday_us() - start) * 4;
+               rtt_4 = (MONOTONIC_US() - start) * 4;
                if (rtt_4 < min_rtt)
                        rtt_4 = min_rtt;
                if (rtt_4 > timeout)