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 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. };
  72. DECL_NETLINK_ROUTE_DECODER(decode_ifaddrmsg)
  73. {
  74. struct ifaddrmsg ifaddr = { .ifa_family = family };
  75. size_t offset = sizeof(ifaddr.ifa_family);
  76. bool decode_nla = false;
  77. PRINT_FIELD_XVAL("{", ifaddr, ifa_family, addrfams, "AF_???");
  78. tprints(", ");
  79. if (len >= sizeof(ifaddr)) {
  80. if (!umoven_or_printaddr(tcp, addr + offset,
  81. sizeof(ifaddr) - offset,
  82. (char *) &ifaddr + offset)) {
  83. PRINT_FIELD_U("", ifaddr, ifa_prefixlen);
  84. PRINT_FIELD_FLAGS(", ", ifaddr, ifa_flags,
  85. ifaddrflags, "IFA_F_???");
  86. PRINT_FIELD_XVAL(", ", ifaddr, ifa_scope,
  87. routing_scopes, NULL);
  88. PRINT_FIELD_IFINDEX(", ", ifaddr, ifa_index);
  89. decode_nla = true;
  90. }
  91. } else
  92. tprints("...");
  93. tprints("}");
  94. offset = NLMSG_ALIGN(sizeof(ifaddr));
  95. if (decode_nla && len > offset) {
  96. tprints(", ");
  97. decode_nlattr(tcp, addr + offset, len - offset,
  98. rtnl_addr_attrs, "IFA_???",
  99. ifaddrmsg_nla_decoders,
  100. ARRAY_SIZE(ifaddrmsg_nla_decoders), &ifaddr);
  101. }
  102. }