home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / nmap254b.zip / timing.c < prev    next >
C/C++ Source or Header  |  2001-07-02  |  7KB  |  163 lines

  1.  
  2. /***********************************************************************/
  3. /* timing.c -- Functions related to computing scan timing (such as     */
  4. /* keeping track of and adjusting smoothed round trip times,           */
  5. /* statistical deviations, timeout values, etc.  Various user options  */
  6. /* (such as the timing policy (-T)) also play a role in these          */
  7. /* calculations                                                        */
  8. /*                                                                     */
  9. /***********************************************************************/
  10. /*  The Nmap Security Scanner is (C) 1995-2001 Insecure.Com LLC. This  */
  11. /*  program is free software; you can redistribute it and/or modify    */
  12. /*  it under the terms of the GNU General Public License as published  */
  13. /*  by the Free Software Foundation; Version 2.  This guarantees your  */
  14. /*  right to use, modify, and redistribute this software under certain */
  15. /*  conditions.  If this license is unacceptable to you, we may be     */
  16. /*  willing to sell alternative licenses (contact sales@insecure.com). */
  17. /*                                                                     */
  18. /*  If you received these files with a written license agreement       */
  19. /*  stating terms other than the (GPL) terms above, then that          */
  20. /*  alternative license agreement takes precendence over this comment. */
  21. /*                                                                     */
  22. /*  Source is provided to this software because we believe users have  */
  23. /*  a right to know exactly what a program is going to do before they  */
  24. /*  run it.  This also allows you to audit the software for security   */
  25. /*  holes (none have been found so far).                               */
  26. /*                                                                     */
  27. /*  Source code also allows you to port Nmap to new platforms, fix     */
  28. /*  bugs, and add new features.  You are highly encouraged to send     */
  29. /*  your changes to fyodor@insecure.org for possible incorporation     */
  30. /*  into the main distribution.  By sending these changes to Fyodor or */
  31. /*  one the insecure.org development mailing lists, it is assumed that */
  32. /*  you are offering Fyodor the unlimited, non-exclusive right to      */
  33. /*  reuse, modify, and relicense the code.  This is important because  */
  34. /*  the inability to relicense code has caused devastating problems    */
  35. /*  for other Free Software projects (such as KDE and NASM).  Nmap     */
  36. /*  will always be available Open Source.  If you wish to specify      */
  37. /*  special license conditions of your contributions, just say so      */
  38. /*  when you send them.                                                */
  39. /*                                                                     */
  40. /*  This program is distributed in the hope that it will be useful,    */
  41. /*  but WITHOUT ANY WARRANTY; without even the implied warranty of     */
  42. /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  */
  43. /*  General Public License for more details (                          */
  44. /*  http://www.gnu.org/copyleft/gpl.html ).                            */
  45. /*                                                                     */
  46. /***********************************************************************/
  47.  
  48. /* $Id: timing.c,v 1.3 2001/07/02 09:38:14 fyodor Exp $ */
  49.  
  50. #include "timing.h"
  51.  
  52. extern struct ops o;
  53.  
  54. /* Adjust our timeout values based on the time the latest probe took for a 
  55.    response.  We update our RTT averages, etc. */
  56. void adjust_timeouts(struct timeval sent, struct timeout_info *to) {
  57.   struct timeval received;
  58.   gettimeofday(&received, NULL);
  59.  
  60.   adjust_timeouts2(&sent, &received, to);
  61.   return;
  62. }
  63.  
  64. /* Same as adjust_timeouts(), except this one allows you to specify
  65.  the receive time too (which could be because it was received a while
  66.  back or it could be for efficiency because the caller already knows
  67.  the current time */
  68. void adjust_timeouts2(const struct timeval *sent, 
  69.               const struct timeval *received, 
  70.               struct timeout_info *to) {
  71.   int delta = 0;
  72.  
  73.   if (o.debugging > 1) {
  74.     log_write(LOG_STDOUT, "Timeout vals: srtt: %d rttvar: %d to: %d ", to->srtt, to->rttvar, to->timeout);
  75.   }
  76.   if (to->srtt == -1 && to->rttvar == -1) {
  77.     /* We need to initialize the sucker ... */
  78.     to->srtt = TIMEVAL_SUBTRACT(*received, *sent);
  79.     to->rttvar = MAX(5000, MIN(to->srtt, 2000000));
  80.     to->timeout = to->srtt + (to->rttvar << 2);
  81.   }
  82.   else {
  83.     delta = TIMEVAL_SUBTRACT(*received, *sent);
  84.     if (delta >= 8000000 || delta < 0) {
  85.       if (o.verbose)
  86.     error("adjust_timeout: packet supposedly had rtt of %lu microseconds.  Ignoring time.", delta);
  87.       return;
  88.     }
  89.     delta -= to->srtt;
  90.     /* sanity check 2*/
  91.     if (delta > 1500000 && delta > 3 * to->srtt + 2 * to->rttvar) {
  92.       /* WANKER ALERT! */
  93.       if (o.debugging) {
  94.     log_write(LOG_STDOUT, "Bogus delta: %d (srtt %d) ... ignoring\n", delta, to->srtt);
  95.       }
  96.       return;
  97.     }
  98.     to->srtt += delta >> 3;
  99.     to->rttvar += (ABS(delta) - to->rttvar) >> 2;
  100.     to->timeout = to->srtt + (to->rttvar << 2);  
  101.   }
  102.   if (to->rttvar > 2300000) {
  103.     fprintf(stderr, "RTTVAR has grown to over 2.3 seconds, decreasing to 2.0\n");
  104.     to->rttvar = 2000000;
  105.   }
  106.   
  107.   /* It hurts to do this ... it really does ... but otherwise we are being
  108.      too risky */
  109.   to->timeout = MAX(to->timeout, o.min_rtt_timeout * 1000);
  110.   to->timeout = MIN(to->timeout, o.max_rtt_timeout * 1000);
  111.  
  112.   if (o.scan_delay)
  113.     to->timeout = MAX(to->timeout, o.scan_delay * 1000);
  114.  
  115.   if (o.debugging > 1) {
  116.     log_write(LOG_STDOUT, "delta %d ==> srtt: %d rttvar: %d to: %d\n", delta, to->srtt, to->rttvar, to->timeout);
  117.   }
  118.  
  119.   if (to->srtt < 0 || to->rttvar < 0 || to->timeout < 0 || delta < -50000000) {
  120.     fatal("Serious time computation problem in adjust_timeout ... received = (%d, %d) sent=(%d,%d) delta = %d srtt = %d rttvar = %d to = %d", received->tv_sec, received->tv_usec, sent->tv_sec, sent->tv_usec, delta, to->srtt, to->rttvar, to->timeout);
  121.   }
  122. }
  123.  
  124. /* Sleeps if necessary to ensure that it isn't called twice withen less
  125.    time than o.send_delay.  If it is passed a non-null tv, the POST-SLEEP
  126.    time is recorded in it */
  127. void enforce_scan_delay(struct timeval *tv) {
  128.   static int init = -1;
  129.   static struct timeval lastcall;
  130.   struct timeval now;
  131.   int time_diff;
  132.  
  133.   if (!o.scan_delay) {
  134.     if (tv) gettimeofday(tv, NULL);
  135.     return;
  136.   }
  137.  
  138.   if (init == -1) {
  139.     gettimeofday(&lastcall, NULL);
  140.     init = 0;
  141.     if (tv)
  142.       memcpy(tv, &lastcall, sizeof(struct timeval));
  143.     return;
  144.   }
  145.  
  146.   gettimeofday(&now, NULL);
  147.   time_diff = TIMEVAL_MSEC_SUBTRACT(now, lastcall);
  148.   if (time_diff < o.scan_delay) {  
  149.     if (o.debugging > 1) {
  150.       printf("Sleeping for %d milliseconds in enforce_scan_delay()\n", o.scan_delay - time_diff);
  151.     }
  152.     usleep((o.scan_delay - time_diff) * 1000);
  153.     gettimeofday(&lastcall, NULL);
  154.   } else
  155.     memcpy(&lastcall, &now, sizeof(struct timeval));
  156.   if (tv) {
  157.     memcpy(tv, &lastcall, sizeof(struct timeval));
  158.   }
  159.  
  160.   return;    
  161. }
  162.  
  163.