[PATCH 3/3] tests: Add tests for AF_TIPC decoding

sahilcdq0 at gmail.com sahilcdq0 at gmail.com
Thu May 22 19:34:01 UTC 2025


From: Sahil Siddiq <sahilcdq0 at gmail.com>

Add tests to verify decoding of AF_TIPC socket addresses and
socket options.

* tests/.gitignore: Add sol_tipc-* entries.
* tests/Makefile.am: Likewise.
* tests/gen_tests.in: Likewise.
* tests/sockaddr_xlat.c:
(struct tipc_socket_addr): New struct.
(struct tipc_service_addr): Likewise.
(tipc_service_range): Likewise.
(sockaddr_tipc): Likewise.
(check_tipc): New function.
(main): Invoke check_tipc.
* tests/sol_tipc-group_join.c: New file.
* tests/sol_tipc-group_join-Xabbrev.c: Likewise.
* tests/sol_tipc-group_join-Xraw.c: Likewise.
* tests/sol_tipc-group_join-Xverbose.c: Likewise.
* tests/sol_tipc-group_join-success.c: Likewise.
* tests/sol_tipc-group_join-success-Xabbrev.c: Likewise.
* tests/sol_tipc-group_join-success-Xraw.c: Likewise.
* tests/sol_tipc-group_join-success-Xverbose.c: Likewise.
* tests/sol_tipc-importance.c: Likewise.
* tests/sol_tipc-importance-Xabbrev: Likewise.
* tests/sol_tipc-importance-Xraw: Likewise.
* tests/sol_tipc-importance-Xverbose: Likewise.
* tests/sol_tipc-importance-success: Likewise.
* tests/sol_tipc-importance-success-Xabbrev: Likewise.
* tests/sol_tipc-importance-success-Xraw: Likewise.
* tests/sol_tipc-importance-success-Xverbose: Likewise.

Signed-off-by: Sahil Siddiq <sahilcdq0 at gmail.com>
---
 tests/.gitignore                             |  16 ++
 tests/Makefile.am                            |  16 ++
 tests/gen_tests.in                           |  16 ++
 tests/sockaddr_xlat.c                        | 112 ++++++++++++
 tests/sol_tipc-group_join-Xabbrev.c          |   2 +
 tests/sol_tipc-group_join-Xraw.c             |   2 +
 tests/sol_tipc-group_join-Xverbose.c         |   2 +
 tests/sol_tipc-group_join-success-Xabbrev.c  |   2 +
 tests/sol_tipc-group_join-success-Xraw.c     |   2 +
 tests/sol_tipc-group_join-success-Xverbose.c |   2 +
 tests/sol_tipc-group_join-success.c          |   2 +
 tests/sol_tipc-group_join.c                  | 169 +++++++++++++++++++
 tests/sol_tipc-importance-Xabbrev.c          |   2 +
 tests/sol_tipc-importance-Xraw.c             |   2 +
 tests/sol_tipc-importance-Xverbose.c         |   2 +
 tests/sol_tipc-importance-success-Xabbrev.c  |   2 +
 tests/sol_tipc-importance-success-Xraw.c     |   2 +
 tests/sol_tipc-importance-success-Xverbose.c |   2 +
 tests/sol_tipc-importance-success.c          |   2 +
 tests/sol_tipc-importance.c                  | 167 ++++++++++++++++++
 20 files changed, 524 insertions(+)
 create mode 100644 tests/sol_tipc-group_join-Xabbrev.c
 create mode 100644 tests/sol_tipc-group_join-Xraw.c
 create mode 100644 tests/sol_tipc-group_join-Xverbose.c
 create mode 100644 tests/sol_tipc-group_join-success-Xabbrev.c
 create mode 100644 tests/sol_tipc-group_join-success-Xraw.c
 create mode 100644 tests/sol_tipc-group_join-success-Xverbose.c
 create mode 100644 tests/sol_tipc-group_join-success.c
 create mode 100644 tests/sol_tipc-group_join.c
 create mode 100644 tests/sol_tipc-importance-Xabbrev.c
 create mode 100644 tests/sol_tipc-importance-Xraw.c
 create mode 100644 tests/sol_tipc-importance-Xverbose.c
 create mode 100644 tests/sol_tipc-importance-success-Xabbrev.c
 create mode 100644 tests/sol_tipc-importance-success-Xraw.c
 create mode 100644 tests/sol_tipc-importance-success-Xverbose.c
 create mode 100644 tests/sol_tipc-importance-success.c
 create mode 100644 tests/sol_tipc-importance.c

