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_addr.c 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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_IF_ADDR_H
  16. # include <linux/if_addr.h>
  17. #endif
  18. #include "xlat/ifaddrflags.h"
  19. #include "xlat/routing_scopes.h"
  20. #include "xlat/rtnl_addr_attrs.h"
  21. static bool
  22. decode_ifa_address(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 ifaddrmsg *const ifaddr = opaque_data;
  28. decode_inet_addr(tcp, addr, len, ifaddr->ifa_family, NULL);
  29. return true;
  30. }
  31. static bool
  32. decode_ifa_cacheinfo(struct tcb *const tcp,
  33. const kernel_ulong_t addr,
  34. const unsigned int len,
  35. const void *const opaque_data)
  36. {
  37. struct ifa_cacheinfo ci;
  38. if (len < sizeof(ci))
  39. return false;
  40. else if (!umove_or_printaddr(tcp, addr, &ci)) {
  41. PRINT_FIELD_U("{", ci, ifa_prefered);
  42. PRINT_FIELD_U(", ", ci, ifa_valid);
  43. PRINT_FIELD_U(", ", ci, cstamp);
  44. PRINT_FIELD_U(", ", ci, tstamp);
  45. tprintf("}");
  46. }
  47. return true;
  48. }
  49. static bool
  50. decode_ifa_flags(struct tcb *const tcp,
  51. const kernel_ulong_t addr,
  52. const unsigned int len,
  53. const void *const opaque_data)
  54. {
  55. uint32_t ifa_flags;
  56. if (len < sizeof(ifa_flags))
  57. return false;
  58. else if (!umove_or_printaddr(tcp, addr, &ifa_flags))
  59. printflags(ifaddrflags, ifa_flags, "IFA_F_???");
  60. return true;
  61. }
  62. static const nla_decoder_t ifaddrmsg_nla_decoders[] = {
  63. [IFA_ADDRESS] = decode_ifa_address,
  64. [IFA_LOCAL] = decode_ifa_address,
  65. [IFA_LABEL] = decode_nla_str,
  66. [IFA_BROADCAST] = decode_ifa_address,
  67. [IFA_ANYCAST] = decode_ifa_address,
  68. [IFA_CACHEINFO] = decode_ifa_cacheinfo,
  69. [IFA_MULTICAST] = decode_ifa_address,
  70. [IFA_FLAGS] = decode_ifa_flags,
  71. [IFA_RT_PRIORITY] = decode_nla_u32,
  72. [IFA_TARGET_NETNSID] = decode_nla_s32,
  73. };
  74. DECL_NETLINK_ROUTE_DECODER(decode_ifaddrmsg)
  75. {
  76. struct ifaddrmsg ifaddr = { .ifa_family = family };
  77. size_t offset = sizeof(ifaddr.ifa_family);
  78. bool decode_nla = false;
  79. PRINT_FIELD_XVAL("{", ifaddr, ifa_family, addrfams, "AF_???");
  80. tprints(", ");
  81. if (len >= sizeof(ifaddr)) {
  82. if (!umoven_or_printaddr(tcp, addr + offset,
  83. sizeof(ifaddr) - offset,
  84. (char *) &ifaddr + offset)) {
  85. PRINT_FIELD_U("", ifaddr, ifa_prefixlen);
  86. PRINT_FIELD_FLAGS(", ", ifaddr, ifa_flags,
  87. ifaddrflags, "IFA_F_???");
  88. PRINT_FIELD_XVAL(", ", ifaddr, ifa_scope,
  89. routing_scopes, NULL);
  90. PRINT_FIELD_IFINDEX(", ", ifaddr, ifa_index);
  91. decode_nla = true;
  92. }
  93. } else
  94. tprints("...");
  95. tprints("}");
  96. offset = NLMSG_ALIGN(sizeof(ifaddr));
  97. if (decode_nla && len > offset) {
  98. tprints(", ");
  99. decode_nlattr(tcp, addr + offset, len - offset,
  100. rtnl_addr_attrs, "IFA_???",
  101. ifaddrmsg_nla_decoders,
  102. ARRAY_SIZE(ifaddrmsg_nla_decoders), &ifaddr);
  103. }
  104. }