]> git.gsnw.org Git - fping.git/commitdiff
use correct data size when sending ICMP Timestamp
authorErik Auerswald <auerswal@unix-ag.uni-kl.de>
Sat, 30 Nov 2024 18:38:05 +0000 (19:38 +0100)
committerErik Auerswald <auerswal@unix-ag.uni-kl.de>
Sat, 7 Dec 2024 19:04:17 +0000 (20:04 +0100)
ICMP Timestamp messages have a fixed size.  The data portion
following the ICMP header comprises 12 octets to hold three
timestamps of 4 octets each.

Giving the --icmp-timestamp option now automatically sets the
data size to 12 octets.

Error out when -b N is used together with --icmp-timestamp.

Adjust man page to mention incompatibility of -b N, --size=N
with --icmp-timestamp.  Also mention in man page that
cap_net_raw can be used instead of root privileges for ICMP
Timestamp.

ci/test-04-options-a-b.pl
doc/fping.pod
src/fping.c

index 90afa9bbd1ff080f89fd751daa718e27bee177b8..36e3acbb69b73a3ee8cee60dd8b8f1ba08c2b411 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -w
 
-use Test::Command tests => 47;
+use Test::Command tests => 53;
 use Test::More;
 use Time::HiRes qw(gettimeofday tv_interval);
 
@@ -127,7 +127,23 @@ $cmd->stderr_is_eq("");
 my $cmd = Test::Command->new(cmd => "fping --icmp-timestamp -b 1000 127.0.0.1");
 $cmd->exit_is_num(1);
 $cmd->stdout_is_eq("");
-$cmd->stderr_like(qr{Usage:});
+$cmd->stderr_like(qr{cannot change ICMP Timestamp size});
+}
+
+# fping -b --icmp-timestamp
+{
+my $cmd = Test::Command->new(cmd => "fping -b 1000 --icmp-timestamp 127.0.0.1");
+$cmd->exit_is_num(1);
+$cmd->stdout_is_eq("");
+$cmd->stderr_like(qr{cannot change ICMP Timestamp size});
+}
+
+# fping --icmp-timestamp -b 12 (ICMP Timestamp data size)
+{
+my $cmd = Test::Command->new(cmd => "fping --icmp-timestamp -b 12 127.0.0.1");
+$cmd->exit_is_num(1);
+$cmd->stdout_is_eq("");
+$cmd->stderr_like(qr{cannot change ICMP Timestamp size});
 }
 
 # fping -B
index bc3a44d0c3e074d925b19686aeb21f687c61cff7..e155a96d017494e70338a42d13b9e46fa74ff75d 100644 (file)
@@ -51,7 +51,7 @@ timestamp).  The reported received data size includes the IP header (normally
 20 bytes) and ICMP header (8 bytes), so the minimum total size is 40 bytes.
 Default is 56, as in B<ping>. Maximum is the theoretical maximum IP datagram
 size (64K), though most systems limit this to a smaller, system-dependent
-number.
+number. Cannot be used together with B<--icmp-timestamp>.
 
 =item B<-B>, B<--backoff>=I<N>
 
@@ -159,7 +159,7 @@ Set the interface (requires SO_BINDTODEVICE support).
 
 Send ICMP timestamp requests (ICMP type 13) instead of ICMP Echo requests.
 Cannot be used together with B<-b> because ICMP timestamp messages have a fixed size.
-IPv4 only, requires root privileges.
+IPv4 only, requires root privileges or cap_net_raw.
 
 =item B<-k>, B<--fwmark>=I<FWMARK>
 
index 1f57aa17770e26343875391fe8b5db354faacde5..38fa0a3f6e69d114ac77b4cb00455549e8b8ac80 100644 (file)
@@ -144,6 +144,9 @@ extern int h_errno;
 /* sized so as to be like traditional ping */
 #define DEFAULT_PING_DATA_SIZE 56
 
+/* ICMP Timestamp has a fixed payload size of 12 bytes */
+#define ICMP_TIMESTAMP_DATA_SIZE 12
+
 /* maxima and minima */
 #ifdef FPING_SAFE_LIMITS
 #define MIN_INTERVAL 1 /* in millisec */
@@ -364,6 +367,7 @@ int check_source_flag = 0;
 int icmp_request_typ = 0;
 int print_tos_flag = 0;
 int print_ttl_flag = 0;
+int size_flag = 0;
 #if defined(DEBUG) || defined(_DEBUG)
 int randomly_lose_flag, trace_flag, print_per_system_flag;
 int lose_factor;
@@ -588,6 +592,7 @@ int main(int argc, char **argv)
                 check_source_flag = 1;
             } else if (strstr(optparse_state.optlongname, "icmp-timestamp") != NULL) {
                 icmp_request_typ = 13;
+                ping_data_size = ICMP_TIMESTAMP_DATA_SIZE;
             } else if (strstr(optparse_state.optlongname, "print-tos") != NULL) {
                 print_tos_flag = 1;
             } else if (strstr(optparse_state.optlongname, "print-ttl") != NULL) {
@@ -691,9 +696,7 @@ int main(int argc, char **argv)
         case 'b':
             if (sscanf(optparse_state.optarg, "%u", &ping_data_size) != 1)
                 usage(1);
-            if (icmp_request_typ > 0)
-                usage(1);
-
+            size_flag = 1;
             break;
 
         case 'h':
@@ -973,6 +976,11 @@ int main(int argc, char **argv)
         exit(1);
     }
 
+    if (icmp_request_typ == 13 && size_flag != 0) {
+        fprintf(stderr, "%s: cannot change ICMP Timestamp size\n", prog);
+        exit(1);
+    }
+
     if (count_flag) {
         if (verbose_flag)
             per_recv_flag = 1;
@@ -2290,7 +2298,7 @@ int decode_icmp_ipv4(
     if(icp->icmp_type == ICMP_TSTAMPREPLY) {
 
         /* Check that reply_buf_len is sufficiently big to contain the timestamps */
-        if (reply_buf_len < hlen + ICMP_MINLEN + 3 * sizeof(uint32_t)) {
+        if (reply_buf_len < hlen + ICMP_MINLEN + ICMP_TIMESTAMP_DATA_SIZE) {
             if (verbose_flag) {
                 char buf[INET6_ADDRSTRLEN];
                 getnameinfo(response_addr, response_addr_len, buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);