diff --git a/mping.c b/mping.c index 29f79ec..1106873 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 @@ -369,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) { @@ -526,10 +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; - packet->tv.tv_sec = htonl(packet->tv.tv_sec); - packet->tv.tv_usec = htonl(packet->tv.tv_usec); + + ntoh_packet(packet); send_packet(packet, sizeof(struct mping) + arg_payload); seqno++; @@ -547,9 +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); - rcvd_pkt->tv.tv_sec = ntohl(rcvd_pkt->tv.tv_sec); - 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); @@ -654,9 +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); - rcvd_pkt->tv.tv_sec = htonl(rcvd_pkt->tv.tv_sec); - rcvd_pkt->tv.tv_usec = htonl(rcvd_pkt->tv.tv_usec); + + hton_packet(rcvd_pkt); /* send reply immediately */ send_packet(rcvd_pkt, len); @@ -798,6 +834,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;