[PATCH] netlink: add type decoding
Dmitry V. Levin
ldv at altlinux.org
Sun Jun 4 19:40:09 UTC 2017
On Mon, Jul 11, 2016 at 12:54:59PM +0000, Fabien Siron wrote:
> Decode and print the type of the main netlink protocols.
JingPiao Chen, I've reworked Fabien's commits from your netlink branch
up to and including this one (52dc63cc "netlink: add type decoding")
for merge into master. I've pushed them to ldv/netlink branch
and now waiting for a new version of your
"tests: add check for nlmsg_type decoding" commit to test these changes.
A few notes about Fabien's code that might be useful for your netlink efforts:
> @@ -96,7 +96,8 @@ print_iovec(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
> len = c->data_size;
> if (c->data_size != (kernel_ulong_t) -1)
> c->data_size -= len;
> - decode_netlink(tcp, iov[0], len);
> + decode_netlink(tcp, *(int *)c->optional_data,
> + iov[0], len);
> break;
> default:
> printaddr(iov[0]);
> @@ -354,7 +354,7 @@ print_struct_msghdr(struct tcb *tcp, const struct msghdr *msg,
> tprints(", msg_iov=");
>
> tprint_iov_upto(tcp, msg->msg_iovlen, ptr_to_kulong(msg->msg_iov),
> - decode, data_size, NULL);
> + decode, data_size, &tcp->u_arg[0]);
> tprintf(", msg_iovlen=%" PRI_klu, (kernel_ulong_t) msg->msg_iovlen);
>
> decode_msg_control(tcp, ptr_to_kulong(msg->msg_control),
If sizeof(tcp->u_arg[0]) > sizeof(int), a wrong value will be passed to decode_netlink.
> @@ -29,9 +29,23 @@
>
> #include "defs.h"
> #include <sys/socket.h>
> +#include <linux/audit.h>
> +#include <linux/inet_diag.h>
> +#include <linux/netfilter/nfnetlink.h>
linux/netfilter/nfnetlink.h was introduced in 2.6.14
> @@ -55,13 +69,62 @@ fetch_nlmsghdr(struct tcb *const tcp, struct nlmsghdr *const nlmsghdr,
> }
>
> static void
> -print_nlmsghdr(struct tcb *tcp, const struct nlmsghdr *const nlmsghdr)
> +decode_netlink_type(int type, int proto)
> +{
> + if (type < NLMSG_MIN_TYPE) {
> + printxval(netlink_types, type, "NLMSG_???");
> + } else {
> + const struct xlat *x;
> + const char *dflt;
> +
> + switch (proto) {
> + case NETLINK_ROUTE:
> + x = netlink_route_types;
> + dflt = "RTM_???";
> + break;
> + case NETLINK_SOCK_DIAG:
> + x = netlink_sock_diag_types;
> + dflt = "SOCK_DIAG_???";
> + break;
> + case NETLINK_XFRM:
> + x = netlink_xfrm_types;
> + dflt = "XFRM_MSG_???";
> + break;
> + case NETLINK_AUDIT:
> + x = netlink_audit_types;
> + dflt = "AUDIT_???";
> + break;
> + case NETLINK_SELINUX:
> + x = netlink_selinux_types;
> + dflt = "SELNL_MSG_???";
> + break;
> + case NETLINK_NETFILTER:
> + x = netlink_netfilter_ids;
> + dflt = "NFNL_SUBSYS_???";
> + break;
> + default:
> + x = netlink_types;
> + dflt = "NLMSG_???";
> + }
> + if (proto == NETLINK_NETFILTER) {
> + tprints("{");
> + printxval(x, NFNL_SUBSYS_ID(type), dflt);
> + tprintf(", %d}", NFNL_MSG_TYPE(type));
> + } else {
> + printxval(x, type, dflt);
> + }
> + }
> +}
Too much cut-n-paste in this switch statement.
I transformed it into a table:
static const struct {
const struct xlat *const xlat;
const char *const dflt;
} nlmsg_types[] = {
[NETLINK_AUDIT] = { nl_audit_types, "AUDIT_???" },
[NETLINK_ROUTE] = { nl_route_types, "RTM_???" },
[NETLINK_SELINUX] = { nl_selinux_types, "SELNL_MSG_???" },
[NETLINK_SOCK_DIAG] = { nl_sock_diag_types, "SOCK_DIAG_???" },
[NETLINK_XFRM] = { nl_xfrm_types, "XFRM_MSG_???" }
};
if (family < ARRAY_SIZE(nlmsg_types)
&& nlmsg_types[family].xlat) {
printxval(nlmsg_types[family].xlat, type, nlmsg_types[family].dflt);
} else {
printxval(netlink_types, type, "NLMSG_???");
}
Well, not exactly into this because NETLINK_NETFILTER message types are not as
simple (even more complex than Fabien thought when he wrote this code).
> @@ -132,20 +196,21 @@ decode_payload(struct tcb *const tcp,
> }
>
> static void
> -decode_nlmsghdr_with_payload(struct tcb *const tcp,
> +decode_nlmsghdr_with_payload(struct tcb *const tcp, int fd,
> const struct nlmsghdr *const nlmsghdr,
> const kernel_ulong_t addr,
> const kernel_ulong_t len)
> {
> tprints("{");
>
> - print_nlmsghdr(tcp, nlmsghdr);
> + int proto = getfdnlproto(tcp, fd, netlink_protocols);
> + print_nlmsghdr(tcp, nlmsghdr, proto);
getfdnlproto (get_fd_nl_family in my edition) is not cheap
(it invokes syscalls), needless calls should be avoided.
--
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/c5e7bbd2/attachment.bin>
More information about the Strace-devel
mailing list