blob: bcb9e4f642e734e92b935b64c89e12b2ca3f95d9 [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. Levin45ae9372016-06-23 17:38:18 +000095void
Dmitry V. Levinae280932015-06-05 20:13:21 +000096print_ifindex(unsigned int ifindex)
97{
98#ifdef HAVE_IF_INDEXTONAME
99 char buf[IFNAMSIZ + 1];
100
101 if (if_indextoname(ifindex, buf)) {
102 tprints("if_nametoindex(");
103 print_quoted_string(buf, sizeof(buf), QUOTE_0_TERMINATED);
104 tprints(")");
105 return;
106 }
107#endif
108 tprintf("%u", ifindex);
109}
110
Fabien Siron2850f742016-07-06 15:49:22 +0000111static void
112decode_sockbuf(struct tcb *tcp, int fd, long addr, long addrlen)
113{
114
115 switch (verbose(tcp) ? getfdproto(tcp, fd) : SOCK_PROTO_UNKNOWN) {
116 case SOCK_PROTO_NETLINK:
117 decode_netlink(tcp, addr, addrlen);
118 break;
119 default:
120 printstr(tcp, addr, addrlen);
121 }
122}
123
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000124/*
125 * low bits of the socket type define real socket type,
126 * other bits are socket type flags.
127 */
128static void
Dmitry V. Levin9134aab2016-05-14 21:46:05 +0000129tprint_sock_type(unsigned int flags)
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000130{
131 const char *str = xlookup(socktypes, flags & SOCK_TYPE_MASK);
132
Denys Vlasenko7b609d52011-06-22 14:32:43 +0200133 if (str) {
Denys Vlasenko5940e652011-09-01 09:55:05 +0200134 tprints(str);
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000135 flags &= ~SOCK_TYPE_MASK;
136 if (!flags)
137 return;
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200138 tprints("|");
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000139 }
140 printflags(sock_type_flags, flags, "SOCK_???");
141}
142
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000143SYS_FUNC(socket)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000144{
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000145 printxval(addrfams, tcp->u_arg[0], "AF_???");
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000146 tprints(", ");
147 tprint_sock_type(tcp->u_arg[1]);
148 tprints(", ");
149 switch (tcp->u_arg[0]) {
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000150 case AF_INET:
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000151 case AF_INET6:
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000152 printxval(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
153 break;
Dmitry V. Levineb1c22b2016-06-19 22:02:45 +0000154
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000155 case AF_NETLINK:
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000156 printxval(netlink_protocols, tcp->u_arg[2], "NETLINK_???");
157 break;
Dmitry V. Levinbc4102e2016-06-19 22:02:45 +0000158
Dmitry V. Levin43369fc2016-06-21 16:43:30 +0000159#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000160 case AF_BLUETOOTH:
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000161 printxval(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
162 break;
Lubomir Rintelc400a1c2014-10-03 11:40:28 +0200163#endif
Dmitry V. Levinbc4102e2016-06-19 22:02:45 +0000164
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000165 default:
166 tprintf("%lu", tcp->u_arg[2]);
167 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000168 }
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000169
Dmitry V. Levin3d463be2015-08-02 01:41:26 +0000170 return RVAL_DECODED | RVAL_FD;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000171}
172
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000173SYS_FUNC(bind)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000174{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000175 printfd(tcp, tcp->u_arg[0]);
176 tprints(", ");
Dmitry V. Levin42e566a2016-06-25 11:31:48 +0000177 decode_sockaddr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000178 tprintf(", %lu", tcp->u_arg[2]);
179
180 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000181}
182
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000183SYS_FUNC(listen)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000184{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000185 printfd(tcp, tcp->u_arg[0]);
186 tprints(", ");
187 tprintf("%lu", tcp->u_arg[1]);
188
189 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000190}
191
Paolo Bonzini705ff102009-08-14 12:34:05 +0200192static int
Dmitry V. Levin15114ec2014-08-06 16:46:13 +0000193do_sockname(struct tcb *tcp, int flags_arg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000194{
195 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800196 printfd(tcp, tcp->u_arg[0]);
197 tprints(", ");
Paolo Bonzini705ff102009-08-14 12:34:05 +0200198 return 0;
199 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000200
201 int len;
202 if (!tcp->u_arg[2] || !verbose(tcp) || syserror(tcp) ||
203 umove(tcp, tcp->u_arg[2], &len) < 0) {
204 printaddr(tcp->u_arg[1]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200205 tprints(", ");
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000206 printaddr(tcp->u_arg[2]);
207 } else {
Dmitry V. Levin42e566a2016-06-25 11:31:48 +0000208 decode_sockaddr(tcp, tcp->u_arg[1], len);
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000209 tprintf(", [%d]", len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000210 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000211
Paolo Bonzini705ff102009-08-14 12:34:05 +0200212 if (flags_arg >= 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200213 tprints(", ");
Paolo Bonzini705ff102009-08-14 12:34:05 +0200214 printflags(sock_type_flags, tcp->u_arg[flags_arg],
215 "SOCK_???");
216 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000217 return 0;
218}
219
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000220SYS_FUNC(accept)
Paolo Bonzini705ff102009-08-14 12:34:05 +0200221{
Dmitry V. Levin15114ec2014-08-06 16:46:13 +0000222 do_sockname(tcp, -1);
223 return RVAL_FD;
Paolo Bonzini705ff102009-08-14 12:34:05 +0200224}
225
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000226SYS_FUNC(accept4)
Paolo Bonzini705ff102009-08-14 12:34:05 +0200227{
Dmitry V. Levin15114ec2014-08-06 16:46:13 +0000228 do_sockname(tcp, 3);
229 return RVAL_FD;
Paolo Bonzini705ff102009-08-14 12:34:05 +0200230}
Paolo Bonzini705ff102009-08-14 12:34:05 +0200231
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000232SYS_FUNC(send)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000233{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000234 printfd(tcp, tcp->u_arg[0]);
235 tprints(", ");
Fabien Siron2850f742016-07-06 15:49:22 +0000236 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000237 tprintf(", %lu, ", tcp->u_arg[2]);
238 /* flags */
239 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
240
241 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000242}
243
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000244SYS_FUNC(sendto)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000245{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000246 printfd(tcp, tcp->u_arg[0]);
247 tprints(", ");
Fabien Siron2850f742016-07-06 15:49:22 +0000248 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000249 tprintf(", %lu, ", tcp->u_arg[2]);
250 /* flags */
251 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
252 /* to address */
253 tprints(", ");
Dmitry V. Levin42e566a2016-06-25 11:31:48 +0000254 decode_sockaddr(tcp, tcp->u_arg[4], tcp->u_arg[5]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000255 /* to length */
256 tprintf(", %lu", tcp->u_arg[5]);
257
258 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000259}
260
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000261SYS_FUNC(sendmsg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000262{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000263 printfd(tcp, tcp->u_arg[0]);
264 tprints(", ");
Dmitry V. Levin3e514c02016-06-26 23:57:29 +0000265 decode_msghdr(tcp, tcp->u_arg[1], (unsigned long) -1L);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000266 /* flags */
267 tprints(", ");
268 printflags(msg_flags, tcp->u_arg[2], "MSG_???");
269
270 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000271}
272
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000273SYS_FUNC(sendmmsg)
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000274{
275 if (entering(tcp)) {
276 /* sockfd */
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800277 printfd(tcp, tcp->u_arg[0]);
278 tprints(", ");
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000279 if (!verbose(tcp)) {
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000280 printaddr(tcp->u_arg[1]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000281 /* vlen */
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000282 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000283 /* flags */
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000284 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000285 return RVAL_DECODED;
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000286 }
287 } else {
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000288 decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval, false);
289 /* vlen */
290 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
291 /* flags */
292 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000293 }
294 return 0;
295}
296
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000297SYS_FUNC(recv)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000298{
299 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800300 printfd(tcp, tcp->u_arg[0]);
301 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000302 } else {
Fabien Siron2850f742016-07-06 15:49:22 +0000303 if (syserror(tcp)) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000304 printaddr(tcp->u_arg[1]);
Fabien Siron2850f742016-07-06 15:49:22 +0000305 } else {
306 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
307 tcp->u_rval);
308 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000309
310 tprintf(", %lu, ", tcp->u_arg[2]);
Roland McGrathb2dee132005-06-01 19:02:36 +0000311 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000312 }
313 return 0;
314}
315
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000316SYS_FUNC(recvfrom)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000317{
318 int fromlen;
319
320 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800321 printfd(tcp, tcp->u_arg[0]);
322 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000323 } else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000324 /* buf */
Denys Vlasenko383386d2015-07-30 13:29:20 +0200325 if (syserror(tcp)) {
Dmitry V. Levin52dc1502015-07-30 13:53:42 +0000326 printaddr(tcp->u_arg[1]);
Denys Vlasenko383386d2015-07-30 13:29:20 +0200327 } else {
Fabien Siron2850f742016-07-06 15:49:22 +0000328 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
329 tcp->u_rval);
Denys Vlasenko383386d2015-07-30 13:29:20 +0200330 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000331 /* len */
332 tprintf(", %lu, ", tcp->u_arg[2]);
333 /* flags */
Roland McGrathb2dee132005-06-01 19:02:36 +0000334 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200335 tprints(", ");
Dmitry V. Levin52dc1502015-07-30 13:53:42 +0000336 if (syserror(tcp) || !tcp->u_arg[4] || !tcp->u_arg[5] ||
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000337 umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
Denys Vlasenko383386d2015-07-30 13:29:20 +0200338 /* from address, len */
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000339 printaddr(tcp->u_arg[4]);
340 tprints(", ");
341 printaddr(tcp->u_arg[5]);
342 return 0;
343 }
Denys Vlasenko383386d2015-07-30 13:29:20 +0200344 /* from address */
Dmitry V. Levin42e566a2016-06-25 11:31:48 +0000345 decode_sockaddr(tcp, tcp->u_arg[4], fromlen);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000346 /* from length */
347 tprintf(", [%u]", fromlen);
348 }
349 return 0;
350}
351
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000352SYS_FUNC(recvmsg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000353{
354 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800355 printfd(tcp, tcp->u_arg[0]);
356 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000357 } else {
Dmitry V. Levin00244b92015-01-28 01:52:25 +0000358 if (syserror(tcp))
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000359 printaddr(tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000360 else
Dmitry V. Levin3e514c02016-06-26 23:57:29 +0000361 decode_msghdr(tcp, tcp->u_arg[1], tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000362 /* flags */
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200363 tprints(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +0000364 printflags(msg_flags, tcp->u_arg[2], "MSG_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000365 }
366 return 0;
367}
368
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000369SYS_FUNC(recvmmsg)
Andreas Schwab0873f292010-02-12 21:39:12 +0100370{
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000371 static char str[sizeof("left") + TIMESPEC_TEXT_BUFSIZE];
Dmitry V. Levine6591032010-03-29 20:45:48 +0400372
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100373 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800374 printfd(tcp, tcp->u_arg[0]);
375 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +0400376 if (verbose(tcp)) {
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100377 /* Abusing tcp->auxstr as temp storage.
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000378 * Will be used and cleared on syscall exit.
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100379 */
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000380 tcp->auxstr = sprint_timespec(tcp, tcp->u_arg[4]);
Dmitry V. Levine6591032010-03-29 20:45:48 +0400381 } else {
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000382 printaddr(tcp->u_arg[1]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000383 /* vlen */
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000384 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000385 /* flags */
Dmitry V. Levine6591032010-03-29 20:45:48 +0400386 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200387 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +0400388 print_timespec(tcp, tcp->u_arg[4]);
389 }
390 return 0;
391 } else {
392 if (verbose(tcp)) {
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000393 decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval, true);
394 /* vlen */
395 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
396 /* flags */
397 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000398 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +0400399 /* timeout on entrance */
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000400 tprints(tcp->auxstr);
Dmitry V. Levine6591032010-03-29 20:45:48 +0400401 tcp->auxstr = NULL;
402 }
403 if (syserror(tcp))
404 return 0;
405 if (tcp->u_rval == 0) {
406 tcp->auxstr = "Timeout";
407 return RVAL_STR;
408 }
409 if (!verbose(tcp))
410 return 0;
411 /* timeout on exit */
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000412 snprintf(str, sizeof(str), "left %s",
413 sprint_timespec(tcp, tcp->u_arg[4]));
Dmitry V. Levine6591032010-03-29 20:45:48 +0400414 tcp->auxstr = str;
415 return RVAL_STR;
Andreas Schwab0873f292010-02-12 21:39:12 +0100416 }
Andreas Schwab0873f292010-02-12 21:39:12 +0100417}
Andreas Schwab0873f292010-02-12 21:39:12 +0100418
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000419#include "xlat/shutdown_modes.h"
Sebastian Pipping9cd38502011-03-03 01:12:25 +0100420
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000421SYS_FUNC(shutdown)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000422{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000423 printfd(tcp, tcp->u_arg[0]);
424 tprints(", ");
425 printxval(shutdown_modes, tcp->u_arg[1], "SHUT_???");
426
427 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000428}
429
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000430SYS_FUNC(getsockname)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000431{
Dmitry V. Levin15114ec2014-08-06 16:46:13 +0000432 return do_sockname(tcp, -1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000433}
434
Dmitry V. Levin2a4f0522015-08-02 01:54:48 +0000435static void
436printpair_fd(struct tcb *tcp, const int i0, const int i1)
437{
438 tprints("[");
439 printfd(tcp, i0);
440 tprints(", ");
441 printfd(tcp, i1);
442 tprints("]");
443}
444
445static void
446decode_pair_fd(struct tcb *tcp, const long addr)
447{
448 int pair[2];
449
450 if (umove_or_printaddr(tcp, addr, &pair))
451 return;
452
453 printpair_fd(tcp, pair[0], pair[1]);
454}
455
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000456static int
457do_pipe(struct tcb *tcp, int flags_arg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000458{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000459 if (exiting(tcp)) {
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000460 decode_pair_fd(tcp, tcp->u_arg[0]);
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000461 if (flags_arg >= 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200462 tprints(", ");
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000463 printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
464 }
465 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000466 return 0;
467}
468
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000469SYS_FUNC(pipe)
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000470{
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000471#ifdef HAVE_GETRVAL2
472 if (exiting(tcp) && !syserror(tcp))
473 printpair_fd(tcp, tcp->u_rval, getrval2(tcp));
474 return 0;
475#else
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000476 return do_pipe(tcp, -1);
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000477#endif
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000478}
479
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000480SYS_FUNC(pipe2)
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000481{
482 return do_pipe(tcp, 1);
483}
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000484
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000485SYS_FUNC(socketpair)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000486{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000487 if (entering(tcp)) {
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000488 printxval(addrfams, tcp->u_arg[0], "AF_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200489 tprints(", ");
Dmitry V. Levin1e42f2d2014-09-10 17:48:28 +0000490 tprint_sock_type(tcp->u_arg[1]);
Dmitry V. Levin033fb912014-03-11 22:50:39 +0000491 tprintf(", %lu", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000492 } else {
Dmitry V. Levinb6795082015-07-06 22:33:39 +0000493 tprints(", ");
Dmitry V. Levin2a4f0522015-08-02 01:54:48 +0000494 decode_pair_fd(tcp, tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000495 }
496 return 0;
497}
498
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000499#include "xlat/sockoptions.h"
500#include "xlat/sockipoptions.h"
Mike Frysinger54646b82015-08-19 13:29:27 -0400501#include "xlat/getsockipoptions.h"
502#include "xlat/setsockipoptions.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000503#include "xlat/sockipv6options.h"
Mike Frysinger54646b82015-08-19 13:29:27 -0400504#include "xlat/getsockipv6options.h"
505#include "xlat/setsockipv6options.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000506#include "xlat/sockipxoptions.h"
507#include "xlat/sockrawoptions.h"
508#include "xlat/sockpacketoptions.h"
509#include "xlat/socksctpoptions.h"
510#include "xlat/socktcpoptions.h"
511
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000512static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +0000513print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
514 unsigned int name, bool is_getsockopt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000515{
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000516 printfd(tcp, fd);
517 tprints(", ");
John Hughes38ae88d2002-05-23 11:48:58 +0000518 printxval(socketlayers, level, "SOL_??");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200519 tprints(", ");
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000520
John Hughes38ae88d2002-05-23 11:48:58 +0000521 switch (level) {
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100522 case SOL_SOCKET:
John Hughes38ae88d2002-05-23 11:48:58 +0000523 printxval(sockoptions, name, "SO_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000524 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100525 case SOL_IP:
Mike Frysinger54646b82015-08-19 13:29:27 -0400526 printxvals(name, "IP_???", sockipoptions,
527 is_getsockopt ? getsockipoptions : setsockipoptions, NULL);
John Hughes38ae88d2002-05-23 11:48:58 +0000528 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100529 case SOL_IPV6:
Mike Frysinger54646b82015-08-19 13:29:27 -0400530 printxvals(name, "IPV6_???", sockipv6options,
531 is_getsockopt ? getsockipv6options : setsockipv6options, NULL);
Roland McGrath4f6ba692004-08-31 07:01:26 +0000532 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100533 case SOL_IPX:
John Hughes38ae88d2002-05-23 11:48:58 +0000534 printxval(sockipxoptions, name, "IPX_???");
535 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100536 case SOL_PACKET:
John Hughes38ae88d2002-05-23 11:48:58 +0000537 printxval(sockpacketoptions, name, "PACKET_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000538 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100539 case SOL_TCP:
John Hughes38ae88d2002-05-23 11:48:58 +0000540 printxval(socktcpoptions, name, "TCP_???");
541 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100542 case SOL_SCTP:
Holger Hans Peter Freyther7fea79b2011-01-14 11:08:12 +0100543 printxval(socksctpoptions, name, "SCTP_???");
544 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100545 case SOL_RAW:
John Hughes38ae88d2002-05-23 11:48:58 +0000546 printxval(sockrawoptions, name, "RAW_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000547 break;
John Hughes38ae88d2002-05-23 11:48:58 +0000548
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000549 /* Other SOL_* protocol levels still need work. */
John Hughes38ae88d2002-05-23 11:48:58 +0000550
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100551 default:
John Hughes38ae88d2002-05-23 11:48:58 +0000552 tprintf("%u", name);
553 }
554
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000555 tprints(", ");
556}
557
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000558static void
559print_linger(struct tcb *tcp, long addr, int len)
560{
561 struct linger linger;
562
563 if (len != sizeof(linger) ||
564 umove(tcp, addr, &linger) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000565 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000566 return;
567 }
568
569 tprintf("{onoff=%d, linger=%d}",
570 linger.l_onoff,
571 linger.l_linger);
572}
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000573
574#ifdef SO_PEERCRED
575static void
576print_ucred(struct tcb *tcp, long addr, int len)
577{
578 struct ucred uc;
579
580 if (len != sizeof(uc) ||
581 umove(tcp, addr, &uc) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000582 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000583 } else {
584 tprintf("{pid=%u, uid=%u, gid=%u}",
585 (unsigned) uc.pid,
586 (unsigned) uc.uid,
587 (unsigned) uc.gid);
588 }
589}
590#endif /* SO_PEERCRED */
591
592#ifdef PACKET_STATISTICS
593static void
594print_tpacket_stats(struct tcb *tcp, long addr, int len)
595{
596 struct tpacket_stats stats;
597
598 if (len != sizeof(stats) ||
599 umove(tcp, addr, &stats) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000600 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000601 } else {
602 tprintf("{packets=%u, drops=%u}",
603 stats.tp_packets,
604 stats.tp_drops);
605 }
606}
607#endif /* PACKET_STATISTICS */
608
Dmitry V. Levinfba9db22016-06-15 21:29:07 +0000609#include "xlat/icmpfilterflags.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000610
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000611static void
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000612print_icmp_filter(struct tcb *tcp, const long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000613{
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000614 struct icmp_filter filter = {};
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000615
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000616 if (len > (int) sizeof(filter))
617 len = sizeof(filter);
618 else if (len <= 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000619 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000620 return;
621 }
622
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000623 if (umoven_or_printaddr(tcp, addr, len, &filter))
624 return;
625
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000626 tprints("~(");
627 printflags(icmpfilterflags, ~filter.data, "ICMP_???");
628 tprints(")");
629}
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000630
631static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +0000632print_getsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
633 long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000634{
635 if (addr && verbose(tcp))
636 switch (level) {
637 case SOL_SOCKET:
638 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000639 case SO_LINGER:
640 print_linger(tcp, addr, len);
641 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000642#ifdef SO_PEERCRED
643 case SO_PEERCRED:
644 print_ucred(tcp, addr, len);
645 goto done;
646#endif
647 }
648 break;
649
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000650 case SOL_PACKET:
651 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000652#ifdef PACKET_STATISTICS
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000653 case PACKET_STATISTICS:
654 print_tpacket_stats(tcp, addr, len);
655 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000656#endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000657 }
658 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000659
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000660 case SOL_RAW:
661 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000662 case ICMP_FILTER:
663 print_icmp_filter(tcp, addr, len);
664 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000665 }
666 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000667 }
668
John Hughes38ae88d2002-05-23 11:48:58 +0000669 /* default arg printing */
670
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000671 if (verbose(tcp)) {
672 if (len == sizeof(int)) {
673 printnum_int(tcp, addr, "%d");
674 } else {
675 printstr(tcp, addr, len);
676 }
677 } else {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000678 printaddr(addr);
John Hughes38ae88d2002-05-23 11:48:58 +0000679 }
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000680done:
681 tprintf(", [%d]", len);
682}
683
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000684SYS_FUNC(getsockopt)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000685{
686 if (entering(tcp)) {
687 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
Mike Frysinger54646b82015-08-19 13:29:27 -0400688 tcp->u_arg[1], tcp->u_arg[2], true);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000689 } else {
690 int len;
691
692 if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &len) < 0) {
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000693 printaddr(tcp->u_arg[3]);
694 tprints(", ");
695 printaddr(tcp->u_arg[4]);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000696 } else {
697 print_getsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
698 tcp->u_arg[3], len);
699 }
John Hughes38ae88d2002-05-23 11:48:58 +0000700 }
701 return 0;
702}
703
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000704#ifdef IP_ADD_MEMBERSHIP
705static void
706print_mreq(struct tcb *tcp, long addr, unsigned int len)
707{
708 struct ip_mreq mreq;
709
710 if (len < sizeof(mreq)) {
711 printstr(tcp, addr, len);
712 return;
713 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000714 if (umove_or_printaddr(tcp, addr, &mreq))
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000715 return;
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000716
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000717 tprints("{imr_multiaddr=inet_addr(");
718 print_quoted_string(inet_ntoa(mreq.imr_multiaddr),
719 16, QUOTE_0_TERMINATED);
720 tprints("), imr_interface=inet_addr(");
721 print_quoted_string(inet_ntoa(mreq.imr_interface),
722 16, QUOTE_0_TERMINATED);
723 tprints(")}");
724}
725#endif /* IP_ADD_MEMBERSHIP */
726
727#ifdef IPV6_ADD_MEMBERSHIP
728static void
729print_mreq6(struct tcb *tcp, long addr, unsigned int len)
730{
731 struct ipv6_mreq mreq;
732
733 if (len < sizeof(mreq))
734 goto fail;
735
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000736 if (umove_or_printaddr(tcp, addr, &mreq))
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000737 return;
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000738
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000739 const struct in6_addr *in6 = &mreq.ipv6mr_multiaddr;
740 char address[INET6_ADDRSTRLEN];
741
742 if (!inet_ntop(AF_INET6, in6, address, sizeof(address)))
743 goto fail;
744
745 tprints("{ipv6mr_multiaddr=inet_pton(");
746 print_quoted_string(address, sizeof(address), QUOTE_0_TERMINATED);
747 tprints("), ipv6mr_interface=");
748 print_ifindex(mreq.ipv6mr_interface);
749 tprints("}");
750 return;
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000751
752fail:
753 printstr(tcp, addr, len);
754}
755#endif /* IPV6_ADD_MEMBERSHIP */
756
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000757#ifdef MCAST_JOIN_GROUP
758static void
759print_group_req(struct tcb *tcp, long addr, int len)
760{
761 struct group_req greq;
762
763 if (len != sizeof(greq) ||
764 umove(tcp, addr, &greq) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000765 printaddr(addr);
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000766 return;
767 }
768
Dmitry V. Levin1019f002015-11-21 02:38:59 +0000769 tprintf("{gr_interface=%u, gr_group=", greq.gr_interface);
Dmitry V. Levin3bf9c192016-06-21 16:45:40 +0000770 print_sockaddr(tcp, &greq.gr_group, sizeof(greq.gr_group));
Dmitry V. Levin1019f002015-11-21 02:38:59 +0000771 tprintf("}");
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000772
773}
774#endif /* MCAST_JOIN_GROUP */
775
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000776#ifdef PACKET_RX_RING
777static void
778print_tpacket_req(struct tcb *tcp, long addr, int len)
779{
780 struct tpacket_req req;
781
782 if (len != sizeof(req) ||
783 umove(tcp, addr, &req) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000784 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000785 } else {
786 tprintf("{block_size=%u, block_nr=%u, "
787 "frame_size=%u, frame_nr=%u}",
788 req.tp_block_size,
789 req.tp_block_nr,
790 req.tp_frame_size,
791 req.tp_frame_nr);
792 }
793}
794#endif /* PACKET_RX_RING */
795
Dmitry V. Levin02f2f092015-01-29 03:26:53 +0000796#ifdef PACKET_ADD_MEMBERSHIP
797# include "xlat/packet_mreq_type.h"
798
799static void
800print_packet_mreq(struct tcb *tcp, long addr, int len)
801{
802 struct packet_mreq mreq;
803
804 if (len != sizeof(mreq) ||
805 umove(tcp, addr, &mreq) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000806 printaddr(addr);
Dmitry V. Levin02f2f092015-01-29 03:26:53 +0000807 } else {
808 unsigned int i;
809
810 tprintf("{mr_ifindex=%u, mr_type=", mreq.mr_ifindex);
811 printxval(packet_mreq_type, mreq.mr_type, "PACKET_MR_???");
812 tprintf(", mr_alen=%u, mr_address=", mreq.mr_alen);
813 if (mreq.mr_alen > ARRAY_SIZE(mreq.mr_address))
814 mreq.mr_alen = ARRAY_SIZE(mreq.mr_address);
815 for (i = 0; i < mreq.mr_alen; ++i)
816 tprintf("%02x", mreq.mr_address[i]);
817 tprints("}");
818 }
819}
820#endif /* PACKET_ADD_MEMBERSHIP */
821
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000822static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +0000823print_setsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
824 long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000825{
826 if (addr && verbose(tcp))
827 switch (level) {
828 case SOL_SOCKET:
829 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000830 case SO_LINGER:
831 print_linger(tcp, addr, len);
832 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000833 }
834 break;
835
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000836 case SOL_IP:
837 switch (name) {
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000838#ifdef IP_ADD_MEMBERSHIP
839 case IP_ADD_MEMBERSHIP:
840 case IP_DROP_MEMBERSHIP:
841 print_mreq(tcp, addr, len);
842 goto done;
843#endif /* IP_ADD_MEMBERSHIP */
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000844#ifdef MCAST_JOIN_GROUP
845 case MCAST_JOIN_GROUP:
846 case MCAST_LEAVE_GROUP:
847 print_group_req(tcp, addr, len);
848 goto done;
849#endif /* MCAST_JOIN_GROUP */
850 }
Dmitry V. Levin3910d0f2015-02-08 01:19:06 +0000851 break;
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000852
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000853 case SOL_IPV6:
854 switch (name) {
855#ifdef IPV6_ADD_MEMBERSHIP
856 case IPV6_ADD_MEMBERSHIP:
857 case IPV6_DROP_MEMBERSHIP:
858# ifdef IPV6_JOIN_ANYCAST
859 case IPV6_JOIN_ANYCAST:
860# endif
861# ifdef IPV6_LEAVE_ANYCAST
862 case IPV6_LEAVE_ANYCAST:
863# endif
864 print_mreq6(tcp, addr, len);
865 goto done;
866#endif /* IPV6_ADD_MEMBERSHIP */
867 }
868 break;
869
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000870 case SOL_PACKET:
871 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000872#ifdef PACKET_RX_RING
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000873 case PACKET_RX_RING:
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000874# ifdef PACKET_TX_RING
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000875 case PACKET_TX_RING:
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000876# endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000877 print_tpacket_req(tcp, addr, len);
878 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000879#endif /* PACKET_RX_RING */
880#ifdef PACKET_ADD_MEMBERSHIP
Dmitry V. Levin02f2f092015-01-29 03:26:53 +0000881 case PACKET_ADD_MEMBERSHIP:
882 case PACKET_DROP_MEMBERSHIP:
883 print_packet_mreq(tcp, addr, len);
884 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000885#endif /* PACKET_ADD_MEMBERSHIP */
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000886 }
887 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000888
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000889 case SOL_RAW:
890 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000891 case ICMP_FILTER:
892 print_icmp_filter(tcp, addr, len);
893 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000894 }
895 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000896 }
897
898 /* default arg printing */
899
900 if (verbose(tcp)) {
901 if (len == sizeof(int)) {
902 printnum_int(tcp, addr, "%d");
903 } else {
904 printstr(tcp, addr, len);
905 }
906 } else {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000907 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000908 }
909done:
910 tprintf(", %d", len);
911}
912
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000913SYS_FUNC(setsockopt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000914{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000915 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
Mike Frysinger54646b82015-08-19 13:29:27 -0400916 tcp->u_arg[1], tcp->u_arg[2], false);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000917 print_setsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
918 tcp->u_arg[3], tcp->u_arg[4]);
919
920 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000921}