[PATCH 1/1] inet: add support for 64-bit network byte order
Philip Prindeville
philipp@redfish-solutions.com
Mon Mar 10 00:09:36 GMT 2025
From: Philip Prindeville <philipp@redfish-solutions.com>
As 32-bit machines become increasingly supplanted by 64-bit
architectures, network protocols likewise leverage those
larger word capabilities. A good example is POSIX supporting
64-bit time_t's to avoid the 2038 problem, or timestamps that
include micro- or nanosecond precision.
---
conform/data/arpa/inet.h-data | 2 ++
conform/data/netinet/in.h-data | 2 ++
inet/Makefile | 1 +
inet/htonll.c | 35 +++++++++++++++++++
inet/htontest.c | 11 ++++++
inet/netinet/in.h | 11 ++++++
inet/test-hnto-types.c | 4 +++
manual/socket.texi | 15 ++++++++
sysdeps/unix/sysv/linux/arm/be/libc.abilist | 2 ++
sysdeps/unix/sysv/linux/arm/le/libc.abilist | 2 ++
.../sysv/linux/loongarch/lp64/libc.abilist | 2 ++
.../sysv/linux/m68k/coldfire/libc.abilist | 2 ++
.../unix/sysv/linux/m68k/m680x0/libc.abilist | 2 ++
.../sysv/linux/microblaze/be/libc.abilist | 2 ++
.../sysv/linux/microblaze/le/libc.abilist | 2 ++
.../unix/sysv/linux/riscv/rv32/libc.abilist | 2 ++
.../unix/sysv/linux/riscv/rv64/libc.abilist | 2 ++
.../unix/sysv/linux/s390/s390-32/libc.abilist | 2 ++
.../unix/sysv/linux/s390/s390-64/libc.abilist | 2 ++
sysdeps/unix/sysv/linux/sh/be/libc.abilist | 2 ++
sysdeps/unix/sysv/linux/sh/le/libc.abilist | 2 ++
.../sysv/linux/sparc/sparc32/libc.abilist | 2 ++
.../sysv/linux/sparc/sparc64/libc.abilist | 2 ++
.../unix/sysv/linux/x86_64/64/libc.abilist | 2 ++
.../unix/sysv/linux/x86_64/x32/libc.abilist | 2 ++
25 files changed, 115 insertions(+)
diff --git a/conform/data/arpa/inet.h-data b/conform/data/arpa/inet.h-data
index 040b8212c73778d2e1272a2841424fdb098ddde2..c80912ffde59e1d6da1c548f3a0e072f4b4ab5f6 100644
--- a/conform/data/arpa/inet.h-data
+++ b/conform/data/arpa/inet.h-data
@@ -11,8 +11,10 @@ macro INET_ADDRSTRLEN
macro INET6_ADDRSTRLEN
// The following can be declared as functions, defined as macros or both:
+function uint64_t htonll (uint64_t)
function uint32_t htonl (uint32_t)
function uint16_t htons (uint16_t)
+function uint64_t ntohll (uint64_t)
function uint32_t ntohl (uint32_t)
function uint16_t htons (uint16_t)
diff --git a/conform/data/netinet/in.h-data b/conform/data/netinet/in.h-data
index ccc74db608727200161d2713a2f7fb171d8b8138..27a8628a99f749e69c0b6456fb875da5cd8da367 100644
--- a/conform/data/netinet/in.h-data
+++ b/conform/data/netinet/in.h-data
@@ -53,8 +53,10 @@ macro INADDR_BROADCAST
constant INET_ADDRSTRLEN == 16
+function uint64_t htonll (uint64_t)
function uint32_t htonl (uint32_t)
function uint16_t htons (uint16_t)
+function uint64_t ntohll (uint64_t)
function uint32_t ntohl (uint32_t)
function uint16_t ntohs (uint16_t)
diff --git a/inet/Makefile b/inet/Makefile
index 79bacddfd5fd7e161be7e6ea0d89d74667ab604a..3a835512fcb2e1a8e8596c960e815190842e03e5 100644
--- a/inet/Makefile
+++ b/inet/Makefile
@@ -51,6 +51,7 @@ routines := \
herrno \
herrno-loc \
htonl \
+ htonll \
htons \
idna \
idna_name_classify \
diff --git a/inet/htonll.c b/inet/htonll.c
new file mode 100644
index 0000000000000000000000000000000000000000..7f6656c60587daecccaca9fa38a9cdffd079ba9a
--- /dev/null
+++ b/inet/htonll.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdint.h>
+#include <netinet/in.h>
+
+#undef htonll
+#undef ntohll
+
+uint64_t
+htonll (uint64_t x)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+ return x;
+#elif BYTE_ORDER == LITTLE_ENDIAN
+ return __bswap_64 (x);
+#else
+# error "What kind of system is this?"
+#endif
+}
+weak_alias (htonll, ntohll)
diff --git a/inet/htontest.c b/inet/htontest.c
index 3e04967a07835cf1f6b26a80ad44c48cb8b6a8f7..4939616d967894243a66844325754003af04faf1 100644
--- a/inet/htontest.c
+++ b/inet/htontest.c
@@ -37,6 +37,7 @@
# error "Bah, what kind of system do you use?"
#endif
+uint64_t lots = 0xefcdab8967452301;
uint32_t lo = 0x67452301;
uint16_t foo = 0x1234;
@@ -45,6 +46,16 @@ main (void)
{
int result = 0;
+ TEST (0xefcdab8967452301, 0x0123456789abcdef, htonll);
+ TEST (0xefcdab8967452301, 0x0123456789abcdef, (htonll));
+ TEST (0xefcdab8967452301, 0x0123456789abcdef, ntohll);
+ TEST (0xefcdab8967452301, 0x0123456789abcdef, (ntohll));
+
+ TEST (lots, 0x0123456789abcdef, htonl);
+ TEST (lots, 0x0123456789abcdef, (htonl));
+ TEST (lots, 0x0123456789abcdef, ntohl);
+ TEST (lots, 0x0123456789abcdef, (ntohl));
+
TEST (0x67452301, 0x01234567, htonl);
TEST (0x67452301, 0x01234567, (htonl));
TEST (0x67452301, 0x01234567, ntohl);
diff --git a/inet/netinet/in.h b/inet/netinet/in.h
index fa796be406a7120fd6b85d7851b94fe5938bebc0..4fe19b9ee5181a43cb42b86bae603b1f47cb1c3e 100644
--- a/inet/netinet/in.h
+++ b/inet/netinet/in.h
@@ -406,6 +406,13 @@ extern uint32_t htonl (uint32_t __hostlong)
extern uint16_t htons (uint16_t __hostshort)
__THROW __attribute__ ((__const__));
+/* Address the following shortcoming by including unsigned long long,
+ which is useful for things such as nanosecond timestamps, etc. */
+
+extern uint64_t ntohll (uint64_t __netlonglong) __THROW __attribute__ ((__const__));
+extern uint64_t htonll (uint64_t __hostlonglong)
+ __THROW __attribute__ ((__const__));
+
#include <endian.h>
/* Get machine dependent optimized versions of byte swapping functions. */
@@ -419,14 +426,18 @@ extern uint16_t htons (uint16_t __hostshort)
# if __BYTE_ORDER == __BIG_ENDIAN
/* The host byte order is the same as network byte order,
so these functions are all just identity. */
+# define ntohll(x) __uint64_identity (x)
# define ntohl(x) __uint32_identity (x)
# define ntohs(x) __uint16_identity (x)
+# define htonll(x) __uint64_identity (x)
# define htonl(x) __uint32_identity (x)
# define htons(x) __uint16_identity (x)
# else
# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define ntohll(x) __bswap_64 (x)
# define ntohl(x) __bswap_32 (x)
# define ntohs(x) __bswap_16 (x)
+# define htonll(x) __bswap_64 (x)
# define htonl(x) __bswap_32 (x)
# define htons(x) __bswap_16 (x)
# endif
diff --git a/inet/test-hnto-types.c b/inet/test-hnto-types.c
index c396f4f27aca6fe3a87be5cb0f9c8e3a5b2e7371..8165d16c28febda69999238c0f25ca9034009d31 100644
--- a/inet/test-hnto-types.c
+++ b/inet/test-hnto-types.c
@@ -22,6 +22,7 @@
int i;
uint16_t u16;
uint32_t u32;
+uint64_t u64;
int
do_test (void)
@@ -31,8 +32,11 @@ do_test (void)
extern __typeof (ntohs (i)) u16;
extern __typeof (htonl (i)) u32;
extern __typeof (ntohl (i)) u32;
+ extern __typeof (htonll (i)) u64;
+ extern __typeof (ntohll (i)) u64;
(void) u16;
(void) u32;
+ (void) u64;
return 0;
}
diff --git a/manual/socket.texi b/manual/socket.texi
index 8708cbb07ca02b5c6b38f1bc68c714f13471e3f3..3d0d7793a5974741a7b7a7f492bba1f02eaeae79 100644
--- a/manual/socket.texi
+++ b/manual/socket.texi
@@ -1957,6 +1957,14 @@ host byte order to network byte order.
This is used for IPv4 Internet addresses.
@end deftypefun
+@deftypefun {uint64_t} htonll (uint64_t @var{hostlonglong})
+@standards{BSD, netinet/in.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c htonll ok
+@c bswap_64 dup ok
+This function converts the @code{uint64_t} integer @var{hostlonglong} from
+host byte order to network byte order.
+
@deftypefun {uint32_t} ntohl (uint32_t @var{netlong})
@standards{BSD, netinet/in.h}
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
@@ -1967,6 +1975,13 @@ network byte order to host byte order.
This is used for IPv4 Internet addresses.
@end deftypefun
+@deftypefun {uint64_t} ntohll (uint64_t @var{netlonglong})
+@standards{BSD, netinet/in.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Alias to htonll.
+This function converts the @code{uint64_t} integer @var{netlonglong} from
+network byte order to host byte order.
+
@node Protocols Database
@subsection Protocols Database
@cindex protocols database
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 1d54f71b146d00a004926af01e12158a5b8e728b..aeb3406f1a51b763815914775577fb3ac8febf8d 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -2876,3 +2876,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index ff7e8bc40beb21de35f1706f0452b0cd329896a5..88e2ee34968bc57b7cff793b4e5d4337bcd911c0 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -2873,3 +2873,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
index 0024282289ffbee67ae570d5ef6d7ca55a2ca1ca..e25c704a124313eed280d0ed1ec136b3b6f3e7c1 100644
--- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
@@ -2271,3 +2271,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 142595eb3ed52656a159f38428972a57fe23ab75..4629f21fc433f1e24ba9fdb5298a1077c003b8e6 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -2855,3 +2855,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 85e7746c10a125b398c62e1e6136581418e909a4..f5199a56a1a05def380331eee7473a6beb9932a5 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -3022,3 +3022,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 91dc1b83785655a57ed05e74829a116de278c2b5..1bdd27c4411dfe6571322a63c5934c6daf25b861 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2836,3 +2836,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 3440e90f6fda9abbe969df7bbc7b1c04fd6c8acd..cfb46ee43b07cfe912717c3c73aec5f772844253 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2833,3 +2833,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 4187241f5030d411d225a5cfce94db53b98ff01c..cc76d2c38611b0c1dbe0599b0440c57f4fc643aa 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -2514,3 +2514,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.40 __riscv_hwprobe F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 8935beccac1a2c693e664f634aa27cd671dc852b..057d8af9ed273238fd687811fc4cb1386a54cde4 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2714,3 +2714,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.40 __riscv_hwprobe F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index e69dc7ccf6952f895e04aedd80f19f5af28e14e6..729c5c4b078b5393db204627b0b660789e44294b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -3244,3 +3244,5 @@ GLIBC_2.9 pututline F
GLIBC_2.9 pututxline F
GLIBC_2.9 updwtmp F
GLIBC_2.9 updwtmpx F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 7d860001d8a57160e8fe33ada27abb8875bea8c2..4137ce6862cbca97da5990a04b4ce2a101196212 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -3021,3 +3021,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index fcb8161841078f2bc6dcef904dd85a2d4b8a4a40..810317887daa47a195937068f5df260e85b05eab 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2902,3 +2902,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 3fd078d1257bf8d93b990cf2c10bfe4091ac8d56..f64c3942b990c6bd7bb81157622c6470f20c091d 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2899,3 +2899,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 1ce1fe9da7180b4fa65ceab1983b66e7876e70d9..b3144bee4f4a5ce548476d5a53dde2ae55981bd9 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -3249,3 +3249,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 07507b86f6bd506c7549cd2e47eee2c6df815b4f..2b8a9aa8632ed8df9bed772b73272c54632c41e0 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2867,3 +2867,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 5acf49dbe82a1a41c62df4fb8bfd178904225908..4d20d64b0ff310bf4f6c165ce0ea1ca7a007b397 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2818,3 +2818,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 02d1bb97dca5f0a5d576d2dbaac9f844b4b5b6c2..29d40ab353633969d5fba7e4085747a9704f3d75 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2765,3 +2765,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
--
2.43.0
More information about the Libc-alpha
mailing list