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