Skip to content

Commit 28cedef

Browse files
committed
ping: Split JSON hostname and IP address
Previously hostname and IP were printed together in "host" key: {"bytes": 64, "host": "www.seznam.cz (77.75.77.222)", "seq": 1, "ttl": 55, "time": "11.0"} {"host": "seznam.cz", "transmitted": 1, "received": 1, "duplicates": 0, "corrupted": 0, "errors": 0, "loss": 0, "time": 0, "rtt": {"min": "11.015", "avg": "11.015", "max": "11.015", "mdev": "0.000"}} Now output has new array "host", with "arg", "cname" and "ip" keys, replacing the original "host" key: {"bytes": 64, "host": {"arg": "seznam.cz", "cname": "www.seznam.cz", "ip": "77.75.79.222"}, "seq": 1, "ttl": 55, "time": "11.4"} {"transmitted": 1, "received": 1, "duplicates": 0, "corrupted": 0, "errors": 0, "loss": 0, "time": 0, "rtt": {"min": "11.384", "avg": "11.384", "max": "11.384", "mdev": "0.000"}} * "arg" - original argv[1] parameter (destination). * "cname" - getaddrinfo() reverse DNS resolution (PTR lookup), NOTE: not added if empty due calling ping with "-n" * "ip" - IPv4 or IPv6 That required rewrite handling hostname and reverse IP resolution. Previously were both hostname and IP address passed to gather_statistics() in a single string. Now function have both as separate parameters. That required adding new function set_cname_ip(). Fixes: iputils#609 Signed-off-by: Petr Vorel <pvorel@suse.cz>
1 parent 9900265 commit 28cedef

8 files changed

Lines changed: 88 additions & 27 deletions

File tree

