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.

rtnl_rule.c 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
  3. * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
  4. * Copyright (c) 2016-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_route.h"
  11. #include "nlattr.h"
  12. #include "print_fields.h"
  13. #include "netlink.h"
  14. #include <linux/rtnetlink.h>
  15. #ifdef HAVE_LINUX_FIB_RULES_H
  16. # include <linux/fib_rules.h>
  17. #endif
  18. #include "xlat/fib_rule_actions.h"
  19. #include "xlat/fib_rule_flags.h"
  20. #include "xlat/rtnl_rule_attrs.h"
  21. static bool
  22. decode_rule_addr(struct tcb *const tcp,
  23. const kernel_ulong_t addr,
  24. const unsigned int len,
  25. const void *const opaque_data)
  26. {
  27. const struct rtmsg *const rtmsg = opaque_data;
  28. decode_inet_addr(tcp, addr, len, rtmsg->rtm_family, NULL);
  29. return true;
  30. }
  31. static bool
  32. decode_fib_rule_uid_range(struct tcb *const tcp,
  33. const kernel_ulong_t addr,
  34. const unsigned int len,
  35. const void *const opaque_data)
  36. {
  37. struct /* fib_rule_uid_range */ {
  38. uint32_t start;
  39. uint32_t end;
  40. } range;
  41. if (len < sizeof(range))
  42. return false;
  43. else if (!umove_or_printaddr(tcp, addr, &range)) {
  44. PRINT_FIELD_U("{", range, start);
  45. PRINT_FIELD_U(", ", range, end);
  46. tprints("}");
  47. }
  48. return true;
  49. }
  50. static bool
  51. decode_rule_port_range(struct tcb *const tcp,
  52. const kernel_ulong_t addr,
  53. const unsigned int len,
  54. const void *const opaque_data)
  55. {
  56. struct /* fib_rule_port_range */ {
  57. uint16_t start;
  58. uint16_t end;
  59. } range;
  60. if (len < sizeof(range))
  61. return false;
  62. else if (!umove_or_printaddr(tcp, addr, &range)) {
  63. PRINT_FIELD_U("{", range, start);
  64. PRINT_FIELD_U(", ", range, end);
  65. tprints("}");
  66. }
  67. return true;
  68. }
  69. static const nla_decoder_t fib_rule_hdr_nla_decoders[] = {
  70. [FRA_DST] = decode_rule_addr,
  71. [FRA_SRC] = decode_rule_addr,
  72. [FRA_IIFNAME] = decode_nla_str,
  73. [FRA_GOTO] = decode_nla_u32,
  74. [FRA_PRIORITY] = decode_nla_u32,
  75. [FRA_FWMARK] = decode_nla_u32,
  76. [FRA_FLOW] = decode_nla_u32,
  77. [FRA_TUN_ID] = decode_nla_be64,
  78. [FRA_SUPPRESS_IFGROUP] = decode_nla_u32,
  79. [FRA_SUPPRESS_PREFIXLEN] = decode_nla_u32,
  80. [FRA_TABLE] = decode_nla_rt_class,
  81. [FRA_FWMASK] = decode_nla_u32,
  82. [FRA_OIFNAME] = decode_nla_str,
  83. [FRA_PAD] = NULL,
  84. [FRA_L3MDEV] = decode_nla_u8,
  85. [FRA_UID_RANGE] = decode_fib_rule_uid_range,
  86. [FRA_PROTOCOL] = decode_nla_rt_proto,
  87. [FRA_IP_PROTO] = decode_nla_ip_proto,
  88. [FRA_SPORT_RANGE] = decode_rule_port_range,
  89. [FRA_DPORT_RANGE] = decode_rule_port_range,
  90. };
  91. DECL_NETLINK_ROUTE_DECODER(decode_fib_rule_hdr)
  92. {
  93. /*
  94. * struct rtmsg and struct fib_rule_hdr are essentially
  95. * the same structure, use struct rtmsg but treat it as
  96. * struct fib_rule_hdr.
  97. */
  98. struct rtmsg msg = { .rtm_family = family };
  99. size_t offset = sizeof(msg.rtm_family);
  100. bool decode_nla = false;
  101. tprints("{family=");
  102. printxval(addrfams, msg.rtm_family, "AF_???");
  103. tprints(", ");
  104. if (len >= sizeof(msg)) {
  105. if (!umoven_or_printaddr(tcp, addr + offset,
  106. sizeof(msg) - offset,
  107. (char *) &msg + offset)) {
  108. tprintf("dst_len=%u, src_len=%u",
  109. msg.rtm_dst_len, msg.rtm_src_len);
  110. tprints(", tos=");
  111. printflags(ip_type_of_services, msg.rtm_tos,
  112. "IPTOS_TOS_???");
  113. tprints(", table=");
  114. printxval(routing_table_ids, msg.rtm_table, NULL);
  115. tprints(", action=");
  116. printxval(fib_rule_actions, msg.rtm_type, "FR_ACT_???");
  117. tprints(", flags=");
  118. printflags(fib_rule_flags, msg.rtm_flags,
  119. "FIB_RULE_???");
  120. decode_nla = true;
  121. }
  122. } else
  123. tprints("...");
  124. tprints("}");
  125. offset = NLMSG_ALIGN(sizeof(msg));
  126. if (decode_nla && len > offset) {
  127. tprints(", ");
  128. decode_nlattr(tcp, addr + offset, len - offset,
  129. rtnl_rule_attrs, "FRA_???",
  130. fib_rule_hdr_nla_decoders,
  131. ARRAY_SIZE(fib_rule_hdr_nla_decoders), &msg);
  132. }
  133. }