diff --git a/tests/.gitignore b/tests/.gitignore
index da4935129..7b1ad8f20 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1205,6 +1205,22 @@ times-Xabbrev
 times-Xraw
 times-Xverbose
 times-fail
+sol_tipc-group_join
+sol_tipc-group_join-Xabbrev
+sol_tipc-group_join-Xraw
+sol_tipc-group_join-Xverbose
+sol_tipc-group_join-success
+sol_tipc-group_join-success-Xabbrev
+sol_tipc-group_join-success-Xraw
+sol_tipc-group_join-success-Xverbose
+sol_tipc-importance
+sol_tipc-importance-Xabbrev
+sol_tipc-importance-Xraw
+sol_tipc-importance-Xverbose
+sol_tipc-importance-success
+sol_tipc-importance-success-Xabbrev
+sol_tipc-importance-success-Xraw
+sol_tipc-importance-success-Xverbose
 tkill
 tkill--pidns-translation
 tracer_ppid_pgid_sid
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0462563fd..b29471f45 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -407,6 +407,22 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
 	sockopt-sol_socket-success-Xabbrev \
 	sockopt-sol_socket-success-Xraw \
 	sockopt-sol_socket-success-Xverbose \
+	sol_tipc-group_join \
+	sol_tipc-group_join-Xabbrev \
+	sol_tipc-group_join-Xraw \
+	sol_tipc-group_join-Xverbose \
+	sol_tipc-group_join-success \
+	sol_tipc-group_join-success-Xabbrev \
+	sol_tipc-group_join-success-Xraw \
+	sol_tipc-group_join-success-Xverbose \
+	sol_tipc-importance \
+	sol_tipc-importance-Xabbrev \
+	sol_tipc-importance-Xraw \
+	sol_tipc-importance-Xverbose \
+	sol_tipc-importance-success \
+	sol_tipc-importance-success-Xabbrev \
+	sol_tipc-importance-success-Xraw \
+	sol_tipc-importance-success-Xverbose \
 	stack-fcall \
 	stack-fcall-attach \
 	stack-fcall-mangled \
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 56291595e..ad2fd0111 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -1108,6 +1108,22 @@ sockopt-sol_socket-success-Xabbrev	-einject=getsockopt,setsockopt:retval=42 -etr
 sockopt-sol_socket-success-Xraw		-einject=getsockopt,setsockopt:retval=42 -etrace=getsockopt,setsockopt -Xraw -a32
 sockopt-sol_socket-success-Xverbose	-einject=getsockopt,setsockopt:retval=42 -etrace=getsockopt,setsockopt -Xverbose
 sockopt-timestamp	-e trace=recvmsg
+sol_tipc-group_join -etrace=getsockopt,setsockopt
+sol_tipc-group_join-Xabbrev	-etrace=getsockopt,setsockopt -Xabbrev
+sol_tipc-group_join-Xraw	-etrace=getsockopt,setsockopt -Xraw -a32
+sol_tipc-group_join-Xverbose	-etrace=getsockopt,setsockopt -Xverbose
+sol_tipc-group_join-success	-einject=getsockopt,setsockopt:retval=42 -etrace=getsockopt,setsockopt
+sol_tipc-group_join-success-Xabbrev	-einject=getsockopt,setsockopt:retval=42 -etrace=getsockopt,setsockopt -Xabbrev
+sol_tipc-group_join-success-Xraw	-einject=getsockopt,setsockopt:retval=42 -etrace=getsockopt,setsockopt -Xraw -a32
+sol_tipc-group_join-success-Xverbose	-einject=getsockopt,setsockopt:retval=42 -etrace=getsockopt,setsockopt -Xverbose
+sol_tipc-importance	-e trace=getsockopt,setsockopt
+sol_tipc-importance-Xabbrev	-etrace=getsockopt,setsockopt -Xabbrev
+sol_tipc-importance-Xraw	-etrace=getsockopt,setsockopt -Xraw -a32
+sol_tipc-importance-Xverbose	-etrace=getsockopt,setsockopt -Xverbose
+sol_tipc-importance-success	-einject=getsockopt,setsockopt:retval=42 -etrace=getsockopt,setsockopt
+sol_tipc-importance-success-Xabbrev	-einject=getsockopt,setsockopt:retval=42 -etrace=getsockopt,setsockopt -Xabbrev
+sol_tipc-importance-success-Xraw	-einject=getsockopt,setsockopt:retval=42 -etrace=getsockopt,setsockopt -Xraw -a32
+sol_tipc-importance-success-Xverbose	-einject=getsockopt,setsockopt:retval=42 -etrace=getsockopt,setsockopt -Xverbose
 splice
 stat	-a30 --no-abbrev --trace-path=stat.sample --trace-path=/dev/full
 stat64	-a32 --no-abbrev --trace-path=stat.sample --trace-path=/dev/full
