(root)/
strace-6.5/
src/
rtnl_addr.c
       1  /*
       2   * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
       3   * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
       4   * Copyright (c) 2016-2021 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: LGPL-2.1-or-later
       8   */
       9  
      10  #include "defs.h"
      11  #include "netlink_route.h"
      12  #include "nlattr.h"
      13  
      14  #include "netlink.h"
      15  #include <linux/rtnetlink.h>
      16  #include <linux/if_addr.h>
      17  
      18  #include "xlat/ifaddrflags.h"
      19  #include "xlat/routing_scopes.h"
      20  #include "xlat/rtnl_addr_attrs.h"
      21  
      22  static bool
      23  decode_ifa_address(struct tcb *const tcp,
      24  		   const kernel_ulong_t addr,
      25  		   const unsigned int len,
      26  		   const void *const opaque_data)
      27  {
      28  	const struct ifaddrmsg *const ifaddr = opaque_data;
      29  
      30  	decode_inet_addr(tcp, addr, len, ifaddr->ifa_family, NULL);
      31  
      32  	return true;
      33  }
      34  
      35  static bool
      36  decode_ifa_cacheinfo(struct tcb *const tcp,
      37  		     const kernel_ulong_t addr,
      38  		     const unsigned int len,
      39  		     const void *const opaque_data)
      40  {
      41  	struct ifa_cacheinfo ci;
      42  
      43  	if (len < sizeof(ci))
      44  		return false;
      45  	else if (!umove_or_printaddr(tcp, addr, &ci)) {
      46  		tprint_struct_begin();
      47  		PRINT_FIELD_U(ci, ifa_prefered);
      48  		tprint_struct_next();
      49  		PRINT_FIELD_U(ci, ifa_valid);
      50  		tprint_struct_next();
      51  		PRINT_FIELD_U(ci, cstamp);
      52  		tprint_struct_next();
      53  		PRINT_FIELD_U(ci, tstamp);
      54  		tprint_struct_end();
      55  	}
      56  
      57  	return true;
      58  }
      59  
      60  static bool
      61  decode_ifa_flags(struct tcb *const tcp,
      62  		 const kernel_ulong_t addr,
      63  		 const unsigned int len,
      64  		 const void *const opaque_data)
      65  {
      66  	uint32_t ifa_flags;
      67  
      68  	if (len < sizeof(ifa_flags))
      69  		return false;
      70  	else if (!umove_or_printaddr(tcp, addr, &ifa_flags))
      71  		printflags(ifaddrflags, ifa_flags, "IFA_F_???");
      72  
      73  	return true;
      74  }
      75  
      76  static const nla_decoder_t ifaddrmsg_nla_decoders[] = {
      77  	[IFA_ADDRESS]		= decode_ifa_address,
      78  	[IFA_LOCAL]		= decode_ifa_address,
      79  	[IFA_LABEL]		= decode_nla_str,
      80  	[IFA_BROADCAST]		= decode_ifa_address,
      81  	[IFA_ANYCAST]		= decode_ifa_address,
      82  	[IFA_CACHEINFO]		= decode_ifa_cacheinfo,
      83  	[IFA_MULTICAST]		= decode_ifa_address,
      84  	[IFA_FLAGS]		= decode_ifa_flags,
      85  	[IFA_RT_PRIORITY]	= decode_nla_u32,
      86  	[IFA_TARGET_NETNSID]	= decode_nla_s32,
      87  };
      88  
      89  DECL_NETLINK_ROUTE_DECODER(decode_ifaddrmsg)
      90  {
      91  	struct ifaddrmsg ifaddr = { .ifa_family = family };
      92  	size_t offset = sizeof(ifaddr.ifa_family);
      93  	bool decode_nla = false;
      94  
      95  	tprint_struct_begin();
      96  	PRINT_FIELD_XVAL(ifaddr, ifa_family, addrfams, "AF_???");
      97  	tprint_struct_next();
      98  
      99  	if (len >= sizeof(ifaddr)) {
     100  		if (!umoven_or_printaddr(tcp, addr + offset,
     101  					 sizeof(ifaddr) - offset,
     102  					 (char *) &ifaddr + offset)) {
     103  			PRINT_FIELD_U(ifaddr, ifa_prefixlen);
     104  			tprint_struct_next();
     105  			PRINT_FIELD_FLAGS(ifaddr, ifa_flags,
     106  					  ifaddrflags, "IFA_F_???");
     107  			tprint_struct_next();
     108  			PRINT_FIELD_XVAL(ifaddr, ifa_scope,
     109  					 routing_scopes, NULL);
     110  			tprint_struct_next();
     111  			PRINT_FIELD_IFINDEX(ifaddr, ifa_index);
     112  			decode_nla = true;
     113  		}
     114  	} else
     115  		tprint_more_data_follows();
     116  	tprint_struct_end();
     117  
     118  	offset = NLMSG_ALIGN(sizeof(ifaddr));
     119  	if (decode_nla && len > offset) {
     120  		tprint_array_next();
     121  		decode_nlattr(tcp, addr + offset, len - offset,
     122  			      rtnl_addr_attrs, "IFA_???",
     123  			      ifaddrmsg_nla_decoders,
     124  			      ARRAY_SIZE(ifaddrmsg_nla_decoders), &ifaddr);
     125  	}
     126  }