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.8KB

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