aboutsummaryrefslogtreecommitdiff
path: root/sbin/ping/ping.c
diff options
context:
space:
mode:
authorJose Luis Duran <jlduran@gmail.com>2023-02-09 15:47:53 +0000
committerMark Johnston <markj@FreeBSD.org>2023-03-19 16:23:06 +0000
commit20b41303140eee4dfb896558fb83600c5f013d39 (patch)
treec3041cab2ee4c9d2192abeea8bbb0ee778fb2ed8 /sbin/ping/ping.c
parentce7b20e5129cf0f269951b313d336a9c7d54d790 (diff)
downloadsrc-20b41303140eee4dfb896558fb83600c5f013d39.tar.gz
src-20b41303140eee4dfb896558fb83600c5f013d39.zip
ping: Print the IP options of the original packet
When an ICMP packet contains an IP packet in its payload, and that original IP packet contains options, these options were not displayed accordingly in pr_iph(). pr_iph() is a function that prints the original "quoted packet" IP header, with only an IP struct as an argument. The IP struct does not contain IP options, and it is not guaranteed that the options will be contiguous in memory to the IP struct after d9cacf605e2ac0f704e1ce76357cbfbe6cb63d52. Pass the raw ICMP data along with the IP struct, in order to print the options, if any. Reviewed by: markj MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D38469
Diffstat (limited to 'sbin/ping/ping.c')
-rw-r--r--sbin/ping/ping.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c
index fe319bfb70a5..b1721ad72a5c 100644
--- a/sbin/ping/ping.c
+++ b/sbin/ping/ping.c
@@ -225,7 +225,7 @@ static void pinger(void);
static char *pr_addr(struct in_addr);
static char *pr_ntime(n_time);
static void pr_icmph(struct icmp *, struct ip *, const u_char *const);
-static void pr_iph(struct ip *);
+static void pr_iph(struct ip *, const u_char *);
static void pr_pack(char *, ssize_t, struct sockaddr_in *, struct timespec *);
static void pr_retip(struct ip *, const u_char *);
static void status(int);
@@ -1157,7 +1157,6 @@ pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
struct ip oip;
u_char oip_header_len;
struct icmp oicmp;
- const u_char *oicmp_raw;
/*
* Get size of IP header of the received packet.
@@ -1355,8 +1354,6 @@ pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
}
memcpy(&oip, icmp_data_raw, sizeof(struct ip));
- oicmp_raw = icmp_data_raw + oip_header_len;
- memcpy(&oicmp, oicmp_raw, sizeof(struct icmp));
if (((options & F_VERBOSE) && uid == 0) ||
(!(options & F_QUIET2) &&
@@ -1366,7 +1363,7 @@ pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
(oicmp.icmp_id == ident))) {
(void)printf("%zd bytes from %s: ", cc,
pr_addr(from->sin_addr));
- pr_icmph(&icp, &oip, oicmp_raw);
+ pr_icmph(&icp, &oip, icmp_data_raw);
} else
return;
}
@@ -1663,14 +1660,13 @@ pr_icmph(struct icmp *icp, struct ip *oip, const u_char *const oicmp_raw)
* Print an IP header with options.
*/
static void
-pr_iph(struct ip *ip)
+pr_iph(struct ip *ip, const u_char *cp)
{
struct in_addr ina;
- u_char *cp;
int hlen;
hlen = ip->ip_hl << 2;
- cp = (u_char *)ip + sizeof(struct ip); /* point to options */
+ cp = cp + sizeof(struct ip); /* point to options */
(void)printf("Vr HL TOS Len ID Flg off TTL Pro cks Src Dst\n");
(void)printf(" %1x %1x %02x %04x %04x",
@@ -1723,7 +1719,12 @@ pr_addr(struct in_addr ina)
static void
pr_retip(struct ip *ip, const u_char *cp)
{
- pr_iph(ip);
+ int8_t hlen;
+
+ pr_iph(ip, cp);
+
+ hlen = ip->ip_hl << 2;
+ cp = cp + hlen;
if (ip->ip_p == 6)
(void)printf("TCP: from port %u, to port %u (decimal)\n",