[PATCH v2 5/7] Introduce getfdnlproto to obtain netlink protocol from fd

Fabien Siron fabien.siron at epita.fr
Mon Jun 13 14:37:25 UTC 2016


* defs.h (getfdnlproto): Add.
* utils.c (getfdinode): New function.
(getfdnlproto): Likewise.
---
 defs.h |  1 +
 util.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/defs.h b/defs.h
index 06dba19..87ae043 100644
--- a/defs.h
+++ b/defs.h
@@ -545,6 +545,7 @@ extern void pathtrace_select(const char *);
 extern int pathtrace_match(struct tcb *);
 extern int getfdpath(struct tcb *, int, char *, unsigned);
 extern int getfdproto(struct tcb *, int);
+extern int getfdnlproto(struct tcb *, int, const struct xlat *);
 
 extern const char *xlookup(const struct xlat *, const uint64_t);
 extern const char *xlat_search(const struct xlat *, const size_t, const uint64_t);
diff --git a/util.c b/util.c
index f1ca079..3e93380 100644
--- a/util.c
+++ b/util.c
@@ -516,21 +516,77 @@ getfdproto(struct tcb *tcp, int fd)
 #endif
 }
 
-void
-printfd(struct tcb *tcp, int fd)
+static unsigned long
+getfdinode(struct tcb *tcp, int fd)
 {
 	char path[PATH_MAX + 1];
-	if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
+	if (getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
 		static const char socket_prefix[] = "socket:[";
 		const size_t socket_prefix_len = sizeof(socket_prefix) - 1;
 		const size_t path_len = strlen(path);
 
-		tprintf("%d<", fd);
-		if (show_fd_path > 1 &&
-		    strncmp(path, socket_prefix, socket_prefix_len) == 0 &&
+		if (strncmp(path, socket_prefix, socket_prefix_len) == 0 &&
 		    path[path_len - 1] == ']') {
 			unsigned long inode =
 				strtoul(path + socket_prefix_len, NULL, 10);
+			return inode;
+		}
+	}
+	return -1;
+}
+
+int
+getfdnlproto(struct tcb *tcp, int fd, const struct xlat *xprotocols)
+{
+	unsigned long inode = getfdinode(tcp, fd);
+
+	if (inode != 0) {
+		char *nl_proto = NULL;
+		static const char socket_prefix[] = "NETLINK:[";
+		const size_t socket_prefix_len =
+				sizeof(socket_prefix) -1;
+		nl_proto = get_sockaddr_by_inode_cached(inode);
+		if (nl_proto == NULL) {
+			int proto = getfdproto(tcp, fd);
+			nl_proto = get_sockaddr_by_inode(inode, proto);
+		}
+		if (nl_proto == NULL)
+			return -1;
+
+		if (strncmp(nl_proto, socket_prefix,
+			    socket_prefix_len) == 0) {
+			static const char define_prefix[] = "NETLINK_";
+			const size_t define_prefix_len =
+				sizeof(define_prefix) -1;
+			nl_proto += socket_prefix_len;
+
+			for (;xprotocols->str != NULL; xprotocols++) {
+				if (strncmp(xprotocols->str,
+					       define_prefix,
+					    define_prefix_len) != 0)
+					return -1;
+				if (strncmp(nl_proto,
+					    xprotocols->str + define_prefix_len,
+					    strlen(xprotocols->str +
+						   define_prefix_len)) == 0)
+					return xprotocols->val;
+			}
+		}
+	}
+
+	return -1;
+}
+
+void
+printfd(struct tcb *tcp, int fd)
+{
+	char path[PATH_MAX + 1];
+	if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
+		const size_t path_len = strlen(path);
+
+		tprintf("%d<", fd);
+		if (show_fd_path > 1) {
+				unsigned long inode = getfdinode(tcp, fd);
 
 			if (!print_sockaddr_by_inode_cached(inode)) {
 				const int proto =
-- 
2.8.3





More information about the Strace-devel mailing list