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