[PATCH strace v2] Implement decoding of RXRPC_* control messages

David Howells dhowells at redhat.com
Wed May 31 14:42:39 UTC 2023


* src/xlat/rxrpc_cmsg_types.in: New file
* src/msghdr.c (print_cmsg_rxrpc_user_call_id, print_cmsg_ullong):
  New functions.
* NEWS: Mention this change.

Signed-off-by: David Howells <dhowells at redhat.com>
---
 NEWS                         |    1 
 src/msghdr.c                 |   68 +++++++++++++++++++++++++++++++++++++++++++
 src/xlat/rxrpc_cmsg_types.in |   15 +++++++++
 3 files changed, 84 insertions(+)

diff --git a/NEWS b/NEWS
index 6cdeb64a5..5c237a6ce 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ Noteworthy changes in release ?.? (????-??-??)
   * Implemented decoding of IFLA_BRPORT_MCAST_N_GROUPS,
     IFLA_BRPORT_MCAST_MAX_GROUPS, IFLA_GSO_IPV4_MAX_SIZE,
     IFLA_GRO_IPV4_MAX_SIZE, and TCA_EXT_WARN_MSG netlink attributes.
+  * Implemented decoding of RXRPC_* control messages.
   * Updated lists of F_SEAL_*, IFLA_*, IORING_*, MFD_*, NFT_*, TCA_*,
     and V4L2_PIX_FMT_* constants.
   * Updated lists of ioctl commands from Linux 6.3.
diff --git a/src/msghdr.c b/src/msghdr.c
index cbcb8b9a4..882875242 100644
--- a/src/msghdr.c
+++ b/src/msghdr.c
@@ -22,6 +22,7 @@
 #include "xlat/msg_flags.h"
 #include "xlat/scmvals.h"
 #include "xlat/ip_cmsg_types.h"
+#include "xlat/rxrpc_cmsg_types.h"
 
 #ifndef current_wordsize
 struct cmsghdr32 {
@@ -159,6 +160,16 @@ print_cmsg_uint(struct tcb *tcp, const void *cmsg_data,
 			     print_uint_array_member, NULL, 0, NULL, NULL);
 }
 
+static void
+print_cmsg_xint(struct tcb *tcp, const void *cmsg_data,
+		const unsigned int data_len)
+{
+	const unsigned int *p = cmsg_data;
+
+	print_local_array_ex(tcp, p, data_len / sizeof(*p), sizeof(*p),
+			     print_xint_array_member, NULL, 0, NULL, NULL);
+}
+
 static void
 print_cmsg_xint8_t(struct tcb *tcp, const void *cmsg_data,
 		   const unsigned int data_len)
@@ -167,6 +178,16 @@ print_cmsg_xint8_t(struct tcb *tcp, const void *cmsg_data,
 			     print_xint_array_member, NULL, 0, NULL, NULL);
 }
 
