[PATCH 4/5] Introduce get_sockaddr_by_inode_cached and get_sockaddr_by_inode
Fabien Siron
fabien.siron at epita.fr
Wed Jun 1 10:15:09 UTC 2016
Because netlink parsing needs a way to get the netlink protocol and the
socketutils.c file can only print the protocol, this commit adds an interface
to get some socket information without printing it.
* defs.h
(get_sockaddr_by_inode_cached, get_sockaddr_by_inode): Add.
* socketutils.c (cache_print_inode_details): Remove function.
(cache_inode_details, get_sockaddr_by_inode_cached, get_sockaddr_by_inode,
netlink_get): New functions.
(inet_print): Call print_sockaddr_by_inode_details.
(unix_print): Likewise.
(netlink_print): Likewise.
(unix_parse_response): Call cache_inode_details.
(netlink_parse_resonse): Likewise.
(inet_parse_response): Likewise.
---
defs.h | 2 ++
socketutils.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 69 insertions(+), 8 deletions(-)
diff --git a/defs.h b/defs.h
index 134e0fe..06dba19 100644
--- a/defs.h
+++ b/defs.h
@@ -513,6 +513,8 @@ extern int umoven_or_printaddr(struct tcb *, long, unsigned int, void *);
umoven_or_printaddr((pid), (addr), sizeof(*(objp)), (void *) (objp))
extern int umovestr(struct tcb *, long, unsigned int, char *);
extern int upeek(int pid, long, long *);
+extern char *get_sockaddr_by_inode_cached(const unsigned long);
+extern char *get_sockaddr_by_inode(const unsigned long inode, int);
extern bool
print_array(struct tcb *tcp,
diff --git a/socketutils.c b/socketutils.c
index 0ac8463..3c2ba75 100644
--- a/socketutils.c
+++ b/socketutils.c
@@ -57,14 +57,13 @@ static cache_entry cache[CACHE_SIZE];
#define CACHE_MASK (CACHE_SIZE - 1)
static int
-cache_and_print_inode_details(const unsigned long inode, char *const details)
+cache_inode_details(const unsigned long inode, char *const details)
{
cache_entry *e = &cache[inode & CACHE_MASK];
free(e->details);
e->inode = inode;
e->details = details;
- tprints(details);
return 1;
}
@@ -79,6 +78,16 @@ print_sockaddr_by_inode_cached(const unsigned long inode)
return false;
}
+char *
+get_sockaddr_by_inode_cached(const unsigned long inode)
+{
+ const cache_entry *const e = &cache[inode & CACHE_MASK];
+ if (e && inode == e->inode) {
+ return e->details;
+ }
+ return NULL;
+}
+
static bool
send_query(const int fd, void *req, size_t req_size)
{
@@ -178,7 +187,7 @@ inet_parse_response(const char *const proto_name, const void *const data,
return false;
}
- return cache_and_print_inode_details(inode, details);
+ return cache_inode_details(inode, details);
}
static bool
@@ -238,7 +247,8 @@ inet_print(const int fd, const int family, const int protocol,
const unsigned long inode, const char *proto_name)
{
return inet_send_query(fd, family, protocol)
- && receive_responses(fd, inode, proto_name, inet_parse_response);
+ && receive_responses(fd, inode, proto_name, inet_parse_response)
+ && print_sockaddr_by_inode_cached(inode);
}
static bool
@@ -337,7 +347,7 @@ unix_parse_response(const char *proto_name, const void *data,
peer_str, path_str) < 0)
return -1;
- return cache_and_print_inode_details(inode, details);
+ return cache_inode_details(inode, details);
}
static bool
@@ -396,14 +406,15 @@ netlink_parse_response(const char *proto_name, const void *data,
return -1;
}
- return cache_and_print_inode_details(inode, details);
+ return cache_inode_details(inode, details);
}
static bool
unix_print(const int fd, const unsigned long inode)
{
return unix_send_query(fd, inode)
- && receive_responses(fd, inode, "UNIX", unix_parse_response);
+ && receive_responses(fd, inode, "UNIX", unix_parse_response)
+ && print_sockaddr_by_inode_cached(inode);
}
static bool
@@ -435,10 +446,58 @@ netlink_print(const int fd, const unsigned long inode)
{
return netlink_send_query(fd, inode)
&& receive_responses(fd, inode, "NETLINK",
- netlink_parse_response);
+ netlink_parse_response)
+ && print_sockaddr_by_inode_cached(inode);
+}
+
+static char *
+netlink_get(const int fd, const unsigned long inode)
+{
+ if (netlink_send_query(fd, inode)
+ && receive_responses(fd, inode, "NETLINK",
+ netlink_parse_response)) {
+ cache_entry *e = &cache[inode & CACHE_MASK];
+ if (e && inode == e->inode)
+ return e->details;
+ }
+
+ return NULL;
}
#include "socketutils.h"
+char *
+get_sockaddr_by_inode(const unsigned long inode, const int proto)
+{
+ const int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
+ if (fd < 0)
+ return NULL;
+ char *details = NULL;
+ unsigned int i;
+
+ if (proto != -1) {
+ switch (proto) {
+ case NETLINK:
+ details = netlink_get(fd, inode);
+ break;
+ }
+
+ } else {
+ char *(*const protocols_get[])(int, unsigned long) =
+ {
+ netlink_get
+ };
+
+ for (i = 0; i < ARRAY_SIZE(protocols_get); ++i) {
+ if ((details = protocols_get[i](fd, inode)))
+ break;
+ }
+ }
+
+ close(fd);
+
+ return details;
+}
+
/* Given an inode number of a socket, print out the details
* of the ip address and port. */
bool
--
2.8.0
More information about the Strace-devel
mailing list