diff options
author | Jose Luis Duran <jlduran@gmail.com> | 2023-02-09 15:47:53 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2023-03-19 16:23:06 +0000 |
commit | 20b41303140eee4dfb896558fb83600c5f013d39 (patch) | |
tree | c3041cab2ee4c9d2192abeea8bbb0ee778fb2ed8 /sbin/ping/ping.c | |
parent | ce7b20e5129cf0f269951b313d336a9c7d54d790 (diff) | |
download | src-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.c | 19 |
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", |