[PATCH v3] Print ip and port associated with descriptor with -yy

Masatake YAMATO yamato at redhat.com
Thu Aug 7 13:28:37 UTC 2014


> From: Zubin Mithra <zubin.mithra at gmail.com>
> 
> * defs.h: Add Add header files netinet/in.h, sys/socket.h,
> arpa/inet.h, linux/netlink.h and linux/inet_diag.h.
>   Change type of show_fd_path to unsigned int.
>   Add macros SOCK_DIAG_BY_FAMILY, SOCKET_BUFFER_SIZE.
>   Add structs sock_diag_req, inet_diag_req_v2.
> * strace.c (init): Change usage of show_fd_path.
> * util.c (parse_response): New function to parse and
> print ip, port from a message response.
> (send_query): New function.
> (receive_responses): New function.
> (printsockdetails): New function.
> (printfd): Modified to use printsockdetails.

Wow!

The feature looks important. People including I may want extend to
handle more families and get information.

It is nice if you prepare a test case, too. See code/tests/.

On Thu,  7 Aug 2014 18:17:12 +0530, zubin.mithra at gmail.com wrote:
> +	if (diag_msg->idiag_family == AF_INET)
> +		inet_ntop(AF_INET, (struct in_addr*) &(diag_msg->id.idiag_dst),
> +			  remote_addr_buf, INET_ADDRSTRLEN);
> +	else if (diag_msg->idiag_family == AF_INET6)
> +		inet_ntop(AF_INET6, (struct in_addr6*) &(diag_msg->id.idiag_dst),
> +			  remote_addr_buf, INET6_ADDRSTRLEN);
> +	else
> +		return -1;

To make adding more families a bit easier how do you think use switch/case
instead of if/else? Like:

	switch (diag_msg->idiag_family) {
	       case AF_INET:
	       	    ...
	       case AF_INET6:
	       	    ...	
	}

On Thu,  7 Aug 2014 18:17:12 +0530, zubin.mithra at gmail.com wrote:
> +/* Given an inode number of a socket, print out the details
> + * of the remote ip address and remote port */
> +int
> +printsockdetails(int inodenr)
> +{
> +	int sockfd;
> +	int i, j;
> +	int protocols[] = {IPPROTO_TCP, IPPROTO_UDP};
> +	int families[] = {AF_INET, AF_INET6};
> +
> +	//Create the monitoring socket
> +	if((sockfd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_INET_DIAG)) == -1)
> +		return -1;

Do we have to create a netlink socket each time printsockdetails is inovked?
How do you think cache the response from the netlink socket?

System calls that adding and removing a socket from fd table of process are
enumerable. So you can cache the response from the netlink socket safely
if the target program is not multi-threaded.

* adding

  + socket
  + accept
  + passing

* removing

  + close
  + shutdown?


Could the technique I used in commit 1d78d22058da04eac7bf726c059d5c3fb193da08 
help you?

> +
> +	for (i = 0; i < 2; i++) {

"2" is hardcoded here. sizeof(families)/sizeof(families[0]) may be better
because it makes adding more families a bit easier.

On Thu,  7 Aug 2014 18:17:12 +0530, zubin.mithra at gmail.com wrote:
>  void
>  printfd(struct tcb *tcp, int fd)
>  {
>  	char path[PATH_MAX + 1];
>  
> -	if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0)
> +	if (show_fd_path == 1 && getfdpath(tcp, fd, path, sizeof(path)) >= 0)
>  		tprintf("%d<%s>", fd, path);
> +	else if (show_fd_path > 1 && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
> +		char *ptr = NULL;
> +		int inodenr;
> +		ptr = strstr(path, "socket:[");
> +		if (ptr != path) {
> +			tprintf("%d<%s>", fd, path);
> +		}
> +		else {
> +			int retval;
> +			ptr = path + 8;
> +			path[strlen(path)-1] = '\0';
> +			inodenr = strtol(ptr, NULL, 10);
> +			tprintf("%d<", fd);
> +			retval = printsockdetails(inodenr);
> +			if (retval == -1) tprintf("socket:[%d]",inodenr);
> +			tprints(">");
> +		}
> +	}
>  	else
>  		tprintf("%d", fd);

I cannot show even pseudo code but if possible, could you consider
adding code to handle other fd type like pipe, device?

Masatake YAMATO





More information about the Strace-devel mailing list