Matt Kimball [Tue, 24 Oct 2023 02:02:43 +0000 (03:02 +0100)]
Update Cygwin ICMP service thread for asynchronous pipes
Recent versions of Cygwin implement pipe() using Windows' named
pipes, and put the read end of the pipe in FILE_PIPE_COMPLETE_OPERATION
mode, which doesn't allow overlapped I/O operations.
The solution here is to maintain a Windows event object which is
set only when any ICMP requests are pending. We can do an alertable
wait on that event object, which will allow us to complete ICMP
requests.
Thanks to Adam Schultz for research into this issue and a first
attempt at a fix.
flu0r1ne [Wed, 4 Oct 2023 03:31:23 +0000 (22:31 -0500)]
Use Packet Marking for IP Address Selection
In certain scenarios, the routing policy database may affect packet
routing. When selecting an address in `mtr`, assign a packet mark if
`SO_MARK` is defined and a mark has been supplied.
flu0r1ne [Mon, 2 Oct 2023 23:10:43 +0000 (18:10 -0500)]
Annotate `set_privileged_socket_opt` with UNUSED
The `set_privileged_socket_opt` function is currently called only when
`SO_MARK` or `SO_BINDTODEVICE` are defined. On systems that do not support
either feature, `set_privileged_socket_opt` is expected to be unused. Adding
an annotation suppresses compiler warnings.
flu0r1ne [Mon, 2 Oct 2023 08:53:16 +0000 (03:53 -0500)]
Linux-Only Interface, Marking, and IP Unit Tests
This commit introduces three unit tests focused on interface binding,
packet marking, and IP source address spoofing/selection. Each of these
tests builds upon the original `MtrPacketTest` base class. To evaluate
these network-dependent features, the tests utilize an emulated network
environment. To enable this, a small network emulation library, `netem`,
has been developed specifically for this purpose. `Netem` allows for the
creation of arbitrary network configurations for testing and can reliably
set up and clean up virtual network environments on Linux systems. The only
dependencies are `iproute2` and `libc`, which are generally pre-installed
on most Linux hosts.
The commit adds three tests that are expected to fail:
1. Interface Binding: Evaluates the capability of `mtr-packet` to bind to
a specific interface.
2. Packet Marking: Assesses the ability of `mtr-packet` to apply a Linux
networking mark (fwmark).
3. Source Address Selection: Tests `mtr-packet`'s ability to spoof or bind
to a specified source address.
This commit addresses an issue where mtr would fail with EPERM because setting the
SO_BINDTODEVICE socket option requires the CAP_NET_RAW capability.
Changes:
- Refactor the code to abstract setting privileged socket options. This
includes a common interface for setting capabilities depending on the
platform (with or without LIBCAP).
- Replace direct setsockopt calls with the new abstracted function for
setting both SO_MARK and SO_BINDTODEVICE.
- Update capability management in `drop_excess_capabilities` to retain
CAP_NET_RAW when needed.
Modify the capability-dropping logic to specifically retain CAP_NET_ADMIN if it
is initially provided, in adherence to least-privilege principles.
Details:
1. Update the `drop_excess_capabilities` function to only drop capabilities that
are unnecessary, retaining CAP_NET_ADMIN when needed for setting the socket
mark.
2. Introduce logic in `set_socket_mark` to temporarily elevate CAP_NET_ADMIN
into the effective set for the duration of the packet mark setting
operation.
In the test folder, there was lint.sh, but I think flake8 is a better
tool.
Added a compile job for linux, this runs compilation as defined in
the README, runs a sample mtr and runs cmdparse.py test. Need
documentation on what other tests to run and whether to include the
testing in tox instead of running them individually.
Not adding in this PR support for cygwin or freebsd, as that will need
investigation on how to run.
Minor:
- Fixed a typo in configure.ac that used ---- vs -- for a flag option.
Sami Kerola [Tue, 6 Sep 2022 13:16:04 +0000 (14:16 +0100)]
ui: make interactive and non-interactive exit code the same
Before this change the report gave successful exit value when destination
hostname could not be found.
$ ./mtr --report nxdomain. ; echo $?
./mtr: Failed to resolve host: nxdomain.: Name or service not known
0
Quickly looking 'git grep ---after-context if.*Interactive' there does not
appear to be more than the two instances in main() where exit is called
depending on interactive, so this change should cover all these cases.
Reported-by: Marek Kroemeke <mkroemeke@cloudflare.com> Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Brandon Ewing [Fri, 13 May 2022 16:18:38 +0000 (11:18 -0500)]
add --max-display-paths option
It is not unknown to have datacenters with over 8 ECMP paths between two
hops. Expand the maximum number of ECMP hosts stored in addrs to 128,
and add a new option to control the number to display, defaulting to the
old MAX_PATHS of 8
Brandon Ewing [Fri, 13 May 2022 15:27:55 +0000 (10:27 -0500)]
use addrs for static host ordering in curses
Change d2552ca has the side effect of moving hosts around in the
multipath view, as the last host to reply to a packet was set as
addr. Using addrs[0] istead of addr to draw the first host keeps
the ordering deterministic, in order of first reply.
Andrew Marshall [Wed, 23 Mar 2022 15:36:48 +0000 (11:36 -0400)]
Adjust MIN_PORT to match other implementations
Port 33434 is the IANA-reserved port for traceroute. It also seems to be
the most common start port. The following implementations, and
likely others, use it as their start port:
- Apple macOS traceroute
- FreeBSD traceroute
- GNU inetutils-traceroute
- Modern traceroute for Linux
- OpenBSD traceroute
The benefit to using a standard starting port is that some firewalls may
have these ports allowed, whereas other ports may be blocked, so there
is a greater probability the probe will succeed.
hiro [Tue, 9 Nov 2021 17:50:12 +0000 (17:50 +0000)]
ipv6 udp checksums like ipv4 but with ipv6 pseudoheader
this fixes a problem where both source and destination port are supplied on the commandline,
this lead to packets not showing up any more due to checksum being different.
this was mentioned first on https://github.com/traviscross/mtr/issues/351
ui/curses: always use "%s"-style format for printf()-style functions
`ncuses-6.3` added printf-style function attributes and now makes
it easier to catch cases when user input is used in palce of format
string when built with CFLAGS=-Werror=format-security:
ui/curses.c:765:42:
error: format not a string literal and no format arguments [-Werror=format-security]
765 | mvprintw(rowstat - 1, startstat, msg);
| ^~~
Let's wrap all the missing places with "%s" format.