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_packet_diag.c 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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/filter.h>
  15. #include <linux/sock_diag.h>
  16. #include <linux/packet_diag.h>
  17. #include "xlat/af_packet_versions.h"
  18. #include "xlat/packet_diag_attrs.h"
  19. #include "xlat/packet_diag_info_flags.h"
  20. #include "xlat/packet_diag_show.h"
  21. DECL_NETLINK_DIAG_DECODER(decode_packet_diag_req)
  22. {
  23. struct packet_diag_req req = { .sdiag_family = family };
  24. const size_t offset = sizeof(req.sdiag_family);
  25. PRINT_FIELD_XVAL("{", req, sdiag_family, addrfams, "AF_???");
  26. tprints(", ");
  27. if (len >= sizeof(req)) {
  28. if (!umoven_or_printaddr(tcp, addr + offset,
  29. sizeof(req) - offset,
  30. (char *) &req + offset)) {
  31. /*
  32. * AF_PACKET currently doesn't support protocol values
  33. * other than 0.
  34. */
  35. PRINT_FIELD_X("", req, sdiag_protocol);
  36. PRINT_FIELD_U(", ", req, pdiag_ino);
  37. PRINT_FIELD_FLAGS(", ", req, pdiag_show,
  38. packet_diag_show, "PACKET_SHOW_???");
  39. PRINT_FIELD_COOKIE(", ", req, pdiag_cookie);
  40. }
  41. } else
  42. tprints("...");
  43. tprints("}");
  44. }
  45. static bool
  46. decode_packet_diag_info(struct tcb *const tcp,
  47. const kernel_ulong_t addr,
  48. const unsigned int len,
  49. const void *const opaque_data)
  50. {
  51. struct packet_diag_info pinfo;
  52. if (len < sizeof(pinfo))
  53. return false;
  54. if (umove_or_printaddr(tcp, addr, &pinfo))
  55. return true;
  56. PRINT_FIELD_IFINDEX("{", pinfo, pdi_index);
  57. PRINT_FIELD_XVAL(", ", pinfo, pdi_version, af_packet_versions,
  58. "TPACKET_???");
  59. PRINT_FIELD_U(", ", pinfo, pdi_reserve);
  60. PRINT_FIELD_U(", ", pinfo, pdi_copy_thresh);
  61. PRINT_FIELD_U(", ", pinfo, pdi_tstamp);
  62. PRINT_FIELD_FLAGS(", ", pinfo, pdi_flags,
  63. packet_diag_info_flags, "PDI_???");
  64. tprints("}");
  65. return true;
  66. }
  67. static bool
  68. print_packet_diag_mclist(struct tcb *const tcp, void *const elem_buf,
  69. const size_t elem_size, void *const opaque_data)
  70. {
  71. struct packet_diag_mclist *dml = elem_buf;
  72. uint16_t alen = MIN(dml->pdmc_alen, sizeof(dml->pdmc_addr));
  73. PRINT_FIELD_IFINDEX("{", *dml, pdmc_index);
  74. PRINT_FIELD_U(", ", *dml, pdmc_count);
  75. PRINT_FIELD_U(", ", *dml, pdmc_type);
  76. PRINT_FIELD_U(", ", *dml, pdmc_alen);
  77. PRINT_FIELD_STRING(", ", *dml, pdmc_addr, alen, QUOTE_FORCE_HEX);
  78. tprints("}");
  79. return true;
  80. }
  81. static bool
  82. decode_packet_diag_mclist(struct tcb *const tcp,
  83. const kernel_ulong_t addr,
  84. const unsigned int len,
  85. const void *const opaque_data)
  86. {
  87. struct packet_diag_mclist dml;
  88. const size_t nmemb = len / sizeof(dml);
  89. if (!nmemb)
  90. return false;
  91. print_array(tcp, addr, nmemb, &dml, sizeof(dml),
  92. tfetch_mem, print_packet_diag_mclist, 0);
  93. return true;
  94. }
  95. static bool
  96. decode_packet_diag_ring(struct tcb *const tcp,
  97. const kernel_ulong_t addr,
  98. const unsigned int len,
  99. const void *const opaque_data)
  100. {
  101. struct packet_diag_ring pdr;
  102. if (len < sizeof(pdr))
  103. return false;
  104. if (umove_or_printaddr(tcp, addr, &pdr))
  105. return true;
  106. PRINT_FIELD_U("{", pdr, pdr_block_size);
  107. PRINT_FIELD_U(", ", pdr, pdr_block_nr);
  108. PRINT_FIELD_U(", ", pdr, pdr_frame_size);
  109. PRINT_FIELD_U(", ", pdr, pdr_frame_nr);
  110. PRINT_FIELD_U(", ", pdr, pdr_retire_tmo);
  111. PRINT_FIELD_U(", ", pdr, pdr_sizeof_priv);
  112. PRINT_FIELD_U(", ", pdr, pdr_features);
  113. tprints("}");
  114. return true;
  115. }
  116. static bool
  117. decode_packet_diag_filter(struct tcb *const tcp,
  118. const kernel_ulong_t addr,
  119. const unsigned int len,
  120. const void *const opaque_data)
  121. {
  122. const unsigned int nmemb = len / sizeof(struct sock_filter);
  123. if (!nmemb || (unsigned short) nmemb != nmemb)
  124. return false;
  125. print_sock_fprog(tcp, addr, nmemb);
  126. return true;
  127. }
  128. static const nla_decoder_t packet_diag_msg_nla_decoders[] = {
  129. [PACKET_DIAG_INFO] = decode_packet_diag_info,
  130. [PACKET_DIAG_MCLIST] = decode_packet_diag_mclist,
  131. [PACKET_DIAG_RX_RING] = decode_packet_diag_ring,
  132. [PACKET_DIAG_TX_RING] = decode_packet_diag_ring,
  133. [PACKET_DIAG_FANOUT] = decode_nla_u32,
  134. [PACKET_DIAG_UID] = decode_nla_uid,
  135. [PACKET_DIAG_MEMINFO] = decode_nla_meminfo,
  136. [PACKET_DIAG_FILTER] = decode_packet_diag_filter
  137. };
  138. DECL_NETLINK_DIAG_DECODER(decode_packet_diag_msg)
  139. {
  140. struct packet_diag_msg msg = { .pdiag_family = family };
  141. size_t offset = sizeof(msg.pdiag_family);
  142. bool decode_nla = false;
  143. PRINT_FIELD_XVAL("{", msg, pdiag_family, addrfams, "AF_???");
  144. tprints(", ");
  145. if (len >= sizeof(msg)) {
  146. if (!umoven_or_printaddr(tcp, addr + offset,
  147. sizeof(msg) - offset,
  148. (char *) &msg + offset)) {
  149. PRINT_FIELD_XVAL("", msg, pdiag_type,
  150. socktypes, "SOCK_???");
  151. PRINT_FIELD_XVAL(", ", msg, pdiag_num,
  152. ethernet_protocols, "ETH_P_???");
  153. PRINT_FIELD_U(", ", msg, pdiag_ino);
  154. PRINT_FIELD_COOKIE(", ", msg, pdiag_cookie);
  155. decode_nla = true;
  156. }
  157. } else
  158. tprints("...");
  159. tprints("}");
  160. offset = NLMSG_ALIGN(sizeof(msg));
  161. if (decode_nla && len > offset) {
  162. tprints(", ");
  163. decode_nlattr(tcp, addr + offset, len - offset,
  164. packet_diag_attrs, "PACKET_DIAG_???",
  165. packet_diag_msg_nla_decoders,
  166. ARRAY_SIZE(packet_diag_msg_nla_decoders), NULL);
  167. }
  168. }