diff --git a/tests/sockaddr_xlat.c b/tests/sockaddr_xlat.c
index cd79d319b..b262a68bc 100644
--- a/tests/sockaddr_xlat.c
+++ b/tests/sockaddr_xlat.c
@@ -17,6 +17,40 @@
 #include <linux/if_packet.h>
 #include <linux/mctp.h>
 
+#ifdef HAVE_LINUX_TIPC_H
+# include <linux/tipc.h>
+#else
+struct tipc_socket_addr {
+	uint32_t ref;
+	uint32_t node;
+};
+
+struct tipc_service_addr {
+	uint32_t type;
+	uint32_t instance;
+};
+
+struct tipc_service_range {
+	uint32_t type;
+	uint32_t lower;
+	uint32_t upper;
+};
+
+struct sockaddr_tipc {
+	unsigned short family;
+	unsigned char  addrtype;
+	signed   char  scope;
+	union {
+		struct tipc_socket_addr id;
+		struct tipc_service_range nameseq;
+		struct {
+			struct tipc_service_addr name;
+			__u32 domain;
+		} name;
+	} addr;
+};
+#endif
+
 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
 # include <bluetooth/bluetooth.h>
 # include <bluetooth/hci.h>
@@ -340,6 +374,83 @@ check_in6(void)
 	validate_in6(&in6, "::1");
 }
 
