]> git.ipfire.org Git - thirdparty/mtr.git/commitdiff
packet: avoid privileged default udp source ports 571/head
authorDarafei Praliaskouski <me@komzpa.net>
Thu, 7 May 2026 16:34:54 +0000 (20:34 +0400)
committerDarafei Praliaskouski <me@komzpa.net>
Thu, 7 May 2026 16:53:55 +0000 (20:53 +0400)
man/mtr.8.in
packet/construct_unix.c

index abf7f5b190d1d3c0b5788e75d8eae4ae0a16faa5..0f402f662d2a4ede4b112786208c8b6974d6a7c5 100644 (file)
@@ -452,7 +452,8 @@ instead, so the destination port changes for each probe.
 .TP
 .B \-L \fILOCALPORT\fR, \fB\-\-localport \fILOCALPORT
 The source port number for UDP traces.  When this option is not given,
-UDP traces use the mtr process ID as the source port, unless
+UDP traces use the low 16 bits of the mtr process ID as the source port,
+rotating privileged ports into the high end of the UDP port range unless
 .B \-\-port
 was given; in that case, UDP traces encode the probe sequence number in
 the source port instead.
index f86fd5279cd1a8e45a23f6928ea596a6cb001be4..dac91d92be568cebd61b460fa61bb8ac66463553 100644 (file)
 #include <sys/capability.h>
 #endif
 
+#define MIN_UNPRIVILEGED_PORT 1024
+#define UDP_PORT_RANGE 65536
+
 /*  A source of data for computing a checksum  */
 struct checksum_source_t {
     const void *data;
     size_t size;
 };
 
+static
+uint16_t udp_source_port_from_pid(void)
+{
+    uint16_t port = getpid() & 0xffff;
+
+    if (port < MIN_UNPRIVILEGED_PORT) {
+        port += UDP_PORT_RANGE - MIN_UNPRIVILEGED_PORT;
+    }
+
+    return port;
+}
+
 /*  Compute the IP checksum (or ICMP checksum) of a packet.  */
 static
 uint16_t compute_checksum(
@@ -164,7 +179,7 @@ void set_udp_ports(
         if (param->local_port) {
             udp->srcport = htons(param->local_port);
         } else {
-            udp->srcport = htons(getpid());
+            udp->srcport = htons(udp_source_port_from_pid());
         }
 
         udp->checksum = 0;