1*cf84ac9aSAndroid Build Coastguard Worker /*
2*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 1991, 1992 Paul Kranenburg <[email protected]>
3*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 1993 Branko Lankester <[email protected]>
4*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <[email protected]>
5*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 1996-2000 Wichert Akkerman <[email protected]>
6*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 2005-2016 Dmitry V. Levin <[email protected]>
7*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 2016-2018 The strace developers.
8*cf84ac9aSAndroid Build Coastguard Worker * All rights reserved.
9*cf84ac9aSAndroid Build Coastguard Worker *
10*cf84ac9aSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
11*cf84ac9aSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
12*cf84ac9aSAndroid Build Coastguard Worker * are met:
13*cf84ac9aSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
14*cf84ac9aSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
15*cf84ac9aSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
16*cf84ac9aSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
17*cf84ac9aSAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
18*cf84ac9aSAndroid Build Coastguard Worker * 3. The name of the author may not be used to endorse or promote products
19*cf84ac9aSAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
20*cf84ac9aSAndroid Build Coastguard Worker *
21*cf84ac9aSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22*cf84ac9aSAndroid Build Coastguard Worker * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23*cf84ac9aSAndroid Build Coastguard Worker * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24*cf84ac9aSAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25*cf84ac9aSAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26*cf84ac9aSAndroid Build Coastguard Worker * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27*cf84ac9aSAndroid Build Coastguard Worker * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28*cf84ac9aSAndroid Build Coastguard Worker * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29*cf84ac9aSAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30*cf84ac9aSAndroid Build Coastguard Worker * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*cf84ac9aSAndroid Build Coastguard Worker */
32*cf84ac9aSAndroid Build Coastguard Worker
33*cf84ac9aSAndroid Build Coastguard Worker #include "defs.h"
34*cf84ac9aSAndroid Build Coastguard Worker #include "print_fields.h"
35*cf84ac9aSAndroid Build Coastguard Worker #include "msghdr.h"
36*cf84ac9aSAndroid Build Coastguard Worker #include <limits.h>
37*cf84ac9aSAndroid Build Coastguard Worker #include <arpa/inet.h>
38*cf84ac9aSAndroid Build Coastguard Worker #include <netinet/in.h>
39*cf84ac9aSAndroid Build Coastguard Worker
40*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/msg_flags.h"
41*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/scmvals.h"
42*cf84ac9aSAndroid Build Coastguard Worker #include "xlat/ip_cmsg_types.h"
43*cf84ac9aSAndroid Build Coastguard Worker
44*cf84ac9aSAndroid Build Coastguard Worker #ifndef current_wordsize
45*cf84ac9aSAndroid Build Coastguard Worker struct cmsghdr32 {
46*cf84ac9aSAndroid Build Coastguard Worker uint32_t cmsg_len;
47*cf84ac9aSAndroid Build Coastguard Worker int cmsg_level;
48*cf84ac9aSAndroid Build Coastguard Worker int cmsg_type;
49*cf84ac9aSAndroid Build Coastguard Worker };
50*cf84ac9aSAndroid Build Coastguard Worker #endif
51*cf84ac9aSAndroid Build Coastguard Worker
52*cf84ac9aSAndroid Build Coastguard Worker typedef union {
53*cf84ac9aSAndroid Build Coastguard Worker char *ptr;
54*cf84ac9aSAndroid Build Coastguard Worker struct cmsghdr *cmsg;
55*cf84ac9aSAndroid Build Coastguard Worker #ifndef current_wordsize
56*cf84ac9aSAndroid Build Coastguard Worker struct cmsghdr32 *cmsg32;
57*cf84ac9aSAndroid Build Coastguard Worker #endif
58*cf84ac9aSAndroid Build Coastguard Worker } union_cmsghdr;
59*cf84ac9aSAndroid Build Coastguard Worker
60*cf84ac9aSAndroid Build Coastguard Worker static void
print_scm_rights(struct tcb * tcp,const void * cmsg_data,const unsigned int data_len)61*cf84ac9aSAndroid Build Coastguard Worker print_scm_rights(struct tcb *tcp, const void *cmsg_data,
62*cf84ac9aSAndroid Build Coastguard Worker const unsigned int data_len)
63*cf84ac9aSAndroid Build Coastguard Worker {
64*cf84ac9aSAndroid Build Coastguard Worker const int *fds = cmsg_data;
65*cf84ac9aSAndroid Build Coastguard Worker const unsigned int nfds = data_len / sizeof(*fds);
66*cf84ac9aSAndroid Build Coastguard Worker unsigned int i;
67*cf84ac9aSAndroid Build Coastguard Worker
68*cf84ac9aSAndroid Build Coastguard Worker tprints("[");
69*cf84ac9aSAndroid Build Coastguard Worker
70*cf84ac9aSAndroid Build Coastguard Worker for (i = 0; i < nfds; ++i) {
71*cf84ac9aSAndroid Build Coastguard Worker if (i)
72*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
73*cf84ac9aSAndroid Build Coastguard Worker if (abbrev(tcp) && i >= max_strlen) {
74*cf84ac9aSAndroid Build Coastguard Worker tprints("...");
75*cf84ac9aSAndroid Build Coastguard Worker break;
76*cf84ac9aSAndroid Build Coastguard Worker }
77*cf84ac9aSAndroid Build Coastguard Worker printfd(tcp, fds[i]);
78*cf84ac9aSAndroid Build Coastguard Worker }
79*cf84ac9aSAndroid Build Coastguard Worker
80*cf84ac9aSAndroid Build Coastguard Worker tprints("]");
81*cf84ac9aSAndroid Build Coastguard Worker }
82*cf84ac9aSAndroid Build Coastguard Worker
83*cf84ac9aSAndroid Build Coastguard Worker static void
print_scm_creds(struct tcb * tcp,const void * cmsg_data,const unsigned int data_len)84*cf84ac9aSAndroid Build Coastguard Worker print_scm_creds(struct tcb *tcp, const void *cmsg_data,
85*cf84ac9aSAndroid Build Coastguard Worker const unsigned int data_len)
86*cf84ac9aSAndroid Build Coastguard Worker {
87*cf84ac9aSAndroid Build Coastguard Worker const struct ucred *uc = cmsg_data;
88*cf84ac9aSAndroid Build Coastguard Worker
89*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U("{", *uc, pid);
90*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_UID(", ", *uc, uid);
91*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_UID(", ", *uc, gid);
92*cf84ac9aSAndroid Build Coastguard Worker tprints("}");
93*cf84ac9aSAndroid Build Coastguard Worker }
94*cf84ac9aSAndroid Build Coastguard Worker
95*cf84ac9aSAndroid Build Coastguard Worker static void
print_scm_security(struct tcb * tcp,const void * cmsg_data,const unsigned int data_len)96*cf84ac9aSAndroid Build Coastguard Worker print_scm_security(struct tcb *tcp, const void *cmsg_data,
97*cf84ac9aSAndroid Build Coastguard Worker const unsigned int data_len)
98*cf84ac9aSAndroid Build Coastguard Worker {
99*cf84ac9aSAndroid Build Coastguard Worker print_quoted_string(cmsg_data, data_len, 0);
100*cf84ac9aSAndroid Build Coastguard Worker }
101*cf84ac9aSAndroid Build Coastguard Worker
102*cf84ac9aSAndroid Build Coastguard Worker static void
print_scm_timestamp(struct tcb * tcp,const void * cmsg_data,const unsigned int data_len)103*cf84ac9aSAndroid Build Coastguard Worker print_scm_timestamp(struct tcb *tcp, const void *cmsg_data,
104*cf84ac9aSAndroid Build Coastguard Worker const unsigned int data_len)
105*cf84ac9aSAndroid Build Coastguard Worker {
106*cf84ac9aSAndroid Build Coastguard Worker print_struct_timeval_data_size(cmsg_data, data_len);
107*cf84ac9aSAndroid Build Coastguard Worker }
108*cf84ac9aSAndroid Build Coastguard Worker
109*cf84ac9aSAndroid Build Coastguard Worker static void
print_scm_timestampns(struct tcb * tcp,const void * cmsg_data,const unsigned int data_len)110*cf84ac9aSAndroid Build Coastguard Worker print_scm_timestampns(struct tcb *tcp, const void *cmsg_data,
111*cf84ac9aSAndroid Build Coastguard Worker const unsigned int data_len)
112*cf84ac9aSAndroid Build Coastguard Worker {
113*cf84ac9aSAndroid Build Coastguard Worker print_struct_timespec_data_size(cmsg_data, data_len);
114*cf84ac9aSAndroid Build Coastguard Worker }
115*cf84ac9aSAndroid Build Coastguard Worker
116*cf84ac9aSAndroid Build Coastguard Worker static void
print_scm_timestamping(struct tcb * tcp,const void * cmsg_data,const unsigned int data_len)117*cf84ac9aSAndroid Build Coastguard Worker print_scm_timestamping(struct tcb *tcp, const void *cmsg_data,
118*cf84ac9aSAndroid Build Coastguard Worker const unsigned int data_len)
119*cf84ac9aSAndroid Build Coastguard Worker {
120*cf84ac9aSAndroid Build Coastguard Worker print_struct_timespec_array_data_size(cmsg_data, 3, data_len);
121*cf84ac9aSAndroid Build Coastguard Worker }
122*cf84ac9aSAndroid Build Coastguard Worker
123*cf84ac9aSAndroid Build Coastguard Worker static void
print_cmsg_ip_pktinfo(struct tcb * tcp,const void * cmsg_data,const unsigned int data_len)124*cf84ac9aSAndroid Build Coastguard Worker print_cmsg_ip_pktinfo(struct tcb *tcp, const void *cmsg_data,
125*cf84ac9aSAndroid Build Coastguard Worker const unsigned int data_len)
126*cf84ac9aSAndroid Build Coastguard Worker {
127*cf84ac9aSAndroid Build Coastguard Worker const struct in_pktinfo *info = cmsg_data;
128*cf84ac9aSAndroid Build Coastguard Worker
129*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_IFINDEX("{", *info, ipi_ifindex);
130*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_INET4_ADDR(", ", *info, ipi_spec_dst);
131*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_INET4_ADDR(", ", *info, ipi_addr);
132*cf84ac9aSAndroid Build Coastguard Worker tprints("}");
133*cf84ac9aSAndroid Build Coastguard Worker }
134*cf84ac9aSAndroid Build Coastguard Worker
135*cf84ac9aSAndroid Build Coastguard Worker static void
print_cmsg_uint(struct tcb * tcp,const void * cmsg_data,const unsigned int data_len)136*cf84ac9aSAndroid Build Coastguard Worker print_cmsg_uint(struct tcb *tcp, const void *cmsg_data,
137*cf84ac9aSAndroid Build Coastguard Worker const unsigned int data_len)
138*cf84ac9aSAndroid Build Coastguard Worker {
139*cf84ac9aSAndroid Build Coastguard Worker const unsigned int *p = cmsg_data;
140*cf84ac9aSAndroid Build Coastguard Worker
141*cf84ac9aSAndroid Build Coastguard Worker tprintf("[%u]", *p);
142*cf84ac9aSAndroid Build Coastguard Worker }
143*cf84ac9aSAndroid Build Coastguard Worker
144*cf84ac9aSAndroid Build Coastguard Worker static void
print_cmsg_uint8_t(struct tcb * tcp,const void * cmsg_data,const unsigned int data_len)145*cf84ac9aSAndroid Build Coastguard Worker print_cmsg_uint8_t(struct tcb *tcp, const void *cmsg_data,
146*cf84ac9aSAndroid Build Coastguard Worker const unsigned int data_len)
147*cf84ac9aSAndroid Build Coastguard Worker {
148*cf84ac9aSAndroid Build Coastguard Worker const uint8_t *p = cmsg_data;
149*cf84ac9aSAndroid Build Coastguard Worker
150*cf84ac9aSAndroid Build Coastguard Worker tprintf("[%#x]", *p);
151*cf84ac9aSAndroid Build Coastguard Worker }
152*cf84ac9aSAndroid Build Coastguard Worker
153*cf84ac9aSAndroid Build Coastguard Worker static void
print_cmsg_ip_opts(struct tcb * tcp,const void * cmsg_data,const unsigned int data_len)154*cf84ac9aSAndroid Build Coastguard Worker print_cmsg_ip_opts(struct tcb *tcp, const void *cmsg_data,
155*cf84ac9aSAndroid Build Coastguard Worker const unsigned int data_len)
156*cf84ac9aSAndroid Build Coastguard Worker {
157*cf84ac9aSAndroid Build Coastguard Worker const unsigned char *opts = cmsg_data;
158*cf84ac9aSAndroid Build Coastguard Worker unsigned int i;
159*cf84ac9aSAndroid Build Coastguard Worker
160*cf84ac9aSAndroid Build Coastguard Worker tprints("[");
161*cf84ac9aSAndroid Build Coastguard Worker for (i = 0; i < data_len; ++i) {
162*cf84ac9aSAndroid Build Coastguard Worker if (i)
163*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
164*cf84ac9aSAndroid Build Coastguard Worker if (abbrev(tcp) && i >= max_strlen) {
165*cf84ac9aSAndroid Build Coastguard Worker tprints("...");
166*cf84ac9aSAndroid Build Coastguard Worker break;
167*cf84ac9aSAndroid Build Coastguard Worker }
168*cf84ac9aSAndroid Build Coastguard Worker tprintf("0x%02x", opts[i]);
169*cf84ac9aSAndroid Build Coastguard Worker }
170*cf84ac9aSAndroid Build Coastguard Worker tprints("]");
171*cf84ac9aSAndroid Build Coastguard Worker }
172*cf84ac9aSAndroid Build Coastguard Worker
173*cf84ac9aSAndroid Build Coastguard Worker struct sock_ee {
174*cf84ac9aSAndroid Build Coastguard Worker uint32_t ee_errno;
175*cf84ac9aSAndroid Build Coastguard Worker uint8_t ee_origin;
176*cf84ac9aSAndroid Build Coastguard Worker uint8_t ee_type;
177*cf84ac9aSAndroid Build Coastguard Worker uint8_t ee_code;
178*cf84ac9aSAndroid Build Coastguard Worker uint8_t ee_pad;
179*cf84ac9aSAndroid Build Coastguard Worker uint32_t ee_info;
180*cf84ac9aSAndroid Build Coastguard Worker uint32_t ee_data;
181*cf84ac9aSAndroid Build Coastguard Worker struct sockaddr_in offender;
182*cf84ac9aSAndroid Build Coastguard Worker };
183*cf84ac9aSAndroid Build Coastguard Worker
184*cf84ac9aSAndroid Build Coastguard Worker static void
print_cmsg_ip_recverr(struct tcb * tcp,const void * cmsg_data,const unsigned int data_len)185*cf84ac9aSAndroid Build Coastguard Worker print_cmsg_ip_recverr(struct tcb *tcp, const void *cmsg_data,
186*cf84ac9aSAndroid Build Coastguard Worker const unsigned int data_len)
187*cf84ac9aSAndroid Build Coastguard Worker {
188*cf84ac9aSAndroid Build Coastguard Worker const struct sock_ee *const err = cmsg_data;
189*cf84ac9aSAndroid Build Coastguard Worker
190*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U("{", *err, ee_errno);
191*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *err, ee_origin);
192*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *err, ee_type);
193*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *err, ee_code);
194*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *err, ee_info);
195*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *err, ee_data);
196*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_SOCKADDR(", ", *err, offender);
197*cf84ac9aSAndroid Build Coastguard Worker tprints("}");
198*cf84ac9aSAndroid Build Coastguard Worker }
199*cf84ac9aSAndroid Build Coastguard Worker
200*cf84ac9aSAndroid Build Coastguard Worker static void
print_cmsg_ip_origdstaddr(struct tcb * tcp,const void * cmsg_data,const unsigned int data_len)201*cf84ac9aSAndroid Build Coastguard Worker print_cmsg_ip_origdstaddr(struct tcb *tcp, const void *cmsg_data,
202*cf84ac9aSAndroid Build Coastguard Worker const unsigned int data_len)
203*cf84ac9aSAndroid Build Coastguard Worker {
204*cf84ac9aSAndroid Build Coastguard Worker const unsigned int addr_len =
205*cf84ac9aSAndroid Build Coastguard Worker data_len > sizeof(struct sockaddr_storage)
206*cf84ac9aSAndroid Build Coastguard Worker ? sizeof(struct sockaddr_storage) : data_len;
207*cf84ac9aSAndroid Build Coastguard Worker
208*cf84ac9aSAndroid Build Coastguard Worker print_sockaddr(cmsg_data, addr_len);
209*cf84ac9aSAndroid Build Coastguard Worker }
210*cf84ac9aSAndroid Build Coastguard Worker
211*cf84ac9aSAndroid Build Coastguard Worker typedef void (* const cmsg_printer)(struct tcb *, const void *, unsigned int);
212*cf84ac9aSAndroid Build Coastguard Worker
213*cf84ac9aSAndroid Build Coastguard Worker static const struct {
214*cf84ac9aSAndroid Build Coastguard Worker const cmsg_printer printer;
215*cf84ac9aSAndroid Build Coastguard Worker const unsigned int min_len;
216*cf84ac9aSAndroid Build Coastguard Worker } cmsg_socket_printers[] = {
217*cf84ac9aSAndroid Build Coastguard Worker [SCM_RIGHTS] = { print_scm_rights, sizeof(int) },
218*cf84ac9aSAndroid Build Coastguard Worker [SCM_CREDENTIALS] = { print_scm_creds, sizeof(struct ucred) },
219*cf84ac9aSAndroid Build Coastguard Worker [SCM_SECURITY] = { print_scm_security, 1 },
220*cf84ac9aSAndroid Build Coastguard Worker [SCM_TIMESTAMP] = { print_scm_timestamp, 1 },
221*cf84ac9aSAndroid Build Coastguard Worker [SCM_TIMESTAMPNS] = { print_scm_timestampns, 1 },
222*cf84ac9aSAndroid Build Coastguard Worker [SCM_TIMESTAMPING] = { print_scm_timestamping, 1 }
223*cf84ac9aSAndroid Build Coastguard Worker }, cmsg_ip_printers[] = {
224*cf84ac9aSAndroid Build Coastguard Worker [IP_PKTINFO] = { print_cmsg_ip_pktinfo, sizeof(struct in_pktinfo) },
225*cf84ac9aSAndroid Build Coastguard Worker [IP_TTL] = { print_cmsg_uint, sizeof(unsigned int) },
226*cf84ac9aSAndroid Build Coastguard Worker [IP_TOS] = { print_cmsg_uint8_t, 1 },
227*cf84ac9aSAndroid Build Coastguard Worker [IP_RECVOPTS] = { print_cmsg_ip_opts, 1 },
228*cf84ac9aSAndroid Build Coastguard Worker [IP_RETOPTS] = { print_cmsg_ip_opts, 1 },
229*cf84ac9aSAndroid Build Coastguard Worker [IP_RECVERR] = { print_cmsg_ip_recverr, sizeof(struct sock_ee) },
230*cf84ac9aSAndroid Build Coastguard Worker [IP_ORIGDSTADDR] = { print_cmsg_ip_origdstaddr, sizeof(struct sockaddr_in) },
231*cf84ac9aSAndroid Build Coastguard Worker [IP_CHECKSUM] = { print_cmsg_uint, sizeof(unsigned int) },
232*cf84ac9aSAndroid Build Coastguard Worker [SCM_SECURITY] = { print_scm_security, 1 }
233*cf84ac9aSAndroid Build Coastguard Worker };
234*cf84ac9aSAndroid Build Coastguard Worker
235*cf84ac9aSAndroid Build Coastguard Worker static void
print_cmsg_type_data(struct tcb * tcp,const int cmsg_level,const int cmsg_type,const void * cmsg_data,const unsigned int data_len)236*cf84ac9aSAndroid Build Coastguard Worker print_cmsg_type_data(struct tcb *tcp, const int cmsg_level, const int cmsg_type,
237*cf84ac9aSAndroid Build Coastguard Worker const void *cmsg_data, const unsigned int data_len)
238*cf84ac9aSAndroid Build Coastguard Worker {
239*cf84ac9aSAndroid Build Coastguard Worker const unsigned int utype = cmsg_type;
240*cf84ac9aSAndroid Build Coastguard Worker switch (cmsg_level) {
241*cf84ac9aSAndroid Build Coastguard Worker case SOL_SOCKET:
242*cf84ac9aSAndroid Build Coastguard Worker printxval(scmvals, cmsg_type, "SCM_???");
243*cf84ac9aSAndroid Build Coastguard Worker if (utype < ARRAY_SIZE(cmsg_socket_printers)
244*cf84ac9aSAndroid Build Coastguard Worker && cmsg_socket_printers[utype].printer
245*cf84ac9aSAndroid Build Coastguard Worker && data_len >= cmsg_socket_printers[utype].min_len) {
246*cf84ac9aSAndroid Build Coastguard Worker tprints(", cmsg_data=");
247*cf84ac9aSAndroid Build Coastguard Worker cmsg_socket_printers[utype].printer(tcp, cmsg_data, data_len);
248*cf84ac9aSAndroid Build Coastguard Worker }
249*cf84ac9aSAndroid Build Coastguard Worker break;
250*cf84ac9aSAndroid Build Coastguard Worker case SOL_IP:
251*cf84ac9aSAndroid Build Coastguard Worker printxval(ip_cmsg_types, cmsg_type, "IP_???");
252*cf84ac9aSAndroid Build Coastguard Worker if (utype < ARRAY_SIZE(cmsg_ip_printers)
253*cf84ac9aSAndroid Build Coastguard Worker && cmsg_ip_printers[utype].printer
254*cf84ac9aSAndroid Build Coastguard Worker && data_len >= cmsg_ip_printers[utype].min_len) {
255*cf84ac9aSAndroid Build Coastguard Worker tprints(", cmsg_data=");
256*cf84ac9aSAndroid Build Coastguard Worker cmsg_ip_printers[utype].printer(tcp, cmsg_data, data_len);
257*cf84ac9aSAndroid Build Coastguard Worker }
258*cf84ac9aSAndroid Build Coastguard Worker break;
259*cf84ac9aSAndroid Build Coastguard Worker default:
260*cf84ac9aSAndroid Build Coastguard Worker tprintf("%#x", cmsg_type);
261*cf84ac9aSAndroid Build Coastguard Worker }
262*cf84ac9aSAndroid Build Coastguard Worker }
263*cf84ac9aSAndroid Build Coastguard Worker
264*cf84ac9aSAndroid Build Coastguard Worker static unsigned int
get_optmem_max(struct tcb * tcp)265*cf84ac9aSAndroid Build Coastguard Worker get_optmem_max(struct tcb *tcp)
266*cf84ac9aSAndroid Build Coastguard Worker {
267*cf84ac9aSAndroid Build Coastguard Worker static int optmem_max;
268*cf84ac9aSAndroid Build Coastguard Worker
269*cf84ac9aSAndroid Build Coastguard Worker if (!optmem_max) {
270*cf84ac9aSAndroid Build Coastguard Worker if (read_int_from_file(tcp, "/proc/sys/net/core/optmem_max",
271*cf84ac9aSAndroid Build Coastguard Worker &optmem_max) || optmem_max <= 0) {
272*cf84ac9aSAndroid Build Coastguard Worker optmem_max = sizeof(long long) * (2 * IOV_MAX + 512);
273*cf84ac9aSAndroid Build Coastguard Worker } else {
274*cf84ac9aSAndroid Build Coastguard Worker optmem_max = (optmem_max + sizeof(long long) - 1)
275*cf84ac9aSAndroid Build Coastguard Worker & ~(sizeof(long long) - 1);
276*cf84ac9aSAndroid Build Coastguard Worker }
277*cf84ac9aSAndroid Build Coastguard Worker }
278*cf84ac9aSAndroid Build Coastguard Worker
279*cf84ac9aSAndroid Build Coastguard Worker return optmem_max;
280*cf84ac9aSAndroid Build Coastguard Worker }
281*cf84ac9aSAndroid Build Coastguard Worker
282*cf84ac9aSAndroid Build Coastguard Worker static void
decode_msg_control(struct tcb * const tcp,const kernel_ulong_t addr,const kernel_ulong_t in_control_len)283*cf84ac9aSAndroid Build Coastguard Worker decode_msg_control(struct tcb *const tcp, const kernel_ulong_t addr,
284*cf84ac9aSAndroid Build Coastguard Worker const kernel_ulong_t in_control_len)
285*cf84ac9aSAndroid Build Coastguard Worker {
286*cf84ac9aSAndroid Build Coastguard Worker if (!in_control_len)
287*cf84ac9aSAndroid Build Coastguard Worker return;
288*cf84ac9aSAndroid Build Coastguard Worker tprints(", msg_control=");
289*cf84ac9aSAndroid Build Coastguard Worker
290*cf84ac9aSAndroid Build Coastguard Worker const unsigned int cmsg_size =
291*cf84ac9aSAndroid Build Coastguard Worker #ifndef current_wordsize
292*cf84ac9aSAndroid Build Coastguard Worker (current_wordsize < sizeof(long)) ? sizeof(struct cmsghdr32) :
293*cf84ac9aSAndroid Build Coastguard Worker #endif
294*cf84ac9aSAndroid Build Coastguard Worker sizeof(struct cmsghdr);
295*cf84ac9aSAndroid Build Coastguard Worker
296*cf84ac9aSAndroid Build Coastguard Worker unsigned int control_len = in_control_len > get_optmem_max(tcp)
297*cf84ac9aSAndroid Build Coastguard Worker ? get_optmem_max(tcp) : in_control_len;
298*cf84ac9aSAndroid Build Coastguard Worker unsigned int buf_len = control_len;
299*cf84ac9aSAndroid Build Coastguard Worker char *buf = buf_len < cmsg_size ? NULL : malloc(buf_len);
300*cf84ac9aSAndroid Build Coastguard Worker if (!buf || umoven(tcp, addr, buf_len, buf) < 0) {
301*cf84ac9aSAndroid Build Coastguard Worker printaddr(addr);
302*cf84ac9aSAndroid Build Coastguard Worker free(buf);
303*cf84ac9aSAndroid Build Coastguard Worker return;
304*cf84ac9aSAndroid Build Coastguard Worker }
305*cf84ac9aSAndroid Build Coastguard Worker
306*cf84ac9aSAndroid Build Coastguard Worker union_cmsghdr u = { .ptr = buf };
307*cf84ac9aSAndroid Build Coastguard Worker
308*cf84ac9aSAndroid Build Coastguard Worker tprints("[");
309*cf84ac9aSAndroid Build Coastguard Worker while (buf_len >= cmsg_size) {
310*cf84ac9aSAndroid Build Coastguard Worker const kernel_ulong_t cmsg_len =
311*cf84ac9aSAndroid Build Coastguard Worker #ifndef current_wordsize
312*cf84ac9aSAndroid Build Coastguard Worker (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_len :
313*cf84ac9aSAndroid Build Coastguard Worker #endif
314*cf84ac9aSAndroid Build Coastguard Worker u.cmsg->cmsg_len;
315*cf84ac9aSAndroid Build Coastguard Worker const int cmsg_level =
316*cf84ac9aSAndroid Build Coastguard Worker #ifndef current_wordsize
317*cf84ac9aSAndroid Build Coastguard Worker (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_level :
318*cf84ac9aSAndroid Build Coastguard Worker #endif
319*cf84ac9aSAndroid Build Coastguard Worker u.cmsg->cmsg_level;
320*cf84ac9aSAndroid Build Coastguard Worker const int cmsg_type =
321*cf84ac9aSAndroid Build Coastguard Worker #ifndef current_wordsize
322*cf84ac9aSAndroid Build Coastguard Worker (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_type :
323*cf84ac9aSAndroid Build Coastguard Worker #endif
324*cf84ac9aSAndroid Build Coastguard Worker u.cmsg->cmsg_type;
325*cf84ac9aSAndroid Build Coastguard Worker
326*cf84ac9aSAndroid Build Coastguard Worker if (u.ptr != buf)
327*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
328*cf84ac9aSAndroid Build Coastguard Worker tprintf("{cmsg_len=%" PRI_klu ", cmsg_level=", cmsg_len);
329*cf84ac9aSAndroid Build Coastguard Worker printxval(socketlayers, cmsg_level, "SOL_???");
330*cf84ac9aSAndroid Build Coastguard Worker tprints(", cmsg_type=");
331*cf84ac9aSAndroid Build Coastguard Worker
332*cf84ac9aSAndroid Build Coastguard Worker kernel_ulong_t len = cmsg_len > buf_len ? buf_len : cmsg_len;
333*cf84ac9aSAndroid Build Coastguard Worker
334*cf84ac9aSAndroid Build Coastguard Worker print_cmsg_type_data(tcp, cmsg_level, cmsg_type,
335*cf84ac9aSAndroid Build Coastguard Worker (const void *) (u.ptr + cmsg_size),
336*cf84ac9aSAndroid Build Coastguard Worker len > cmsg_size ? len - cmsg_size : 0);
337*cf84ac9aSAndroid Build Coastguard Worker tprints("}");
338*cf84ac9aSAndroid Build Coastguard Worker
339*cf84ac9aSAndroid Build Coastguard Worker if (len < cmsg_size) {
340*cf84ac9aSAndroid Build Coastguard Worker buf_len -= cmsg_size;
341*cf84ac9aSAndroid Build Coastguard Worker break;
342*cf84ac9aSAndroid Build Coastguard Worker }
343*cf84ac9aSAndroid Build Coastguard Worker len = (cmsg_len + current_wordsize - 1) &
344*cf84ac9aSAndroid Build Coastguard Worker ~((kernel_ulong_t) current_wordsize - 1);
345*cf84ac9aSAndroid Build Coastguard Worker if (len >= buf_len) {
346*cf84ac9aSAndroid Build Coastguard Worker buf_len = 0;
347*cf84ac9aSAndroid Build Coastguard Worker break;
348*cf84ac9aSAndroid Build Coastguard Worker }
349*cf84ac9aSAndroid Build Coastguard Worker u.ptr += len;
350*cf84ac9aSAndroid Build Coastguard Worker buf_len -= len;
351*cf84ac9aSAndroid Build Coastguard Worker }
352*cf84ac9aSAndroid Build Coastguard Worker if (buf_len) {
353*cf84ac9aSAndroid Build Coastguard Worker tprints(", ...");
354*cf84ac9aSAndroid Build Coastguard Worker printaddr_comment(addr + (control_len - buf_len));
355*cf84ac9aSAndroid Build Coastguard Worker } else if (control_len < in_control_len) {
356*cf84ac9aSAndroid Build Coastguard Worker tprints(", ...");
357*cf84ac9aSAndroid Build Coastguard Worker }
358*cf84ac9aSAndroid Build Coastguard Worker tprints("]");
359*cf84ac9aSAndroid Build Coastguard Worker free(buf);
360*cf84ac9aSAndroid Build Coastguard Worker }
361*cf84ac9aSAndroid Build Coastguard Worker
362*cf84ac9aSAndroid Build Coastguard Worker void
print_struct_msghdr(struct tcb * tcp,const struct msghdr * msg,const int * const p_user_msg_namelen,const kernel_ulong_t data_size)363*cf84ac9aSAndroid Build Coastguard Worker print_struct_msghdr(struct tcb *tcp, const struct msghdr *msg,
364*cf84ac9aSAndroid Build Coastguard Worker const int *const p_user_msg_namelen,
365*cf84ac9aSAndroid Build Coastguard Worker const kernel_ulong_t data_size)
366*cf84ac9aSAndroid Build Coastguard Worker {
367*cf84ac9aSAndroid Build Coastguard Worker const int msg_namelen =
368*cf84ac9aSAndroid Build Coastguard Worker p_user_msg_namelen && (int) msg->msg_namelen > *p_user_msg_namelen
369*cf84ac9aSAndroid Build Coastguard Worker ? *p_user_msg_namelen : (int) msg->msg_namelen;
370*cf84ac9aSAndroid Build Coastguard Worker
371*cf84ac9aSAndroid Build Coastguard Worker tprints("{msg_name=");
372*cf84ac9aSAndroid Build Coastguard Worker const int family =
373*cf84ac9aSAndroid Build Coastguard Worker decode_sockaddr(tcp, ptr_to_kulong(msg->msg_name), msg_namelen);
374*cf84ac9aSAndroid Build Coastguard Worker const enum iov_decode decode =
375*cf84ac9aSAndroid Build Coastguard Worker (family == AF_NETLINK) ? IOV_DECODE_NETLINK : IOV_DECODE_STR;
376*cf84ac9aSAndroid Build Coastguard Worker
377*cf84ac9aSAndroid Build Coastguard Worker tprints(", msg_namelen=");
378*cf84ac9aSAndroid Build Coastguard Worker if (p_user_msg_namelen && *p_user_msg_namelen != (int) msg->msg_namelen)
379*cf84ac9aSAndroid Build Coastguard Worker tprintf("%d->", *p_user_msg_namelen);
380*cf84ac9aSAndroid Build Coastguard Worker tprintf("%d", msg->msg_namelen);
381*cf84ac9aSAndroid Build Coastguard Worker
382*cf84ac9aSAndroid Build Coastguard Worker tprints(", msg_iov=");
383*cf84ac9aSAndroid Build Coastguard Worker tprint_iov_upto(tcp, msg->msg_iovlen,
384*cf84ac9aSAndroid Build Coastguard Worker ptr_to_kulong(msg->msg_iov), decode, data_size);
385*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *msg, msg_iovlen);
386*cf84ac9aSAndroid Build Coastguard Worker
387*cf84ac9aSAndroid Build Coastguard Worker decode_msg_control(tcp, ptr_to_kulong(msg->msg_control),
388*cf84ac9aSAndroid Build Coastguard Worker msg->msg_controllen);
389*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_U(", ", *msg, msg_controllen);
390*cf84ac9aSAndroid Build Coastguard Worker
391*cf84ac9aSAndroid Build Coastguard Worker PRINT_FIELD_FLAGS(", ", *msg, msg_flags, msg_flags, "MSG_???");
392*cf84ac9aSAndroid Build Coastguard Worker tprints("}");
393*cf84ac9aSAndroid Build Coastguard Worker }
394*cf84ac9aSAndroid Build Coastguard Worker
395*cf84ac9aSAndroid Build Coastguard Worker static bool
fetch_msghdr_namelen(struct tcb * const tcp,const kernel_ulong_t addr,int * const p_msg_namelen)396*cf84ac9aSAndroid Build Coastguard Worker fetch_msghdr_namelen(struct tcb *const tcp, const kernel_ulong_t addr,
397*cf84ac9aSAndroid Build Coastguard Worker int *const p_msg_namelen)
398*cf84ac9aSAndroid Build Coastguard Worker {
399*cf84ac9aSAndroid Build Coastguard Worker struct msghdr msg;
400*cf84ac9aSAndroid Build Coastguard Worker
401*cf84ac9aSAndroid Build Coastguard Worker if (addr && verbose(tcp) && fetch_struct_msghdr(tcp, addr, &msg)) {
402*cf84ac9aSAndroid Build Coastguard Worker *p_msg_namelen = msg.msg_namelen;
403*cf84ac9aSAndroid Build Coastguard Worker return true;
404*cf84ac9aSAndroid Build Coastguard Worker } else {
405*cf84ac9aSAndroid Build Coastguard Worker return false;
406*cf84ac9aSAndroid Build Coastguard Worker }
407*cf84ac9aSAndroid Build Coastguard Worker }
408*cf84ac9aSAndroid Build Coastguard Worker
409*cf84ac9aSAndroid Build Coastguard Worker static void
decode_msghdr(struct tcb * const tcp,const int * const p_user_msg_namelen,const kernel_ulong_t addr,const kernel_ulong_t data_size)410*cf84ac9aSAndroid Build Coastguard Worker decode_msghdr(struct tcb *const tcp, const int *const p_user_msg_namelen,
411*cf84ac9aSAndroid Build Coastguard Worker const kernel_ulong_t addr, const kernel_ulong_t data_size)
412*cf84ac9aSAndroid Build Coastguard Worker {
413*cf84ac9aSAndroid Build Coastguard Worker struct msghdr msg;
414*cf84ac9aSAndroid Build Coastguard Worker
415*cf84ac9aSAndroid Build Coastguard Worker if (addr && verbose(tcp) && fetch_struct_msghdr(tcp, addr, &msg))
416*cf84ac9aSAndroid Build Coastguard Worker print_struct_msghdr(tcp, &msg, p_user_msg_namelen, data_size);
417*cf84ac9aSAndroid Build Coastguard Worker else
418*cf84ac9aSAndroid Build Coastguard Worker printaddr(addr);
419*cf84ac9aSAndroid Build Coastguard Worker }
420*cf84ac9aSAndroid Build Coastguard Worker
421*cf84ac9aSAndroid Build Coastguard Worker void
dumpiov_in_msghdr(struct tcb * const tcp,const kernel_ulong_t addr,const kernel_ulong_t data_size)422*cf84ac9aSAndroid Build Coastguard Worker dumpiov_in_msghdr(struct tcb *const tcp, const kernel_ulong_t addr,
423*cf84ac9aSAndroid Build Coastguard Worker const kernel_ulong_t data_size)
424*cf84ac9aSAndroid Build Coastguard Worker {
425*cf84ac9aSAndroid Build Coastguard Worker struct msghdr msg;
426*cf84ac9aSAndroid Build Coastguard Worker
427*cf84ac9aSAndroid Build Coastguard Worker if (fetch_struct_msghdr(tcp, addr, &msg)) {
428*cf84ac9aSAndroid Build Coastguard Worker dumpiov_upto(tcp, msg.msg_iovlen,
429*cf84ac9aSAndroid Build Coastguard Worker ptr_to_kulong(msg.msg_iov), data_size);
430*cf84ac9aSAndroid Build Coastguard Worker }
431*cf84ac9aSAndroid Build Coastguard Worker }
432*cf84ac9aSAndroid Build Coastguard Worker
SYS_FUNC(sendmsg)433*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(sendmsg)
434*cf84ac9aSAndroid Build Coastguard Worker {
435*cf84ac9aSAndroid Build Coastguard Worker printfd(tcp, tcp->u_arg[0]);
436*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
437*cf84ac9aSAndroid Build Coastguard Worker decode_msghdr(tcp, 0, tcp->u_arg[1], -1);
438*cf84ac9aSAndroid Build Coastguard Worker /* flags */
439*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
440*cf84ac9aSAndroid Build Coastguard Worker printflags(msg_flags, tcp->u_arg[2], "MSG_???");
441*cf84ac9aSAndroid Build Coastguard Worker
442*cf84ac9aSAndroid Build Coastguard Worker return RVAL_DECODED;
443*cf84ac9aSAndroid Build Coastguard Worker }
444*cf84ac9aSAndroid Build Coastguard Worker
SYS_FUNC(recvmsg)445*cf84ac9aSAndroid Build Coastguard Worker SYS_FUNC(recvmsg)
446*cf84ac9aSAndroid Build Coastguard Worker {
447*cf84ac9aSAndroid Build Coastguard Worker int msg_namelen;
448*cf84ac9aSAndroid Build Coastguard Worker
449*cf84ac9aSAndroid Build Coastguard Worker if (entering(tcp)) {
450*cf84ac9aSAndroid Build Coastguard Worker printfd(tcp, tcp->u_arg[0]);
451*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
452*cf84ac9aSAndroid Build Coastguard Worker if (fetch_msghdr_namelen(tcp, tcp->u_arg[1], &msg_namelen)) {
453*cf84ac9aSAndroid Build Coastguard Worker set_tcb_priv_ulong(tcp, msg_namelen);
454*cf84ac9aSAndroid Build Coastguard Worker return 0;
455*cf84ac9aSAndroid Build Coastguard Worker }
456*cf84ac9aSAndroid Build Coastguard Worker printaddr(tcp->u_arg[1]);
457*cf84ac9aSAndroid Build Coastguard Worker } else {
458*cf84ac9aSAndroid Build Coastguard Worker msg_namelen = get_tcb_priv_ulong(tcp);
459*cf84ac9aSAndroid Build Coastguard Worker
460*cf84ac9aSAndroid Build Coastguard Worker if (syserror(tcp))
461*cf84ac9aSAndroid Build Coastguard Worker tprintf("{msg_namelen=%d}", msg_namelen);
462*cf84ac9aSAndroid Build Coastguard Worker else
463*cf84ac9aSAndroid Build Coastguard Worker decode_msghdr(tcp, &msg_namelen, tcp->u_arg[1],
464*cf84ac9aSAndroid Build Coastguard Worker tcp->u_rval);
465*cf84ac9aSAndroid Build Coastguard Worker }
466*cf84ac9aSAndroid Build Coastguard Worker
467*cf84ac9aSAndroid Build Coastguard Worker /* flags */
468*cf84ac9aSAndroid Build Coastguard Worker tprints(", ");
469*cf84ac9aSAndroid Build Coastguard Worker printflags(msg_flags, tcp->u_arg[2], "MSG_???");
470*cf84ac9aSAndroid Build Coastguard Worker
471*cf84ac9aSAndroid Build Coastguard Worker return RVAL_DECODED;
472*cf84ac9aSAndroid Build Coastguard Worker }
473