[PATCH] netlink: decode NLMSG_DONE messages

Dmitry V. Levin ldv at altlinux.org
Sun Jun 4 14:26:01 UTC 2017


On Fri, May 05, 2017 at 06:21:17PM +0800, JingPiao Chen wrote:
> * netlink.c (decode_payload): Decode NLMSG_DONE messages.
> * tests/netlink_protocol.c (test_nlmsg_done): New function
> for checking decoding of NLMSG_DONE messages.
> (main): Use it.
> ---
>  netlink.c                |  6 ++++++
>  tests/netlink_protocol.c | 37 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 43 insertions(+)
> 
> diff --git a/netlink.c b/netlink.c
> index 678343c..daaa745 100644
> --- a/netlink.c
> +++ b/netlink.c
> @@ -120,6 +120,12 @@ decode_payload(struct tcb *const tcp,
>  	if (nlmsghdr->nlmsg_type == NLMSG_ERROR) {
>  		decode_nlmsgerr(tcp, addr, len);
>  		return;
> +	} else if (nlmsghdr->nlmsg_type == NLMSG_DONE && len == sizeof(int)) {
> +		int num;
> +
> +		if (!umove_or_printaddr(tcp, addr, &num))
> +			tprintf("%d", num);
> +		return;
>  	}

The "else" part of "else if" in conjunction with "return" statements
is redundant, but it causes no harm either, so I left it intact.

>  	printstrn(tcp, addr, len);
> diff --git a/tests/netlink_protocol.c b/tests/netlink_protocol.c
> index 35f954f..121c83d 100644
> --- a/tests/netlink_protocol.c
> +++ b/tests/netlink_protocol.c
> @@ -314,6 +314,42 @@ test_nlmsgerr(const int fd)
>  	       nlh->nlmsg_len, sprintrc(rc));
>  }
>  
> +static void
> +test_nlmsg_done(const int fd)
> +{
> +	struct nlmsghdr *nlh;
> +	int total_len;
> +	void *const nlh0 = tail_alloc(NLMSG_HDRLEN);
> +	long rc;
> +
> +	nlh = nlh0;
> +	nlh->nlmsg_len = NLMSG_HDRLEN + sizeof(int);
> +	nlh->nlmsg_type = NLMSG_DONE;
> +	nlh->nlmsg_flags = NLM_F_MULTI;
> +	nlh->nlmsg_seq = 0;
> +	nlh->nlmsg_pid = 0;
> +
> +	rc = sendto(fd, nlh, nlh->nlmsg_len, MSG_DONTWAIT, NULL, 0);
> +	printf("sendto(%d, {{len=%u, type=NLMSG_DONE, flags=NLM_F_MULTI"
> +	       ", seq=0, pid=0}, %p}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
> +	       fd, nlh->nlmsg_len, nlh0 + NLMSG_HDRLEN,
> +	       nlh->nlmsg_len, sprintrc(rc));
> +
> +	nlh = nlh0 - sizeof(int);
> +	nlh->nlmsg_len = NLMSG_HDRLEN + sizeof(int);
> +	nlh->nlmsg_type = NLMSG_DONE;
> +	nlh->nlmsg_flags = NLM_F_MULTI;
> +	nlh->nlmsg_seq = 0;
> +	nlh->nlmsg_pid = 0;
> +	total_len = nlh->nlmsg_len;
> +	memcpy(NLMSG_DATA(nlh), &total_len, sizeof(total_len));
> +
> +	rc = sendto(fd, nlh, nlh->nlmsg_len, MSG_DONTWAIT, NULL, 0);
> +	printf("sendto(%d, {{len=%u, type=NLMSG_DONE, flags=NLM_F_MULTI"
> +	       ", seq=0, pid=0}, %d}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
> +	       fd, nlh->nlmsg_len, nlh->nlmsg_len, total_len, sprintrc(rc));
> +}
> +
>  int main(void)
>  {
>  	struct sockaddr_nl addr;

According to the coverage, one NLMSG_DONE case is missing, so I added it
in a follow-up comment.  While at it, I also changed nlh initialization
to use designated initializers, e.g.

-	nlh->nlmsg_len = NLMSG_HDRLEN + sizeof(int);
-	nlh->nlmsg_type = NLMSG_DONE;
-	nlh->nlmsg_flags = NLM_F_MULTI;
-	nlh->nlmsg_seq = 0;
-	nlh->nlmsg_pid = 0;
+	*nlh = (struct nlmsghdr) {
+		.nlmsg_len = NLMSG_HDRLEN + sizeof(num),
+		.nlmsg_type = NLMSG_DONE,
+		.nlmsg_flags = NLM_F_MULTI
+	};

As you are going to add more tests of this kind soon,
consider using this C99 syntax.


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20170604/bffee838/attachment.bin>


More information about the Strace-devel mailing list