From a787d4fd4d9e21dc4e338a697da4d930ea767fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20K=C3=BCthe?= Date: Thu, 4 Dec 2025 10:49:05 +0000 Subject: [PATCH 1/2] Fix htonl on 64-bit values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On modern systems, time values may be stored in a 64-bit integer. To send this over the network, it is necessary to package it appropriately. htonl is insufficient for this purpose, as it is limited to 32-bit values. See also https://stackoverflow.com/questions/3022552/is-there-any-standard-htonl-like-function-for-64-bits-integers-in-c Signed-off-by: Marek Küthe --- mping.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/mping.c b/mping.c index 29f79ec..bda051b 100644 --- a/mping.c +++ b/mping.c @@ -48,6 +48,14 @@ #define dbg(fmt,args...) do { if (debug) printf(fmt "\n", ##args); } while (0) #define sig(s,c) do { struct sigaction a = {.sa_handler=c};sigaction(s,&a,0); } while(0) +#if __BIG_ENDIAN__ +# define htonll(x) (x) +# define ntohll(x) (x) +#else +# define htonll(x) (((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) +# define ntohll(x) (((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) +#endif + #define MC_GROUP_DEFAULT "225.1.2.3" #define MC_GROUP_INET6 "ff2e::42" #define MC_PORT_DEFAULT 4321 @@ -528,8 +536,16 @@ void send_mping(int signo) packet->dest_host = mcaddr; packet->seq_no = htonl(seqno); packet->pid = pid; - packet->tv.tv_sec = htonl(packet->tv.tv_sec); - packet->tv.tv_usec = htonl(packet->tv.tv_usec); + + if (sizeof(packet->tv.tv_sec) == 8) + packet->tv.tv_sec = htonll(packet->tv.tv_sec); + else + packet->tv.tv_sec = htonl(packet->tv.tv_sec); + + if (sizeof(packet->tv.tv_usec) == 8) + packet->tv.tv_usec = htonll(packet->tv.tv_usec); + else + packet->tv.tv_usec = htonl(packet->tv.tv_usec); send_packet(packet, sizeof(struct mping) + arg_payload); seqno++; @@ -548,8 +564,17 @@ int process_mping(char *packet, int len, unsigned char type) rcvd_pkt = (struct mping *)packet; rcvd_pkt->seq_no = ntohl(rcvd_pkt->seq_no); - rcvd_pkt->tv.tv_sec = ntohl(rcvd_pkt->tv.tv_sec); - rcvd_pkt->tv.tv_usec = ntohl(rcvd_pkt->tv.tv_usec); + + + if (sizeof(rcvd_pkt->tv.tv_sec) == 8) + rcvd_pkt->tv.tv_sec = ntohll(rcvd_pkt->tv.tv_sec); + else + rcvd_pkt->tv.tv_sec = ntohl(rcvd_pkt->tv.tv_sec); + + if (sizeof(rcvd_pkt->tv.tv_usec) == 8) + rcvd_pkt->tv.tv_usec = ntohll(rcvd_pkt->tv.tv_usec); + else + rcvd_pkt->tv.tv_usec = ntohl(rcvd_pkt->tv.tv_usec); if (strcmp(rcvd_pkt->version, VERSION)) { dbg("Discarding packet: version mismatch (%s)", rcvd_pkt->version); @@ -655,8 +680,16 @@ void receiver_listen_loop(void) rcvd_pkt->src_host = myaddr; rcvd_pkt->dest_host = rcvd_pkt->src_host; rcvd_pkt->seq_no = htonl(rcvd_pkt->seq_no); - rcvd_pkt->tv.tv_sec = htonl(rcvd_pkt->tv.tv_sec); - rcvd_pkt->tv.tv_usec = htonl(rcvd_pkt->tv.tv_usec); + + if (sizeof(rcvd_pkt->tv.tv_sec) == 8) + rcvd_pkt->tv.tv_sec = htonll(rcvd_pkt->tv.tv_sec); + else + rcvd_pkt->tv.tv_sec = htonl(rcvd_pkt->tv.tv_sec); + + if (sizeof(rcvd_pkt->tv.tv_usec) == 8) + rcvd_pkt->tv.tv_usec = htonll(rcvd_pkt->tv.tv_usec); + else + rcvd_pkt->tv.tv_usec = htonl(rcvd_pkt->tv.tv_usec); /* send reply immediately */ send_packet(rcvd_pkt, len); @@ -798,6 +831,11 @@ int main(int argc, char **argv) if (ifindex <= 0) exit(1); + if (debug) { + struct mping packet; + printf("tv_sec/tv_usec size: %zu/%zu\n", sizeof(packet.tv.tv_sec), sizeof(packet.tv.tv_usec)); + } + init_socket(mcaddr.ss_family, ifindex); myaddr = addr; From f4659742c53b81113846f46a82a4de90554891df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20K=C3=BCthe?= Date: Thu, 4 Dec 2025 15:06:20 +0000 Subject: [PATCH 2/2] Refactor: Extract packet encoding functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marek Küthe --- mping.c | 65 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/mping.c b/mping.c index bda051b..1106873 100644 --- a/mping.c +++ b/mping.c @@ -377,6 +377,36 @@ char *ifdefault(char *iface, size_t len) return ifany(iface, len); } +static void hton_packet(struct mping *packet) +{ + packet->seq_no = htonl(packet->seq_no); + + if (sizeof(packet->tv.tv_sec) == 8) + packet->tv.tv_sec = htonll(packet->tv.tv_sec); + else + packet->tv.tv_sec = htonl(packet->tv.tv_sec); + + if (sizeof(packet->tv.tv_usec) == 8) + packet->tv.tv_usec = htonll(packet->tv.tv_usec); + else + packet->tv.tv_usec = htonl(packet->tv.tv_usec); +} + +static void ntoh_packet(struct mping *packet) +{ + packet->seq_no = ntohl(packet->seq_no); + + if (sizeof(packet->tv.tv_sec) == 8) + packet->tv.tv_sec = ntohll(packet->tv.tv_sec); + else + packet->tv.tv_sec = ntohl(packet->tv.tv_sec); + + if (sizeof(packet->tv.tv_usec) == 8) + packet->tv.tv_usec = ntohll(packet->tv.tv_usec); + else + packet->tv.tv_usec = ntohl(packet->tv.tv_usec); +} + /* Find IP address of default outbound LAN interface */ int ifinfo(char *iface, inet_addr_t *addr, int family) { @@ -534,18 +564,10 @@ void send_mping(int signo) packet->ttl = arg_ttl; packet->src_host = myaddr; packet->dest_host = mcaddr; - packet->seq_no = htonl(seqno); + packet->seq_no = seqno; packet->pid = pid; - if (sizeof(packet->tv.tv_sec) == 8) - packet->tv.tv_sec = htonll(packet->tv.tv_sec); - else - packet->tv.tv_sec = htonl(packet->tv.tv_sec); - - if (sizeof(packet->tv.tv_usec) == 8) - packet->tv.tv_usec = htonll(packet->tv.tv_usec); - else - packet->tv.tv_usec = htonl(packet->tv.tv_usec); + ntoh_packet(packet); send_packet(packet, sizeof(struct mping) + arg_payload); seqno++; @@ -563,18 +585,8 @@ int process_mping(char *packet, int len, unsigned char type) } rcvd_pkt = (struct mping *)packet; - rcvd_pkt->seq_no = ntohl(rcvd_pkt->seq_no); - - if (sizeof(rcvd_pkt->tv.tv_sec) == 8) - rcvd_pkt->tv.tv_sec = ntohll(rcvd_pkt->tv.tv_sec); - else - rcvd_pkt->tv.tv_sec = ntohl(rcvd_pkt->tv.tv_sec); - - if (sizeof(rcvd_pkt->tv.tv_usec) == 8) - rcvd_pkt->tv.tv_usec = ntohll(rcvd_pkt->tv.tv_usec); - else - rcvd_pkt->tv.tv_usec = ntohl(rcvd_pkt->tv.tv_usec); + ntoh_packet(rcvd_pkt); if (strcmp(rcvd_pkt->version, VERSION)) { dbg("Discarding packet: version mismatch (%s)", rcvd_pkt->version); @@ -679,17 +691,8 @@ void receiver_listen_loop(void) rcvd_pkt->type = RECEIVER; rcvd_pkt->src_host = myaddr; rcvd_pkt->dest_host = rcvd_pkt->src_host; - rcvd_pkt->seq_no = htonl(rcvd_pkt->seq_no); - - if (sizeof(rcvd_pkt->tv.tv_sec) == 8) - rcvd_pkt->tv.tv_sec = htonll(rcvd_pkt->tv.tv_sec); - else - rcvd_pkt->tv.tv_sec = htonl(rcvd_pkt->tv.tv_sec); - if (sizeof(rcvd_pkt->tv.tv_usec) == 8) - rcvd_pkt->tv.tv_usec = htonll(rcvd_pkt->tv.tv_usec); - else - rcvd_pkt->tv.tv_usec = htonl(rcvd_pkt->tv.tv_usec); + hton_packet(rcvd_pkt); /* send reply immediately */ send_packet(rcvd_pkt, len);