Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

netlink_netlink_diag.c 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
  3. * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
  4. * Copyright (c) 2017-2018 The strace developers.
  5. * All rights reserved.
  6. *
  7. * SPDX-License-Identifier: LGPL-2.1-or-later
  8. */
  9. #include "defs.h"
  10. #include "netlink.h"
  11. #include "netlink_sock_diag.h"
  12. #include "nlattr.h"
  13. #include "print_fields.h"
  14. #include <linux/sock_diag.h>
  15. #include <linux/netlink_diag.h>
  16. #include "xlat/netlink_diag_attrs.h"
  17. #include "xlat/netlink_diag_show.h"
  18. #include "xlat/netlink_socket_flags.h"
  19. #include "xlat/netlink_states.h"
  20. DECL_NETLINK_DIAG_DECODER(decode_netlink_diag_req)
  21. {
  22. struct netlink_diag_req req = { .sdiag_family = family };
  23. const size_t offset = sizeof(req.sdiag_family);
  24. PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
  25. tprints(", ");
  26. if (len >= sizeof(req)) {
  27. if (!umoven_or_printaddr(tcp, addr + offset,
  28. sizeof(req) - offset,
  29. (char *) &req + offset)) {
  30. if (NDIAG_PROTO_ALL == req.sdiag_protocol)
  31. tprintf("%s=%s",
  32. "sdiag_protocol", "NDIAG_PROTO_ALL");
  33. else
  34. PRINT_FIELD_XVAL("", req, sdiag_protocol,
  35. netlink_protocols,
  36. "NETLINK_???");
  37. PRINT_FIELD_U(", ", req, ndiag_ino);
  38. PRINT_FIELD_FLAGS(", ", req, ndiag_show,
  39. netlink_diag_show, "NDIAG_SHOW_???");
  40. PRINT_FIELD_COOKIE(", ", req, ndiag_cookie);
  41. }
  42. } else
  43. tprints("...");
  44. tprints("}");
  45. }
  46. static bool
  47. print_group(struct tcb *const tcp,
  48. void *const elem_buf,
  49. const size_t elem_size,
  50. void *const opaque_data)
  51. {
  52. if (elem_size < sizeof(kernel_ulong_t))
  53. tprintf("%#0*x", (int) elem_size * 2 + 2,
  54. *(unsigned int *) elem_buf);
  55. else
  56. tprintf("%#0*" PRI_klx, (int) elem_size * 2 + 2,
  57. *(kernel_ulong_t *) elem_buf);
  58. return true;
  59. }
  60. static bool
  61. decode_netlink_diag_groups(struct tcb *const tcp,
  62. const kernel_ulong_t addr,
  63. const unsigned int len,
  64. const void *const opaque_data)
  65. {
  66. kernel_ulong_t buf;
  67. const size_t nmemb = len / current_wordsize;
  68. if (!nmemb)
  69. return false;
  70. print_array(tcp, addr, nmemb, &buf, current_wordsize,
  71. tfetch_mem, print_group, 0);
  72. return true;
  73. }
  74. static bool
  75. decode_netlink_diag_ring(struct tcb *const tcp,
  76. const kernel_ulong_t addr,
  77. const unsigned int len,
  78. const void *const opaque_data)
  79. {
  80. struct netlink_diag_ring ndr;
  81. if (len < sizeof(ndr))
  82. return false;
  83. if (umove_or_printaddr(tcp, addr, &ndr))
  84. return true;
  85. PRINT_FIELD_U("{", ndr, ndr_block_size);
  86. PRINT_FIELD_U(", ", ndr, ndr_block_nr);
  87. PRINT_FIELD_U(", ", ndr, ndr_frame_size);
  88. PRINT_FIELD_U(", ", ndr, ndr_frame_nr);
  89. tprints("}");
  90. return true;
  91. }
  92. static bool
  93. decode_netlink_diag_flags(struct tcb *const tcp,
  94. const kernel_ulong_t addr,
  95. const unsigned int len,
  96. const void *const opaque_data)
  97. {
  98. uint32_t flags;
  99. if (len < sizeof(flags))
  100. return false;
  101. if (umove_or_printaddr(tcp, addr, &flags))
  102. return true;
  103. printflags(netlink_socket_flags, flags, "NDIAG_FLAG_???");
  104. return true;
  105. }
  106. static const nla_decoder_t netlink_diag_msg_nla_decoders[] = {
  107. [NETLINK_DIAG_MEMINFO] = decode_nla_meminfo,
  108. [NETLINK_DIAG_GROUPS] = decode_netlink_diag_groups,
  109. [NETLINK_DIAG_RX_RING] = decode_netlink_diag_ring,
  110. [NETLINK_DIAG_TX_RING] = decode_netlink_diag_ring,
  111. [NETLINK_DIAG_FLAGS] = decode_netlink_diag_flags
  112. };
  113. DECL_NETLINK_DIAG_DECODER(decode_netlink_diag_msg)
  114. {
  115. struct netlink_diag_msg msg = { .ndiag_family = family };
  116. size_t offset = sizeof(msg.ndiag_family);
  117. bool decode_nla = false;
  118. PRINT_FIELD_XVAL("{", msg, ndiag_family, addrfams, "AF_???");
  119. tprints(", ");
  120. if (len >= sizeof(msg)) {
  121. if (!umoven_or_printaddr(tcp, addr + offset,
  122. sizeof(msg) - offset,
  123. (char *) &msg + offset)) {
  124. PRINT_FIELD_XVAL("", msg, ndiag_type,
  125. socktypes, "SOCK_???");
  126. PRINT_FIELD_XVAL(", ", msg, ndiag_protocol,
  127. netlink_protocols, "NETLINK_???");
  128. PRINT_FIELD_XVAL(", ", msg, ndiag_state,
  129. netlink_states, "NETLINK_???");
  130. PRINT_FIELD_U(", ", msg, ndiag_portid);
  131. PRINT_FIELD_U(", ", msg, ndiag_dst_portid);
  132. PRINT_FIELD_U(", ", msg, ndiag_dst_group);
  133. PRINT_FIELD_U(", ", msg, ndiag_ino);
  134. PRINT_FIELD_COOKIE(", ", msg, ndiag_cookie);
  135. decode_nla = true;
  136. }
  137. } else
  138. tprints("...");
  139. tprints("}");
  140. offset = NLMSG_ALIGN(sizeof(msg));
  141. if (decode_nla && len > offset) {
  142. tprints(", ");
  143. decode_nlattr(tcp, addr + offset, len - offset,
  144. netlink_diag_attrs, "NETLINK_DIAG_???",
  145. netlink_diag_msg_nla_decoders,
  146. ARRAY_SIZE(netlink_diag_msg_nla_decoders), NULL);
  147. }
  148. }