import CS iputils-20210202-11.el9

This commit is contained in:
eabdullin 2025-03-11 07:28:49 +00:00
parent 01318bfa1c
commit efc90e9db1
12 changed files with 854 additions and 1 deletions

View File

@ -0,0 +1,40 @@
From a1890739e9d5953897cec43c59d5fea922384d5b Mon Sep 17 00:00:00 2001
From: Petr Vorel <pvorel@suse.cz>
Date: Wed, 22 May 2024 07:05:14 +0200
Subject: [PATCH 1/2] arping: Fix 1s delay on exit for unsolicited arpings
Commit 67e070d introduced 1s poll() delay for unsolicited arpings,
when using -U or -A, e.g.:
# arping -A -c1 -I eth0 [IP address of eth0 interface]
# arping -U -c1 -I eth0 [IP address of eth0 interface]
Restore correct condition.
Fixes: 67e070d ("arping: use signalfd() and timerfd() rather than signals")
Fixes: https://github.com/iputils/iputils/issues/536
Closes: https://github.com/iputils/iputils/pull/541
Reported-by: <Curtis Taylor cjebpub@gmail.com>
Suggested-by: <Curtis Taylor cjebpub@gmail.com>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
(cherry picked from commit 4db1de672559804bebcb7073d231924339ca8cd8)
---
arping.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arping.c b/arping.c
index 53fdbb4..8929f8f 100644
--- a/arping.c
+++ b/arping.c
@@ -749,7 +749,7 @@ static int event_loop(struct run_state *ctl)
pfds[POLLFD_SOCKET].events = POLLIN | POLLERR | POLLHUP;
send_pack(ctl);
- while (!exit_loop) {
+ while (!(exit_loop || ctl->unsolicited)) {
int ret;
size_t i;
--
2.46.0

View File

@ -0,0 +1,61 @@
From 5564dd9f224a7354a55c8f57ac0da9c2e58b18e5 Mon Sep 17 00:00:00 2001
From: Petr Vorel <pvorel@suse.cz>
Date: Fri, 24 May 2024 00:05:53 +0200
Subject: [PATCH 2/2] arping: Fix unsolicited ARP regressions on -c > 1
4db1de6 tried to fix a regression 1 sec delay due poll() for unsolicited
ARP, .i.e. -A and -U (introduced in 67e070d, reported as issue #536).
But skipping the while loop entirely introduced another regression for
-A and -U, which behave like -c1 (sending *always* only a single packet).
Fixing it by checking in while loop and comparing also count (as it was
done in 67e070d before the rewrite).
NOTE: use exit_loop with continue instead of simple break to keep things
consistent.
Fixes: 4db1de6 ("arping: Fix 1s delay on exit for unsolicited arpings")
Fixes: 67e070d ("arping: use signalfd() and timerfd() rather than signals")
Fixes: https://github.com/iputils/iputils/issues/536
Closes: https://github.com/iputils/iputils/pull/543
Reported-by: David Bond <dbond@suse.com>
Reviewed-by: Andrea Cervesato <andrea.cervesato@suse.com>
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
(cherry picked from commit 5de892d15eea467775420c4fd641df229f024259)
---
arping.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arping.c b/arping.c
index 8929f8f..ee9da1d 100644
--- a/arping.c
+++ b/arping.c
@@ -749,10 +749,15 @@ static int event_loop(struct run_state *ctl)
pfds[POLLFD_SOCKET].events = POLLIN | POLLERR | POLLHUP;
send_pack(ctl);
- while (!(exit_loop || ctl->unsolicited)) {
+ while (!exit_loop) {
int ret;
size_t i;
+ if ((ctl->sent == ctl->count) && ctl->unsolicited) {
+ exit_loop = 1;
+ continue;
+ }
+
ret = poll(pfds, POLLFD_COUNT, -1);
if (ret <= 0) {
if (errno == EAGAIN)
@@ -813,6 +818,7 @@ static int event_loop(struct run_state *ctl)
}
}
}
+
close(sfd);
close(tfd);
freeifaddrs(ctl->ifa0);
--
2.46.0

View File

@ -0,0 +1,33 @@
From 357b788e667bdd51b66bbc0cc88cf82ae3169455 Mon Sep 17 00:00:00 2001
From: Noah Meyerhans <noahm@debian.org>
Date: Wed, 16 Feb 2022 22:25:30 -0800
Subject: [PATCH 1/2] arping: fix typo in error checking
When attempting to check the return value of timerfd_create(), we were
not checking the value of the variable containing the return value.
Fixes: e594ca5 ("arping: use additional timerfd to control when timeout happens")
Reviewed-by: Petr Vorel <petr.vorel@gmail.com>
Signed-off-by: Noah Meyerhans <noahm@debian.org>
(cherry picked from commit 8a6a2ce3cd0cdf69f0551a3a1e598a191561d18e)
---
arping.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arping.c b/arping.c
index ee9da1d..8059517 100644
--- a/arping.c
+++ b/arping.c
@@ -733,7 +733,7 @@ static int event_loop(struct run_state *ctl)
/* timeout timerfd */
timeoutfd = timerfd_create(CLOCK_MONOTONIC, 0);
- if (tfd == -1) {
+ if (timeoutfd == -1) {
error(0, errno, "timerfd_create failed");
return 1;
}
--
2.46.0

View File

@ -0,0 +1,62 @@
From bf2900d716397734136ec3014a591281504aa00b Mon Sep 17 00:00:00 2001
From: Noah Meyerhans <noahm@debian.org>
Date: Wed, 16 Feb 2022 22:27:49 -0800
Subject: [PATCH 2/2] arping: exit 0 if running in deadline mode and we see
replies
The arping behavior when running in deadline mode without a packet
count (-w without -c) should match that of ping: any replies indicate
that the host is up and should result in a zero (success) exit status.
Fixes: https://github.com/iputils/iputils/issues/392
Closes: https://github.com/iputils/iputils/pull/395
Reviewed-by: Petr Vorel <petr.vorel@gmail.com>
Signed-off-by: Noah Meyerhans <noahm@debian.org>
(cherry picked from commit 854873bdd28fcdd9cc3fe0c2d29c083a07d07a86)
---
arping.c | 2 ++
doc/arping.xml | 14 +++++++-------
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/arping.c b/arping.c
index 8059517..6f94e90 100644
--- a/arping.c
+++ b/arping.c
@@ -828,6 +828,8 @@ static int event_loop(struct run_state *ctl)
else if (ctl->dad && ctl->quit_on_reply)
/* Duplicate address detection mode return value */
rc |= !(ctl->brd_sent != ctl->received);
+ else if (ctl->timeout && !(ctl->count > 0))
+ rc |= !(ctl->received > 0);
else
rc |= (ctl->sent != ctl->received);
return rc;
diff --git a/doc/arping.xml b/doc/arping.xml
index 711718f..9adbc0c 100644
--- a/doc/arping.xml
+++ b/doc/arping.xml
@@ -202,13 +202,13 @@ xml:id="man.arping">
<listitem>
<para>Specify a timeout, in seconds, before
<command>arping</command> exits regardless of how many
- packets have been sent or received. In this case
- <command>arping</command> does not stop after
- <emphasis remap='I'>count</emphasis> packet are sent, it
- waits either for
- <emphasis remap='I'>deadline</emphasis> expire or until
- <emphasis remap='I'>count</emphasis> probes are
- answered.</para>
+ packets have been sent or received. If any replies are
+ received, exit with status 0, otherwise status 1. When
+ combined with the <emphasis remap="I">count</emphasis>
+ option, exit with status 0 if <emphasis
+ remap="I">count</emphasis> replies are received before the
+ deadline expiration, otherwise status 1.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
--
2.46.0

View File

@ -0,0 +1,119 @@
From 7d62be648f03adba22bcccd2eb3506d51169b85d Mon Sep 17 00:00:00 2001
From: Petr Vorel <pvorel@suse.cz>
Date: Thu, 15 Apr 2021 07:48:03 +0200
Subject: [PATCH 1/3] Revert "Add strict pattern matching on response when
pattern was provided"
This reverts commit f7710a17c4d5994313a64583f511bcdb9559f2a9.
Commit broke report of truncated packets:
$ ping -c2 -s100 google.com
PING google.com (142.250.185.238) 100(128) bytes of data.
Running ping from both s20161105 (which does not contain f7710a1) and
reverted f7710a1 on master reports truncated packets:
$ ping -c2 -s100 google.com
PING google.com (142.250.185.238) 100(128) bytes of data.
76 bytes from fra16s53-in-f14.1e100.net (142.250.185.238): icmp_seq=1 ttl=116 (truncated)
76 bytes from fra16s53-in-f14.1e100.net (142.250.185.238): icmp_seq=2 ttl=116 (truncated)
There was unreachable code in gather_statistics() because
contains_pattern_in_payload() added in f7710a1 always found a mismatch
first. Due that all of these did not work:
* updating counters for statistics generation
* keeping track of timestamps and time-of-flight using the first section
of the payload
* checking for duplicate replies and report them
* printing basic info about the reply
* printing "(truncated)" if the reply was truncated
* checking the checksum
* validating the rest of the payload (bytes 17 and above) against the
ICMP request that was sent, and report any differences
Fixes: f7710a1 ("Add strict pattern matching on response when pattern was provided")
Closes: https://github.com/iputils/iputils/issues/320
Closes: https://github.com/iputils/iputils/pull/331
Reported-by: Paul Swirhun <paulswirhun@gmail.com>
Suggested-by: Paul Swirhun <paulswirhun@gmail.com>
Reviewed-by: Noah Meyerhans <noahm@debian.org>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
(cherry picked from commit dff5d82dadab1b04400b2f9e1eb10a0d124868ed)
---
ping/ping.c | 2 --
ping/ping.h | 1 -
ping/ping6_common.c | 2 --
ping/ping_common.c | 18 ------------------
4 files changed, 23 deletions(-)
diff --git a/ping/ping.c b/ping/ping.c
index 1c98733..0655bf4 100644
--- a/ping/ping.c
+++ b/ping/ping.c
@@ -1549,8 +1549,6 @@ int ping4_parse_reply(struct ping_rts *rts, struct socket_st *sock,
return 1;
if (!is_ours(rts, sock, icp->un.echo.id))
return 1; /* 'Twas not our ECHO */
- if (!contains_pattern_in_payload(rts, (uint8_t *)(icp + 1)))
- return 1; /* 'Twas really not our ECHO */
if (gather_statistics(rts, (uint8_t *)icp, sizeof(*icp), cc,
ntohs(icp->un.echo.sequence),
reply_ttl, 0, tv, pr_addr(rts, from, sizeof *from),
diff --git a/ping/ping.h b/ping/ping.h
index c8bbcf6..86652bf 100644
--- a/ping/ping.h
+++ b/ping/ping.h
@@ -380,7 +380,6 @@ int is_ours(struct ping_rts *rts, socket_st *sock, uint16_t id);
extern int pinger(struct ping_rts *rts, ping_func_set_st *fset, socket_st *sock);
extern void sock_setbufs(struct ping_rts *rts, socket_st *, int alloc);
extern void setup(struct ping_rts *rts, socket_st *);
-extern int contains_pattern_in_payload(struct ping_rts *rts, uint8_t *ptr);
extern int main_loop(struct ping_rts *rts, ping_func_set_st *fset, socket_st*,
uint8_t *packet, int packlen);
extern int finish(struct ping_rts *rts);
diff --git a/ping/ping6_common.c b/ping/ping6_common.c
index 459f63e..fcb48be 100644
--- a/ping/ping6_common.c
+++ b/ping/ping6_common.c
@@ -823,8 +823,6 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
return 1;
if (!is_ours(rts, sock, icmph->icmp6_id))
return 1;
- if (!contains_pattern_in_payload(rts, (uint8_t *)(icmph + 1)))
- return 1; /* 'Twas really not our ECHO */
if (gather_statistics(rts, (uint8_t *)icmph, sizeof(*icmph), cc,
ntohs(icmph->icmp6_seq),
hops, 0, tv, pr_addr(rts, from, sizeof *from),
diff --git a/ping/ping_common.c b/ping/ping_common.c
index 33e6003..357c39d 100644
--- a/ping/ping_common.c
+++ b/ping/ping_common.c
@@ -553,24 +553,6 @@ void setup(struct ping_rts *rts, socket_st *sock)
}
}
-/*
- * Return 0 if pattern in payload point to be ptr did not match the pattern that was sent
- */
-int contains_pattern_in_payload(struct ping_rts *rts, uint8_t *ptr)
-{
- size_t i;
- uint8_t *cp, *dp;
-
- /* check the data */
- cp = ((u_char *)ptr) + sizeof(struct timeval);
- dp = &rts->outpack[8 + sizeof(struct timeval)];
- for (i = sizeof(struct timeval); i < rts->datalen; ++i, ++cp, ++dp) {
- if (*cp != *dp)
- return 0;
- }
- return 1;
-}
-
int main_loop(struct ping_rts *rts, ping_func_set_st *fset, socket_st *sock,
uint8_t *packet, int packlen)
{
--
2.46.0

View File

@ -0,0 +1,36 @@
From 1c66917a079e95f00e9a1f2af1329c65501e8a60 Mon Sep 17 00:00:00 2001
From: Petr Vorel <pvorel@suse.cz>
Date: Mon, 18 Oct 2021 15:27:35 +0200
Subject: [PATCH 1/4] ping: Move ping_rts->multicast
as it's used for both IPv4 and IPv6.
Signed-off-by: Petr Vorel <pvorel@suse.cz>
(cherry picked from commit 7a4ec7532871772cb22a3b2c42f6006f95f8b263)
---
ping/ping.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ping/ping.h b/ping/ping.h
index 703296d..a5f05f4 100644
--- a/ping/ping.h
+++ b/ping/ping.h
@@ -192,6 +192,7 @@ struct ping_rts {
struct sockaddr_in6 source6;
struct sockaddr_in6 whereto6;
struct sockaddr_in6 firsthop6;
+ int multicast;
/* Used only in ping.c */
int ts_type;
@@ -201,7 +202,6 @@ struct ping_rts {
int optlen;
int settos; /* Set TOS, Precedence or other QOS options */
int broadcast_pings;
- int multicast;
struct sockaddr_in source;
/* Used only in ping_common.c */
--
2.46.0

View File

@ -0,0 +1,133 @@
From aa75473cac4a37cd673da3a66904878efcfdbd6f Mon Sep 17 00:00:00 2001
From: Petr Vorel <pvorel@suse.cz>
Date: Mon, 18 Oct 2021 15:13:44 +0200
Subject: [PATCH 2/3] ping: Print reply from Subnet-Router anycast address
by detecting Subnet-Router address for 64 bit prefix and suppress
address comparison check.
5e052ad ("ping: discard packets with wrong source address") correctly
hid replies with wrong source address to comply RFC 1122 (Section
3.2.1.3: "The IP source address in an ICMP Echo Reply MUST be the same
as the specific-destination address").
While change in 5e052ad works for broadcast and multicast addresses and
some of anycast addresses, it does not work for (at least) Subnet-Router
anycast address):
# VETH1_IPV6=fd00:dead:beef:1234::1
# VPEER1_IPV6=fd00:dead:beef:1234::2
# ip netns add ns-ipv6
# ip li add name veth1 type veth peer name vpeer1
# ip -6 addr add $VETH1_IPV6/64 dev veth1
# ip li set dev veth1 up
# ip li set dev vpeer1 netns ns-ipv6
# ip netns exec ns-ipv6 ip li set dev lo up
# ip netns exec ns-ipv6 ip -6 addr add $VPEER1_IPV6/64 dev vpeer1
# ip netns exec ns-ipv6 ip li set vpeer1 up
# ip netns exec ns-ipv6 ip -6 route add default dev vpeer1 via $VETH1_IPV6
# sysctl -w net.ipv6.conf.all.forwarding=1
$ ping -c1 ff02::1 # anycast - all nodes
PING ff02::1(ff02::1) 56 data bytes
64 bytes from fe80::9c9c:ffff:fe14:e9d2%vpeer1: icmp_seq=1 ttl=64 time=0.064 ms
$ ping -c1 ff02::2 # anycast - all routers
PING ff02::2(ff02::2) 56 data bytes
64 bytes from fe80::5496:9ff:fef5:8f01%vpeer1: icmp_seq=1 ttl=64 time=0.088 ms
$ ping -c1 -W5 fd00:dead:beef:1234:: # Subnet-Router anycast
PING fd00:dead:beef:1234::(fd00:dead:beef:1234::) 56 data bytes
Subnet-Router anycast address works for both busybox ping (without
printing the real source address) and fping:
$ busybox ping -c1 fd00:dead:beef:1234::
PING fd00:dead:beef:1234:: (fd00:dead:beef:1234::): 56 data bytes
64 bytes from fd00:dead:beef:1234::1: seq=0 ttl=64 time=0.122 ms
$ fping -c1 fd00:dead:beef:1234::
[<- fd00:dead:beef:1234::1]fd00:dead:beef:1234:: : [0], 64 bytes, 0.096 ms (0.096 avg, 0% loss)
RFC 4291 specifies Subnet-Router anycast address as [1]:
The Subnet-Router anycast address is predefined. Its format is as
follows:
| n bits | 128-n bits |
+------------------------------------------------+----------------+
| subnet prefix | 00000000000000 |
+------------------------------------------------+----------------+
The "subnet prefix" in an anycast address is the prefix that
identifies a specific link. This anycast address is syntactically
the same as a unicast address for an interface on the link with the
interface identifier set to zero.
=> to detect Subnet-Router anycast address we need to know prefix, which
we don't know, thus detect it for prefix 64 (the default IPv6 prefix).
[1] https://datatracker.ietf.org/doc/html/rfc4291#section-2.6.1
Fixes: 5e052ad ("ping: discard packets with wrong source address")
Closes: https://github.com/iputils/iputils/issues/371
Reported-by: Tim Sandquist
Signed-off-by: Petr Vorel <pvorel@suse.cz>
(cherry picked from commit 15a5e5c7aace5a7a782ff802988e04ed4c1148a5)
---
ping/ping.h | 1 +
ping/ping6_common.c | 12 +++++++++++-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/ping/ping.h b/ping/ping.h
index 86652bf..f26fdac 100644
--- a/ping/ping.h
+++ b/ping/ping.h
@@ -212,6 +212,7 @@ struct ping_rts {
#endif
/* Used only in ping6_common.c */
+ int subnet_router_anycast; /* Subnet-Router anycast (RFC 4291) */
struct sockaddr_in6 firsthop;
unsigned char cmsgbuf[4096];
size_t cmsglen;
diff --git a/ping/ping6_common.c b/ping/ping6_common.c
index fcb48be..d0d2d84 100644
--- a/ping/ping6_common.c
+++ b/ping/ping6_common.c
@@ -101,6 +101,7 @@ int ping6_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
struct socket_st *sock)
{
int hold, packlen;
+ size_t i;
unsigned char *packet;
char *target;
struct icmp6_filter filter;
@@ -247,6 +248,15 @@ int ping6_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
rts->pmtudisc = IPV6_PMTUDISC_DO;
}
+ /* detect Subnet-Router anycast at least for the default prefix 64 */
+ rts->subnet_router_anycast = 1;
+ for (i = 8; i < sizeof(struct in6_addr); i++) {
+ if (rts->whereto6.sin6_addr.s6_addr[i]) {
+ rts->subnet_router_anycast = 0;
+ break;
+ }
+ }
+
if (rts->pmtudisc >= 0) {
if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &rts->pmtudisc,
sizeof rts->pmtudisc) == -1)
@@ -818,7 +828,7 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
}
if (icmph->icmp6_type == ICMP6_ECHO_REPLY) {
- if (!rts->multicast &&
+ if (!rts->multicast && !rts->subnet_router_anycast &&
memcmp(&from->sin6_addr.s6_addr, &rts->whereto6.sin6_addr.s6_addr, 16))
return 1;
if (!is_ours(rts, sock, icmph->icmp6_id))
--
2.46.0

View File

@ -0,0 +1,149 @@
From ea2808dc199b89c12dd3b3a968e67bc0f522d399 Mon Sep 17 00:00:00 2001
From: Petr Vorel <pvorel@suse.cz>
Date: Fri, 15 Oct 2021 17:38:51 +0200
Subject: [PATCH 3/3] ping: Print reply with wrong source with warning
5e052ad ("ping: discard packets with wrong source address") correctly
hid replies with wrong source address to comply RFC 1122 (Section
3.2.1.3: "The IP source address in an ICMP Echo Reply MUST be the same
as the specific-destination address").
This caused to hide reply when pinging Subnet-Router anycast address.
Although it was fixed in the previous commit, relax this to admit the
reply but print warning "DIFFERENT ADDRESS!". ping is diagnostic program,
with insisting on RFC we force people to use tcpdump to see replies.
Link: https://github.com/iputils/iputils/issues/371
Reviewed-by: Matteo Croce <mcroce@microsoft.com>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
(cherry picked from commit 5f6bec5ab57cc8beaa78f5756a0ffbdf01f28d36)
---
ping/ping.c | 10 ++++++----
ping/ping.h | 3 ++-
ping/ping6_common.c | 13 ++++++++-----
ping/ping_common.c | 6 +++++-
4 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/ping/ping.c b/ping/ping.c
index 0655bf4..81ee7c8 100644
--- a/ping/ping.c
+++ b/ping/ping.c
@@ -1504,6 +1504,7 @@ int ping4_parse_reply(struct ping_rts *rts, struct socket_st *sock,
int reply_ttl;
uint8_t *opts, *tmp_ttl;
int olen;
+ int wrong_source = 0;
/* Check the IP header */
ip = (struct iphdr *)buf;
@@ -1544,15 +1545,16 @@ int ping4_parse_reply(struct ping_rts *rts, struct socket_st *sock,
csfailed = in_cksum((unsigned short *)icp, cc, 0);
if (icp->type == ICMP_ECHOREPLY) {
- if (!rts->broadcast_pings && !rts->multicast &&
- from->sin_addr.s_addr != rts->whereto.sin_addr.s_addr)
- return 1;
if (!is_ours(rts, sock, icp->un.echo.id))
return 1; /* 'Twas not our ECHO */
+
+ if (!rts->broadcast_pings && !rts->multicast &&
+ from->sin_addr.s_addr != rts->whereto.sin_addr.s_addr)
+ wrong_source = 1;
if (gather_statistics(rts, (uint8_t *)icp, sizeof(*icp), cc,
ntohs(icp->un.echo.sequence),
reply_ttl, 0, tv, pr_addr(rts, from, sizeof *from),
- pr_echo_reply, rts->multicast)) {
+ pr_echo_reply, rts->multicast, wrong_source)) {
fflush(stdout);
return 0;
}
diff --git a/ping/ping.h b/ping/ping.h
index f26fdac..703296d 100644
--- a/ping/ping.h
+++ b/ping/ping.h
@@ -389,7 +389,8 @@ extern void common_options(int ch);
extern int gather_statistics(struct ping_rts *rts, uint8_t *icmph, int icmplen,
int cc, uint16_t seq, int hops,
int csfailed, struct timeval *tv, char *from,
- void (*pr_reply)(uint8_t *ptr, int cc), int multicast);
+ void (*pr_reply)(uint8_t *ptr, int cc), int multicast,
+ int wrong_source);
extern void print_timestamp(struct ping_rts *rts);
void fill(struct ping_rts *rts, char *patp, unsigned char *packet, size_t packet_size);
diff --git a/ping/ping6_common.c b/ping/ping6_common.c
index d0d2d84..4712928 100644
--- a/ping/ping6_common.c
+++ b/ping/ping6_common.c
@@ -802,6 +802,7 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
struct cmsghdr *c;
struct icmp6_hdr *icmph;
int hops = -1;
+ int wrong_source = 0;
for (c = CMSG_FIRSTHDR(msg); c; c = CMSG_NXTHDR(msg, c)) {
if (c->cmsg_level != IPPROTO_IPV6)
@@ -828,16 +829,18 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
}
if (icmph->icmp6_type == ICMP6_ECHO_REPLY) {
- if (!rts->multicast && !rts->subnet_router_anycast &&
- memcmp(&from->sin6_addr.s6_addr, &rts->whereto6.sin6_addr.s6_addr, 16))
- return 1;
if (!is_ours(rts, sock, icmph->icmp6_id))
return 1;
+
+ if (!rts->multicast && !rts->subnet_router_anycast &&
+ memcmp(&from->sin6_addr.s6_addr, &rts->whereto6.sin6_addr.s6_addr, 16))
+ wrong_source = 1;
+
if (gather_statistics(rts, (uint8_t *)icmph, sizeof(*icmph), cc,
ntohs(icmph->icmp6_seq),
hops, 0, tv, pr_addr(rts, from, sizeof *from),
pr_echo_reply,
- rts->multicast)) {
+ rts->multicast, wrong_source)) {
fflush(stdout);
return 0;
}
@@ -850,7 +853,7 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
seq,
hops, 0, tv, pr_addr(rts, from, sizeof *from),
pr_niquery_reply,
- rts->multicast))
+ rts->multicast, 0))
return 0;
} else {
int nexthdr;
diff --git a/ping/ping_common.c b/ping/ping_common.c
index 357c39d..0336259 100644
--- a/ping/ping_common.c
+++ b/ping/ping_common.c
@@ -711,7 +711,8 @@ int main_loop(struct ping_rts *rts, ping_func_set_st *fset, socket_st *sock,
int gather_statistics(struct ping_rts *rts, uint8_t *icmph, int icmplen,
int cc, uint16_t seq, int hops,
int csfailed, struct timeval *tv, char *from,
- void (*pr_reply)(uint8_t *icmph, int cc), int multicast)
+ void (*pr_reply)(uint8_t *icmph, int cc), int multicast,
+ int wrong_source)
{
int dupflag = 0;
long triptime = 0;
@@ -804,10 +805,13 @@ restamp:
printf(_(" time=%ld.%03ld ms"), triptime / 1000,
triptime % 1000);
}
+
if (dupflag && (!multicast || rts->opt_verbose))
printf(_(" (DUP!)"));
if (csfailed)
printf(_(" (BAD CHECKSUM!)"));
+ if (wrong_source)
+ printf(_(" (DIFFERENT ADDRESS!)"));
/* check the data */
cp = ((unsigned char *)ptr) + sizeof(struct timeval);
--
2.46.0

View File

@ -0,0 +1,51 @@
From 42ff1833920e2524b07790243ef9146125f5b2c4 Mon Sep 17 00:00:00 2001
From: Petr Vorel <pvorel@suse.cz>
Date: Wed, 10 Aug 2022 21:05:22 +0200
Subject: [PATCH] ping: Fix socket error reporting
There is actually no need for errno EAFNOSUPPORT special handling,
nor for any other errno. *All* errors needs to be reported on verbose
mode or when socket is required. If AF_INET6 socket is used with
disabled IPv6, error reporting is done by gai_strerror() (ipv6.disable=1)
or by connect() error handling in ping6_run() (EADDRNOTAVAIL on
net.ipv6.conf.all.disable_ipv6=1).
Bug was hidden because condition "errno == EAFNOSUPPORT && socktype ==
AF_INET6" introduced in d141cb6 was always false as AF_INET6 is is an address
family not a socket type, until otherwise correct fix 904cdb6. Attempt
to fix it in 79d713e introduced regression that other errors weren't
reported (e.g. EPERM on RAW socket on non-root, see #406).
Closes: https://github.com/iputils/iputils/pull/418
Fixes: https://github.com/iputils/iputils/issues/406
Fixes: 79d713e ("ping: Remove 'unsupported IPv6' warning on disabled IPv6")
Fixes: d141cb6 ("ping: work with older kernels that don't support ping sockets")
Reported-by: Benjamin Poirier <benjamin.poirier@gmail.com>
Tested-by: Benjamin Poirier <benjamin.poirier@gmail.com>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
(cherry picked from commit bbe451f91ecc769ac5f70c1269372a6cc28d6814)
---
ping/ping.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/ping/ping.c b/ping/ping.c
index 81ee7c8..ff7e742 100644
--- a/ping/ping.c
+++ b/ping/ping.c
@@ -147,11 +147,7 @@ static void create_socket(struct ping_rts *rts, socket_st *sock, int family,
}
if (sock->fd == -1) {
- /* Report error related to disabled IPv6 only when IPv6 also failed or in
- * verbose mode. Report other errors always.
- */
- if ((errno == EAFNOSUPPORT && family == AF_INET6 && requisite) ||
- rts->opt_verbose)
+ if (requisite || rts->opt_verbose)
error(0, errno, "socket");
if (requisite)
exit(2);
--
2.46.0

View File

@ -0,0 +1,95 @@
From 36580e1d539b4bb7c187d4cf9ccc63afad9edbb1 Mon Sep 17 00:00:00 2001
From: Lahav Schlesinger <lschlesinger@drivenets.com>
Date: Wed, 30 Jun 2021 13:06:13 +0300
Subject: [PATCH 1/2] ping: Fix ping6 binding to VRF and address
Since Linux kernel commit 1893ff20275b ("net/ipv6: Add l3mdev check to
ipv6_chk_addr_and_flags") from v4.17-rc1 ping fails when trying to
create IPv6 SOCK_RAW socket (e.g. if net.ipv4.ping_group_range = 1 0)
and passing both -I <vrf_interface> and -I <local_ipv6_addr>.
It works for IPv4 SOCK_RAW socket.
# ip netns add tmp_ns
# ip -n tmp_ns link add vrf_1 type vrf table 10001
# ip -n tmp_ns link add lo10 type dummy
# ip -n tmp_ns link set lo10 master vrf_1
# ip -n tmp_ns link set vrf_1 up
# ip -n tmp_ns link set lo10 up
# ip -n tmp_ns link set lo up
# ip -n tmp_ns addr add 1:2::3:4/128 dev lo10
# ip -n tmp_ns addr add 1.2.3.4/32 dev lo10
# ip netns exec tmp_ns ping -6 1:2::3:4 -I vrf_1 -I 1:2::3:4 -c 1 # IPv6 broken
ping: bind icmp socket: Cannot assign requested address
# ping 1.2.3.4 -I vrf_1 -I 1.2.3.4 -c 1 # IPv4 working
PING 1.2.3.4 (1.2.3.4) from 1.2.3.4 vrf_1: 56(84) bytes of data.
64 bytes from 1.2.3.4: icmp_seq=1 ttl=64 time=0.090 ms
--- 1.2.3.4 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.090/0.090/0.090/0.000 ms
ping fails because it doesn't actually bind to the VRF interface, while
after 1893ff20275b, binding to an IPv6 address searches only on the same
l3mdev as the device the function receives. If the socket wasn't
SO_BINDTODEVICE-ed, then the kernel will only search for devices that
are not ensalved to an l3mdev device (= in the default VRF), which will
cause the bind() to fail.
Only SOCK_RAW socket is affected. SOCK_DGRAM is not affected because
Linux kernel doesn't check the device the socket was SO_BINDTODEVICE-ed
to, but only the device from addr->sin6_scope_id (which if none is
passed, it will again only search devices in the default VRF).
NOTE: creating network namespace to reproduce the issue is needed just
on systems with net.ipv4.ping_group_range = 0 2147483647 (e.g. current
Fedora, openSUSE, Ubuntu), which causes to use SOCK_DGRAM socket.
Alternatively to force SOCK_RAW to it'd be enough just to properly set
net.ipv4.ping_group_range:
# echo "1 0" > /proc/sys/net/ipv4/ping_group_range
Closes: https://github.com/iputils/iputils/pull/344
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Lahav Schlesinger <lschlesinger@drivenets.com>
[ pvorel: adjusted commit message ]
Signed-off-by: Petr Vorel <pvorel@suse.cz>
(cherry picked from commit 7c65999f98bc4a1984594b7fad1af0eaf0b9d34b)
---
ping/ping6_common.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/ping/ping6_common.c b/ping/ping6_common.c
index 4712928..98b5adb 100644
--- a/ping/ping6_common.c
+++ b/ping/ping6_common.c
@@ -223,6 +223,8 @@ int ping6_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
if (rts->device) {
struct cmsghdr *cmsg;
struct in6_pktinfo *ipi;
+ int rc;
+ int errno_save;
cmsg = (struct cmsghdr *)(rts->cmsgbuf + rts->cmsglen);
rts->cmsglen += CMSG_SPACE(sizeof(*ipi));
@@ -233,6 +235,15 @@ int ping6_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
ipi = (struct in6_pktinfo *)CMSG_DATA(cmsg);
memset(ipi, 0, sizeof(*ipi));
ipi->ipi6_ifindex = if_name2index(rts->device);
+
+ enable_capability_raw();
+ rc = setsockopt(sock->fd, SOL_SOCKET, SO_BINDTODEVICE,
+ rts->device, strlen(rts->device) + 1);
+ errno_save = errno;
+ disable_capability_raw();
+
+ if (rc == -1)
+ error(2, errno_save, "SO_BINDTODEVICE %s", rts->device);
}
if (IN6_IS_ADDR_MULTICAST(&rts->whereto6.sin6_addr)) {
--
2.46.0

View File

@ -0,0 +1,54 @@
From a2d2428c5fa6bf370486f509b18862c5c7b8b47e Mon Sep 17 00:00:00 2001
From: Petr Vorel <pvorel@suse.cz>
Date: Tue, 9 Nov 2021 02:39:56 +0100
Subject: [PATCH 2/2] ping6: Avoid binding to non-VRF
This fixes permission issue when specifying just address (without VRF)
unless having CAP_NET_ADMIN (i.e. root) permission:
$ ./builddir/ping/ping -c1 -I lo ::1
./builddir/ping/ping: SO_BINDTODEVICE lo: Operation not permitted
because setsockopt() SO_BINDTODEVICE (similar to bind()) can be only done on
opt_strictsource.
Fixes: 7c65999 ("ping: Fix ping6 binding to VRF and address")
Signed-off-by: Petr Vorel <pvorel@suse.cz>
(cherry picked from commit f52b582248f1f870e870a9973621805d969906b4)
---
ping/ping6_common.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/ping/ping6_common.c b/ping/ping6_common.c
index 98b5adb..a784be0 100644
--- a/ping/ping6_common.c
+++ b/ping/ping6_common.c
@@ -236,14 +236,16 @@ int ping6_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
memset(ipi, 0, sizeof(*ipi));
ipi->ipi6_ifindex = if_name2index(rts->device);
- enable_capability_raw();
- rc = setsockopt(sock->fd, SOL_SOCKET, SO_BINDTODEVICE,
- rts->device, strlen(rts->device) + 1);
- errno_save = errno;
- disable_capability_raw();
-
- if (rc == -1)
- error(2, errno_save, "SO_BINDTODEVICE %s", rts->device);
+ if (rts->opt_strictsource) {
+ enable_capability_raw();
+ rc = setsockopt(sock->fd, SOL_SOCKET, SO_BINDTODEVICE,
+ rts->device, strlen(rts->device) + 1);
+ errno_save = errno;
+ disable_capability_raw();
+
+ if (rc == -1)
+ error(2, errno_save, "SO_BINDTODEVICE %s", rts->device);
+ }
}
if (IN6_IS_ADDR_MULTICAST(&rts->whereto6.sin6_addr)) {
--
2.46.0

View File

@ -3,7 +3,7 @@
Summary: Network monitoring tools including ping Summary: Network monitoring tools including ping
Name: iputils Name: iputils
Version: 20210202 Version: 20210202
Release: 9%{?dist} Release: 11%{?dist}
# some parts are under the original BSD (ping.c) # some parts are under the original BSD (ping.c)
# some are under GPLv2+ (tracepath.c) # some are under GPLv2+ (tracepath.c)
License: BSD and GPLv2+ License: BSD and GPLv2+
@ -20,6 +20,17 @@ Source5: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
# Upstream patches # Upstream patches
Patch001: 001-ping-remove-unsupported-IPv6-warning-on-disabled-IPv6.patch Patch001: 001-ping-remove-unsupported-IPv6-warning-on-disabled-IPv6.patch
Patch002: 002-arping-Fix-1s-delay-on-exit-for-unsolicited-arpings.patch
Patch003: 003-arping-Fix-unsolicited-ARP-regressions-on-c-1.patch
Patch004: 004-arping-fix-typo-in-error-checking.patch
Patch005: 005-arping-exit-0-if-running-in-deadline-mode-and-we-see.patch
Patch006: 006-Revert-Add-strict-pattern-matching-on-response-when-.patch
Patch007: 007-ping-Move-ping_rts-multicast.patch
Patch008: 008-ping-Print-reply-from-Subnet-Router-anycast-address.patch
Patch009: 009-ping-Print-reply-with-wrong-source-with-warning.patch
Patch010: 010-ping-Fix-socket-error-reporting.patch
Patch011: 011-ping-Fix-ping6-binding-to-VRF-and-address.patch
Patch012: 012-ping6-Avoid-binding-to-non-VRF.patch
# Downstream-only patches # Downstream-only patches
Patch100: 100-iputils-ifenslave.patch Patch100: 100-iputils-ifenslave.patch
@ -130,6 +141,15 @@ install -cp ifenslave.8 ${RPM_BUILD_ROOT}%{_mandir}/man8/
%attr(644,root,root) %{_mandir}/man8/ninfod.8.gz %attr(644,root,root) %{_mandir}/man8/ninfod.8.gz
%changelog %changelog
* Fri Sep 06 2024 Jan Macku <jamacku@redhat.com> - 20210202-11
- ping: Fix ping6 binding to VRF and address (RHEL-57734)
* Wed Aug 28 2024 Jan Macku <jamacku@redhat.com> - 20210202-10
- arping: Fix 1s delay on exit for unsolicited arpings (RHEL-34110)
- arping: exit 0 if running in deadline mode and we see replies (RHEL-27718)
- ping: Print reply with wrong source with warning & some follow-up fixes (RHEL-12789, RHEL-13480)
- ping: Fix socket error reporting (RHEL-4608)
* Wed May 03 2023 Jan Macku <jamacku@redhat.com> - 20210202-9 * Wed May 03 2023 Jan Macku <jamacku@redhat.com> - 20210202-9
- ping: Remove 'unsupported IPv6' warning on disabled IPv6 (rhbz#2152511) - ping: Remove 'unsupported IPv6' warning on disabled IPv6 (rhbz#2152511)