Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 2016 Fabien Siron <fabien.siron (at) epita.fr>
      3  * Copyright (c) 2016 Dmitry V. Levin <ldv (at) altlinux.org>
      4  * Copyright (c) 2016-2018 The strace developers.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. The name of the author may not be used to endorse or promote products
     16  *    derived from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include "defs.h"
     31 #include "netlink.h"
     32 #include "nlattr.h"
     33 #include <linux/audit.h>
     34 #include <linux/rtnetlink.h>
     35 #include <linux/xfrm.h>
     36 #include "xlat/netlink_ack_flags.h"
     37 #include "xlat/netlink_delete_flags.h"
     38 #include "xlat/netlink_flags.h"
     39 #include "xlat/netlink_get_flags.h"
     40 #include "xlat/netlink_new_flags.h"
     41 #include "xlat/netlink_protocols.h"
     42 #include "xlat/netlink_types.h"
     43 #include "xlat/nf_acct_msg_types.h"
     44 #include "xlat/nf_cthelper_msg_types.h"
     45 #include "xlat/nf_ctnetlink_exp_msg_types.h"
     46 #include "xlat/nf_ctnetlink_msg_types.h"
     47 #include "xlat/nf_cttimeout_msg_types.h"
     48 #include "xlat/nf_ipset_msg_types.h"
     49 #include "xlat/nf_nft_compat_msg_types.h"
     50 #include "xlat/nf_nftables_msg_types.h"
     51 #include "xlat/nf_osf_msg_types.h"
     52 #include "xlat/nf_queue_msg_types.h"
     53 #include "xlat/nf_ulog_msg_types.h"
     54 #include "xlat/nl_audit_types.h"
     55 #include "xlat/nl_crypto_types.h"
     56 #include "xlat/nl_netfilter_subsys_ids.h"
     57 #include "xlat/nl_selinux_types.h"
     58 #include "xlat/nl_sock_diag_types.h"
     59 #include "xlat/nl_xfrm_types.h"
     60 #include "xlat/nlmsgerr_attrs.h"
     61 
     62 /*
     63  * Fetch a struct nlmsghdr from the given address.
     64  */
     65 static bool
     66 fetch_nlmsghdr(struct tcb *const tcp, struct nlmsghdr *const nlmsghdr,
     67 	       const kernel_ulong_t addr, const kernel_ulong_t len,
     68 	       const bool in_array)
     69 {
     70 	if (len < sizeof(struct nlmsghdr)) {
     71 		printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX);
     72 		return false;
     73 	}
     74 
     75 	if (tfetch_obj(tcp, addr, nlmsghdr))
     76 		return true;
     77 
     78 	if (in_array) {
     79 		tprints("...");
     80 		printaddr_comment(addr);
     81 	} else {
     82 		printaddr(addr);
     83 	}
     84 
     85 	return false;
     86 }
     87 
     88 static int
     89 get_fd_nl_family(struct tcb *const tcp, const int fd)
     90 {
     91 	const unsigned long inode = getfdinode(tcp, fd);
     92 	if (!inode)
     93 		return -1;
     94 
     95 	const char *const details = get_sockaddr_by_inode(tcp, fd, inode);
     96 	if (!details)
     97 		return -1;
     98 
     99 	const char *const nl_details = STR_STRIP_PREFIX(details, "NETLINK:[");
    100 	if (nl_details == details)
    101 		return -1;
    102 
    103 	const struct xlat *xlats = netlink_protocols;
    104 	for (; xlats->str; ++xlats) {
    105 		const char *name = STR_STRIP_PREFIX(xlats->str, "NETLINK_");
    106 		if (!strncmp(nl_details, name, strlen(name)))
    107 			return xlats->val;
    108 	}
    109 
    110 	if (*nl_details >= '0' && *nl_details <= '9')
    111 		return atoi(nl_details);
    112 
    113 	return -1;
    114 }
    115 
    116 static void
    117 decode_nlmsg_type_default(struct tcb *tcp, const struct xlat *const xlat,
    118 			  const uint16_t type,
    119 			  const char *const dflt)
    120 {
    121 	printxval(xlat, type, dflt);
    122 }
    123 
    124 static void
    125 decode_nlmsg_type_generic(struct tcb *tcp, const struct xlat *const xlat,
    126 			  const uint16_t type,
    127 			  const char *const dflt)
    128 {
    129 	printxval(genl_families_xlat(tcp), type, dflt);
    130 }
    131 
    132 static const struct {
    133 	const struct xlat *const xlat;
    134 	const char *const dflt;
    135 } nf_nlmsg_types[] = {
    136 	[NFNL_SUBSYS_CTNETLINK] = {
    137 		nf_ctnetlink_msg_types,
    138 		"IPCTNL_MSG_CT_???"
    139 	},
    140 	[NFNL_SUBSYS_CTNETLINK_EXP] = {
    141 		nf_ctnetlink_exp_msg_types,
    142 		"IPCTNL_MSG_EXP_???"
    143 	},
    144 	[NFNL_SUBSYS_QUEUE] = { nf_queue_msg_types, "NFQNL_MSG_???" },
    145 	[NFNL_SUBSYS_ULOG] = { nf_ulog_msg_types, "NFULNL_MSG_???" },
    146 	[NFNL_SUBSYS_OSF] = { nf_osf_msg_types, "OSF_MSG_???" },
    147 	[NFNL_SUBSYS_IPSET] = { nf_ipset_msg_types, "IPSET_CMD_???" },
    148 	[NFNL_SUBSYS_ACCT] = { nf_acct_msg_types, "NFNL_MSG_ACCT_???" },
    149 	[NFNL_SUBSYS_CTNETLINK_TIMEOUT] = {
    150 		nf_cttimeout_msg_types,
    151 		"IPCTNL_MSG_TIMEOUT_???"
    152 	},
    153 	[NFNL_SUBSYS_CTHELPER] = {
    154 		nf_cthelper_msg_types,
    155 		"NFNL_MSG_CTHELPER_???"
    156 	},
    157 	[NFNL_SUBSYS_NFTABLES] = { nf_nftables_msg_types, "NFT_MSG_???" },
    158 	[NFNL_SUBSYS_NFT_COMPAT] = {
    159 		nf_nft_compat_msg_types,
    160 		"NFNL_MSG_COMPAT_???"
    161 	}
    162 };
    163 
    164 static void
    165 decode_nlmsg_type_netfilter(struct tcb *tcp, const struct xlat *const xlat,
    166 			    const uint16_t type,
    167 			    const char *const dflt)
    168 {
    169 	/* Reserved control nfnetlink messages first. */
    170 	const char *const text = xlookup(nl_netfilter_msg_types, type);
    171 	if (text) {
    172 		print_xlat_ex(type, text, XLAT_STYLE_DEFAULT);
    173 		return;
    174 	}
    175 
    176 	/*
    177 	 * Other netfilter message types are split
    178 	 * in two pieces: 8 bits subsystem and 8 bits type.
    179 	 */
    180 	const uint8_t subsys_id = (uint8_t) (type >> 8);
    181 	const uint8_t msg_type = (uint8_t) type;
    182 
    183 	printxval(xlat, subsys_id, dflt);
    184 
    185 	tprints("<<8|");
    186 	if (subsys_id < ARRAY_SIZE(nf_nlmsg_types))
    187 		printxval(nf_nlmsg_types[subsys_id].xlat,
    188 			  msg_type, nf_nlmsg_types[subsys_id].dflt);
    189 	else
    190 		tprintf("%#x", msg_type);
    191 }
    192 
    193 typedef void (*nlmsg_types_decoder_t)(struct tcb *, const struct xlat *,
    194 				      uint16_t type,
    195 				      const char *dflt);
    196 
    197 static const struct {
    198 	const nlmsg_types_decoder_t decoder;
    199 	const struct xlat *const xlat;
    200 	const char *const dflt;
    201 } nlmsg_types[] = {
    202 	[NETLINK_AUDIT] = { NULL, nl_audit_types, "AUDIT_???" },
    203 	[NETLINK_CRYPTO] = { NULL, nl_crypto_types, "CRYPTO_MSG_???" },
    204 	[NETLINK_GENERIC] = {
    205 		decode_nlmsg_type_generic,
    206 		NULL,
    207 		"GENERIC_FAMILY_???"
    208 	},
    209 	[NETLINK_NETFILTER] = {
    210 		decode_nlmsg_type_netfilter,
    211 		nl_netfilter_subsys_ids,
    212 		"NFNL_SUBSYS_???"
    213 	},
    214 	[NETLINK_ROUTE] = { NULL, nl_route_types, "RTM_???" },
    215 	[NETLINK_SELINUX] = { NULL, nl_selinux_types, "SELNL_MSG_???" },
    216 	[NETLINK_SOCK_DIAG] = { NULL, nl_sock_diag_types, "SOCK_DIAG_???" },
    217 	[NETLINK_XFRM] = { NULL, nl_xfrm_types, "XFRM_MSG_???" }
    218 };
    219 
    220 /*
    221  * As all valid netlink families are positive integers, use unsigned int
    222  * for family here to filter out -1.
    223  */
    224 static void
    225 decode_nlmsg_type(struct tcb *tcp, const uint16_t type,
    226 		  const unsigned int family)
    227 {
    228 	nlmsg_types_decoder_t decoder = decode_nlmsg_type_default;
    229 	const struct xlat *xlat = netlink_types;
    230 	const char *dflt = "NLMSG_???";
    231 
    232 	/*
    233 	 * type < NLMSG_MIN_TYPE are reserved control messages
    234 	 * that need no family-specific decoding.
    235 	 */
    236 	if (type >= NLMSG_MIN_TYPE && family < ARRAY_SIZE(nlmsg_types)) {
    237 		if (nlmsg_types[family].decoder)
    238 			decoder = nlmsg_types[family].decoder;
    239 		if (nlmsg_types[family].xlat)
    240 			xlat = nlmsg_types[family].xlat;
    241 		if (nlmsg_types[family].dflt)
    242 			dflt = nlmsg_types[family].dflt;
    243 	}
    244 
    245 	decoder(tcp, xlat, type, dflt);
    246 }
    247 
    248 static const struct xlat *
    249 decode_nlmsg_flags_crypto(const uint16_t type)
    250 {
    251 	switch (type) {
    252 	case CRYPTO_MSG_NEWALG:
    253 		return netlink_new_flags;
    254 	case CRYPTO_MSG_DELALG:
    255 	case CRYPTO_MSG_DELRNG:
    256 		return netlink_delete_flags;
    257 	case CRYPTO_MSG_GETALG:
    258 		return netlink_get_flags;
    259 	}
    260 
    261 	return NULL;
    262 }
    263 
    264 static const struct xlat *
    265 decode_nlmsg_flags_netfilter(const uint16_t type)
    266 {
    267 	const uint8_t subsys_id = (uint8_t) (type >> 8);
    268 	const uint8_t msg_type = (uint8_t) type;
    269 
    270 	switch (subsys_id) {
    271 	case NFNL_SUBSYS_CTNETLINK:
    272 		switch (msg_type) {
    273 		case IPCTNL_MSG_CT_NEW:
    274 			return netlink_new_flags;
    275 		case IPCTNL_MSG_CT_GET:
    276 		case IPCTNL_MSG_CT_GET_CTRZERO:
    277 		case IPCTNL_MSG_CT_GET_STATS_CPU:
    278 		case IPCTNL_MSG_CT_GET_STATS:
    279 		case IPCTNL_MSG_CT_GET_DYING:
    280 		case IPCTNL_MSG_CT_GET_UNCONFIRMED:
    281 			return netlink_get_flags;
    282 		case IPCTNL_MSG_CT_DELETE:
    283 			return netlink_delete_flags;
    284 		}
    285 		break;
    286 	case NFNL_SUBSYS_CTNETLINK_EXP:
    287 		switch (msg_type) {
    288 		case IPCTNL_MSG_EXP_NEW:
    289 			return netlink_new_flags;
    290 		case IPCTNL_MSG_EXP_GET:
    291 		case IPCTNL_MSG_EXP_GET_STATS_CPU:
    292 			return netlink_get_flags;
    293 		case IPCTNL_MSG_EXP_DELETE:
    294 			return netlink_delete_flags;
    295 		}
    296 		break;
    297 	case NFNL_SUBSYS_ACCT:
    298 		switch (msg_type) {
    299 		case NFNL_MSG_ACCT_NEW:
    300 			return netlink_new_flags;
    301 		case NFNL_MSG_ACCT_GET:
    302 		case NFNL_MSG_ACCT_GET_CTRZERO:
    303 			return netlink_get_flags;
    304 		case NFNL_MSG_ACCT_DEL:
    305 			return netlink_delete_flags;
    306 		}
    307 		break;
    308 	case NFNL_SUBSYS_CTNETLINK_TIMEOUT:
    309 		switch (msg_type) {
    310 		case IPCTNL_MSG_TIMEOUT_NEW:
    311 			return netlink_new_flags;
    312 		case IPCTNL_MSG_TIMEOUT_GET:
    313 			return netlink_get_flags;
    314 		case IPCTNL_MSG_TIMEOUT_DELETE:
    315 			return netlink_delete_flags;
    316 		}
    317 		break;
    318 	case NFNL_SUBSYS_CTHELPER:
    319 		switch (msg_type) {
    320 		case NFNL_MSG_CTHELPER_NEW:
    321 			return netlink_new_flags;
    322 		case NFNL_MSG_CTHELPER_GET:
    323 			return netlink_get_flags;
    324 		case NFNL_MSG_CTHELPER_DEL:
    325 			return netlink_delete_flags;
    326 		}
    327 		break;
    328 	case NFNL_SUBSYS_NFTABLES:
    329 		switch (msg_type) {
    330 		case NFT_MSG_NEWTABLE:
    331 		case NFT_MSG_NEWCHAIN:
    332 		case NFT_MSG_NEWRULE:
    333 		case NFT_MSG_NEWSET:
    334 		case NFT_MSG_NEWSETELEM:
    335 		case NFT_MSG_NEWGEN:
    336 		case NFT_MSG_NEWOBJ:
    337 			return netlink_new_flags;
    338 		case NFT_MSG_GETTABLE:
    339 		case NFT_MSG_GETCHAIN:
    340 		case NFT_MSG_GETRULE:
    341 		case NFT_MSG_GETSET:
    342 		case NFT_MSG_GETSETELEM:
    343 		case NFT_MSG_GETGEN:
    344 		case NFT_MSG_GETOBJ:
    345 		case NFT_MSG_GETOBJ_RESET:
    346 			return netlink_get_flags;
    347 		case NFT_MSG_DELTABLE:
    348 		case NFT_MSG_DELCHAIN:
    349 		case NFT_MSG_DELRULE:
    350 		case NFT_MSG_DELSET:
    351 		case NFT_MSG_DELSETELEM:
    352 		case NFT_MSG_DELOBJ:
    353 			return netlink_delete_flags;
    354 		}
    355 		break;
    356 	case NFNL_SUBSYS_NFT_COMPAT:
    357 		switch (msg_type) {
    358 		case NFNL_MSG_COMPAT_GET:
    359 			return netlink_get_flags;
    360 		}
    361 		break;
    362 	}
    363 
    364 	return NULL;
    365 }
    366 
    367 static const struct xlat *
    368 decode_nlmsg_flags_route(const uint16_t type)
    369 {
    370 	/* RTM_DELACTION uses NLM_F_ROOT flags */
    371 	if (type == RTM_DELACTION)
    372 		return netlink_get_flags;
    373 	switch (type & 3) {
    374 	case  0:
    375 		return netlink_new_flags;
    376 	case  1:
    377 		return netlink_delete_flags;
    378 	case  2:
    379 		return netlink_get_flags;
    380 	}
    381 
    382 	return NULL;
    383 }
    384 
    385 static const struct xlat *
    386 decode_nlmsg_flags_sock_diag(const uint16_t type)
    387 {
    388 	return netlink_get_flags;
    389 }
    390 
    391 static const struct xlat *
    392 decode_nlmsg_flags_xfrm(const uint16_t type)
    393 {
    394 	switch (type) {
    395 	case XFRM_MSG_NEWSA:
    396 	case XFRM_MSG_NEWPOLICY:
    397 	case XFRM_MSG_NEWAE:
    398 	case XFRM_MSG_NEWSADINFO:
    399 	case XFRM_MSG_NEWSPDINFO:
    400 		return netlink_new_flags;
    401 	case XFRM_MSG_DELSA:
    402 	case XFRM_MSG_DELPOLICY:
    403 		return netlink_delete_flags;
    404 	case XFRM_MSG_GETSA:
    405 	case XFRM_MSG_GETPOLICY:
    406 	case XFRM_MSG_GETAE:
    407 	case XFRM_MSG_GETSADINFO:
    408 	case XFRM_MSG_GETSPDINFO:
    409 		return netlink_get_flags;
    410 	}
    411 
    412 	return NULL;
    413 }
    414 
    415 typedef const struct xlat *(*nlmsg_flags_decoder_t)(const uint16_t type);
    416 
    417 static const nlmsg_flags_decoder_t nlmsg_flags[] = {
    418 	[NETLINK_CRYPTO] = decode_nlmsg_flags_crypto,
    419 	[NETLINK_NETFILTER] = decode_nlmsg_flags_netfilter,
    420 	[NETLINK_ROUTE] = decode_nlmsg_flags_route,
    421 	[NETLINK_SOCK_DIAG] = decode_nlmsg_flags_sock_diag,
    422 	[NETLINK_XFRM] = decode_nlmsg_flags_xfrm
    423 };
    424 
    425 /*
    426  * As all valid netlink families are positive integers, use unsigned int
    427  * for family here to filter out -1.
    428  */
    429 static void
    430 decode_nlmsg_flags(const uint16_t flags, const uint16_t type,
    431 		   const unsigned int family)
    432 {
    433 	const struct xlat *table = NULL;
    434 
    435 	if (type < NLMSG_MIN_TYPE) {
    436 		if (type == NLMSG_ERROR)
    437 			table = netlink_ack_flags;
    438 	} else if (family < ARRAY_SIZE(nlmsg_flags) && nlmsg_flags[family])
    439 		table = nlmsg_flags[family](type);
    440 
    441 	printflags_ex(flags, "NLM_F_???", XLAT_STYLE_DEFAULT,
    442 		      netlink_flags, table, NULL);
    443 }
    444 
    445 static void
    446 print_nlmsghdr(struct tcb *tcp,
    447 	       const int fd,
    448 	       const int family,
    449 	       const struct nlmsghdr *const nlmsghdr)
    450 {
    451 	/* print the whole structure regardless of its nlmsg_len */
    452 
    453 	tprintf("{len=%u, type=", nlmsghdr->nlmsg_len);
    454 
    455 	decode_nlmsg_type(tcp, nlmsghdr->nlmsg_type, family);
    456 
    457 	tprints(", flags=");
    458 	decode_nlmsg_flags(nlmsghdr->nlmsg_flags,
    459 			   nlmsghdr->nlmsg_type, family);
    460 
    461 	tprintf(", seq=%u, pid=%u}", nlmsghdr->nlmsg_seq,
    462 		nlmsghdr->nlmsg_pid);
    463 }
    464 
    465 static bool
    466 print_cookie(struct tcb *const tcp, void *const elem_buf,
    467 	     const size_t elem_size, void *const opaque_data)
    468 {
    469 	tprintf("%" PRIu8, *(uint8_t *) elem_buf);
    470 
    471 	return true;
    472 }
    473 
    474 static bool
    475 decode_nlmsgerr_attr_cookie(struct tcb *const tcp,
    476 			    const kernel_ulong_t addr,
    477 			    const unsigned int len,
    478 			    const void *const opaque_data)
    479 {
    480 	uint8_t cookie;
    481 	const size_t nmemb = len / sizeof(cookie);
    482 
    483 	print_array(tcp, addr, nmemb, &cookie, sizeof(cookie),
    484 		    tfetch_mem, print_cookie, 0);
    485 
    486 	return true;
    487 }
    488 
    489 static const nla_decoder_t nlmsgerr_nla_decoders[] = {
    490 	[NLMSGERR_ATTR_MSG]	= decode_nla_str,
    491 	[NLMSGERR_ATTR_OFFS]	= decode_nla_u32,
    492 	[NLMSGERR_ATTR_COOKIE]	= decode_nlmsgerr_attr_cookie
    493 };
    494 
    495 static void
    496 decode_nlmsghdr_with_payload(struct tcb *const tcp,
    497 			     const int fd,
    498 			     const int family,
    499 			     const struct nlmsghdr *const nlmsghdr,
    500 			     const kernel_ulong_t addr,
    501 			     const kernel_ulong_t len);
    502 
    503 static void
    504 decode_nlmsgerr(struct tcb *const tcp,
    505 		const int fd,
    506 		const int family,
    507 		kernel_ulong_t addr,
    508 		unsigned int len,
    509 		const bool capped)
    510 {
    511 	struct nlmsgerr err;
    512 
    513 	if (len < sizeof(err.error)) {
    514 		printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX);
    515 		return;
    516 	}
    517 
    518 	if (umove_or_printaddr(tcp, addr, &err.error))
    519 		return;
    520 
    521 	tprints("{error=");
    522 	if (err.error < 0 && (unsigned) -err.error < nerrnos) {
    523 		tprintf("-%s", errnoent[-err.error]);
    524 	} else {
    525 		tprintf("%d", err.error);
    526 	}
    527 
    528 	addr += offsetof(struct nlmsgerr, msg);
    529 	len -= offsetof(struct nlmsgerr, msg);
    530 
    531 	if (len) {
    532 		tprints(", msg=");
    533 		if (fetch_nlmsghdr(tcp, &err.msg, addr, len, false)) {
    534 			unsigned int payload =
    535 				capped ? sizeof(err.msg) : err.msg.nlmsg_len;
    536 			if (payload > len)
    537 				payload = len;
    538 
    539 			decode_nlmsghdr_with_payload(tcp, fd, family,
    540 						     &err.msg, addr, payload);
    541 			if (len > payload) {
    542 				tprints(", ");
    543 				decode_nlattr(tcp, addr + payload,
    544 					      len - payload, nlmsgerr_attrs,
    545 					      "NLMSGERR_ATTR_???",
    546 					      nlmsgerr_nla_decoders,
    547 					      ARRAY_SIZE(nlmsgerr_nla_decoders),
    548 					      NULL);
    549 			}
    550 		}
    551 	}
    552 
    553 	tprints("}");
    554 }
    555 
    556 static const netlink_decoder_t netlink_decoders[] = {
    557 #ifdef HAVE_LINUX_CRYPTOUSER_H
    558 	[NETLINK_CRYPTO] = decode_netlink_crypto,
    559 #endif
    560 #ifdef HAVE_LINUX_NETFILTER_NFNETLINK_H
    561 	[NETLINK_NETFILTER] = decode_netlink_netfilter,
    562 #endif
    563 	[NETLINK_ROUTE] = decode_netlink_route,
    564 	[NETLINK_SELINUX] = decode_netlink_selinux,
    565 	[NETLINK_SOCK_DIAG] = decode_netlink_sock_diag
    566 };
    567 
    568 static void
    569 decode_payload(struct tcb *const tcp,
    570 	       const int fd,
    571 	       const int family,
    572 	       const struct nlmsghdr *const nlmsghdr,
    573 	       const kernel_ulong_t addr,
    574 	       const unsigned int len)
    575 {
    576 	if (nlmsghdr->nlmsg_type == NLMSG_ERROR) {
    577 		decode_nlmsgerr(tcp, fd, family, addr, len,
    578 				nlmsghdr->nlmsg_flags & NLM_F_CAPPED);
    579 		return;
    580 	}
    581 
    582 	/*
    583 	 * While most of NLMSG_DONE messages indeed have payloads
    584 	 * containing just a single integer, there are few exceptions,
    585 	 * so pass payloads of NLMSG_DONE messages to family-specific
    586 	 * netlink payload decoders.
    587 	 *
    588 	 * Other types of reserved control messages need no family-specific
    589 	 * netlink payload decoding.
    590 	 */
    591 	if ((nlmsghdr->nlmsg_type >= NLMSG_MIN_TYPE
    592 	    || nlmsghdr->nlmsg_type == NLMSG_DONE)
    593 	    && (unsigned int) family < ARRAY_SIZE(netlink_decoders)
    594 	    && netlink_decoders[family]
    595 	    && netlink_decoders[family](tcp, nlmsghdr, addr, len)) {
    596 		return;
    597 	}
    598 
    599 	if (nlmsghdr->nlmsg_type == NLMSG_DONE && len == sizeof(int)) {
    600 		int num;
    601 
    602 		if (!umove_or_printaddr(tcp, addr, &num))
    603 			tprintf("%d", num);
    604 		return;
    605 	}
    606 
    607 	printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX);
    608 }
    609 
    610 static void
    611 decode_nlmsghdr_with_payload(struct tcb *const tcp,
    612 			     const int fd,
    613 			     const int family,
    614 			     const struct nlmsghdr *const nlmsghdr,
    615 			     const kernel_ulong_t addr,
    616 			     const kernel_ulong_t len)
    617 {
    618 	const unsigned int nlmsg_len = MIN(nlmsghdr->nlmsg_len, len);
    619 
    620 	if (nlmsg_len > NLMSG_HDRLEN)
    621 		tprints("{");
    622 
    623 	print_nlmsghdr(tcp, fd, family, nlmsghdr);
    624 
    625 	if (nlmsg_len > NLMSG_HDRLEN) {
    626 		tprints(", ");
    627 		decode_payload(tcp, fd, family, nlmsghdr, addr + NLMSG_HDRLEN,
    628 						     nlmsg_len - NLMSG_HDRLEN);
    629 		tprints("}");
    630 	}
    631 }
    632 
    633 void
    634 decode_netlink(struct tcb *const tcp,
    635 	       const int fd,
    636 	       kernel_ulong_t addr,
    637 	       kernel_ulong_t len)
    638 {
    639 	const int family = get_fd_nl_family(tcp, fd);
    640 
    641 	if (family == NETLINK_KOBJECT_UEVENT) {
    642 		decode_netlink_kobject_uevent(tcp, addr, len);
    643 		return;
    644 	}
    645 
    646 	struct nlmsghdr nlmsghdr;
    647 	bool is_array = false;
    648 	unsigned int elt;
    649 
    650 	for (elt = 0; fetch_nlmsghdr(tcp, &nlmsghdr, addr, len, is_array);
    651 	     elt++) {
    652 		if (abbrev(tcp) && elt == max_strlen) {
    653 			tprints("...");
    654 			break;
    655 		}
    656 
    657 		unsigned int nlmsg_len = NLMSG_ALIGN(nlmsghdr.nlmsg_len);
    658 		kernel_ulong_t next_addr = 0;
    659 		kernel_ulong_t next_len = 0;
    660 
    661 		if (nlmsghdr.nlmsg_len >= NLMSG_HDRLEN) {
    662 			next_len = (len >= nlmsg_len) ? len - nlmsg_len : 0;
    663 
    664 			if (next_len && addr + nlmsg_len > addr)
    665 				next_addr = addr + nlmsg_len;
    666 		}
    667 
    668 		if (!is_array && next_addr) {
    669 			tprints("[");
    670 			is_array = true;
    671 		}
    672 
    673 		decode_nlmsghdr_with_payload(tcp, fd, family,
    674 					     &nlmsghdr, addr, len);
    675 
    676 		if (!next_addr)
    677 			break;
    678 
    679 		tprints(", ");
    680 		addr = next_addr;
    681 		len = next_len;
    682 	}
    683 
    684 	if (is_array) {
    685 		tprints("]");
    686 	}
    687 }
    688