+static void
+check_tipc(void)
+{
+	static const struct {
+		struct sockaddr_tipc sa;
+		const char *str;
+	} tipc_vecs[] = {
+		{ { AF_TIPC },
+		  "{sa_family=" XLAT_KNOWN(0x1e, "AF_TIPC")
+		  ", addrtype=0" NRAW(" /* TIPC_ADDR_??? */")
+		  ", scope=0" NRAW(" /* TIPC_???_SCOPE */")
+		  ", addr=\"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"}" },
+		{ { AF_TIPC, .addrtype = 0x1, .scope = 0x2,
+		    .addr = { .nameseq = { .type = 42, .lower = 2, .upper = 20 } } },
+		  "{sa_family=" XLAT_KNOWN(0x1e, "AF_TIPC")
+		  ", addrtype=0x1" NRAW(" /* TIPC_SERVICE_RANGE */")
+		  ", scope=" XLAT_KNOWN(0x2, "TIPC_CLUSTER_SCOPE")
+		  ", addr={nameseq={type=42, lower=2, upper=20}}}" },
+		{ { AF_TIPC, .addrtype = 0x1, .scope = -0x2,
+		    .addr = { .nameseq = { .type = 42, .lower = 2, .upper = 20 } } },
+		  "{sa_family=" XLAT_KNOWN(0x1e, "AF_TIPC")
+		  ", addrtype=0x1" NRAW(" /* TIPC_SERVICE_RANGE */")
+		  ", scope=-" XLAT_KNOWN(0x2, "TIPC_CLUSTER_SCOPE")
+		  ", addr={nameseq={type=42, lower=2, upper=20}}}" },
+		{ { AF_TIPC, .addrtype = 0x3, .scope = 0x3,
+		    .addr = { .id = { .ref = 10, .node = 0xfeedbabe } } },
+		  "{sa_family=" XLAT_KNOWN(0x1e, "AF_TIPC")
+		  ", addrtype=0x3" NRAW(" /* TIPC_SOCKET_ADDR */")
+		  ", scope=" XLAT_KNOWN(0x3, "TIPC_NODE_SCOPE")
+		  ", addr={id={ref=10, node=0xfeedbabe}}}" },
+		{ { AF_TIPC, .addrtype = 0x3, .scope = -0x3,
+		    .addr = { .id = { .ref = 10, .node = 0xfeedbabe } } },
+		  "{sa_family=" XLAT_KNOWN(0x1e, "AF_TIPC")
+		  ", addrtype=0x3" NRAW(" /* TIPC_SOCKET_ADDR */")
+		  ", scope=-" XLAT_KNOWN(0x3, "TIPC_NODE_SCOPE")
+		  ", addr={id={ref=10, node=0xfeedbabe}}}" },
+		{ { AF_TIPC, .addrtype = 0x2, .scope = 0x3,
+		    .addr = { .name = { .name = { .type = 42, .instance = 2 }, .domain = 0 } } },
+		  "{sa_family=" XLAT_KNOWN(0x1e, "AF_TIPC")
+		  ", addrtype=0x2" NRAW(" /* TIPC_SERVICE_ADDR */")
+		  ", scope=" XLAT_KNOWN(0x3, "TIPC_NODE_SCOPE")
+		  ", addr={name={name={type=42, instance=2}, domain=0}}}" },
+		{ { AF_TIPC, .addrtype = 0x2, .scope = -0x3,
+		    .addr = { .name = { .name = { .type = 42, .instance = 2 }, .domain = 0xfeedbabe } } },
+		  "{sa_family=" XLAT_KNOWN(0x1e, "AF_TIPC")
+		  ", addrtype=0x2" NRAW(" /* TIPC_SERVICE_ADDR */")
+		  ", scope=-" XLAT_KNOWN(0x3, "TIPC_NODE_SCOPE")
+		  ", addr={name={name={type=42, instance=2}, domain=0xfeedbabe}}}" }
+	};
+
+	TAIL_ALLOC_OBJECT_CONST_PTR(struct sockaddr_tipc, sa_tipc);
+	int rc;
+
+	fill_memory(sa_tipc, sizeof(*sa_tipc));
+	sa_tipc->family = AF_TIPC;
+
+	rc = connect(-1, (void *) sa_tipc, sizeof(*sa_tipc) + 1);
+	printf("connect(-1, %p, %zu) = %s\n",
+	       (void *) sa_tipc, sizeof(*sa_tipc) + 1, sprintrc(rc));
+
+	rc = connect(-1, (void *) sa_tipc, sizeof(*sa_tipc) - 1);
+	const char *errstr = sprintrc(rc);
+	printf("connect(-1, {sa_family=" XLAT_KNOWN(0x1e, "AF_TIPC")
+	       ", sa_data=");
+	print_quoted_memory((void *) sa_tipc + sizeof(sa_tipc->family),
+			    sizeof(*sa_tipc) - sizeof(sa_tipc->family) - 1);
+	printf("}, %zu) = %s\n", sizeof(*sa_tipc) - 1, errstr);
+
+	for (size_t i = 0; i < ARRAY_SIZE(tipc_vecs); i++) {
+		*sa_tipc = tipc_vecs[i].sa;
+
+		rc = connect(-1, (void *) sa_tipc, sizeof(*sa_tipc));
+		printf("connect(-1, %s, %zu) = %s\n",
+		       tipc_vecs[i].str, sizeof(*sa_tipc), sprintrc(rc));
+	}
+}
+
 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
 static void
 check_sco(void)
@@ -1257,6 +1368,7 @@ main(void)
 	check_ll();
 	check_in();
 	check_in6();
+	check_tipc();
 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
 	check_sco();
 	check_rc();