ping/ping.c

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,9 +1701,13 @@ int ping4_parse_reply(struct ping_rts *rts, struct socket_st *sock,
17011701
if (!rts->broadcast_pings && !rts->multicast &&
17021702
from->sin_addr.s_addr != rts->whereto.sin_addr.s_addr)
17031703
wrong_source = 1;
1704+
1705+
char cname[NI_MAXHOST] = "";
1706+
char ip[NI_MAXHOST] = "";
1707+
set_cname_ip(rts, from, sizeof(*from), 1, cname, sizeof(cname), ip, sizeof(ip));
17041708
if (gather_statistics(rts, (uint8_t *)icp, sizeof(*icp), cc,
17051709
ntohs(icp->un.echo.sequence),
1706-
reply_ttl, csfailed, tv, pr_addr(rts, from, sizeof *from),
1710+
reply_ttl, csfailed, tv, cname, ip,
17071711
pr_echo_reply, rts->multicast, wrong_source)) {
17081712
fflush(stdout);
17091713
return 0;
@@ -1804,44 +1808,55 @@ char *pr_addr(struct ping_rts *rts, void *sa, socklen_t salen)
18041808
*
18051809
* Return an ascii host address. Reverse name resolution is not performed.
18061810
*/
1807-
18081811
char *pr_raw_addr(struct ping_rts *rts, void *sa, socklen_t salen)
18091812
{
18101813
return _pr_addr(rts, sa, salen, 0);
18111814
}
18121815

18131816
/*
1814-
* _pr_addr --
1817+
* set_cname_ip --
18151818
*
1816-
* Return an ascii host address optionally with a hostname.
1819+
* Set an ascii host address and IP via reverse name resolution.
18171820
*/
1818-
char *_pr_addr(struct ping_rts *rts, void *sa, socklen_t salen, int resolve_name)
1821+
void set_cname_ip(struct ping_rts *rts, void *sa, socklen_t salen, int resolve_name,
1822+
char *cname, size_t cname_len, char *ip, size_t ip_len)
18191823
{
1820-
static char buffer[4096] = "";
18211824
static struct sockaddr_storage last_sa = {0};
18221825
static socklen_t last_salen = 0;
1823-
char name[NI_MAXHOST] = "";
1824-
char address[NI_MAXHOST] = "";
18251826

18261827
if (salen == last_salen && !memcmp(sa, &last_sa, salen))
1827-
return buffer;
1828+
return;
18281829

18291830
memcpy(&last_sa, sa, (last_salen = salen));
18301831

18311832
rts->in_pr_addr = !setjmp(rts->pr_addr_jmp);
18321833

1833-
getnameinfo(sa, salen, address, sizeof address, NULL, 0, getnameinfo_flags | NI_NUMERICHOST);
1834+
getnameinfo(sa, salen, ip, ip_len, NULL, 0, getnameinfo_flags | NI_NUMERICHOST);
18341835
if (!rts->exiting && resolve_name && (rts->opt_force_lookup || !rts->opt_numeric))
1835-
getnameinfo(sa, salen, name, sizeof name, NULL, 0, getnameinfo_flags);
1836-
1837-
if (*name && strncmp(name, address, NI_MAXHOST))
1838-
snprintf(buffer, sizeof buffer, "%s (%s)", name, address);
1839-
else
1840-
snprintf(buffer, sizeof buffer, "%s", address);
1836+
getnameinfo(sa, salen, cname, cname_len, NULL, 0, getnameinfo_flags);
18411837

18421838
rts->in_pr_addr = 0;
1839+
}
1840+
1841+
/*
1842+
* _pr_addr --
1843+
*
1844+
* Return an ascii host address optionally with a hostname.
1845+
*/
1846+
char *_pr_addr(struct ping_rts *rts, void *sa, socklen_t salen, int resolve_name)
1847+
{
1848+
static char buffer[4096] = "";
1849+
char cname[NI_MAXHOST] = "";
1850+
char ip[NI_MAXHOST] = "";
1851+
1852+
set_cname_ip(rts, sa, salen, resolve_name, cname, sizeof(cname), ip, sizeof(ip));
1853+
1854+
if (*cname)
1855+
snprintf(buffer, sizeof buffer, "%s (%s)", cname, ip);
1856+
else
1857+
snprintf(buffer, sizeof buffer, "%s", ip);
18431858

1844-
return (buffer);
1859+
return buffer;
18451860
}
18461861

18471862
void ping4_install_filter(struct ping_rts *rts, socket_st *sock)

ping/ping.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,9 @@ extern void drop_capabilities(void);
415415

416416
char *pr_addr(struct ping_rts *rts, void *sa, socklen_t salen);
417417
char *pr_raw_addr(struct ping_rts *rts, void *sa, socklen_t salen);
418+
void set_cname_ip(struct ping_rts *rts, void *sa, socklen_t salen, int resolve_name,
419+
char *cname, size_t cname_len, char *ip, size_t ip_len);
420+
418421
char *str_interval(int interval);
419422

420423
int is_ours(struct ping_rts *rts, socket_st *sock, uint16_t id);
@@ -429,8 +432,8 @@ extern void status(struct ping_rts *rts);
429432
extern void common_options(int ch);
430433
extern int gather_statistics(struct ping_rts *rts, uint8_t *icmph, int icmplen,
431434
int cc, uint16_t seq, int hops,
432-
int csfailed, struct timeval *tv, char *from,
433-
void (*pr_reply)(struct ping_rts *rts, uint8_t *ptr, int cc), int multicast,
435+
int csfailed, struct timeval *tv, char *cname, char *ip,
436+
void (*pr_reply)(struct ping_rts *rts, uint8_t *icmph, int cc), int multicast,
434437
int wrong_source);
435438
extern void print_timestamp(struct ping_rts *rts);
436439
void fill(struct ping_rts *rts, char *patp, unsigned char *packet, unsigned packet_size);

ping/ping6_common.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,8 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
849849
return 1;
850850
}
851851

852+
char cname[NI_MAXHOST] = "";
853+
char ip[NI_MAXHOST] = "";
852854
if (icmph->icmp6_type == ICMP6_ECHO_REPLY) {
853855
if (!is_ours(rts, sock, icmph->icmp6_id))
854856
return 1;
@@ -857,9 +859,10 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
857859
memcmp(&from->sin6_addr.s6_addr, &rts->whereto6.sin6_addr.s6_addr, 16))
858860
wrong_source = 1;
859861

862+
set_cname_ip(rts, from, sizeof(*from), 1, cname, sizeof(cname), ip, sizeof(ip));
860863
if (gather_statistics(rts, (uint8_t *)icmph, sizeof(*icmph), cc,
861864
ntohs(icmph->icmp6_seq),
862-
hops, 0, tv, pr_addr(rts, from, sizeof *from),
865+
hops, 0, tv, cname, ip,
863866
pr_echo_reply,
864867
rts->multicast, wrong_source)) {
865868
fflush(stdout);
@@ -870,9 +873,11 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
870873
int seq = niquery_check_nonce(&rts->ni, nih->ni_nonce);
871874
if (seq < 0)
872875
return 1;
876+
877+
set_cname_ip(rts, from, sizeof(*from), 1, cname, sizeof(cname), ip, sizeof(ip));
873878
if (gather_statistics(rts, (uint8_t *)icmph, sizeof(*icmph), cc,
874879
seq,
875-
hops, 0, tv, pr_addr(rts, from, sizeof *from),
880+
hops, 0, tv, cname, ip,
876881
pr_niquery_reply,
877882
rts->multicast, 0))
878883
return 0;

ping/ping_common.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,7 @@ int main_loop(struct ping_rts *rts, ping_func_set_st *fset, socket_st *sock,
748748

749749
int gather_statistics(struct ping_rts *rts, uint8_t *icmph, int icmplen,
750750
int cc, uint16_t seq, int hops,
751-
int csfailed, struct timeval *tv, char *from,
751+
int csfailed, struct timeval *tv, char *cname, char *ip,
752752
void (*pr_reply)(struct ping_rts *rts, uint8_t *icmph, int cc), int multicast,
753753
int wrong_source)
754754
{
@@ -835,8 +835,8 @@ int gather_statistics(struct ping_rts *rts, uint8_t *icmph, int icmplen,
835835

836836
print_timestamp(rts);
837837
ping_print_int(rts, _("%d bytes "), "bytes", cc);
838-
// TODO: split host IP address and name into separate attributes in JSON?
839-
ping_print_str(rts, _("from %s:"), "host", from);
838+
839+
ping_print_host(rts, cname, ip);
840840

841841
if (pr_reply)
842842
pr_reply(rts, icmph, cc);

ping/ping_json.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: BSD-3-Clause
22
/*
33
* Copyright (c) 2024-2025 Georg Pfuetzenreuter <mail+ip@georg-pfuetzenreuter.net>
4+
* Copyright (c) Iputils Project, 2026
45
*/
56

67
#include "ping.h"
@@ -140,6 +141,28 @@ void construct_json(struct ping_rts *rts, enum PING_JSON_TYPE ptype, char *key,
140141
va_end(ap);
141142
}
142143

144+
void construct_json_host(struct ping_rts *rts, char *cname, char *ip)
145+
{
146+
if (!rts->opt_json)
147+
return;
148+
149+
if (*rts->json_packet.object)
150+
json_continue(&rts->json_packet);
151+
else
152+
json_start_object(&rts->json_packet);
153+
154+
struct ping_json_buffer json_host;
155+
156+
json_start_object(&json_host);
157+
158+
json_kv_str_continue(&json_host, "arg", rts->hostname);
159+
if (*cname)
160+
json_kv_str_continue(&json_host, "cname", cname);
161+
json_kv_str(&json_host, "ip", ip);
162+
163+
json_kv_object(&rts->json_packet, "host", &json_host);
164+
}
165+
143166
void construct_json_statistics(struct ping_rts *rts, struct timespec tv, char *rttmin, char *rttavg, char *rttmax, char *rttmdev)
144167
{
145168
if (!rts->opt_json)
@@ -150,7 +173,6 @@ void construct_json_statistics(struct ping_rts *rts, struct timespec tv, char *r
150173
else
151174
json_start_object(&rts->json_stats);
152175

153-
json_kv_str_continue(&rts->json_stats, "host", rts->hostname);
154176
json_kv_int_continue(&rts->json_stats, "transmitted", rts->ntransmitted);
155177
json_kv_int_continue(&rts->json_stats, "received", rts->nreceived);
156178
json_kv_int_continue(&rts->json_stats, "duplicates", rts->nrepeats);

ping/ping_json.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* SPDX-License-Identifier: BSD-3-Clause */
22
/*
33
* Copyright (c) 2024 Georg Pfuetzenreuter <mail+ip@georg-pfuetzenreuter.net>
4+
* Copyright (c) Iputils Project, 2026
45
*/
56

67
#ifndef IPUTILS_PING_JSON_H
@@ -22,6 +23,7 @@ struct ping_json_buffer {
2223

2324
void construct_json(struct ping_rts *rts, enum PING_JSON_TYPE ptype, char *key, ...);
2425
void construct_json_error(struct ping_rts *rts, int errnum, char *errmsg);
26+
void construct_json_host(struct ping_rts *rts, char *cname, char *ip);
2527
void construct_json_statistics(struct ping_rts *rts, struct timespec tv, char *rttmin, char *rttavg, char *rttmax, char *rttmdev);
2628
void construct_json_statistics_flood(struct ping_rts *rts, char *ipg, char *ewma);
2729
void print_json_packet(struct ping_rts *rts);

ping/ping_output.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: BSD-3-Clause
22
/*
33
* Copyright (c) 2024-2025 Georg Pfuetzenreuter <mail+ip@georg-pfuetzenreuter.net>
4-
* Copyright (c) 2014-2025 Iputils project
4+
* Copyright (c) 2014-2026 Iputils project
55
* Copyright (c) 1989-2006 The Regents of the University of California
66
*/
77

@@ -115,6 +115,19 @@ static long llsqrt(long long a)
115115
return (long)x;
116116
}
117117

118+
inline void ping_print_host(struct ping_rts *rts, char *cname, char *ip)
119+
{
120+
if (rts->opt_json) {
121+
construct_json_host(rts, cname, ip);
122+
return;
123+
}
124+
125+
if (*cname && strncmp(cname, ip, NI_MAXHOST))
126+
printf(_("from %s (%s):"), cname, ip);
127+
else
128+
printf(_("from %s:"), ip);
129+
}
130+
118131
inline void ping_print_statistics(struct ping_rts *rts, struct timespec tv)
119132
{
120133
double tmdev;

ping/ping_output.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* SPDX-License-Identifier: BSD-3-Clause */
22
/*
33
* Copyright (c) 2024-2025 Georg Pfuetzenreuter <mail+ip@georg-pfuetzenreuter.net>
4-
* Copyright (c) Iputils Project, 2025
4+
* Copyright (c) Iputils Project, 2025-2026
55
*/
66

77
#define PING_ERROR_MAX 300
@@ -17,6 +17,7 @@ void ping_print_truncated(struct ping_rts *rts);
1717
void ping_print_packet(struct ping_rts *rts, ping_func_set_st *fset);
1818
void ping_print_error_parse(struct ping_rts *rts, char *reason);
1919
void ping_print_finish(struct ping_rts *rts);
20+
void ping_print_host(struct ping_rts *rts, char *cname, char *ip);
2021
void ping_print_statistics(struct ping_rts *rts, struct timespec tv);
2122
void ping_finish_line(struct ping_rts *rts);
2223

0 commit comments

Comments
 (0)