+static void
+print_cmsg_ullong(struct tcb *tcp, const void *cmsg_data,
+		  const unsigned int data_len)
+{
+	const unsigned long long *p = cmsg_data;
+
+	print_local_array_ex(tcp, p, data_len / sizeof(*p), sizeof(*p),
+			     print_uint_array_member, NULL, 0, NULL, NULL);
+}
+
 struct sock_ee {
 	uint32_t ee_errno;
 	uint8_t  ee_origin;
@@ -212,6 +233,30 @@ print_cmsg_ip_origdstaddr(struct tcb *tcp, const void *cmsg_data,
 	print_sockaddr(tcp, cmsg_data, addr_len);
 }
 
+static void
+print_cmsg_rxrpc_user_call_id(struct tcb *tcp, const void *cmsg_data,
+			      const unsigned int data_len)
+{
+	const unsigned int *p = cmsg_data;
+
+	/* Size is "unsigned long" but we might be stracing a 32-bit program
+	 * from a 64-bit strace or vice versa.
+	 */
+	switch (data_len) {
+	case 4:
+		print_local_array_ex(tcp, p, 1, 4,
+				     print_xint_array_member, NULL, 0, NULL, NULL);
+		break;
+	case 8:
+		print_local_array_ex(tcp, p, 1, 8,
+				     print_xint_array_member, NULL, 0, NULL, NULL);
+		break;
+	default:
+		print_cmsg_xint(tcp, cmsg_data, data_len);
+		break;
+	}
+}
+
 typedef void (* const cmsg_printer)(struct tcb *, const void *, unsigned int);
 
 static const struct {
@@ -237,6 +282,19 @@ static const struct {
 	[IP_ORIGDSTADDR] = { print_cmsg_ip_origdstaddr, sizeof(struct sockaddr_in) },
 	[IP_CHECKSUM] = { print_cmsg_uint, sizeof(unsigned int) },
 	[SCM_SECURITY] = { print_scm_security, 1 }
+}, cmsg_rxrpc_printers[] = {
+	[RXRPC_USER_CALL_ID]	= { print_cmsg_rxrpc_user_call_id, sizeof(unsigned int) },
+	[RXRPC_ABORT]		= { print_cmsg_uint, sizeof(unsigned int) },
+	[RXRPC_ACK]		= { print_cmsg_uint, sizeof(unsigned int) },
+	[RXRPC_NET_ERROR]	= { print_cmsg_uint, sizeof(unsigned int) },
+	[RXRPC_BUSY]		= { print_cmsg_uint, sizeof(unsigned int) },
+	[RXRPC_LOCAL_ERROR]	= { print_cmsg_uint, sizeof(unsigned int) },
+	[RXRPC_NEW_CALL]	= { print_cmsg_uint, sizeof(unsigned int) },
+	[RXRPC_EXCLUSIVE_CALL]	= { print_cmsg_uint, sizeof(unsigned int) },
+	[RXRPC_UPGRADE_SERVICE]	= { print_cmsg_uint, sizeof(unsigned int) },
+	[RXRPC_TX_LENGTH]	= { print_cmsg_ullong, sizeof(unsigned long long) },
+	[RXRPC_SET_CALL_TIMEOUT] = { print_cmsg_uint, sizeof(unsigned int) },
+	[RXRPC_CHARGE_ACCEPT]	= { print_cmsg_uint, sizeof(unsigned int) },
 };
 
 static void
@@ -265,6 +323,16 @@ print_cmsg_type_data(struct tcb *tcp, const int cmsg_level, const int cmsg_type,
 			cmsg_ip_printers[utype].printer(tcp, cmsg_data, data_len);
 		}
 		break;
+	case SOL_RXRPC:
+		printxval(rxrpc_cmsg_types, cmsg_type, "RXRPC_???");
+		if (utype < ARRAY_SIZE(cmsg_rxrpc_printers)
+		    && cmsg_rxrpc_printers[utype].printer
+		    && data_len >= cmsg_rxrpc_printers[utype].min_len) {
+			tprint_struct_next();
+			tprints_field_name("cmsg_data");
+			cmsg_rxrpc_printers[utype].printer(tcp, cmsg_data, data_len);
+		}
+		break;
 	default:
 		PRINT_VAL_X(cmsg_type);
 	}
diff --git a/src/xlat/rxrpc_cmsg_types.in b/src/xlat/rxrpc_cmsg_types.in
new file mode 100644
index 000000000..474034e69
--- /dev/null
+++ b/src/xlat/rxrpc_cmsg_types.in
@@ -0,0 +1,15 @@
+#value_indexed
+RXRPC_USER_CALL_ID	1
+RXRPC_ABORT		2
+RXRPC_ACK		3
+RXRPC_RESPONSE		4
+RXRPC_NET_ERROR		5
+RXRPC_BUSY		6
+RXRPC_LOCAL_ERROR	7
+RXRPC_NEW_CALL		8
+RXRPC_ACCEPT		9
+RXRPC_EXCLUSIVE_CALL	10
+RXRPC_UPGRADE_SERVICE	11
+RXRPC_TX_LENGTH		12
+RXRPC_SET_CALL_TIMEOUT	13
+RXRPC_CHARGE_ACCEPT	14



More information about the Strace-devel mailing list