diff --git a/tests/sol_tipc-group_join-Xabbrev.c b/tests/sol_tipc-group_join-Xabbrev.c
new file mode 100644
index 000000000..e8eba5041
--- /dev/null
+++ b/tests/sol_tipc-group_join-Xabbrev.c
@@ -0,0 +1,2 @@
+#define XLAT_ABBREV 1
+#include "sol_tipc-group_join.c"
diff --git a/tests/sol_tipc-group_join-Xraw.c b/tests/sol_tipc-group_join-Xraw.c
new file mode 100644
index 000000000..0a1d05c0e
--- /dev/null
+++ b/tests/sol_tipc-group_join-Xraw.c
@@ -0,0 +1,2 @@
+#define XLAT_RAW 1
+#include "sol_tipc-group_join.c"
diff --git a/tests/sol_tipc-group_join-Xverbose.c b/tests/sol_tipc-group_join-Xverbose.c
new file mode 100644
index 000000000..91a72be66
--- /dev/null
+++ b/tests/sol_tipc-group_join-Xverbose.c
@@ -0,0 +1,2 @@
+#define XLAT_VERBOSE 1
+#include "sol_tipc-group_join.c"
diff --git a/tests/sol_tipc-group_join-success-Xabbrev.c b/tests/sol_tipc-group_join-success-Xabbrev.c
new file mode 100644
index 000000000..f7db91e02
--- /dev/null
+++ b/tests/sol_tipc-group_join-success-Xabbrev.c
@@ -0,0 +1,2 @@
+#define XLAT_ABBREV 1
+#include "sol_tipc-group_join-success.c"
diff --git a/tests/sol_tipc-group_join-success-Xraw.c b/tests/sol_tipc-group_join-success-Xraw.c
new file mode 100644
index 000000000..d2dcd4d2c
--- /dev/null
+++ b/tests/sol_tipc-group_join-success-Xraw.c
@@ -0,0 +1,2 @@
+#define XLAT_RAW 1
+#include "sol_tipc-group_join-success.c"
diff --git a/tests/sol_tipc-group_join-success-Xverbose.c b/tests/sol_tipc-group_join-success-Xverbose.c
new file mode 100644
index 000000000..3d43f360d
--- /dev/null
+++ b/tests/sol_tipc-group_join-success-Xverbose.c
@@ -0,0 +1,2 @@
+#define XLAT_VERBOSE 1
+#include "sol_tipc-group_join-success.c"
diff --git a/tests/sol_tipc-group_join-success.c b/tests/sol_tipc-group_join-success.c
new file mode 100644
index 000000000..e7f05d8e6
--- /dev/null
+++ b/tests/sol_tipc-group_join-success.c
@@ -0,0 +1,2 @@
+#define INJECT_RETVAL 42
+#include "sol_tipc-group_join.c"
diff --git a/tests/sol_tipc-group_join.c b/tests/sol_tipc-group_join.c
new file mode 100644
index 000000000..26c782321
--- /dev/null
+++ b/tests/sol_tipc-group_join.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2025 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+
+#include <stdio.h>
+#include <sys/socket.h>
+#include <linux/tipc.h>
+
+#define VALID_FLAGS   3
+#define INVALID_FLAGS 4
+
+static int rc;
+static const char *errstr;
+
+static int
+set_group_req(const void *optval, socklen_t len)
+{
+	rc = setsockopt(-1, SOL_TIPC, TIPC_GROUP_JOIN, optval, len);
+	errstr = sprintrc(rc);
+
+#ifdef INJECT_RETVAL
+	if (rc != INJECT_RETVAL)
+		error_msg_and_fail("Return value [%d] does not match"
+				   " expectations [%d]", rc, INJECT_RETVAL);
+
+	static char inj_errstr[4096];
+
+	snprintf(inj_errstr, sizeof(inj_errstr), "%s (INJECTED)", errstr);
+	errstr = inj_errstr;
+#endif
+
+	return rc;
+}
+
+static int
+get_group_req(void *optval, socklen_t *len)
+{
+	rc = getsockopt(-1, SOL_TIPC, TIPC_GROUP_JOIN, optval, len);
+	errstr = sprintrc(rc);
+
+#ifdef INJECT_RETVAL
+	if (rc != INJECT_RETVAL)
+		error_msg_and_fail("Return value [%d] does not match"
+				   " expectations [%d]", rc, INJECT_RETVAL);
+
+	static char inj_errstr[4096];
+
+	snprintf(inj_errstr, sizeof(inj_errstr), "%s (INJECTED)", errstr);
+	errstr = inj_errstr;
+#endif
+
+	return rc;
+}
+
+int
+main(void)
+{
+	char pfx_str[256];
+	TAIL_ALLOC_OBJECT_CONST_PTR(struct tipc_group_req, mreq);
+	TAIL_ALLOC_OBJECT_CONST_PTR(socklen_t, len);
+
+	snprintf(pfx_str, sizeof(pfx_str), "etsockopt(-1, "
+		 XLAT_FMT ", " XLAT_FMT, XLAT_ARGS(SOL_TIPC), XLAT_ARGS(TIPC_GROUP_JOIN));
+
+	mreq->type = 42;
+	mreq->instance = 2;
+	mreq->scope = 2;
+	mreq->flags = 2;
+
+	/* classic setsockopt */
+	set_group_req(mreq, sizeof(*mreq));
+	printf("s%s, {type=%u, instance=%u, scope=%s, flags=%s}, %u) = %s\n",
+	       pfx_str, mreq->type, mreq->instance,
+	       XLAT_KNOWN(2, "TIPC_CLUSTER_SCOPE"),
+	       XLAT_KNOWN(0x2, "TIPC_GROUP_MEMBER_EVTS"),
+	       (unsigned int) sizeof(*mreq), errstr);
+
+	mreq->scope = 3;
+	mreq->flags = 3;
+
+	set_group_req(mreq, sizeof(*mreq));
+	printf("s%s, {type=%u, instance=%u, scope=%s, flags=%s}, %u) = %s\n",
+	       pfx_str, mreq->type, mreq->instance,
+	       XLAT_KNOWN(3, "TIPC_NODE_SCOPE"),
+	       XLAT_KNOWN(0x3, "TIPC_GROUP_LOOPBACK|TIPC_GROUP_MEMBER_EVTS"),
+	       (unsigned int) sizeof(*mreq), errstr);
+
+	mreq->scope = 4;
+	mreq->flags = 4;
+
+	set_group_req(mreq, sizeof(*mreq));
+	printf("s%s, {type=%u, instance=%u, scope=%s, flags=%s}, %u) = %s\n",
+	       pfx_str, mreq->type, mreq->instance,
+	       XLAT_UNKNOWN(4, "TIPC_???_SCOPE"),
+	       XLAT_UNKNOWN(0x4, "TIPC_GROUP_???"),
+	       (unsigned int) sizeof(*mreq), errstr);
+
+	/* classic getsockopt */
+	*len = sizeof(*mreq);
+	rc = get_group_req(mreq, len);
+
+	printf("g%s, ", pfx_str);
+	if (rc < 0)
+		printf("%p, ", mreq);
+	else
+		printf("{type=%u, instance=%u, scope=%s, flags=%s}, ",
+		       mreq->type, mreq->instance,
+		       XLAT_UNKNOWN(4, "TIPC_???_SCOPE"),
+		       XLAT_UNKNOWN(0x4, "TIPC_GROUP_???"));
+	printf("[%u]) = %s\n", *len, errstr);
+
+	mreq->scope = 3;
+	mreq->flags = 1;
+
+	rc = get_group_req(mreq, len);
+	printf("g%s, ", pfx_str);
+	if (rc < 0)
+		printf("%p, ", mreq);
+	else
+		printf("{type=%u, instance=%u, scope=%s, flags=%s}, ",
+		       mreq->type, mreq->instance,
+		       XLAT_KNOWN(3, "TIPC_NODE_SCOPE"),
+		       XLAT_KNOWN(0x1, "TIPC_GROUP_LOOPBACK"));
+	printf("[%u]) = %s\n", *len, errstr);
+
+	/* setsockopt with optlen smaller than usual */
+	set_group_req(mreq, sizeof(*mreq) - 1);
+
+	printf("s%s, %p, %u) = %s\n",
+	       pfx_str, mreq, (unsigned int) sizeof(*mreq) - 1, errstr);
+
+	/* getsockopt with optlen smaller than usual */
+	*len = sizeof(*mreq) - 1;
+	get_group_req(mreq, len);
+
+	printf("g%s, %p, [%u]) = %s\n",
+	       pfx_str, mreq, *len, errstr);
+
+	/* setsockopt with optlen larger than usual */
+	set_group_req(mreq, sizeof(*mreq) + 1);
+
+	printf("s%s, {type=%u, instance=%u, scope=%s, flags=%s}, %u) = %s\n",
+	       pfx_str, mreq->type, mreq->instance,
+	       XLAT_KNOWN(3, "TIPC_NODE_SCOPE"),
+	       XLAT_KNOWN(0x1, "TIPC_GROUP_LOOPBACK"),
+	       (unsigned int) sizeof(*mreq) + 1, errstr);
+
+	/* getsockopt with optlen larger than usual */
+	*len = sizeof(*mreq) + 1;
+	rc = get_group_req(mreq, len);
+
+	printf("g%s, ", pfx_str);
+	if (rc < 0)
+		printf("%p, ", mreq);
+	else
+		printf("{type=%u, instance=%u, scope=%s, flags=%s}, ",
+		       mreq->type, mreq->instance,
+		       XLAT_KNOWN(3, "TIPC_NODE_SCOPE"),
+		       XLAT_KNOWN(0x1, "TIPC_GROUP_LOOPBACK"));
+	printf("[%u]) = %s\n", *len, errstr);
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/sol_tipc-importance-Xabbrev.c b/tests/sol_tipc-importance-Xabbrev.c
new file mode 100644
index 000000000..2200553dc
--- /dev/null
+++ b/tests/sol_tipc-importance-Xabbrev.c
@@ -0,0 +1,2 @@
+#define XLAT_ABBREV 1
+#include "sol_tipc-importance.c"
diff --git a/tests/sol_tipc-importance-Xraw.c b/tests/sol_tipc-importance-Xraw.c
new file mode 100644
index 000000000..e936ac563
--- /dev/null
+++ b/tests/sol_tipc-importance-Xraw.c
@@ -0,0 +1,2 @@
+#define XLAT_RAW 1
+#include "sol_tipc-importance.c"
diff --git a/tests/sol_tipc-importance-Xverbose.c b/tests/sol_tipc-importance-Xverbose.c
new file mode 100644
index 000000000..2f0c02e5a
--- /dev/null
+++ b/tests/sol_tipc-importance-Xverbose.c
@@ -0,0 +1,2 @@
+#define XLAT_VERBOSE 1
+#include "sol_tipc-importance.c"
diff --git a/tests/sol_tipc-importance-success-Xabbrev.c b/tests/sol_tipc-importance-success-Xabbrev.c
new file mode 100644
index 000000000..8c93dfc58
--- /dev/null
+++ b/tests/sol_tipc-importance-success-Xabbrev.c
@@ -0,0 +1,2 @@
+#define XLAT_ABBREV 1
+#include "sol_tipc-importance-success.c"
diff --git a/tests/sol_tipc-importance-success-Xraw.c b/tests/sol_tipc-importance-success-Xraw.c
new file mode 100644
index 000000000..0d19d3bf8
--- /dev/null
+++ b/tests/sol_tipc-importance-success-Xraw.c
@@ -0,0 +1,2 @@
+#define XLAT_RAW 1
+#include "sol_tipc-importance-success.c"
diff --git a/tests/sol_tipc-importance-success-Xverbose.c b/tests/sol_tipc-importance-success-Xverbose.c
new file mode 100644
index 000000000..9e00e5786
--- /dev/null
+++ b/tests/sol_tipc-importance-success-Xverbose.c
@@ -0,0 +1,2 @@
+#define XLAT_VERBOSE 1
+#include "sol_tipc-importance-success.c"
diff --git a/tests/sol_tipc-importance-success.c b/tests/sol_tipc-importance-success.c
new file mode 100644
index 000000000..0f1e9ea8e
--- /dev/null
+++ b/tests/sol_tipc-importance-success.c
@@ -0,0 +1,2 @@
+#define INJECT_RETVAL 42
+#include "sol_tipc-importance.c"
diff --git a/tests/sol_tipc-importance.c b/tests/sol_tipc-importance.c
new file mode 100644
index 000000000..347e85ede
--- /dev/null
+++ b/tests/sol_tipc-importance.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2025 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+
+#include <stdio.h>
+#include <sys/socket.h>
+#include <linux/tipc.h>
+
+#define XLAT_MACROS_ONLY
+# include "xlat/af_tipc_importance.h"
+#undef XLAT_MACROS_ONLY
+
+static int rc;
+static const char *errstr;
+
+static int
+set_importance(const void *optval, socklen_t len)
+{
+	rc = setsockopt(-1, SOL_TIPC, TIPC_IMPORTANCE, optval, len);
+	errstr = sprintrc(rc);
+
+#ifdef INJECT_RETVAL
+	if (rc != INJECT_RETVAL)
+		error_msg_and_fail("Return value [%d] does not match"
+				   " expectations [%d]", rc, INJECT_RETVAL);
+
+	static char inj_errstr[4096];
+
+	snprintf(inj_errstr, sizeof(inj_errstr), "%s (INJECTED)", errstr);
+	errstr = inj_errstr;
+#endif
+
+	return rc;
+}
+
+static int
+get_importance(void *optval, socklen_t *len)
+{
+	rc = getsockopt(-1, SOL_TIPC, TIPC_IMPORTANCE, optval, len);
+	errstr = sprintrc(rc);
+
+#ifdef INJECT_RETVAL
+	if (rc != INJECT_RETVAL)
+		error_msg_and_fail("Return value [%d] does not match"
+				   " expectations [%d]", rc, INJECT_RETVAL);
+
+	static char inj_errstr[4096];
+
+	snprintf(inj_errstr, sizeof(inj_errstr), "%s (INJECTED)", errstr);
+	errstr = inj_errstr;
+#endif
+
+	return rc;
+}
+
+int
+main(void)
+{
+	char pfx_str[256];
+	TAIL_ALLOC_OBJECT_CONST_PTR(int, imp);
+	TAIL_ALLOC_OBJECT_CONST_PTR(socklen_t, len);
+
+	static const struct {
+		int optval;
+		const char *str;
+	} imp_optvals[] = {
+		{ ARG_STR(TIPC_LOW_IMPORTANCE) },
+		{ ARG_STR(TIPC_MEDIUM_IMPORTANCE) },
+		{ ARG_STR(TIPC_HIGH_IMPORTANCE) },
+		{ ARG_STR(TIPC_CRITICAL_IMPORTANCE) },
+	};
+
+	snprintf(pfx_str, sizeof(pfx_str), "etsockopt(-1, "
+		 XLAT_FMT ", " XLAT_FMT, XLAT_ARGS(SOL_TIPC), XLAT_ARGS(TIPC_IMPORTANCE));
+
+	/* classic setsockopt */
+	unsigned int i = 0;
+
+	for (i = 0; i < ARRAY_SIZE(imp_optvals); i++) {
+		*imp = imp_optvals[i].optval;
+		set_importance(imp, sizeof(*imp));
+		printf("s%s, [", pfx_str);
+#if XLAT_RAW
+		printf("%u", imp_optvals[i].optval);
+#elif XLAT_VERBOSE
+		printf("%u /* %s */", imp_optvals[i].optval, imp_optvals[i].str);
+#else
+		printf("%s", imp_optvals[i].str);
+#endif
+		printf("], %u) = %s\n", (unsigned int) sizeof(*imp), errstr);
+	}
+
+	*imp = 5;
+	set_importance(imp, sizeof(*imp));
+	printf("s%s, [%s], %u) = %s\n",
+	       pfx_str, XLAT_UNKNOWN(5, "TIPC_???_IMPORTANCE"),
+	       (unsigned int) sizeof(*imp), errstr);
+
+	/* classic getsockopt */
+	*len = sizeof(*imp);
+	for (i = 0; i < ARRAY_SIZE(imp_optvals); i++) {
+		*imp = imp_optvals[i].optval;
+
+		rc = get_importance(imp, len);
+		printf("g%s, ", pfx_str);
+		if (rc < 0)
+			printf("%p", imp);
+		else {
+#if XLAT_RAW
+			printf("[%u]", imp_optvals[i].optval);
+#elif XLAT_VERBOSE
+			printf("[%u /* %s */]", imp_optvals[i].optval, imp_optvals[i].str);
+#else
+			printf("[%s]", imp_optvals[i].str);
+#endif
+		}
+		printf(", [%u]) = %s\n", *len, errstr);
+	}
+
+	*imp = 5;
+	rc = get_importance(imp, len);
+	printf("g%s, ", pfx_str);
+	if (rc < 0)
+		printf("%p, ", imp);
+	else
+		printf("[%s], ", XLAT_UNKNOWN(5, "TIPC_???_IMPORTANCE"));
+	printf("[%u]) = %s\n", *len, errstr);
+
+	*imp = 1;
+
+	/* setsockopt with optlen smaller than usual */
+	set_importance(imp, sizeof(*imp) - 1);
+	printf("s%s, %p, %u) = %s\n",
+	       pfx_str, imp, (unsigned int) sizeof(*imp) - 1, errstr);
+
+	/* getsockopt with optlen smaller than usual */
+	*len = sizeof(*imp) - 1;
+	get_importance(imp, len);
+	printf("g%s, %p, [%u]) = %s\n",
+	       pfx_str, imp, *len, errstr);
+
+	/* setsockopt with optlen larger than usual */
+	set_importance( imp, sizeof(*imp) + 1);
+	printf("s%s, [%s], %u) = %s\n",
+	       pfx_str, XLAT_KNOWN(1, "TIPC_MEDIUM_IMPORTANCE"),
+	       (unsigned int) sizeof(*imp) + 1, errstr);
+
+	/* getsockopt with optlen larger than usual */
+	*len = sizeof(*imp) + 1;
+
+	rc = get_importance(imp, len);
+	printf("g%s, ", pfx_str);
+	if (rc < 0)
+		printf("%p", imp);
+	else
+		printf("[%s]",
+		       XLAT_KNOWN(1, "TIPC_MEDIUM_IMPORTANCE"));
+	printf(", [%u]) = %s\n", *len, errstr);
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
-- 
2.49.0



More information about the Strace-devel mailing list