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        |  3 +++
 socketutils.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 59 insertions(+), 8 deletions(-)

diff --git a/defs.h b/defs.h
index ee35dab..e9a9392 100644
--- a/defs.h
+++ b/defs.h
@@ -523,6 +523,9 @@ 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,
+                                  const enum sock_proto);
 
 extern bool
 print_array(struct tcb *tcp,
diff --git a/socketutils.c b/socketutils.c
index 4a39522..944aec6 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,7 +446,22 @@ 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;
 }
 
 static const struct {
@@ -450,6 +476,28 @@ static const struct {
        [SOCK_PROTO_NETLINK] = { "NETLINK", netlink_print }
 };
 
+char *
+get_sockaddr_by_inode(const unsigned long inode, const enum sock_proto proto)
+{
+       if ((unsigned int) proto >= ARRAY_SIZE(protocols) ||
+           (proto != SOCK_PROTO_UNKNOWN && !protocols[proto].print))
+               return false;
+
+       const int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
+       if (fd < 0)
+               return NULL;
+       char *details = NULL;
+
+       if (proto != SOCK_PROTO_UNKNOWN) {
+               if (proto == SOCK_PROTO_NETLINK)
+                       details = netlink_get(fd, inode);
+       }
+
+       close(fd);
+
+       return details;
+}
+
 /* Given an inode number of a socket, print out the details
  * of the ip address and port. */
 
-- 
2.8.3


------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports. http://pubads.g.doubleclick.net/gampad/clk?id=1444514421&iu=/41014381
_______________________________________________
Strace-devel mailing list
Strace-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to