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_unix_diag.c 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
  3. * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
  4. * Copyright (c) 2017-2019 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/unix_diag.h>
  16. #include "xlat/unix_diag_attrs.h"
  17. #include "xlat/unix_diag_show.h"
  18. DECL_NETLINK_DIAG_DECODER(decode_unix_diag_req)
  19. {
  20. struct unix_diag_req req = { .sdiag_family = family };
  21. const size_t offset = sizeof(req.sdiag_family);
  22. PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
  23. tprints(", ");
  24. if (len >= sizeof(req)) {
  25. if (!umoven_or_printaddr(tcp, addr + offset,
  26. sizeof(req) - offset,
  27. (char *) &req + offset)) {
  28. PRINT_FIELD_U("", req, sdiag_protocol);
  29. PRINT_FIELD_FLAGS(", ", req, udiag_states,
  30. tcp_state_flags, "1<<TCP_???");
  31. PRINT_FIELD_U(", ", req, udiag_ino);
  32. PRINT_FIELD_FLAGS(", ", req, udiag_show,
  33. unix_diag_show, "UDIAG_SHOW_???");
  34. PRINT_FIELD_COOKIE(", ", req, udiag_cookie);
  35. }
  36. } else
  37. tprints("...");
  38. tprints("}");
  39. }
  40. static bool
  41. decode_unix_diag_vfs(struct tcb *const tcp,
  42. const kernel_ulong_t addr,
  43. const unsigned int len,
  44. const void *const opaque_data)
  45. {
  46. struct unix_diag_vfs uv;
  47. if (len < sizeof(uv))
  48. return false;
  49. if (umove_or_printaddr(tcp, addr, &uv))
  50. return true;
  51. PRINT_FIELD_DEV("{", uv, udiag_vfs_dev);
  52. PRINT_FIELD_U(", ", uv, udiag_vfs_ino);
  53. tprints("}");
  54. return true;
  55. }
  56. static bool
  57. print_inode(struct tcb *const tcp,
  58. void *const elem_buf,
  59. const size_t elem_size,
  60. void *const opaque_data)
  61. {
  62. tprintf("%" PRIu32, *(uint32_t *) elem_buf);
  63. return true;
  64. }
  65. static bool
  66. decode_unix_diag_inode(struct tcb *const tcp,
  67. const kernel_ulong_t addr,
  68. const unsigned int len,
  69. const void *const opaque_data)
  70. {
  71. uint32_t inode;
  72. const size_t nmemb = len / sizeof(inode);
  73. if (!nmemb)
  74. return false;
  75. print_array(tcp, addr, nmemb, &inode, sizeof(inode),
  76. tfetch_mem, print_inode, 0);
  77. return true;
  78. }
  79. static bool
  80. decode_unix_diag_rqlen(struct tcb *const tcp,
  81. const kernel_ulong_t addr,
  82. const unsigned int len,
  83. const void *const opaque_data)
  84. {
  85. struct unix_diag_rqlen rql;
  86. if (len < sizeof(rql))
  87. return false;
  88. if (umove_or_printaddr(tcp, addr, &rql))
  89. return true;
  90. PRINT_FIELD_U("{", rql, udiag_rqueue);
  91. PRINT_FIELD_U(", ", rql, udiag_wqueue);
  92. tprints("}");
  93. return true;
  94. }
  95. static const nla_decoder_t unix_diag_msg_nla_decoders[] = {
  96. [UNIX_DIAG_NAME] = decode_nla_str,
  97. [UNIX_DIAG_VFS] = decode_unix_diag_vfs,
  98. [UNIX_DIAG_PEER] = decode_nla_u32,
  99. [UNIX_DIAG_ICONS] = decode_unix_diag_inode,
  100. [UNIX_DIAG_RQLEN] = decode_unix_diag_rqlen,
  101. [UNIX_DIAG_MEMINFO] = decode_nla_meminfo,
  102. [UNIX_DIAG_SHUTDOWN] = decode_nla_u8,
  103. [UNIX_DIAG_UID] = decode_nla_uid
  104. };
  105. DECL_NETLINK_DIAG_DECODER(decode_unix_diag_msg)
  106. {
  107. struct unix_diag_msg msg = { .udiag_family = family };
  108. size_t offset = sizeof(msg.udiag_family);
  109. bool decode_nla = false;
  110. PRINT_FIELD_XVAL("{", msg, udiag_family, addrfams, "AF_???");
  111. tprints(", ");
  112. if (len >= sizeof(msg)) {
  113. if (!umoven_or_printaddr(tcp, addr + offset,
  114. sizeof(msg) - offset,
  115. (char *) &msg + offset)) {
  116. PRINT_FIELD_XVAL("", msg, udiag_type,
  117. socktypes, "SOCK_???");
  118. PRINT_FIELD_XVAL(", ", msg, udiag_state,
  119. tcp_states, "TCP_???");
  120. PRINT_FIELD_U(", ", msg, udiag_ino);
  121. PRINT_FIELD_COOKIE(", ", msg, udiag_cookie);
  122. decode_nla = true;
  123. }
  124. } else
  125. tprints("...");
  126. tprints("}");
  127. offset = NLMSG_ALIGN(sizeof(msg));
  128. if (decode_nla && len > offset) {
  129. tprints(", ");
  130. decode_nlattr(tcp, addr + offset, len - offset,
  131. unix_diag_attrs, "UNIX_DIAG_???",
  132. unix_diag_msg_nla_decoders,
  133. ARRAY_SIZE(unix_diag_msg_nla_decoders), NULL);
  134. }
  135. }