Re: Functions htonq and ntohq in <click/integers.hh>

Markku Savela <[email protected]> Thu, 11 Oct 2012 11:02:06 +0300
Newsgroups gmane.network.routing.click
Message-ID <[email protected]>
On 10/11/2012 10:08 AM, Markku Savela wrote:

> Apparently MIPS in big endian mode and calling htonq is not
> correct. I was using htonq in same sense as "htonl", which
> always works, whether host is big or little endian.

If anyone is insterested, following diff is my attempt to make
htonq/ntohq safe to call regardless of the host endianness?
(works for my MIPS -> x86 case, but of course, these things
are tricky, so some one needs to check this, or think a
better implementation).

_______________________________________________
click mailing list
[email protected]
https://amsterdam.lcs.mit.edu/mailman/listinfo/click
htonq.diff (text/x-patch, 1 KB)
diff --git a/include/click/integers.hh b/include/click/integers.hh
index fec1e59..974dc5a 100644
--- a/include/click/integers.hh
+++ b/include/click/integers.hh
@@ -15,18 +15,26 @@ CLICK_DECLS
 #if HAVE_INT64_TYPES && !defined(htonq)
 /** @brief Return @a x translated from host to network byte order. */
 inline uint64_t htonq(uint64_t x) {
-    uint32_t hi = x >> 32;
-    uint32_t lo = x & 0xffffffff;
-    return (((uint64_t)htonl(lo)) << 32) | htonl(hi);
+    union {
+	uint32_t u32[2];
+	uint64_t u64;
+    } swap;
+
+    swap.u32[0] = htonl(x >> 32);
+    swap.u32[1] = htonl(x & 0xffffffff);
+    return swap.u64;
 }
 #endif
 
 #if HAVE_INT64_TYPES && !defined(ntohq)
 /** @brief Return @a x translated from network to host byte order. */
 inline uint64_t ntohq(uint64_t x) {
-    uint32_t hi = x >> 32;
-    uint32_t lo = x & 0xffffffff;
-    return (((uint64_t)ntohl(lo)) << 32) | ntohl(hi);
+    union {
+	uint32_t u32[2];
+	uint64_t u64;
+    } swap;
+    swap.u64 = x;
+    return (((uint64_t)ntohl(swap.u32[0])) << 32) | ntohl(swap.u32[1]);
 }
 #endif