blob: 7616a5b93a8ee7d6ad16578b6701310460de869c [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
Wichert Akkerman7987cdf2000-07-05 16:05:39 +00005 * Copyright (c) 1996-2000 Wichert Akkerman <wichert@cistron.nl>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00006 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000029 */
30
31#include "defs.h"
Dmitry V. Levin4b38ce92016-06-27 00:02:41 +000032#include "msghdr.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000033#include <sys/stat.h>
34#include <sys/socket.h>
Dmitry V. Levinb2fa2be2014-11-21 20:46:16 +000035#include <sys/uio.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000036#include <sys/un.h>
37#include <netinet/in.h>
Wichert Akkerman8c7122c2001-02-16 19:59:55 +000038#ifdef HAVE_NETINET_TCP_H
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010039# include <netinet/tcp.h>
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000040#endif
Wichert Akkerman8c7122c2001-02-16 19:59:55 +000041#ifdef HAVE_NETINET_UDP_H
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010042# include <netinet/udp.h>
Wichert Akkerman8c7122c2001-02-16 19:59:55 +000043#endif
Holger Hans Peter Freyther7fea79b2011-01-14 11:08:12 +010044#ifdef HAVE_NETINET_SCTP_H
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010045# include <netinet/sctp.h>
Holger Hans Peter Freyther7fea79b2011-01-14 11:08:12 +010046#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000047#include <arpa/inet.h>
Wichert Akkermanf1850652001-02-16 20:29:03 +000048#include <net/if.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000049#include <asm/types.h>
Dmitry V. Levinebda41a2016-06-19 22:02:45 +000050#ifdef HAVE_NETIPX_IPX_H
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010051# include <netipx/ipx.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000052#else
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010053# include <linux/ipx.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000054#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000055
Mike Frysinger54646b82015-08-19 13:29:27 -040056#if defined(HAVE_LINUX_IP_VS_H)
57# include <linux/ip_vs.h>
58#endif
Dmitry V. Levinb10ee4e2016-06-14 13:53:47 +000059#include <linux/netlink.h>
Mike Frysinger54646b82015-08-19 13:29:27 -040060#if defined(HAVE_LINUX_NETFILTER_ARP_ARP_TABLES_H)
61# include <linux/netfilter_arp/arp_tables.h>
62#endif
63#if defined(HAVE_LINUX_NETFILTER_BRIDGE_EBTABLES_H)
64# include <linux/netfilter_bridge/ebtables.h>
65#endif
66#if defined(HAVE_LINUX_NETFILTER_IPV4_IP_TABLES_H)
67# include <linux/netfilter_ipv4/ip_tables.h>
68#endif
69#if defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H)
70# include <linux/netfilter_ipv6/ip6_tables.h>
71#endif
Dmitry V. Levin4f689a12016-06-15 21:35:48 +000072#include <linux/if_packet.h>
Dmitry V. Levind06010b2016-06-15 21:27:41 +000073#include <linux/icmp.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000074
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000075#include "xlat/socktypes.h"
76#include "xlat/sock_type_flags.h"
Dmitry V. Levin8a550d72008-11-10 17:21:23 +000077#ifndef SOCK_TYPE_MASK
78# define SOCK_TYPE_MASK 0xf
79#endif
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +000080
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000081#include "xlat/socketlayers.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +000082
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000083#include "xlat/inet_protocols.h"
Masatake YAMATO2394a3d2014-03-11 23:37:37 +090084
Dmitry V. Levin94573042016-06-14 13:53:47 +000085#if !defined NETLINK_SOCK_DIAG && defined NETLINK_INET_DIAG
86# define NETLINK_SOCK_DIAG NETLINK_INET_DIAG
Masatake YAMATO2394a3d2014-03-11 23:37:37 +090087#endif
Dmitry V. Levin94573042016-06-14 13:53:47 +000088#include "xlat/netlink_protocols.h"
Masatake YAMATO2394a3d2014-03-11 23:37:37 +090089
Dmitry V. Levine96aee72016-06-25 13:47:54 +000090#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
91# include <bluetooth/bluetooth.h>
Lubomir Rintelc400a1c2014-10-03 11:40:28 +020092# include "xlat/bt_protocols.h"
93#endif
94
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000095#include "xlat/msg_flags.h"
Wichert Akkerman7987cdf2000-07-05 16:05:39 +000096
Dmitry V. Levin45ae9372016-06-23 17:38:18 +000097void
Dmitry V. Levinae280932015-06-05 20:13:21 +000098print_ifindex(unsigned int ifindex)
99{
100#ifdef HAVE_IF_INDEXTONAME
101 char buf[IFNAMSIZ + 1];
102
103 if (if_indextoname(ifindex, buf)) {
104 tprints("if_nametoindex(");
105 print_quoted_string(buf, sizeof(buf), QUOTE_0_TERMINATED);
106 tprints(")");
107 return;
108 }
109#endif
110 tprintf("%u", ifindex);
111}
112
Dmitry V. Levinb36d1322015-11-18 23:18:17 +0000113#include "xlat/scmvals.h"
Dmitry V. Levin1f111cf2015-11-21 03:03:54 +0300114#include "xlat/ip_cmsg_types.h"
Roland McGrath50770822004-10-06 22:11:51 +0000115
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000116#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
117struct cmsghdr32 {
118 uint32_t cmsg_len;
119 int cmsg_level;
120 int cmsg_type;
121};
122#endif
123
124typedef union {
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000125 char *ptr;
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000126 struct cmsghdr *cmsg;
127#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
128 struct cmsghdr32 *cmsg32;
129#endif
130} union_cmsghdr;
131
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000132static void
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000133print_scm_rights(struct tcb *tcp, const void *cmsg_data,
134 const size_t data_len)
Roland McGrath50770822004-10-06 22:11:51 +0000135{
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000136 const int *fds = cmsg_data;
137 const char *end = (const char *) cmsg_data + data_len;
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000138 bool seen = false;
139
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000140 if (sizeof(*fds) > data_len)
141 return;
142
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000143 tprints(", [");
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000144 while ((const char *) fds < end) {
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000145 if (seen)
146 tprints(", ");
147 else
148 seen = true;
149 printfd(tcp, *fds++);
150 }
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000151 tprints("]");
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000152}
153
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000154static void
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000155print_scm_creds(struct tcb *tcp, const void *cmsg_data,
156 const size_t data_len)
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000157{
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000158 const struct ucred *uc = cmsg_data;
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000159
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000160 if (sizeof(*uc) > data_len)
161 return;
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000162
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000163 tprintf(", {pid=%u, uid=%u, gid=%u}",
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000164 (unsigned) uc->pid, (unsigned) uc->uid, (unsigned) uc->gid);
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000165}
166
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000167static void
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000168print_scm_security(struct tcb *tcp, const void *cmsg_data,
169 const size_t data_len)
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000170{
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000171 if (!data_len)
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000172 return;
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000173
Dmitry V. Levin513e96e2015-01-26 01:17:08 +0000174 tprints(", ");
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000175 print_quoted_string(cmsg_data, data_len, 0);
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000176}
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000177
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000178static void
Dmitry V. Levin1f111cf2015-11-21 03:03:54 +0300179print_cmsg_ip_pktinfo(struct tcb *tcp, const void *cmsg_data,
180 const size_t data_len)
181{
182 const struct in_pktinfo *info = cmsg_data;
183
184 if (sizeof(*info) > data_len)
185 return;
186
187 tprints(", {ipi_ifindex=");
188 print_ifindex(info->ipi_ifindex);
189 tprintf(", ipi_spec_dst=inet_addr(\"%s\"), ipi_addr=inet_addr(\"%s\")}",
190 inet_ntoa(info->ipi_spec_dst), inet_ntoa(info->ipi_addr));
191}
192
193static void
194print_cmsg_ip_ttl(struct tcb *tcp, const void *cmsg_data,
195 const size_t data_len)
196{
197 const unsigned int *ttl = cmsg_data;
198
199 if (sizeof(*ttl) > data_len)
200 return;
201
202 tprintf(", {ttl=%u}", *ttl);
203}
204
205static void
206print_cmsg_ip_tos(struct tcb *tcp, const void *cmsg_data,
207 const size_t data_len)
208{
209 const uint8_t *tos = cmsg_data;
210
211 if (sizeof(*tos) > data_len)
212 return;
213
214 tprintf(", {tos=%x}", *tos);
215}
216
217static void
218print_cmsg_ip_checksum(struct tcb *tcp, const void *cmsg_data,
219 const size_t data_len)
220{
221 const uint32_t *csum = cmsg_data;
222
223 if (sizeof(*csum) > data_len)
224 return;
225
226 tprintf(", {csum=%u}", *csum);
227}
228
229static void
230print_cmsg_ip_opts(struct tcb *tcp, const void *cmsg_data,
231 const size_t data_len)
232{
Dmitry V. Levina17f5932015-11-22 23:07:52 +0000233 const unsigned char *opts = cmsg_data;
Dmitry V. Levin1f111cf2015-11-21 03:03:54 +0300234 size_t i;
235
236 if (!data_len)
237 return;
238
239 tprints(", {opts=0x");
240 for (i = 0; i < data_len; ++i)
241 tprintf("%02x", opts[i]);
242 tprints("}");
243}
244
245static void
246print_cmsg_ip_recverr(struct tcb *tcp, const void *cmsg_data,
247 const size_t data_len)
248{
249 const struct {
250 uint32_t ee_errno;
251 uint8_t ee_origin;
252 uint8_t ee_type;
253 uint8_t ee_code;
254 uint8_t ee_pad;
255 uint32_t ee_info;
256 uint32_t ee_data;
257 struct sockaddr_in offender;
258 } *err = cmsg_data;
259
260 if (sizeof(*err) > data_len)
261 return;
262
263 tprintf(", {ee_errno=%u, ee_origin=%u, ee_type=%u, ee_code=%u"
264 ", ee_info=%u, ee_data=%u, offender=",
265 err->ee_errno, err->ee_origin, err->ee_type,
266 err->ee_code, err->ee_info, err->ee_data);
Dmitry V. Levin3bf9c192016-06-21 16:45:40 +0000267 print_sockaddr(tcp, &err->offender, sizeof(err->offender));
Dmitry V. Levin1f111cf2015-11-21 03:03:54 +0300268 tprints("}");
269}
270
271static void
272print_cmsg_ip_origdstaddr(struct tcb *tcp, const void *cmsg_data,
273 const size_t data_len)
274{
275 if (sizeof(struct sockaddr_in) > data_len)
276 return;
277
278 tprints(", ");
279 print_sockaddr(tcp, cmsg_data, data_len);
280}
281
282static void
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000283print_cmsg_type_data(struct tcb *tcp, const int cmsg_level, const int cmsg_type,
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000284 const void *cmsg_data, const size_t data_len)
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000285{
286 switch (cmsg_level) {
287 case SOL_SOCKET:
288 printxval(scmvals, cmsg_type, "SCM_???");
289 switch (cmsg_type) {
290 case SCM_RIGHTS:
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000291 print_scm_rights(tcp, cmsg_data, data_len);
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000292 break;
293 case SCM_CREDENTIALS:
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000294 print_scm_creds(tcp, cmsg_data, data_len);
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000295 break;
296 case SCM_SECURITY:
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000297 print_scm_security(tcp, cmsg_data, data_len);
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000298 break;
299 }
300 break;
Dmitry V. Levin1f111cf2015-11-21 03:03:54 +0300301 case SOL_IP:
302 printxval(ip_cmsg_types, cmsg_type, "IP_???");
303 switch (cmsg_type) {
304 case IP_PKTINFO:
305 print_cmsg_ip_pktinfo(tcp, cmsg_data, data_len);
306 break;
307 case IP_TTL:
308 print_cmsg_ip_ttl(tcp, cmsg_data, data_len);
309 break;
310 case IP_TOS:
311 print_cmsg_ip_tos(tcp, cmsg_data, data_len);
312 break;
313 case IP_RECVOPTS:
314 case IP_RETOPTS:
315 print_cmsg_ip_opts(tcp, cmsg_data, data_len);
316 break;
317 case IP_RECVERR:
318 print_cmsg_ip_recverr(tcp, cmsg_data, data_len);
319 break;
320 case IP_ORIGDSTADDR:
321 print_cmsg_ip_origdstaddr(tcp, cmsg_data, data_len);
322 break;
323 case IP_CHECKSUM:
324 print_cmsg_ip_checksum(tcp, cmsg_data, data_len);
325 break;
326 case SCM_SECURITY:
327 print_scm_security(tcp, cmsg_data, data_len);
328 break;
329 }
330 break;
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000331 default:
332 tprintf("%u", cmsg_type);
333 }
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000334}
335
336static void
Dmitry V. Levin3e514c02016-06-26 23:57:29 +0000337decode_msg_control(struct tcb *tcp, unsigned long addr, size_t len)
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000338{
339 const size_t cmsg_size =
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000340#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
341 (current_wordsize < sizeof(long)) ? sizeof(struct cmsghdr32) :
342#endif
343 sizeof(struct cmsghdr);
344
Dmitry V. Levin00ba20a2016-06-26 23:57:18 +0000345 if (!len)
346 return;
347 tprints(", msg_control=");
348
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000349 char *buf = len < cmsg_size ? NULL : malloc(len);
350 if (!buf || umoven(tcp, addr, len, buf) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000351 printaddr(addr);
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000352 free(buf);
Roland McGrath50770822004-10-06 22:11:51 +0000353 return;
354 }
355
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000356 union_cmsghdr u = { .ptr = buf };
357
Dmitry V. Levin00ba20a2016-06-26 23:57:18 +0000358 tprints("[");
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000359 while (len >= cmsg_size) {
360 size_t cmsg_len =
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000361#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000362 (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_len :
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000363#endif
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000364 u.cmsg->cmsg_len;
365 int cmsg_level =
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000366#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000367 (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_level :
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000368#endif
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000369 u.cmsg->cmsg_level;
370 int cmsg_type =
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000371#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000372 (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_type :
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000373#endif
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000374 u.cmsg->cmsg_type;
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000375
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000376 if (u.ptr != buf)
377 tprints(", ");
378 tprintf("{cmsg_len=%lu, cmsg_level=", (unsigned long) cmsg_len);
379 printxval(socketlayers, cmsg_level, "SOL_???");
380 tprints(", cmsg_type=");
Roland McGrath50770822004-10-06 22:11:51 +0000381
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000382 if (cmsg_len > len)
383 cmsg_len = len;
Roland McGrath96ad7b82005-02-02 03:11:32 +0000384
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000385 print_cmsg_type_data(tcp, cmsg_level, cmsg_type,
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000386 (const void *) (u.ptr + cmsg_size),
387 cmsg_len > cmsg_size ? cmsg_len - cmsg_size: 0);
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000388 tprints("}");
389
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000390 if (cmsg_len < cmsg_size) {
391 len -= cmsg_size;
392 break;
Roland McGrath50770822004-10-06 22:11:51 +0000393 }
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000394 cmsg_len = (cmsg_len + current_wordsize - 1) &
395 (size_t) ~(current_wordsize - 1);
396 if (cmsg_len >= len) {
397 len = 0;
398 break;
399 }
400 u.ptr += cmsg_len;
401 len -= cmsg_len;
Roland McGrath50770822004-10-06 22:11:51 +0000402 }
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000403 if (len)
404 tprints(", ...");
405 tprints("]");
406 free(buf);
Roland McGrath50770822004-10-06 22:11:51 +0000407}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000408
409static void
Dmitry V. Levin3e514c02016-06-26 23:57:29 +0000410print_msghdr(struct tcb *tcp, struct msghdr *msg, unsigned long data_size)
Andreas Schwab0873f292010-02-12 21:39:12 +0100411{
Dmitry V. Levin26f90af2016-06-26 23:57:39 +0000412 tprints("{msg_name=");
Dmitry V. Levin42e566a2016-06-25 11:31:48 +0000413 decode_sockaddr(tcp, (long)msg->msg_name, msg->msg_namelen);
Dmitry V. Levin26f90af2016-06-26 23:57:39 +0000414 tprintf(", msg_namelen=%d", msg->msg_namelen);
Andreas Schwab0873f292010-02-12 21:39:12 +0100415
Dmitry V. Levin26f90af2016-06-26 23:57:39 +0000416 tprints(", msg_iov=");
417 tprint_iov_upto(tcp, (unsigned long) msg->msg_iovlen,
418 (unsigned long) msg->msg_iov, IOV_DECODE_STR, data_size);
419 tprintf(", msg_iovlen=%lu", (unsigned long) msg->msg_iovlen);
Andreas Schwab0873f292010-02-12 21:39:12 +0100420
Dmitry V. Levin3e514c02016-06-26 23:57:29 +0000421 decode_msg_control(tcp, (unsigned long) msg->msg_control,
Dmitry V. Levin00ba20a2016-06-26 23:57:18 +0000422 msg->msg_controllen);
423 tprintf(", msg_controllen=%lu", (unsigned long) msg->msg_controllen);
424
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200425 tprints(", msg_flags=");
Andreas Schwab0873f292010-02-12 21:39:12 +0100426 printflags(msg_flags, msg->msg_flags, "MSG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200427 tprints("}");
Andreas Schwab0873f292010-02-12 21:39:12 +0100428}
429
430static void
Dmitry V. Levin3e514c02016-06-26 23:57:29 +0000431decode_msghdr(struct tcb *tcp, long addr, unsigned long data_size)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000432{
433 struct msghdr msg;
434
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000435 if (addr && verbose(tcp) && fetch_struct_msghdr(tcp, addr, &msg))
Dmitry V. Levin3e514c02016-06-26 23:57:29 +0000436 print_msghdr(tcp, &msg, data_size);
Masatake YAMATO02f9f6b2014-10-15 22:11:43 +0900437 else
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000438 printaddr(addr);
Masatake YAMATO02f9f6b2014-10-15 22:11:43 +0900439}
440
441void
Dmitry V. Levin93c9d1c2016-01-20 03:26:37 +0000442dumpiov_in_msghdr(struct tcb *tcp, long addr, unsigned long data_size)
Masatake YAMATO02f9f6b2014-10-15 22:11:43 +0900443{
444 struct msghdr msg;
445
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000446 if (fetch_struct_msghdr(tcp, addr, &msg))
Dmitry V. Levin93c9d1c2016-01-20 03:26:37 +0000447 dumpiov_upto(tcp, msg.msg_iovlen, (long)msg.msg_iov, data_size);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000448}
449
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000450static int
451decode_mmsghdr(struct tcb *tcp, long addr, bool use_msg_len)
Andreas Schwab0873f292010-02-12 21:39:12 +0100452{
Masatake YAMATOcaf6a432014-11-07 01:23:25 +0900453 struct mmsghdr mmsg;
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000454 int fetched = fetch_struct_mmsghdr(tcp, addr, &mmsg);
Andreas Schwab0873f292010-02-12 21:39:12 +0100455
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000456 if (fetched) {
Masatake YAMATOa807dce2014-11-07 01:23:26 +0900457 tprints("{");
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000458 print_msghdr(tcp, &mmsg.msg_hdr, use_msg_len ? mmsg.msg_len : -1UL);
Masatake YAMATOa807dce2014-11-07 01:23:26 +0900459 tprintf(", %u}", mmsg.msg_len);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000460 } else {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000461 printaddr(addr);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000462 }
463
464 return fetched;
Andreas Schwab0873f292010-02-12 21:39:12 +0100465}
Andreas Schwab0873f292010-02-12 21:39:12 +0100466
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000467static void
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000468decode_mmsgvec(struct tcb *tcp, unsigned long addr, unsigned int len,
469 bool use_msg_len)
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000470{
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000471 if (syserror(tcp)) {
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000472 printaddr(addr);
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000473 } else {
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000474 unsigned int i, fetched;
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000475
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000476 tprints("[");
477 for (i = 0; i < len; ++i, addr += fetched) {
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000478 if (i)
479 tprints(", ");
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000480 fetched = decode_mmsghdr(tcp, addr, use_msg_len);
481 if (!fetched)
482 break;
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000483 }
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000484 tprints("]");
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000485 }
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000486}
487
Masatake YAMATOa807dce2014-11-07 01:23:26 +0900488void
489dumpiov_in_mmsghdr(struct tcb *tcp, long addr)
490{
491 unsigned int len = tcp->u_rval;
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000492 unsigned int i, fetched;
Masatake YAMATOa807dce2014-11-07 01:23:26 +0900493 struct mmsghdr mmsg;
494
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000495 for (i = 0; i < len; ++i, addr += fetched) {
496 fetched = fetch_struct_mmsghdr(tcp, addr, &mmsg);
497 if (!fetched)
498 break;
499 tprintf(" = %lu buffers in vector %u\n",
500 (unsigned long)mmsg.msg_hdr.msg_iovlen, i);
501 dumpiov_upto(tcp, mmsg.msg_hdr.msg_iovlen,
502 (long)mmsg.msg_hdr.msg_iov, mmsg.msg_len);
Masatake YAMATOa807dce2014-11-07 01:23:26 +0900503 }
504}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000505
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000506/*
507 * low bits of the socket type define real socket type,
508 * other bits are socket type flags.
509 */
510static void
Dmitry V. Levin9134aab2016-05-14 21:46:05 +0000511tprint_sock_type(unsigned int flags)
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000512{
513 const char *str = xlookup(socktypes, flags & SOCK_TYPE_MASK);
514
Denys Vlasenko7b609d52011-06-22 14:32:43 +0200515 if (str) {
Denys Vlasenko5940e652011-09-01 09:55:05 +0200516 tprints(str);
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000517 flags &= ~SOCK_TYPE_MASK;
518 if (!flags)
519 return;
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200520 tprints("|");
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000521 }
522 printflags(sock_type_flags, flags, "SOCK_???");
523}
524
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000525SYS_FUNC(socket)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000526{
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000527 printxval(addrfams, tcp->u_arg[0], "AF_???");
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000528 tprints(", ");
529 tprint_sock_type(tcp->u_arg[1]);
530 tprints(", ");
531 switch (tcp->u_arg[0]) {
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000532 case AF_INET:
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000533 case AF_INET6:
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000534 printxval(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
535 break;
Dmitry V. Levineb1c22b2016-06-19 22:02:45 +0000536
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000537 case AF_NETLINK:
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000538 printxval(netlink_protocols, tcp->u_arg[2], "NETLINK_???");
539 break;
Dmitry V. Levinbc4102e2016-06-19 22:02:45 +0000540
Dmitry V. Levin43369fc2016-06-21 16:43:30 +0000541#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000542 case AF_BLUETOOTH:
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000543 printxval(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
544 break;
Lubomir Rintelc400a1c2014-10-03 11:40:28 +0200545#endif
Dmitry V. Levinbc4102e2016-06-19 22:02:45 +0000546
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000547 default:
548 tprintf("%lu", tcp->u_arg[2]);
549 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000550 }
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000551
Dmitry V. Levin3d463be2015-08-02 01:41:26 +0000552 return RVAL_DECODED | RVAL_FD;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000553}
554
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000555SYS_FUNC(bind)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000556{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000557 printfd(tcp, tcp->u_arg[0]);
558 tprints(", ");
Dmitry V. Levin42e566a2016-06-25 11:31:48 +0000559 decode_sockaddr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000560 tprintf(", %lu", tcp->u_arg[2]);
561
562 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000563}
564
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000565SYS_FUNC(listen)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000566{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000567 printfd(tcp, tcp->u_arg[0]);
568 tprints(", ");
569 tprintf("%lu", tcp->u_arg[1]);
570
571 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000572}
573
Paolo Bonzini705ff102009-08-14 12:34:05 +0200574static int
Dmitry V. Levin15114ec2014-08-06 16:46:13 +0000575do_sockname(struct tcb *tcp, int flags_arg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000576{
577 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800578 printfd(tcp, tcp->u_arg[0]);
579 tprints(", ");
Paolo Bonzini705ff102009-08-14 12:34:05 +0200580 return 0;
581 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000582
583 int len;
584 if (!tcp->u_arg[2] || !verbose(tcp) || syserror(tcp) ||
585 umove(tcp, tcp->u_arg[2], &len) < 0) {
586 printaddr(tcp->u_arg[1]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200587 tprints(", ");
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000588 printaddr(tcp->u_arg[2]);
589 } else {
Dmitry V. Levin42e566a2016-06-25 11:31:48 +0000590 decode_sockaddr(tcp, tcp->u_arg[1], len);
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000591 tprintf(", [%d]", len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000592 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000593
Paolo Bonzini705ff102009-08-14 12:34:05 +0200594 if (flags_arg >= 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200595 tprints(", ");
Paolo Bonzini705ff102009-08-14 12:34:05 +0200596 printflags(sock_type_flags, tcp->u_arg[flags_arg],
597 "SOCK_???");
598 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000599 return 0;
600}
601
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000602SYS_FUNC(accept)
Paolo Bonzini705ff102009-08-14 12:34:05 +0200603{
Dmitry V. Levin15114ec2014-08-06 16:46:13 +0000604 do_sockname(tcp, -1);
605 return RVAL_FD;
Paolo Bonzini705ff102009-08-14 12:34:05 +0200606}
607
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000608SYS_FUNC(accept4)
Paolo Bonzini705ff102009-08-14 12:34:05 +0200609{
Dmitry V. Levin15114ec2014-08-06 16:46:13 +0000610 do_sockname(tcp, 3);
611 return RVAL_FD;
Paolo Bonzini705ff102009-08-14 12:34:05 +0200612}
Paolo Bonzini705ff102009-08-14 12:34:05 +0200613
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000614SYS_FUNC(send)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000615{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000616 printfd(tcp, tcp->u_arg[0]);
617 tprints(", ");
618 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
619 tprintf(", %lu, ", tcp->u_arg[2]);
620 /* flags */
621 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
622
623 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000624}
625
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000626SYS_FUNC(sendto)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000627{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000628 printfd(tcp, tcp->u_arg[0]);
629 tprints(", ");
630 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
631 tprintf(", %lu, ", tcp->u_arg[2]);
632 /* flags */
633 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
634 /* to address */
635 tprints(", ");
Dmitry V. Levin42e566a2016-06-25 11:31:48 +0000636 decode_sockaddr(tcp, tcp->u_arg[4], tcp->u_arg[5]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000637 /* to length */
638 tprintf(", %lu", tcp->u_arg[5]);
639
640 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000641}
642
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000643SYS_FUNC(sendmsg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000644{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000645 printfd(tcp, tcp->u_arg[0]);
646 tprints(", ");
Dmitry V. Levin3e514c02016-06-26 23:57:29 +0000647 decode_msghdr(tcp, tcp->u_arg[1], (unsigned long) -1L);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000648 /* flags */
649 tprints(", ");
650 printflags(msg_flags, tcp->u_arg[2], "MSG_???");
651
652 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000653}
654
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000655SYS_FUNC(sendmmsg)
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000656{
657 if (entering(tcp)) {
658 /* sockfd */
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800659 printfd(tcp, tcp->u_arg[0]);
660 tprints(", ");
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000661 if (!verbose(tcp)) {
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000662 printaddr(tcp->u_arg[1]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000663 /* vlen */
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000664 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000665 /* flags */
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000666 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000667 return RVAL_DECODED;
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000668 }
669 } else {
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000670 decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval, false);
671 /* vlen */
672 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
673 /* flags */
674 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000675 }
676 return 0;
677}
678
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000679SYS_FUNC(recv)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000680{
681 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800682 printfd(tcp, tcp->u_arg[0]);
683 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000684 } else {
685 if (syserror(tcp))
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000686 printaddr(tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000687 else
688 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
689
690 tprintf(", %lu, ", tcp->u_arg[2]);
Roland McGrathb2dee132005-06-01 19:02:36 +0000691 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000692 }
693 return 0;
694}
695
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000696SYS_FUNC(recvfrom)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000697{
698 int fromlen;
699
700 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800701 printfd(tcp, tcp->u_arg[0]);
702 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000703 } else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000704 /* buf */
Denys Vlasenko383386d2015-07-30 13:29:20 +0200705 if (syserror(tcp)) {
Dmitry V. Levin52dc1502015-07-30 13:53:42 +0000706 printaddr(tcp->u_arg[1]);
Denys Vlasenko383386d2015-07-30 13:29:20 +0200707 } else {
708 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
709 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000710 /* len */
711 tprintf(", %lu, ", tcp->u_arg[2]);
712 /* flags */
Roland McGrathb2dee132005-06-01 19:02:36 +0000713 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200714 tprints(", ");
Dmitry V. Levin52dc1502015-07-30 13:53:42 +0000715 if (syserror(tcp) || !tcp->u_arg[4] || !tcp->u_arg[5] ||
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000716 umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
Denys Vlasenko383386d2015-07-30 13:29:20 +0200717 /* from address, len */
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000718 printaddr(tcp->u_arg[4]);
719 tprints(", ");
720 printaddr(tcp->u_arg[5]);
721 return 0;
722 }
Denys Vlasenko383386d2015-07-30 13:29:20 +0200723 /* from address */
Dmitry V. Levin42e566a2016-06-25 11:31:48 +0000724 decode_sockaddr(tcp, tcp->u_arg[4], fromlen);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000725 /* from length */
726 tprintf(", [%u]", fromlen);
727 }
728 return 0;
729}
730
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000731SYS_FUNC(recvmsg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000732{
733 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800734 printfd(tcp, tcp->u_arg[0]);
735 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000736 } else {
Dmitry V. Levin00244b92015-01-28 01:52:25 +0000737 if (syserror(tcp))
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000738 printaddr(tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000739 else
Dmitry V. Levin3e514c02016-06-26 23:57:29 +0000740 decode_msghdr(tcp, tcp->u_arg[1], tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000741 /* flags */
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200742 tprints(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +0000743 printflags(msg_flags, tcp->u_arg[2], "MSG_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000744 }
745 return 0;
746}
747
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000748SYS_FUNC(recvmmsg)
Andreas Schwab0873f292010-02-12 21:39:12 +0100749{
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000750 static char str[sizeof("left") + TIMESPEC_TEXT_BUFSIZE];
Dmitry V. Levine6591032010-03-29 20:45:48 +0400751
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100752 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800753 printfd(tcp, tcp->u_arg[0]);
754 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +0400755 if (verbose(tcp)) {
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100756 /* Abusing tcp->auxstr as temp storage.
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000757 * Will be used and cleared on syscall exit.
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100758 */
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000759 tcp->auxstr = sprint_timespec(tcp, tcp->u_arg[4]);
Dmitry V. Levine6591032010-03-29 20:45:48 +0400760 } else {
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000761 printaddr(tcp->u_arg[1]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000762 /* vlen */
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000763 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000764 /* flags */
Dmitry V. Levine6591032010-03-29 20:45:48 +0400765 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200766 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +0400767 print_timespec(tcp, tcp->u_arg[4]);
768 }
769 return 0;
770 } else {
771 if (verbose(tcp)) {
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000772 decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval, true);
773 /* vlen */
774 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
775 /* flags */
776 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000777 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +0400778 /* timeout on entrance */
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000779 tprints(tcp->auxstr);
Dmitry V. Levine6591032010-03-29 20:45:48 +0400780 tcp->auxstr = NULL;
781 }
782 if (syserror(tcp))
783 return 0;
784 if (tcp->u_rval == 0) {
785 tcp->auxstr = "Timeout";
786 return RVAL_STR;
787 }
788 if (!verbose(tcp))
789 return 0;
790 /* timeout on exit */
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000791 snprintf(str, sizeof(str), "left %s",
792 sprint_timespec(tcp, tcp->u_arg[4]));
Dmitry V. Levine6591032010-03-29 20:45:48 +0400793 tcp->auxstr = str;
794 return RVAL_STR;
Andreas Schwab0873f292010-02-12 21:39:12 +0100795 }
Andreas Schwab0873f292010-02-12 21:39:12 +0100796}
Andreas Schwab0873f292010-02-12 21:39:12 +0100797
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000798#include "xlat/shutdown_modes.h"
Sebastian Pipping9cd38502011-03-03 01:12:25 +0100799
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000800SYS_FUNC(shutdown)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000801{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000802 printfd(tcp, tcp->u_arg[0]);
803 tprints(", ");
804 printxval(shutdown_modes, tcp->u_arg[1], "SHUT_???");
805
806 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000807}
808
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000809SYS_FUNC(getsockname)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000810{
Dmitry V. Levin15114ec2014-08-06 16:46:13 +0000811 return do_sockname(tcp, -1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000812}
813
Dmitry V. Levin2a4f0522015-08-02 01:54:48 +0000814static void
815printpair_fd(struct tcb *tcp, const int i0, const int i1)
816{
817 tprints("[");
818 printfd(tcp, i0);
819 tprints(", ");
820 printfd(tcp, i1);
821 tprints("]");
822}
823
824static void
825decode_pair_fd(struct tcb *tcp, const long addr)
826{
827 int pair[2];
828
829 if (umove_or_printaddr(tcp, addr, &pair))
830 return;
831
832 printpair_fd(tcp, pair[0], pair[1]);
833}
834
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000835static int
836do_pipe(struct tcb *tcp, int flags_arg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000837{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000838 if (exiting(tcp)) {
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000839 decode_pair_fd(tcp, tcp->u_arg[0]);
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000840 if (flags_arg >= 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200841 tprints(", ");
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000842 printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
843 }
844 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000845 return 0;
846}
847
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000848SYS_FUNC(pipe)
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000849{
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000850#ifdef HAVE_GETRVAL2
851 if (exiting(tcp) && !syserror(tcp))
852 printpair_fd(tcp, tcp->u_rval, getrval2(tcp));
853 return 0;
854#else
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000855 return do_pipe(tcp, -1);
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000856#endif
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000857}
858
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000859SYS_FUNC(pipe2)
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000860{
861 return do_pipe(tcp, 1);
862}
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000863
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000864SYS_FUNC(socketpair)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000865{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000866 if (entering(tcp)) {
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000867 printxval(addrfams, tcp->u_arg[0], "AF_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200868 tprints(", ");
Dmitry V. Levin1e42f2d2014-09-10 17:48:28 +0000869 tprint_sock_type(tcp->u_arg[1]);
Dmitry V. Levin033fb912014-03-11 22:50:39 +0000870 tprintf(", %lu", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000871 } else {
Dmitry V. Levinb6795082015-07-06 22:33:39 +0000872 tprints(", ");
Dmitry V. Levin2a4f0522015-08-02 01:54:48 +0000873 decode_pair_fd(tcp, tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000874 }
875 return 0;
876}
877
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000878#include "xlat/sockoptions.h"
879#include "xlat/sockipoptions.h"
Mike Frysinger54646b82015-08-19 13:29:27 -0400880#include "xlat/getsockipoptions.h"
881#include "xlat/setsockipoptions.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000882#include "xlat/sockipv6options.h"
Mike Frysinger54646b82015-08-19 13:29:27 -0400883#include "xlat/getsockipv6options.h"
884#include "xlat/setsockipv6options.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000885#include "xlat/sockipxoptions.h"
886#include "xlat/sockrawoptions.h"
887#include "xlat/sockpacketoptions.h"
888#include "xlat/socksctpoptions.h"
889#include "xlat/socktcpoptions.h"
890
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000891static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +0000892print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
893 unsigned int name, bool is_getsockopt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000894{
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000895 printfd(tcp, fd);
896 tprints(", ");
John Hughes38ae88d2002-05-23 11:48:58 +0000897 printxval(socketlayers, level, "SOL_??");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200898 tprints(", ");
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000899
John Hughes38ae88d2002-05-23 11:48:58 +0000900 switch (level) {
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100901 case SOL_SOCKET:
John Hughes38ae88d2002-05-23 11:48:58 +0000902 printxval(sockoptions, name, "SO_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000903 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100904 case SOL_IP:
Mike Frysinger54646b82015-08-19 13:29:27 -0400905 printxvals(name, "IP_???", sockipoptions,
906 is_getsockopt ? getsockipoptions : setsockipoptions, NULL);
John Hughes38ae88d2002-05-23 11:48:58 +0000907 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100908 case SOL_IPV6:
Mike Frysinger54646b82015-08-19 13:29:27 -0400909 printxvals(name, "IPV6_???", sockipv6options,
910 is_getsockopt ? getsockipv6options : setsockipv6options, NULL);
Roland McGrath4f6ba692004-08-31 07:01:26 +0000911 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100912 case SOL_IPX:
John Hughes38ae88d2002-05-23 11:48:58 +0000913 printxval(sockipxoptions, name, "IPX_???");
914 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100915 case SOL_PACKET:
John Hughes38ae88d2002-05-23 11:48:58 +0000916 printxval(sockpacketoptions, name, "PACKET_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000917 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100918 case SOL_TCP:
John Hughes38ae88d2002-05-23 11:48:58 +0000919 printxval(socktcpoptions, name, "TCP_???");
920 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100921 case SOL_SCTP:
Holger Hans Peter Freyther7fea79b2011-01-14 11:08:12 +0100922 printxval(socksctpoptions, name, "SCTP_???");
923 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100924 case SOL_RAW:
John Hughes38ae88d2002-05-23 11:48:58 +0000925 printxval(sockrawoptions, name, "RAW_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000926 break;
John Hughes38ae88d2002-05-23 11:48:58 +0000927
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000928 /* Other SOL_* protocol levels still need work. */
John Hughes38ae88d2002-05-23 11:48:58 +0000929
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100930 default:
John Hughes38ae88d2002-05-23 11:48:58 +0000931 tprintf("%u", name);
932 }
933
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000934 tprints(", ");
935}
936
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000937static void
938print_linger(struct tcb *tcp, long addr, int len)
939{
940 struct linger linger;
941
942 if (len != sizeof(linger) ||
943 umove(tcp, addr, &linger) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000944 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000945 return;
946 }
947
948 tprintf("{onoff=%d, linger=%d}",
949 linger.l_onoff,
950 linger.l_linger);
951}
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000952
953#ifdef SO_PEERCRED
954static void
955print_ucred(struct tcb *tcp, long addr, int len)
956{
957 struct ucred uc;
958
959 if (len != sizeof(uc) ||
960 umove(tcp, addr, &uc) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000961 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000962 } else {
963 tprintf("{pid=%u, uid=%u, gid=%u}",
964 (unsigned) uc.pid,
965 (unsigned) uc.uid,
966 (unsigned) uc.gid);
967 }
968}
969#endif /* SO_PEERCRED */
970
971#ifdef PACKET_STATISTICS
972static void
973print_tpacket_stats(struct tcb *tcp, long addr, int len)
974{
975 struct tpacket_stats stats;
976
977 if (len != sizeof(stats) ||
978 umove(tcp, addr, &stats) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000979 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000980 } else {
981 tprintf("{packets=%u, drops=%u}",
982 stats.tp_packets,
983 stats.tp_drops);
984 }
985}
986#endif /* PACKET_STATISTICS */
987
Dmitry V. Levinfba9db22016-06-15 21:29:07 +0000988#include "xlat/icmpfilterflags.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000989
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000990static void
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000991print_icmp_filter(struct tcb *tcp, const long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000992{
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000993 struct icmp_filter filter = {};
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000994
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000995 if (len > (int) sizeof(filter))
996 len = sizeof(filter);
997 else if (len <= 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000998 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000999 return;
1000 }
1001
Dmitry V. Levineb5c2332016-05-06 00:06:15 +00001002 if (umoven_or_printaddr(tcp, addr, len, &filter))
1003 return;
1004
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001005 tprints("~(");
1006 printflags(icmpfilterflags, ~filter.data, "ICMP_???");
1007 tprints(")");
1008}
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001009
1010static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +00001011print_getsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
1012 long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001013{
1014 if (addr && verbose(tcp))
1015 switch (level) {
1016 case SOL_SOCKET:
1017 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001018 case SO_LINGER:
1019 print_linger(tcp, addr, len);
1020 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001021#ifdef SO_PEERCRED
1022 case SO_PEERCRED:
1023 print_ucred(tcp, addr, len);
1024 goto done;
1025#endif
1026 }
1027 break;
1028
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001029 case SOL_PACKET:
1030 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001031#ifdef PACKET_STATISTICS
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001032 case PACKET_STATISTICS:
1033 print_tpacket_stats(tcp, addr, len);
1034 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001035#endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001036 }
1037 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001038
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001039 case SOL_RAW:
1040 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001041 case ICMP_FILTER:
1042 print_icmp_filter(tcp, addr, len);
1043 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001044 }
1045 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001046 }
1047
John Hughes38ae88d2002-05-23 11:48:58 +00001048 /* default arg printing */
1049
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001050 if (verbose(tcp)) {
1051 if (len == sizeof(int)) {
1052 printnum_int(tcp, addr, "%d");
1053 } else {
1054 printstr(tcp, addr, len);
1055 }
1056 } else {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001057 printaddr(addr);
John Hughes38ae88d2002-05-23 11:48:58 +00001058 }
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001059done:
1060 tprintf(", [%d]", len);
1061}
1062
Dmitry V. Levina0bd3742015-04-07 01:36:50 +00001063SYS_FUNC(getsockopt)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001064{
1065 if (entering(tcp)) {
1066 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
Mike Frysinger54646b82015-08-19 13:29:27 -04001067 tcp->u_arg[1], tcp->u_arg[2], true);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001068 } else {
1069 int len;
1070
1071 if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &len) < 0) {
Dmitry V. Levin484326d2016-06-11 01:28:21 +00001072 printaddr(tcp->u_arg[3]);
1073 tprints(", ");
1074 printaddr(tcp->u_arg[4]);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001075 } else {
1076 print_getsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
1077 tcp->u_arg[3], len);
1078 }
John Hughes38ae88d2002-05-23 11:48:58 +00001079 }
1080 return 0;
1081}
1082
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001083#ifdef IP_ADD_MEMBERSHIP
1084static void
1085print_mreq(struct tcb *tcp, long addr, unsigned int len)
1086{
1087 struct ip_mreq mreq;
1088
1089 if (len < sizeof(mreq)) {
1090 printstr(tcp, addr, len);
1091 return;
1092 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001093 if (umove_or_printaddr(tcp, addr, &mreq))
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001094 return;
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001095
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001096 tprints("{imr_multiaddr=inet_addr(");
1097 print_quoted_string(inet_ntoa(mreq.imr_multiaddr),
1098 16, QUOTE_0_TERMINATED);
1099 tprints("), imr_interface=inet_addr(");
1100 print_quoted_string(inet_ntoa(mreq.imr_interface),
1101 16, QUOTE_0_TERMINATED);
1102 tprints(")}");
1103}
1104#endif /* IP_ADD_MEMBERSHIP */
1105
1106#ifdef IPV6_ADD_MEMBERSHIP
1107static void
1108print_mreq6(struct tcb *tcp, long addr, unsigned int len)
1109{
1110 struct ipv6_mreq mreq;
1111
1112 if (len < sizeof(mreq))
1113 goto fail;
1114
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001115 if (umove_or_printaddr(tcp, addr, &mreq))
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001116 return;
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001117
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001118 const struct in6_addr *in6 = &mreq.ipv6mr_multiaddr;
1119 char address[INET6_ADDRSTRLEN];
1120
1121 if (!inet_ntop(AF_INET6, in6, address, sizeof(address)))
1122 goto fail;
1123
1124 tprints("{ipv6mr_multiaddr=inet_pton(");
1125 print_quoted_string(address, sizeof(address), QUOTE_0_TERMINATED);
1126 tprints("), ipv6mr_interface=");
1127 print_ifindex(mreq.ipv6mr_interface);
1128 tprints("}");
1129 return;
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001130
1131fail:
1132 printstr(tcp, addr, len);
1133}
1134#endif /* IPV6_ADD_MEMBERSHIP */
1135
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001136#ifdef MCAST_JOIN_GROUP
1137static void
1138print_group_req(struct tcb *tcp, long addr, int len)
1139{
1140 struct group_req greq;
1141
1142 if (len != sizeof(greq) ||
1143 umove(tcp, addr, &greq) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001144 printaddr(addr);
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001145 return;
1146 }
1147
Dmitry V. Levin1019f002015-11-21 02:38:59 +00001148 tprintf("{gr_interface=%u, gr_group=", greq.gr_interface);
Dmitry V. Levin3bf9c192016-06-21 16:45:40 +00001149 print_sockaddr(tcp, &greq.gr_group, sizeof(greq.gr_group));
Dmitry V. Levin1019f002015-11-21 02:38:59 +00001150 tprintf("}");
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001151
1152}
1153#endif /* MCAST_JOIN_GROUP */
1154
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001155#ifdef PACKET_RX_RING
1156static void
1157print_tpacket_req(struct tcb *tcp, long addr, int len)
1158{
1159 struct tpacket_req req;
1160
1161 if (len != sizeof(req) ||
1162 umove(tcp, addr, &req) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001163 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001164 } else {
1165 tprintf("{block_size=%u, block_nr=%u, "
1166 "frame_size=%u, frame_nr=%u}",
1167 req.tp_block_size,
1168 req.tp_block_nr,
1169 req.tp_frame_size,
1170 req.tp_frame_nr);
1171 }
1172}
1173#endif /* PACKET_RX_RING */
1174
Dmitry V. Levin02f2f092015-01-29 03:26:53 +00001175#ifdef PACKET_ADD_MEMBERSHIP
1176# include "xlat/packet_mreq_type.h"
1177
1178static void
1179print_packet_mreq(struct tcb *tcp, long addr, int len)
1180{
1181 struct packet_mreq mreq;
1182
1183 if (len != sizeof(mreq) ||
1184 umove(tcp, addr, &mreq) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001185 printaddr(addr);
Dmitry V. Levin02f2f092015-01-29 03:26:53 +00001186 } else {
1187 unsigned int i;
1188
1189 tprintf("{mr_ifindex=%u, mr_type=", mreq.mr_ifindex);
1190 printxval(packet_mreq_type, mreq.mr_type, "PACKET_MR_???");
1191 tprintf(", mr_alen=%u, mr_address=", mreq.mr_alen);
1192 if (mreq.mr_alen > ARRAY_SIZE(mreq.mr_address))
1193 mreq.mr_alen = ARRAY_SIZE(mreq.mr_address);
1194 for (i = 0; i < mreq.mr_alen; ++i)
1195 tprintf("%02x", mreq.mr_address[i]);
1196 tprints("}");
1197 }
1198}
1199#endif /* PACKET_ADD_MEMBERSHIP */
1200
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001201static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +00001202print_setsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
1203 long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001204{
1205 if (addr && verbose(tcp))
1206 switch (level) {
1207 case SOL_SOCKET:
1208 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001209 case SO_LINGER:
1210 print_linger(tcp, addr, len);
1211 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001212 }
1213 break;
1214
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001215 case SOL_IP:
1216 switch (name) {
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001217#ifdef IP_ADD_MEMBERSHIP
1218 case IP_ADD_MEMBERSHIP:
1219 case IP_DROP_MEMBERSHIP:
1220 print_mreq(tcp, addr, len);
1221 goto done;
1222#endif /* IP_ADD_MEMBERSHIP */
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001223#ifdef MCAST_JOIN_GROUP
1224 case MCAST_JOIN_GROUP:
1225 case MCAST_LEAVE_GROUP:
1226 print_group_req(tcp, addr, len);
1227 goto done;
1228#endif /* MCAST_JOIN_GROUP */
1229 }
Dmitry V. Levin3910d0f2015-02-08 01:19:06 +00001230 break;
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001231
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001232 case SOL_IPV6:
1233 switch (name) {
1234#ifdef IPV6_ADD_MEMBERSHIP
1235 case IPV6_ADD_MEMBERSHIP:
1236 case IPV6_DROP_MEMBERSHIP:
1237# ifdef IPV6_JOIN_ANYCAST
1238 case IPV6_JOIN_ANYCAST:
1239# endif
1240# ifdef IPV6_LEAVE_ANYCAST
1241 case IPV6_LEAVE_ANYCAST:
1242# endif
1243 print_mreq6(tcp, addr, len);
1244 goto done;
1245#endif /* IPV6_ADD_MEMBERSHIP */
1246 }
1247 break;
1248
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001249 case SOL_PACKET:
1250 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001251#ifdef PACKET_RX_RING
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001252 case PACKET_RX_RING:
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001253# ifdef PACKET_TX_RING
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001254 case PACKET_TX_RING:
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001255# endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001256 print_tpacket_req(tcp, addr, len);
1257 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001258#endif /* PACKET_RX_RING */
1259#ifdef PACKET_ADD_MEMBERSHIP
Dmitry V. Levin02f2f092015-01-29 03:26:53 +00001260 case PACKET_ADD_MEMBERSHIP:
1261 case PACKET_DROP_MEMBERSHIP:
1262 print_packet_mreq(tcp, addr, len);
1263 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001264#endif /* PACKET_ADD_MEMBERSHIP */
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001265 }
1266 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001267
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001268 case SOL_RAW:
1269 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001270 case ICMP_FILTER:
1271 print_icmp_filter(tcp, addr, len);
1272 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001273 }
1274 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001275 }
1276
1277 /* default arg printing */
1278
1279 if (verbose(tcp)) {
1280 if (len == sizeof(int)) {
1281 printnum_int(tcp, addr, "%d");
1282 } else {
1283 printstr(tcp, addr, len);
1284 }
1285 } else {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001286 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001287 }
1288done:
1289 tprintf(", %d", len);
1290}
1291
Dmitry V. Levina0bd3742015-04-07 01:36:50 +00001292SYS_FUNC(setsockopt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001293{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +00001294 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
Mike Frysinger54646b82015-08-19 13:29:27 -04001295 tcp->u_arg[1], tcp->u_arg[2], false);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +00001296 print_setsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
1297 tcp->u_arg[3], tcp->u_arg[4]);
1298
1299 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001300}