Compare commits

...

No commits in common. "c8s" and "c9s" have entirely different histories.
c8s ... c9s

12 changed files with 472 additions and 93 deletions

1
.fmf/version Normal file
View File

@ -0,0 +1 @@
1

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/mtr-0.92.tar.gz
/mtr-*.tar.gz

View File

@ -1 +1 @@
81fe55d8d34cc65f1a03803ada95ce0d7332f8d0 SOURCES/mtr-0.92.tar.gz
bf6b83f72aabffe8825bbde23967a64ddd5b7693 mtr-0.94.tar.gz

View File

@ -0,0 +1,402 @@
From d529dbeefc6dc4b103d395510cd71949cea4f25e Mon Sep 17 00:00:00 2001
From: Alarig Le Lay <alarig@swordarmor.fr>
Date: Mon, 11 Sep 2023 11:48:53 +0200
Subject: [PATCH] Change UDP and ICMP sockets binding to accept a source IP
from the -a CLI option
Issue: #232
Signed-off-by: Alarig Le Lay <alarig@swordarmor.fr>
---
packet/construct_unix.c | 176 +++++++++++++++-------------------------
packet/probe_unix.c | 55 +++++++------
packet/probe_unix.h | 7 +-
3 files changed, 100 insertions(+), 138 deletions(-)
diff --git a/packet/construct_unix.c b/packet/construct_unix.c
index e78228aa..e09d7057 100644
--- a/packet/construct_unix.c
+++ b/packet/construct_unix.c
@@ -71,19 +71,6 @@ uint16_t compute_checksum(
return (~sum & 0xffff);
}
-/* Encode the IP header length field in the order required by the OS. */
-static
-uint16_t length_byte_swap(
- const struct net_state_t *net_state,
- uint16_t length)
-{
- if (net_state->platform.ip_length_host_order) {
- return length;
- } else {
- return htons(length);
- }
-}
-
/* Construct a combined sockaddr from a source address and source port */
static
void construct_addr_port(
@@ -95,38 +82,9 @@ void construct_addr_port(
*sockaddr_port_offset(addr_with_port) = htons(port);
}
-/* Construct a header for IP version 4 */
-static
-void construct_ip4_header(
- const struct net_state_t *net_state,
- const struct probe_t *probe,
- char *packet_buffer,
- int packet_size,
- const struct probe_param_t *param)
-{
- struct IPHeader *ip;
-
- ip = (struct IPHeader *) &packet_buffer[0];
-
- memset(ip, 0, sizeof(struct IPHeader));
-
- ip->version = 0x45;
- ip->tos = param->type_of_service;
- ip->len = length_byte_swap(net_state, packet_size);
- ip->ttl = param->ttl;
- ip->protocol = param->protocol;
-// ip->id = htons(getpid());
- memcpy(&ip->saddr,
- sockaddr_addr_offset(&probe->local_addr),
- sockaddr_addr_size(&probe->local_addr));
- memcpy(&ip->daddr,
- sockaddr_addr_offset(&probe->remote_addr),
- sockaddr_addr_size(&probe->remote_addr));
-}
-
/* Construct an ICMP header for IPv4 */
static
-void construct_icmp4_header(
+int construct_icmp4_packet(
const struct net_state_t *net_state,
struct probe_t *probe,
char *packet_buffer,
@@ -134,22 +92,17 @@ void construct_icmp4_header(
const struct probe_param_t *param)
{
struct ICMPHeader *icmp;
- int icmp_size;
- if (net_state->platform.ip4_socket_raw) {
- icmp = (struct ICMPHeader *) &packet_buffer[sizeof(struct IPHeader)];
- icmp_size = packet_size - sizeof(struct IPHeader);
- } else {
- icmp = (struct ICMPHeader *) &packet_buffer[0];
- icmp_size = packet_size;
- }
+ icmp = (struct ICMPHeader *) packet_buffer;
memset(icmp, 0, sizeof(struct ICMPHeader));
icmp->type = ICMP_ECHO;
icmp->id = htons(getpid());
icmp->sequence = htons(probe->sequence);
- icmp->checksum = htons(compute_checksum(icmp, icmp_size));
+ icmp->checksum = htons(compute_checksum(icmp, packet_size));
+
+ return 0;
}
/* Construct an ICMP header for IPv6 */
@@ -238,7 +191,7 @@ int udp4_checksum(void *pheader, void *udata, int psize, int dsize,
with the probe.
*/
static
-void construct_udp4_header(
+int construct_udp4_packet(
const struct net_state_t *net_state,
struct probe_t *probe,
char *packet_buffer,
@@ -248,13 +201,8 @@ void construct_udp4_header(
struct UDPHeader *udp;
int udp_size;
- if (net_state->platform.ip4_socket_raw) {
- udp = (struct UDPHeader *) &packet_buffer[sizeof(struct IPHeader)];
- udp_size = packet_size - sizeof(struct IPHeader);
- } else {
- udp = (struct UDPHeader *) &packet_buffer[0];
- udp_size = packet_size;
- }
+ udp = (struct UDPHeader *) packet_buffer;
+ udp_size = packet_size;
memset(udp, 0, sizeof(struct UDPHeader));
@@ -283,6 +231,8 @@ void construct_udp4_header(
*checksum_off = htons(udp4_checksum(&udph, udp,
sizeof(struct UDPPseudoHeader),
udp_size, udp->checksum != 0));
+
+ return 0;
}
/* Construct a header for UDPv6 probes */
@@ -561,10 +511,10 @@ int construct_ip4_packet(
int packet_size,
const struct probe_param_t *param)
{
- int send_socket = net_state->platform.ip4_send_socket;
+ int send_socket;
bool is_stream_protocol = false;
- int tos, ttl, socket;
- bool bind_send_socket = false;
+ int tos, ttl;
+ bool bind_send_socket = true;
struct sockaddr_storage current_sockaddr;
int current_sockaddr_len;
@@ -574,23 +524,34 @@ int construct_ip4_packet(
} else if (param->protocol == IPPROTO_SCTP) {
is_stream_protocol = true;
#endif
- } else {
+ } else if (param->protocol == IPPROTO_ICMP) {
if (net_state->platform.ip4_socket_raw) {
- construct_ip4_header(net_state, probe, packet_buffer, packet_size,
- param);
+ send_socket = net_state->platform.icmp4_send_socket;
+ } else {
+ send_socket = net_state->platform.ip4_txrx_icmp_socket;
}
- if (param->protocol == IPPROTO_ICMP) {
- construct_icmp4_header(net_state, probe, packet_buffer,
- packet_size, param);
- } else if (param->protocol == IPPROTO_UDP) {
- construct_udp4_header(net_state, probe, packet_buffer,
- packet_size, param);
+
+ if (construct_icmp4_packet
+ (net_state, probe, packet_buffer, packet_size, param)) {
+ return -1;
+ }
+ } else if (param->protocol == IPPROTO_UDP) {
+ if (net_state->platform.ip4_socket_raw) {
+ send_socket = net_state->platform.udp4_send_socket;
} else {
- errno = EINVAL;
+ send_socket = net_state->platform.ip4_txrx_udp_socket;
+ }
+
+ if (construct_udp4_packet
+ (net_state, probe, packet_buffer, packet_size, param)) {
return -1;
}
+ } else {
+ errno = EINVAL;
+ return -1;
}
+
if (is_stream_protocol) {
send_socket =
open_stream_socket(net_state, param->protocol, probe->sequence,
@@ -633,54 +594,51 @@ int construct_ip4_packet(
#endif
/*
- Bind src port when not using raw socket to pass in ICMP id, kernel
- get ICMP id from src_port when using DGRAM socket.
+ Check the current socket address, and if it is the same
+ as the source address we intend, we will skip the bind.
+ This is to accommodate Solaris, which, as of Solaris 11.3,
+ will return an EINVAL error on bind if the socket is already
+ bound, even if the same address is used.
*/
- if (!net_state->platform.ip4_socket_raw &&
- param->protocol == IPPROTO_ICMP &&
- !param->is_probing_byte_order) {
- current_sockaddr_len = sizeof(struct sockaddr_in);
- bind_send_socket = true;
- socket = net_state->platform.ip4_txrx_icmp_socket;
- if (getsockname(socket, (struct sockaddr *) &current_sockaddr,
- &current_sockaddr_len)) {
- return -1;
- }
- struct sockaddr_in *sin_cur =
- (struct sockaddr_in *) &current_sockaddr;
+ current_sockaddr_len = sizeof(struct sockaddr_in);
+ if (getsockname(send_socket, (struct sockaddr *) &current_sockaddr,
+ &current_sockaddr_len) == 0) {
+ struct sockaddr_in *sin_cur = (struct sockaddr_in *) &current_sockaddr;
- /* avoid double bind */
- if (sin_cur->sin_port) {
- bind_send_socket = false;
+ if (net_state->platform.ip4_socket_raw) {
+ if (memcmp(&current_sockaddr,
+ &probe->local_addr, sizeof(struct sockaddr_in)) == 0) {
+ bind_send_socket = false;
+ }
+ } else {
+ /* avoid double bind for DGRAM socket */
+ if (sin_cur->sin_port) {
+ bind_send_socket = false;
+ }
}
}
/* Bind to our local address */
- if (bind_send_socket && bind(socket, (struct sockaddr *)&probe->local_addr,
+ if (bind_send_socket && bind(send_socket, (struct sockaddr *)&probe->local_addr,
sizeof(struct sockaddr_in))) {
return -1;
}
- /* set TOS and TTL for non-raw socket */
- if (!net_state->platform.ip4_socket_raw && !param->is_probing_byte_order) {
- if (param->protocol == IPPROTO_ICMP) {
- socket = net_state->platform.ip4_txrx_icmp_socket;
- } else if (param->protocol == IPPROTO_UDP) {
- socket = net_state->platform.ip4_txrx_udp_socket;
- } else {
- return 0;
- }
- tos = param->type_of_service;
- if (setsockopt(socket, SOL_IP, IP_TOS, &tos, sizeof(int))) {
- return -1;
- }
- ttl = param->ttl;
- if (setsockopt(socket, SOL_IP, IP_TTL,
- &ttl, sizeof(int)) == -1) {
- return -1;
- }
+ /* Set the type of service */
+ tos = param->type_of_service;
+ if (setsockopt(send_socket, SOL_IP, IP_TOS, &tos, sizeof(int))) {
+ return -1;
}
+ /* Set the time-to-live */
+ ttl = param->ttl;
+ if (setsockopt(send_socket, SOL_IP, IP_TTL,
+ &ttl, sizeof(int)) == -1) {
+ return -1;
+ }
+
+
+
return 0;
}
diff --git a/packet/probe_unix.c b/packet/probe_unix.c
index f7f393fc..012ec0cd 100644
--- a/packet/probe_unix.c
+++ b/packet/probe_unix.c
@@ -87,16 +87,21 @@ int send_packet(
} else if (sockaddr->ss_family == AF_INET) {
sockaddr_length = sizeof(struct sockaddr_in);
- if (net_state->platform.ip4_socket_raw) {
- send_socket = net_state->platform.ip4_send_socket;
- } else {
- if (param->protocol == IPPROTO_ICMP) {
- if (param->is_probing_byte_order) {
- send_socket = net_state->platform.ip4_tmp_icmp_socket;;
- } else {
- send_socket = net_state->platform.ip4_txrx_icmp_socket;
- }
- } else if (param->protocol == IPPROTO_UDP) {
+ if (param->protocol == IPPROTO_ICMP) {
+ if (net_state->platform.ip4_socket_raw) {
+ send_socket = net_state->platform.icmp4_send_socket;
+ } else {
+ send_socket = net_state->platform.ip4_txrx_icmp_socket;
+ }
+ } else if (param->protocol == IPPROTO_UDP) {
+ if (net_state->platform.ip4_socket_raw) {
+ send_socket = net_state->platform.udp4_send_socket;
+ /* we got a ipv4 udp raw socket
+ * the remote port is in the payload
+ * we do not set in the sockaddr
+ */
+ *sockaddr_port_offset(&dst) = 0;
+ } else {
send_socket = net_state->platform.ip4_txrx_udp_socket;
if (param->dest_port) {
*sockaddr_port_offset(&dst) = htons(param->dest_port);
@@ -105,6 +110,7 @@ int send_packet(
}
}
}
+
}
if (send_socket == 0) {
@@ -236,26 +242,19 @@ static
int open_ip4_sockets_raw(
struct net_state_t *net_state)
{
- int send_socket;
+ int send_socket_icmp;
+ int send_socket_udp;
int recv_socket;
- int trueopt = 1;
- send_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
- if (send_socket == -1) {
- send_socket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
- if (send_socket == -1) {
- return -1;
- }
+ send_socket_icmp = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+ if (send_socket_icmp == -1) {
+ return -1;
}
- /*
- We will be including the IP header in transmitted packets.
- Linux doesn't require this, but BSD derived network stacks do.
- */
- if (setsockopt
- (send_socket, IPPROTO_IP, IP_HDRINCL, &trueopt, sizeof(int))) {
+ send_socket_udp = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
+ if (send_socket_udp == -1) {
+ close(send_socket_icmp);
- close(send_socket);
return -1;
}
@@ -265,13 +264,15 @@ int open_ip4_sockets_raw(
*/
recv_socket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (recv_socket == -1) {
- close(send_socket);
+ close(send_socket_icmp);
+ close(send_socket_udp);
return -1;
}
net_state->platform.ip4_present = true;
net_state->platform.ip4_socket_raw = true;
- net_state->platform.ip4_send_socket = send_socket;
+ net_state->platform.icmp4_send_socket = send_socket_icmp;
+ net_state->platform.udp4_send_socket = send_socket_udp;
net_state->platform.ip4_recv_socket = recv_socket;
return 0;
diff --git a/packet/probe_unix.h b/packet/probe_unix.h
index f3e8207b..2ba2fac6 100644
--- a/packet/probe_unix.h
+++ b/packet/probe_unix.h
@@ -54,8 +54,11 @@ struct net_state_platform_t {
/* true if ipv6 socket is raw socket */
bool ip6_socket_raw;
- /* Socket used to send raw IPv4 packets */
- int ip4_send_socket;
+ /* Send socket for ICMPv6 packets */
+ int icmp4_send_socket;
+
+ /* Send socket for UDPv6 packets */
+ int udp4_send_socket;
/* Socket used to receive IPv4 ICMP replies */
int ip4_recv_socket;

View File

@ -1,28 +0,0 @@
From 9d2800441a73a1dfb84f1c97a1e2755b9cac163c Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Fri, 26 Jul 2019 01:56:10 +0200
Subject: [PATCH] buildsys: don't set filecaps nor setuid manually and let
rpmbuild handle it
---
Makefile.am | 4 ----
1 file changed, 4 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index c0709ca..daebb84 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -40,10 +40,6 @@ $(PATHFILES): Makefile
dist_man_MANS = mtr.8 mtr-packet.8
PATHFILES += man/mtr.8 man/mtr-packet.8
-install-exec-hook:
- `setcap cap_net_raw+ep $(DESTDIR)$(sbindir)/mtr-packet` \
- || chmod u+s $(DESTDIR)$(sbindir)/mtr-packet
-
mtr_SOURCES = ui/mtr.c ui/mtr.h \
ui/net.c ui/net.h \
ui/cmdpipe.c ui/cmdpipe.h \
--
2.21.0

View File

@ -1,10 +0,0 @@
#!/bin/sh
error_message="You are trying to run mtr-gtk in a Wayland session, however mtr-gtk requires root privileges and such graphical applications are not allowed to run on Wayland by default.\n\nSee https://fedoraproject.org/wiki/Common_F25_bugs\#wayland-root-apps for more details and possible workarounds.\n"
if [ "$XDG_SESSION_TYPE" = wayland ]; then
zenity --error --title "mtr-gtk on Wayland" --text "$error_message" --width=600 2>/dev/null || printf "$error_message" >&2
exit 1
fi
/usr/bin/pkexec /usr/bin/xmtr.bin

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
<action id="org.fedoraproject.mtr.pkexec.run">
<description>Run mtr</description>
<message>Authentication is required to run traceroute</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/bin/xmtr.bin</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>
</policyconfig>

9
gating.yaml Normal file
View File

@ -0,0 +1,9 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

View File

@ -2,20 +2,17 @@
Summary: Network diagnostic tool combining 'traceroute' and 'ping'
Name: mtr
Version: 0.92
Release: 3%{?dist}
Version: 0.94
Release: 6%{?dist}
Epoch: 2
Group: Applications/Internet
License: GPLv2
URL: https://www.bitwizard.nl/mtr/
Source0: https://github.com/traviscross/mtr/archive/v%{version}/%{name}-%{version}.tar.gz
Source1: net-x%{name}.desktop
Source2: mtr-gtk-pkexec-wrapper.sh
Source3: org.fedoraproject.mtr.policy
Patch0001: 0001-buildsys-don-t-set-filecaps-nor-setuid-manually-and-.patch
Patch0: 74d312d7e67d002e184b37c7f278597ab06bf8e7.patch
BuildRequires: ncurses-devel gtk2-devel desktop-file-utils
BuildRequires: gcc make ncurses-devel libcap-devel jansson-devel
BuildRequires: autoconf automake libtool git
%description
@ -30,18 +27,18 @@ the link to each machine. While doing this, it prints running statistics
about each machine.
MTR provides two user interfaces: an ncurses interface, useful for the
command line, e.g. for SSH sessions; and a GTK+ interface for X (provided
command line, e.g. for SSH sessions; and a GTK interface for X (provided
in the mtr-gtk package).
%package gtk
Summary: GTK+ interface for MTR
Group: Applications/Internet
Summary: GTK interface for MTR
Requires: %{name} = %{epoch}:%{version}-%{release}
BuildRequires: gtk3-devel desktop-file-utils
%description gtk
MTR combines the functionality of the 'traceroute' and 'ping' programs
in a single network diagnostic tool. The mtr-gtk package provides the
GTK+ interface for MTR.
GTK interface for MTR.
When MTR is started, it investigates the network connection between the
host MTR runs on and the user-specified destination host. Afterwards it
@ -51,55 +48,75 @@ the link to each machine. While doing this, it prints running statistics
about each machine.
%prep
%autosetup -S git
%autosetup -p1
%build
autoreconf -vfi
export CFLAGS="%{optflags} -fPIE"
export LDFLAGS="-z now -pie"
# Upstream forgot to ship .tarball-version
echo "%{version}" > .tarball-version
./bootstrap.sh
%configure --with-gtk
%make_build && mv -f mtr xmtr.bin && make distclean
%make_build && mv -f mtr xmtr && make distclean
%configure --without-gtk
%make_build
%install
install -D -p -m 0755 mtr %{buildroot}%{_sbindir}/mtr
install -D -p -m 0755 xmtr.bin %{buildroot}%{_bindir}/xmtr.bin
install -D -p -m 0755 %{SOURCE2} %{buildroot}%{_bindir}/xmtr
install -D -p -m 0644 %{SOURCE3} %{buildroot}%{_datadir}/polkit-1/actions/org.fedoraproject.mtr.policy
install -D -p -m 0644 img/mtr_icon.xpm %{buildroot}%{_datadir}/pixmaps/mtr_icon.xpm
%make_install
install -D -p -m 0755 xmtr %{buildroot}%{_bindir}/xmtr
install -D -p -m 0644 img/mtr_icon.xpm %{buildroot}%{_datadir}/pixmaps/mtr_icon.xpm
desktop-file-install --dir=%{buildroot}%{_datadir}/applications %{SOURCE1}
%files
%{!?_licensedir:%global license %%doc}
%license COPYING
%doc AUTHORS FORMATS NEWS README SECURITY
%doc AUTHORS FORMATS NEWS README.md SECURITY
%{_sbindir}/%{name}
%caps(cap_net_raw=pe) %{_sbindir}/%{name}-packet
%{_mandir}/man8/*
%attr(0755,root,root) %caps(cap_net_raw=pe) %{_sbindir}/%{name}-packet
%{_mandir}/man8/%{name}.8*
%{_mandir}/man8/%{name}-packet.8*
%dir %{_datadir}/bash-completion/
%dir %{_datadir}/bash-completion/completions/
%{_datadir}/bash-completion/completions/%{name}
%files gtk
%{_bindir}/xmtr
%{_bindir}/xmtr.bin
%{_datadir}/pixmaps/mtr_icon.xpm
%{_datadir}/polkit-1/actions/org.fedoraproject.mtr.policy
%{_datadir}/applications/net-x%{name}.desktop
%changelog
* Mon Jul 29 2019 Michal Sekletar <msekleta@redhat.com> - 2:0.92-3
- fix name of the gating config file (#1681042)
* Mon Apr 22 2024 Lukas Nykryn <lnykryn@redhat.com> - 2:0.94-6
- add smoke test
* Fri Jul 26 2019 Michal Sekletar <msekleta@redhat.com> - 2:0.92-2
- don't set setuid and filecaps manually (#1633182)
* Mon Apr 22 2024 Lukas Nykryn <lnykryn@redhat.com> - 2:0.94-5
- Change UDP and ICMP sockets binding to accept a source IP from the -a CLI option
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 2:0.94-4
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 2:0.94-3
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2:0.94-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Sun Jan 24 2021 Robert Scheck <robert@fedoraproject.org> - 2:0.94-1
- Rebase to 0.94 (#1742473, #1840079)
- Drop policykit wrapper for xmtr due to libcap (#1488417, #1488418)
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2:0.92-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2:0.92-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2:0.92-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2:0.92-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2:0.92-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Thu Feb 08 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2:0.92-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Sat Aug 26 2017 Robert Scheck <robert@fedoraproject.org> - 2:0.92-1
- Rebase to 0.92 (#1458265)

View File

@ -4,7 +4,7 @@ Type=Application
Comment=Traces packets between two network hosts
Exec=xmtr
Terminal=false
Icon=mtr_icon.xpm
Icon=mtr_icon
Encoding=UTF-8
X-Desktop-File-Install-Version=0.2
Categories=System;Application;

4
plans/example.fmf Normal file
View File

@ -0,0 +1,4 @@
summary: Basic smoke test
execute:
how: tmt
script: mtr --version

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (mtr-0.94.tar.gz) = 0e58bd79562ff80f9308135562ab22aa1f1eea686aefd3aef07bac05e661e34b60fde7c66c96bf4f0919f546376fbd6106ecd8fa92328c24f6f903097496bf11