• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
3  * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4  * Copyright (c) 2016-2017 The strace developers.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "defs.h"
31 #include "netlink_route.h"
32 #include "nlattr.h"
33 #include "print_fields.h"
34 
35 #include "netlink.h"
36 #include <linux/rtnetlink.h>
37 #ifdef HAVE_LINUX_NEIGHBOUR_H
38 # include <linux/neighbour.h>
39 #endif
40 
41 #include "xlat/rtnl_neightbl_attrs.h"
42 #include "xlat/rtnl_neightbl_parms_attrs.h"
43 
44 static bool
decode_ndt_config(struct tcb * const tcp,const kernel_ulong_t addr,const unsigned int len,const void * const opaque_data)45 decode_ndt_config(struct tcb *const tcp,
46 		  const kernel_ulong_t addr,
47 		  const unsigned int len,
48 		  const void *const opaque_data)
49 {
50 #ifdef HAVE_STRUCT_NDT_CONFIG
51 	struct ndt_config ndtc;
52 
53 	if (len < sizeof(ndtc))
54 		return false;
55 	else if (!umove_or_printaddr(tcp, addr, &ndtc)) {
56 		PRINT_FIELD_U("{", ndtc, ndtc_key_len);
57 		PRINT_FIELD_U(", ", ndtc, ndtc_entry_size);
58 		PRINT_FIELD_U(", ", ndtc, ndtc_entries);
59 		PRINT_FIELD_U(", ", ndtc, ndtc_last_flush);
60 		PRINT_FIELD_U(", ", ndtc, ndtc_last_rand);
61 		PRINT_FIELD_U(", ", ndtc, ndtc_hash_rnd);
62 		PRINT_FIELD_0X(", ", ndtc, ndtc_hash_mask);
63 		PRINT_FIELD_U(", ", ndtc, ndtc_hash_chain_gc);
64 		PRINT_FIELD_U(", ", ndtc, ndtc_proxy_qlen);
65 		tprints("}");
66 	}
67 
68 	return true;
69 #else
70 	return false;
71 #endif
72 }
73 
74 static const nla_decoder_t ndt_parms_nla_decoders[] = {
75 	[NDTPA_IFINDEX]			= decode_nla_ifindex,
76 	[NDTPA_REFCNT]			= decode_nla_u32,
77 	[NDTPA_REACHABLE_TIME]		= decode_nla_u64,
78 	[NDTPA_BASE_REACHABLE_TIME]	= decode_nla_u64,
79 	[NDTPA_RETRANS_TIME]		= decode_nla_u64,
80 	[NDTPA_GC_STALETIME]		= decode_nla_u64,
81 	[NDTPA_DELAY_PROBE_TIME]	= decode_nla_u64,
82 	[NDTPA_QUEUE_LEN]		= decode_nla_u32,
83 	[NDTPA_APP_PROBES]		= decode_nla_u32,
84 	[NDTPA_UCAST_PROBES]		= decode_nla_u32,
85 	[NDTPA_MCAST_PROBES]		= decode_nla_u32,
86 	[NDTPA_ANYCAST_DELAY]		= decode_nla_u64,
87 	[NDTPA_PROXY_DELAY]		= decode_nla_u64,
88 	[NDTPA_PROXY_QLEN]		= decode_nla_u32,
89 	[NDTPA_LOCKTIME]		= decode_nla_u64,
90 	[NDTPA_QUEUE_LENBYTES]		= decode_nla_u32,
91 	[NDTPA_MCAST_REPROBES]		= decode_nla_u32,
92 	[NDTPA_PAD]			= NULL
93 };
94 
95 static bool
decode_ndta_parms(struct tcb * const tcp,const kernel_ulong_t addr,const unsigned int len,const void * const opaque_data)96 decode_ndta_parms(struct tcb *const tcp,
97 		  const kernel_ulong_t addr,
98 		  const unsigned int len,
99 		  const void *const opaque_data)
100 {
101 	decode_nlattr(tcp, addr, len, rtnl_neightbl_parms_attrs, "NDTPA_???",
102 		      ndt_parms_nla_decoders,
103 		      ARRAY_SIZE(ndt_parms_nla_decoders), opaque_data);
104 
105 	return true;
106 }
107 
108 static bool
decode_ndt_stats(struct tcb * const tcp,const kernel_ulong_t addr,const unsigned int len,const void * const opaque_data)109 decode_ndt_stats(struct tcb *const tcp,
110 		 const kernel_ulong_t addr,
111 		 const unsigned int len,
112 		 const void *const opaque_data)
113 {
114 #ifdef HAVE_STRUCT_NDT_STATS
115 	struct ndt_stats ndtst;
116 	const unsigned int min_size =
117 		offsetofend(struct ndt_stats, ndts_forced_gc_runs);
118 	const unsigned int def_size = sizeof(ndtst);
119 	const unsigned int size =
120 		(len >= def_size) ? def_size :
121 				    ((len == min_size) ? min_size : 0);
122 
123 	if (!size)
124 		return false;
125 
126 	if (!umoven_or_printaddr(tcp, addr, size, &ndtst)) {
127 		PRINT_FIELD_U("{", ndtst, ndts_allocs);
128 		PRINT_FIELD_U(", ", ndtst, ndts_destroys);
129 		PRINT_FIELD_U(", ", ndtst, ndts_hash_grows);
130 		PRINT_FIELD_U(", ", ndtst, ndts_res_failed);
131 		PRINT_FIELD_U(", ", ndtst, ndts_lookups);
132 		PRINT_FIELD_U(", ", ndtst, ndts_hits);
133 		PRINT_FIELD_U(", ", ndtst, ndts_rcv_probes_mcast);
134 		PRINT_FIELD_U(", ", ndtst, ndts_rcv_probes_ucast);
135 		PRINT_FIELD_U(", ", ndtst, ndts_periodic_gc_runs);
136 		PRINT_FIELD_U(", ", ndtst, ndts_forced_gc_runs);
137 #ifdef HAVE_STRUCT_NDT_STATS_NDTS_TABLE_FULLS
138 		if (len >= def_size)
139 			PRINT_FIELD_U(", ", ndtst, ndts_table_fulls);
140 #endif
141 		tprints("}");
142 	}
143 
144 	return true;
145 #else
146 	return false;
147 #endif
148 }
149 
150 static const nla_decoder_t ndtmsg_nla_decoders[] = {
151 	[NDTA_NAME]		= decode_nla_str,
152 	[NDTA_THRESH1]		= decode_nla_u32,
153 	[NDTA_THRESH2]		= decode_nla_u32,
154 	[NDTA_THRESH3]		= decode_nla_u32,
155 	[NDTA_CONFIG]		= decode_ndt_config,
156 	[NDTA_PARMS]		= decode_ndta_parms,
157 	[NDTA_STATS]		= decode_ndt_stats,
158 	[NDTA_GC_INTERVAL]	= decode_nla_u64,
159 	[NDTA_PAD]		= NULL,
160 };
161 
DECL_NETLINK_ROUTE_DECODER(decode_ndtmsg)162 DECL_NETLINK_ROUTE_DECODER(decode_ndtmsg)
163 {
164 	struct ndtmsg ndtmsg = { .ndtm_family = family };
165 
166 	PRINT_FIELD_XVAL("{", ndtmsg, ndtm_family, addrfams, "AF_???");
167 	tprints("}");
168 
169 	const size_t offset = NLMSG_ALIGN(sizeof(ndtmsg));
170 	if (len > offset) {
171 		tprints(", ");
172 		decode_nlattr(tcp, addr + offset, len - offset,
173 			      rtnl_neightbl_attrs, "NDTA_???",
174 			      ndtmsg_nla_decoders,
175 			      ARRAY_SIZE(ndtmsg_nla_decoders), NULL);
176 	}
177 }
178