This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
The following commit(s) were added to refs/heads/master by this push:
new c2073a92d testing/libc/inetntop: Add a test of inet_ntop().
c2073a92d is described below
commit c2073a92d744bbde7f6f7579d52949ad08f77d19
Author: Marco Casaroli <[email protected]>
AuthorDate: Wed Nov 11 08:20:01 2026 +0100
testing/libc/inetntop: Add a test of inet_ntop().
No test in nuttx-apps checks inet_ntop(). This test converts IPv6
addresses with inet_ntop(AF_INET6) and compares the text with the
recommended form of RFC 5952: "::" only for the longest run of two or
more 0 fields (the first one on a tie), no "::" for one 0 field, and
lowercase hexadecimal. The IPv4-mapped address (::ffff:127.0.0.1) and
the IPv4-compatible address (::1.2.3.4) end in the dotted-decimal form;
:: and ::1 do not. glibc gives the same text for each case.
Each case also checks the size of the buffer, for AF_INET6 and AF_INET:
the call succeeds with strlen() + 1 bytes and fails with ENOSPC with
strlen() bytes.
The program prints PASS or FAIL for each case and returns the number of
errors.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <[email protected]>
---
testing/libc/inetntop/CMakeLists.txt | 35 +++++
testing/libc/inetntop/Kconfig | 34 +++++
testing/libc/inetntop/Make.defs | 25 ++++
testing/libc/inetntop/Makefile | 36 +++++
testing/libc/inetntop/inetntop_main.c | 255 ++++++++++++++++++++++++++++++++++
5 files changed, 385 insertions(+)
diff --git a/testing/libc/inetntop/CMakeLists.txt
b/testing/libc/inetntop/CMakeLists.txt
new file mode 100644
index 000000000..6103c6dfd
--- /dev/null
+++ b/testing/libc/inetntop/CMakeLists.txt
@@ -0,0 +1,35 @@
+#
##############################################################################
+# apps/testing/libc/inetntop/CMakeLists.txt
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
contributor
+# license agreements. See the NOTICE file distributed with this work for
+# additional information regarding copyright ownership. The ASF licenses this
+# file to you under the Apache License, Version 2.0 (the "License"); you may
not
+# use this file except in compliance with the License. You may obtain a copy
of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+#
+#
##############################################################################
+
+if(CONFIG_TESTING_INETNTOP)
+ nuttx_add_application(
+ NAME
+ ${CONFIG_TESTING_INETNTOP_PROGNAME}
+ PRIORITY
+ ${CONFIG_TESTING_INETNTOP_PRIORITY}
+ STACKSIZE
+ ${CONFIG_TESTING_INETNTOP_STACKSIZE}
+ MODULE
+ ${CONFIG_TESTING_INETNTOP}
+ SRCS
+ inetntop_main.c)
+endif()
diff --git a/testing/libc/inetntop/Kconfig b/testing/libc/inetntop/Kconfig
new file mode 100644
index 000000000..3033aa262
--- /dev/null
+++ b/testing/libc/inetntop/Kconfig
@@ -0,0 +1,34 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+config TESTING_INETNTOP
+ tristate "inet_ntop() test"
+ default n
+ depends on (NET_IPv4 || LIBC_IPv4_ADDRCONV) && (NET_IPv6 ||
LIBC_IPv6_ADDRCONV)
+ ---help---
+ Check the text that inet_ntop(AF_INET6) makes: "::" only for the
+ longest run of two or more 0 fields, lowercase hexadecimal, and
the
+ IPv4 dotted-decimal form for the IPv4-mapped and IPv4-compatible
+ addresses. Also check that inet_ntop() fails with ENOSPC only
when
+ the text does not fit in the buffer, for AF_INET6 and AF_INET.
+
+if TESTING_INETNTOP
+
+config TESTING_INETNTOP_PROGNAME
+ string "Program name"
+ default "inetntop"
+ ---help---
+ This is the name of the program that will be used when the NSH
ELF
+ program is installed.
+
+config TESTING_INETNTOP_PRIORITY
+ int "inetntop task priority"
+ default 100
+
+config TESTING_INETNTOP_STACKSIZE
+ int "inetntop stack size"
+ default DEFAULT_TASK_STACKSIZE
+
+endif
diff --git a/testing/libc/inetntop/Make.defs b/testing/libc/inetntop/Make.defs
new file mode 100644
index 000000000..56aa0ba2d
--- /dev/null
+++ b/testing/libc/inetntop/Make.defs
@@ -0,0 +1,25 @@
+############################################################################
+# apps/testing/libc/inetntop/Make.defs
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+ifneq ($(CONFIG_TESTING_INETNTOP),)
+CONFIGURED_APPS += $(APPDIR)/testing/libc/inetntop
+endif
diff --git a/testing/libc/inetntop/Makefile b/testing/libc/inetntop/Makefile
new file mode 100644
index 000000000..f49e946b6
--- /dev/null
+++ b/testing/libc/inetntop/Makefile
@@ -0,0 +1,36 @@
+############################################################################
+# apps/testing/libc/inetntop/Makefile
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+include $(APPDIR)/Make.defs
+
+# inet_ntop() test built-in application info
+
+PROGNAME = $(CONFIG_TESTING_INETNTOP_PROGNAME)
+PRIORITY = $(CONFIG_TESTING_INETNTOP_PRIORITY)
+STACKSIZE = $(CONFIG_TESTING_INETNTOP_STACKSIZE)
+MODULE = $(CONFIG_TESTING_INETNTOP)
+
+# inet_ntop() test files
+
+MAINSRC = inetntop_main.c
+
+include $(APPDIR)/Application.mk
diff --git a/testing/libc/inetntop/inetntop_main.c
b/testing/libc/inetntop/inetntop_main.c
new file mode 100644
index 000000000..7d699f71e
--- /dev/null
+++ b/testing/libc/inetntop/inetntop_main.c
@@ -0,0 +1,255 @@
+/****************************************************************************
+ * apps/testing/libc/inetntop/inetntop_main.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct ntop_case_s
+{
+ uint16_t words[8]; /* The address, as eight 16-bit fields */
+ FAR const char *text; /* The expected text */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* Convert src with a buffer of size bytes. The text must be expect, or
+ * the call must fail with ENOSPC if expect is NULL. Return the number of
+ * errors: 0 or 1.
+ */
+
+static int check_size(int af, FAR const void *src, socklen_t size,
+ FAR const char *expect, FAR const char *name)
+{
+ FAR const char *ret;
+ char buf[INET6_ADDRSTRLEN + 8];
+
+ memset(buf, 'X', sizeof(buf));
+ errno = 0;
+ ret = inet_ntop(af, src, buf, size);
+ if (expect != NULL && ret == buf && strcmp(buf, expect) == 0)
+ {
+ return 0;
+ }
+
+ if (expect == NULL && ret == NULL && errno == ENOSPC)
+ {
+ return 0;
+ }
+
+ printf("FAIL: %s, size %u: returned \"%s\", errno %d, expected \"%s\"\n",
+ name, size, ret != NULL ? buf : "NULL", errno,
+ expect != NULL ? expect : "ENOSPC");
+ return 1;
+}
+
+/* The text must fit in strlen() + 1 bytes and fail with ENOSPC in
+ * strlen() bytes.
+ */
+
+static int check(int af, FAR const void *src, FAR const char *expect)
+{
+ socklen_t len = strlen(expect);
+ int nerrors;
+
+ nerrors = check_size(af, src, len + 1, expect, expect);
+ nerrors += check_size(af, src, len, NULL, expect);
+ nerrors += check_size(af, src, INET6_ADDRSTRLEN, expect, expect);
+ if (nerrors == 0)
+ {
+ printf("PASS: \"%s\"\n", expect);
+ }
+
+ return nerrors;
+}
+
+static int check_ipv6(FAR const struct ntop_case_s *tc)
+{
+ struct in6_addr addr;
+ int i;
+
+ for (i = 0; i < 8; i++)
+ {
+ addr.s6_addr[2 * i] = tc->words[i] >> 8;
+ addr.s6_addr[2 * i + 1] = tc->words[i] & 0xff;
+ }
+
+ return check(AF_INET6, &addr, tc->text);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, FAR char *argv[])
+{
+ static const struct ntop_case_s cases[] =
+ {
+ /* No 0 field, and the longest text */
+
+ {
+ {1, 2, 3, 4, 5, 6, 7, 8}, "1:2:3:4:5:6:7:8"
+ },
+ {
+ {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
+ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
+ },
+
+ /* "::" at the start, in the middle and at the end */
+
+ {
+ {0, 0, 0, 0, 0, 0, 0, 0}, "::"
+ },
+ {
+ {0, 0, 0, 0, 0, 0, 0, 1}, "::1"
+ },
+ {
+ {1, 0, 0, 0, 0, 0, 0, 0}, "1::"
+ },
+ {
+ {0xfe80, 0, 0, 0, 0, 0, 0xab, 1}, "fe80::ab:1"
+ },
+ {
+ {0x2001, 0xdb8, 0, 0, 0, 0xff00, 0x42, 0x8329},
+ "2001:db8::ff00:42:8329"
+ },
+
+ /* RFC 5952 4.2.2: one 0 field is not shortened */
+
+ {
+ {1, 0, 2, 3, 4, 5, 6, 7}, "1:0:2:3:4:5:6:7"
+ },
+ {
+ {0, 1, 2, 3, 4, 5, 6, 7}, "0:1:2:3:4:5:6:7"
+ },
+ {
+ {1, 2, 3, 4, 5, 6, 7, 0}, "1:2:3:4:5:6:7:0"
+ },
+ {
+ {0x2001, 0xdb8, 0, 1, 1, 1, 1, 1}, "2001:db8:0:1:1:1:1:1"
+ },
+
+ /* RFC 5952 4.2.3: the longest run, the first one on a tie */
+
+ {
+ {1, 0, 0, 2, 0, 0, 0, 3}, "1:0:0:2::3"
+ },
+ {
+ {1, 0, 0, 2, 0, 0, 3, 4}, "1::2:0:0:3:4"
+ },
+ {
+ {0x2001, 0xdb8, 0, 0, 1, 0, 0, 1}, "2001:db8::1:0:0:1"
+ },
+
+ /* RFC 5952 4.3: lowercase */
+
+ {
+ {0x2001, 0xdb8, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0xaaaa},
+ "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"
+ },
+
+ /* RFC 5952 5: IPv4-mapped and IPv4-compatible, but not :: and ::1 */
+
+ {
+ {0, 0, 0, 0, 0, 0xffff, 0x7f00, 1}, "::ffff:127.0.0.1"
+ },
+ {
+ {0, 0, 0, 0, 0, 0xffff, 0, 0}, "::ffff:0.0.0.0"
+ },
+ {
+ {0, 0, 0, 0, 0, 0xffff, 0xffff, 0xffff}, "::ffff:255.255.255.255"
+ },
+ {
+ {0, 0, 0, 0, 0, 0, 0x102, 0x304}, "::1.2.3.4"
+ },
+ {
+ {0, 0, 0, 0, 0, 0, 1, 0}, "::0.1.0.0"
+ },
+ {
+ {0, 0, 0, 0, 0, 0, 0, 0x102}, "::102"
+ },
+
+ /* Near forms that are not IPv4-mapped */
+
+ {
+ {0, 0, 0, 0, 0, 0xfffe, 0x102, 0x304}, "::fffe:102:304"
+ },
+ {
+ {1, 0, 0, 0, 0, 0xffff, 0x102, 0x304}, "1::ffff:102:304"
+ },
+ {
+ {0, 0, 0, 0, 0xffff, 0, 0x102, 0x304}, "::ffff:0:102:304"
+ },
+ {
+ {0x64, 0xff9b, 0, 0, 0, 0, 0xc000, 0x221}, "64:ff9b::c000:221"
+ },
+ };
+
+ static const uint8_t ipv4[][4] =
+ {
+ {0, 0, 0, 0},
+ {1, 2, 3, 4},
+ {192, 168, 10, 200},
+ {255, 255, 255, 255},
+ };
+
+ static const FAR char * const ipv4text[] =
+ {
+ "0.0.0.0", "1.2.3.4", "192.168.10.200", "255.255.255.255",
+ };
+
+ int nerrors = 0;
+ size_t i;
+
+ printf("inetntop: inet_ntop() test\n");
+
+ for (i = 0; i < nitems(cases); i++)
+ {
+ nerrors += check_ipv6(&cases[i]);
+ }
+
+ for (i = 0; i < nitems(ipv4); i++)
+ {
+ nerrors += check(AF_INET, ipv4[i], ipv4text[i]);
+ }
+
+ printf("inetntop: %zu cases, %d errors\n",
+ nitems(cases) + nitems(ipv4), nerrors);
+ return nerrors > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}