@@ -39,6 +39,8 @@ static uint32_t scan_randomness;
3939static atomic_uint pkts_sent , pkts_recv ;
4040static atomic_uchar status_bits ;
4141
42+ static atomic_int_least64_t time_mono_offset ; // us offset
43+
4244static inline int source_port_rand (void );
4345static void * send_thread_tcp (void * unused );
4446static void * send_thread_udp (void * unused );
@@ -77,6 +79,23 @@ void scan_set_output(FILE *_outfile, const struct outputdef *_outdef)
7779 memcpy (& outdef , _outdef , sizeof (struct outputdef ));
7880}
7981
82+ static void update_time_mono_offset (void )
83+ {
84+ if (ip_type != IP_TYPE_ICMPV6 )
85+ return ;
86+ struct timespec real ;
87+ clock_gettime (CLOCK_REALTIME , & real );
88+ int_least64_t val = ((real .tv_sec * 1000000 ) + real .tv_nsec / 1000 ) -
89+ monotonic_us ();
90+
91+ int_least64_t old = atomic_exchange (& time_mono_offset , val );
92+ if (old ) {
93+ val = old > val ? (old - val ) : (val - old );
94+ if (val >= 384 )
95+ log_warning ("Detected clock drift of %dus" , (int )val );
96+ }
97+ }
98+
8099int scan_main (const char * interface , int quiet )
81100{
82101 if (rawsock_open (interface , 65535 ) < 0 )
@@ -85,6 +104,7 @@ int scan_main(const char *interface, int quiet)
85104 atomic_store (& pkts_sent , 0 );
86105 atomic_store (& pkts_recv , 0 );
87106 atomic_store (& status_bits , 0 );
107+ update_time_mono_offset ();
88108 if (banners && ip_type == IP_TYPE_TCP ) {
89109 if (scan_responder_init (outfile , & outdef , source_port ) < 0 )
90110 goto err ;
@@ -128,6 +148,7 @@ int scan_main(const char *interface, int quiet)
128148 unsigned int cur_sent , cur_recv ;
129149 cur_sent = atomic_exchange (& pkts_sent , 0 );
130150 cur_recv = atomic_exchange (& pkts_recv , 0 );
151+ update_time_mono_offset ();
131152 if (!quiet ) {
132153 float progress = target_gen_progress ();
133154 if (progress < 0.0f )
@@ -364,9 +385,9 @@ static void recv_handler(uint64_t ts, int len, const uint8_t *packet)
364385
365386 // handle
366387 if (ip_type == IP_TYPE_TCP )
367- recv_handler_tcp (ts , len , packet , csrcaddr );
388+ recv_handler_tcp (ts / 1000000 , len , packet , csrcaddr );
368389 else if (ip_type == IP_TYPE_UDP )
369- recv_handler_udp (ts , len , packet , csrcaddr );
390+ recv_handler_udp (ts / 1000000 , len , packet , csrcaddr );
370391 else // IP_TYPE_ICMPV6
371392 recv_handler_icmp (ts , len , packet , csrcaddr );
372393
@@ -448,20 +469,22 @@ static void recv_handler_icmp(uint64_t ts, int len, const uint8_t *packet, const
448469 if (ICMP_HEADER (packet )-> body32 != scan_randomness )
449470 return ;
450471
472+ const uint64_t ts_sec = ts / 1000000 ;
473+
451474 int v2 ;
452475 rawsock_ip_decode (IP_FRAME (packet ), NULL , NULL , & v2 , NULL , NULL );
453- outdef .output_status (outfile , ts , csrcaddr , OUTPUT_PROTO_ICMP , 0 , v2 , OUTPUT_STATUS_UP );
476+ outdef .output_status (outfile , ts_sec , csrcaddr , OUTPUT_PROTO_ICMP , 0 , v2 , OUTPUT_STATUS_UP );
454477
455478 uint8_t * d = UDP_DATA (packet );
456- uint32_t xts = monotonic_us ( ) / 100 ;
479+ uint32_t xts = ( ts - atomic_load ( & time_mono_offset ) ) / 100 ;
457480 uint32_t stored = * ((uint32_t * ) d );
458481 if (stored > xts ) // overflow
459482 xts = (UINT32_MAX - stored ) + xts ;
460483 else
461484 xts -= stored ;
462485 char sbuf [32 ];
463486 snprintf (sbuf , sizeof (sbuf ), "%.1fms" , xts / 10.0f );
464- outdef .output_banner (outfile , ts , csrcaddr , OUTPUT_PROTO_ICMP , 0 , sbuf , strlen (sbuf ));
487+ outdef .output_banner (outfile , ts_sec , csrcaddr , OUTPUT_PROTO_ICMP , 0 , sbuf , strlen (sbuf ));
465488
466489 return ;
467490 perr : ;
0 commit comments