blob: bd11741ead4ff4714e9de44c6a51806810759db9 [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
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000192static bool
193fetch_socklen(struct tcb *tcp, int *plen,
194 const unsigned long sockaddr, const unsigned long socklen)
195{
196 return verbose(tcp) && sockaddr && socklen
197 && umove(tcp, socklen, plen) == 0;
198}
199
Paolo Bonzini705ff102009-08-14 12:34:05 +0200200static int
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000201decode_sockname(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000202{
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000203 int ulen, rlen;
204
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000205 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800206 printfd(tcp, tcp->u_arg[0]);
207 tprints(", ");
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000208 if (fetch_socklen(tcp, &ulen, tcp->u_arg[1], tcp->u_arg[2])) {
209 /* abuse of auxstr to retain state */
210 tcp->auxstr = (void *) (long) ulen;
211 return 0;
212 } else {
213 printaddr(tcp->u_arg[1]);
214 tprints(", ");
215 printaddr(tcp->u_arg[2]);
216 return RVAL_DECODED;
217 }
Paolo Bonzini705ff102009-08-14 12:34:05 +0200218 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000219
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000220 ulen = (long) tcp->auxstr;
221 tcp->auxstr = NULL;
222
223 if (syserror(tcp) || umove(tcp, tcp->u_arg[2], &rlen) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000224 printaddr(tcp->u_arg[1]);
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000225 tprintf(", [%d]", ulen);
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000226 } else {
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000227 decode_sockaddr(tcp, tcp->u_arg[1], ulen > rlen ? rlen : ulen);
Dmitry V. Levineca8b5b2016-07-09 21:52:58 +0000228 if (ulen != rlen)
Dmitry V. Levin36df8222016-07-09 21:52:51 +0000229 tprintf(", [%d->%d]", ulen, rlen);
230 else
231 tprintf(", [%d]", rlen);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000232 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000233
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000234 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000235}
236
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000237SYS_FUNC(accept)
Paolo Bonzini705ff102009-08-14 12:34:05 +0200238{
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000239 return decode_sockname(tcp) | RVAL_FD;
Paolo Bonzini705ff102009-08-14 12:34:05 +0200240}
241
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000242SYS_FUNC(accept4)
Paolo Bonzini705ff102009-08-14 12:34:05 +0200243{
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000244 int rc = decode_sockname(tcp);
245
246 if (rc & RVAL_DECODED) {
247 tprints(", ");
248 printflags(sock_type_flags, tcp->u_arg[3], "SOCK_???");
249 }
250
251 return rc | RVAL_FD;
Paolo Bonzini705ff102009-08-14 12:34:05 +0200252}
Paolo Bonzini705ff102009-08-14 12:34:05 +0200253
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000254SYS_FUNC(send)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000255{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000256 printfd(tcp, tcp->u_arg[0]);
257 tprints(", ");
Fabien Siron2850f742016-07-06 15:49:22 +0000258 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000259 tprintf(", %lu, ", tcp->u_arg[2]);
260 /* flags */
261 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
262
263 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000264}
265
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000266SYS_FUNC(sendto)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000267{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000268 printfd(tcp, tcp->u_arg[0]);
269 tprints(", ");
Fabien Siron2850f742016-07-06 15:49:22 +0000270 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000271 tprintf(", %lu, ", tcp->u_arg[2]);
272 /* flags */
273 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
274 /* to address */
275 tprints(", ");
Dmitry V. Levin42e566a2016-06-25 11:31:48 +0000276 decode_sockaddr(tcp, tcp->u_arg[4], tcp->u_arg[5]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000277 /* to length */
278 tprintf(", %lu", tcp->u_arg[5]);
279
280 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000281}
282
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000283SYS_FUNC(sendmsg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000284{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000285 printfd(tcp, tcp->u_arg[0]);
286 tprints(", ");
Dmitry V. Levin3e514c02016-06-26 23:57:29 +0000287 decode_msghdr(tcp, tcp->u_arg[1], (unsigned long) -1L);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000288 /* flags */
289 tprints(", ");
290 printflags(msg_flags, tcp->u_arg[2], "MSG_???");
291
292 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000293}
294
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000295SYS_FUNC(sendmmsg)
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000296{
297 if (entering(tcp)) {
298 /* sockfd */
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800299 printfd(tcp, tcp->u_arg[0]);
300 tprints(", ");
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000301 if (!verbose(tcp)) {
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000302 printaddr(tcp->u_arg[1]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000303 /* vlen */
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000304 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000305 /* flags */
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000306 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000307 return RVAL_DECODED;
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000308 }
309 } else {
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000310 decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval, false);
311 /* vlen */
312 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
313 /* flags */
314 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000315 }
316 return 0;
317}
318
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000319SYS_FUNC(recv)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000320{
321 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800322 printfd(tcp, tcp->u_arg[0]);
323 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000324 } else {
Fabien Siron2850f742016-07-06 15:49:22 +0000325 if (syserror(tcp)) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000326 printaddr(tcp->u_arg[1]);
Fabien Siron2850f742016-07-06 15:49:22 +0000327 } else {
328 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
329 tcp->u_rval);
330 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000331
332 tprintf(", %lu, ", tcp->u_arg[2]);
Roland McGrathb2dee132005-06-01 19:02:36 +0000333 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000334 }
335 return 0;
336}
337
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000338SYS_FUNC(recvfrom)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000339{
340 int fromlen;
341
342 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800343 printfd(tcp, tcp->u_arg[0]);
344 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000345 } else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000346 /* buf */
Denys Vlasenko383386d2015-07-30 13:29:20 +0200347 if (syserror(tcp)) {
Dmitry V. Levin52dc1502015-07-30 13:53:42 +0000348 printaddr(tcp->u_arg[1]);
Denys Vlasenko383386d2015-07-30 13:29:20 +0200349 } else {
Fabien Siron2850f742016-07-06 15:49:22 +0000350 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
351 tcp->u_rval);
Denys Vlasenko383386d2015-07-30 13:29:20 +0200352 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000353 /* len */
354 tprintf(", %lu, ", tcp->u_arg[2]);
355 /* flags */
Roland McGrathb2dee132005-06-01 19:02:36 +0000356 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200357 tprints(", ");
Dmitry V. Levin52dc1502015-07-30 13:53:42 +0000358 if (syserror(tcp) || !tcp->u_arg[4] || !tcp->u_arg[5] ||
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000359 umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
Denys Vlasenko383386d2015-07-30 13:29:20 +0200360 /* from address, len */
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000361 printaddr(tcp->u_arg[4]);
362 tprints(", ");
363 printaddr(tcp->u_arg[5]);
364 return 0;
365 }
Denys Vlasenko383386d2015-07-30 13:29:20 +0200366 /* from address */
Dmitry V. Levin42e566a2016-06-25 11:31:48 +0000367 decode_sockaddr(tcp, tcp->u_arg[4], fromlen);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000368 /* from length */
369 tprintf(", [%u]", fromlen);
370 }
371 return 0;
372}
373
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000374SYS_FUNC(recvmsg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000375{
376 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800377 printfd(tcp, tcp->u_arg[0]);
378 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000379 } else {
Dmitry V. Levin00244b92015-01-28 01:52:25 +0000380 if (syserror(tcp))
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000381 printaddr(tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000382 else
Dmitry V. Levin3e514c02016-06-26 23:57:29 +0000383 decode_msghdr(tcp, tcp->u_arg[1], tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000384 /* flags */
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200385 tprints(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +0000386 printflags(msg_flags, tcp->u_arg[2], "MSG_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000387 }
388 return 0;
389}
390
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000391SYS_FUNC(recvmmsg)
Andreas Schwab0873f292010-02-12 21:39:12 +0100392{
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000393 static char str[sizeof("left") + TIMESPEC_TEXT_BUFSIZE];
Dmitry V. Levine6591032010-03-29 20:45:48 +0400394
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100395 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800396 printfd(tcp, tcp->u_arg[0]);
397 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +0400398 if (verbose(tcp)) {
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100399 /* Abusing tcp->auxstr as temp storage.
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000400 * Will be used and cleared on syscall exit.
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100401 */
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000402 tcp->auxstr = sprint_timespec(tcp, tcp->u_arg[4]);
Dmitry V. Levine6591032010-03-29 20:45:48 +0400403 } else {
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000404 printaddr(tcp->u_arg[1]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000405 /* vlen */
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000406 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000407 /* flags */
Dmitry V. Levine6591032010-03-29 20:45:48 +0400408 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200409 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +0400410 print_timespec(tcp, tcp->u_arg[4]);
411 }
412 return 0;
413 } else {
414 if (verbose(tcp)) {
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000415 decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval, true);
416 /* vlen */
417 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
418 /* flags */
419 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000420 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +0400421 /* timeout on entrance */
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000422 tprints(tcp->auxstr);
Dmitry V. Levine6591032010-03-29 20:45:48 +0400423 tcp->auxstr = NULL;
424 }
425 if (syserror(tcp))
426 return 0;
427 if (tcp->u_rval == 0) {
428 tcp->auxstr = "Timeout";
429 return RVAL_STR;
430 }
431 if (!verbose(tcp))
432 return 0;
433 /* timeout on exit */
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000434 snprintf(str, sizeof(str), "left %s",
435 sprint_timespec(tcp, tcp->u_arg[4]));
Dmitry V. Levine6591032010-03-29 20:45:48 +0400436 tcp->auxstr = str;
437 return RVAL_STR;
Andreas Schwab0873f292010-02-12 21:39:12 +0100438 }
Andreas Schwab0873f292010-02-12 21:39:12 +0100439}
Andreas Schwab0873f292010-02-12 21:39:12 +0100440
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000441#include "xlat/shutdown_modes.h"
Sebastian Pipping9cd38502011-03-03 01:12:25 +0100442
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000443SYS_FUNC(shutdown)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000444{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000445 printfd(tcp, tcp->u_arg[0]);
446 tprints(", ");
447 printxval(shutdown_modes, tcp->u_arg[1], "SHUT_???");
448
449 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000450}
451
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000452SYS_FUNC(getsockname)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000453{
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000454 return decode_sockname(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000455}
456
Dmitry V. Levin2a4f0522015-08-02 01:54:48 +0000457static void
458printpair_fd(struct tcb *tcp, const int i0, const int i1)
459{
460 tprints("[");
461 printfd(tcp, i0);
462 tprints(", ");
463 printfd(tcp, i1);
464 tprints("]");
465}
466
467static void
468decode_pair_fd(struct tcb *tcp, const long addr)
469{
470 int pair[2];
471
472 if (umove_or_printaddr(tcp, addr, &pair))
473 return;
474
475 printpair_fd(tcp, pair[0], pair[1]);
476}
477
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000478static int
479do_pipe(struct tcb *tcp, int flags_arg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000480{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000481 if (exiting(tcp)) {
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000482 decode_pair_fd(tcp, tcp->u_arg[0]);
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000483 if (flags_arg >= 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200484 tprints(", ");
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000485 printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
486 }
487 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000488 return 0;
489}
490
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000491SYS_FUNC(pipe)
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000492{
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000493#ifdef HAVE_GETRVAL2
494 if (exiting(tcp) && !syserror(tcp))
495 printpair_fd(tcp, tcp->u_rval, getrval2(tcp));
496 return 0;
497#else
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000498 return do_pipe(tcp, -1);
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000499#endif
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000500}
501
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000502SYS_FUNC(pipe2)
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000503{
504 return do_pipe(tcp, 1);
505}
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000506
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000507SYS_FUNC(socketpair)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000508{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000509 if (entering(tcp)) {
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000510 printxval(addrfams, tcp->u_arg[0], "AF_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200511 tprints(", ");
Dmitry V. Levin1e42f2d2014-09-10 17:48:28 +0000512 tprint_sock_type(tcp->u_arg[1]);
Dmitry V. Levin033fb912014-03-11 22:50:39 +0000513 tprintf(", %lu", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000514 } else {
Dmitry V. Levinb6795082015-07-06 22:33:39 +0000515 tprints(", ");
Dmitry V. Levin2a4f0522015-08-02 01:54:48 +0000516 decode_pair_fd(tcp, tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000517 }
518 return 0;
519}
520
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000521#include "xlat/sockoptions.h"
522#include "xlat/sockipoptions.h"
Mike Frysinger54646b82015-08-19 13:29:27 -0400523#include "xlat/getsockipoptions.h"
524#include "xlat/setsockipoptions.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000525#include "xlat/sockipv6options.h"
Mike Frysinger54646b82015-08-19 13:29:27 -0400526#include "xlat/getsockipv6options.h"
527#include "xlat/setsockipv6options.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000528#include "xlat/sockipxoptions.h"
529#include "xlat/sockrawoptions.h"
530#include "xlat/sockpacketoptions.h"
531#include "xlat/socksctpoptions.h"
532#include "xlat/socktcpoptions.h"
533
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000534static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +0000535print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
536 unsigned int name, bool is_getsockopt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000537{
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000538 printfd(tcp, fd);
539 tprints(", ");
John Hughes38ae88d2002-05-23 11:48:58 +0000540 printxval(socketlayers, level, "SOL_??");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200541 tprints(", ");
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000542
John Hughes38ae88d2002-05-23 11:48:58 +0000543 switch (level) {
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100544 case SOL_SOCKET:
John Hughes38ae88d2002-05-23 11:48:58 +0000545 printxval(sockoptions, name, "SO_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000546 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100547 case SOL_IP:
Mike Frysinger54646b82015-08-19 13:29:27 -0400548 printxvals(name, "IP_???", sockipoptions,
549 is_getsockopt ? getsockipoptions : setsockipoptions, NULL);
John Hughes38ae88d2002-05-23 11:48:58 +0000550 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100551 case SOL_IPV6:
Mike Frysinger54646b82015-08-19 13:29:27 -0400552 printxvals(name, "IPV6_???", sockipv6options,
553 is_getsockopt ? getsockipv6options : setsockipv6options, NULL);
Roland McGrath4f6ba692004-08-31 07:01:26 +0000554 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100555 case SOL_IPX:
John Hughes38ae88d2002-05-23 11:48:58 +0000556 printxval(sockipxoptions, name, "IPX_???");
557 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100558 case SOL_PACKET:
John Hughes38ae88d2002-05-23 11:48:58 +0000559 printxval(sockpacketoptions, name, "PACKET_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000560 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100561 case SOL_TCP:
John Hughes38ae88d2002-05-23 11:48:58 +0000562 printxval(socktcpoptions, name, "TCP_???");
563 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100564 case SOL_SCTP:
Holger Hans Peter Freyther7fea79b2011-01-14 11:08:12 +0100565 printxval(socksctpoptions, name, "SCTP_???");
566 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100567 case SOL_RAW:
John Hughes38ae88d2002-05-23 11:48:58 +0000568 printxval(sockrawoptions, name, "RAW_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000569 break;
John Hughes38ae88d2002-05-23 11:48:58 +0000570
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000571 /* Other SOL_* protocol levels still need work. */
John Hughes38ae88d2002-05-23 11:48:58 +0000572
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100573 default:
John Hughes38ae88d2002-05-23 11:48:58 +0000574 tprintf("%u", name);
575 }
576
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000577 tprints(", ");
578}
579
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000580static void
581print_linger(struct tcb *tcp, long addr, int len)
582{
583 struct linger linger;
584
585 if (len != sizeof(linger) ||
586 umove(tcp, addr, &linger) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000587 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000588 return;
589 }
590
591 tprintf("{onoff=%d, linger=%d}",
592 linger.l_onoff,
593 linger.l_linger);
594}
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000595
596#ifdef SO_PEERCRED
597static void
598print_ucred(struct tcb *tcp, long addr, int len)
599{
600 struct ucred uc;
601
602 if (len != sizeof(uc) ||
603 umove(tcp, addr, &uc) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000604 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000605 } else {
606 tprintf("{pid=%u, uid=%u, gid=%u}",
607 (unsigned) uc.pid,
608 (unsigned) uc.uid,
609 (unsigned) uc.gid);
610 }
611}
612#endif /* SO_PEERCRED */
613
614#ifdef PACKET_STATISTICS
615static void
616print_tpacket_stats(struct tcb *tcp, long addr, int len)
617{
618 struct tpacket_stats stats;
619
620 if (len != sizeof(stats) ||
621 umove(tcp, addr, &stats) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000622 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000623 } else {
624 tprintf("{packets=%u, drops=%u}",
625 stats.tp_packets,
626 stats.tp_drops);
627 }
628}
629#endif /* PACKET_STATISTICS */
630
Dmitry V. Levinfba9db22016-06-15 21:29:07 +0000631#include "xlat/icmpfilterflags.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000632
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000633static void
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000634print_icmp_filter(struct tcb *tcp, const long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000635{
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000636 struct icmp_filter filter = {};
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000637
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000638 if (len > (int) sizeof(filter))
639 len = sizeof(filter);
640 else if (len <= 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000641 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000642 return;
643 }
644
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000645 if (umoven_or_printaddr(tcp, addr, len, &filter))
646 return;
647
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000648 tprints("~(");
649 printflags(icmpfilterflags, ~filter.data, "ICMP_???");
650 tprints(")");
651}
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000652
653static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +0000654print_getsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
655 long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000656{
657 if (addr && verbose(tcp))
658 switch (level) {
659 case SOL_SOCKET:
660 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000661 case SO_LINGER:
662 print_linger(tcp, addr, len);
663 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000664#ifdef SO_PEERCRED
665 case SO_PEERCRED:
666 print_ucred(tcp, addr, len);
667 goto done;
668#endif
669 }
670 break;
671
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000672 case SOL_PACKET:
673 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000674#ifdef PACKET_STATISTICS
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000675 case PACKET_STATISTICS:
676 print_tpacket_stats(tcp, addr, len);
677 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000678#endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000679 }
680 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000681
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000682 case SOL_RAW:
683 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000684 case ICMP_FILTER:
685 print_icmp_filter(tcp, addr, len);
686 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000687 }
688 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000689 }
690
John Hughes38ae88d2002-05-23 11:48:58 +0000691 /* default arg printing */
692
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000693 if (verbose(tcp)) {
694 if (len == sizeof(int)) {
695 printnum_int(tcp, addr, "%d");
696 } else {
697 printstr(tcp, addr, len);
698 }
699 } else {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000700 printaddr(addr);
John Hughes38ae88d2002-05-23 11:48:58 +0000701 }
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000702done:
703 tprintf(", [%d]", len);
704}
705
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000706SYS_FUNC(getsockopt)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000707{
708 if (entering(tcp)) {
709 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
Mike Frysinger54646b82015-08-19 13:29:27 -0400710 tcp->u_arg[1], tcp->u_arg[2], true);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000711 } else {
712 int len;
713
714 if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &len) < 0) {
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000715 printaddr(tcp->u_arg[3]);
716 tprints(", ");
717 printaddr(tcp->u_arg[4]);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000718 } else {
719 print_getsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
720 tcp->u_arg[3], len);
721 }
John Hughes38ae88d2002-05-23 11:48:58 +0000722 }
723 return 0;
724}
725
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000726#ifdef IP_ADD_MEMBERSHIP
727static void
728print_mreq(struct tcb *tcp, long addr, unsigned int len)
729{
730 struct ip_mreq mreq;
731
732 if (len < sizeof(mreq)) {
733 printstr(tcp, addr, len);
734 return;
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. Levin6c277da2015-07-19 22:36:46 +0000738
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000739 tprints("{imr_multiaddr=inet_addr(");
740 print_quoted_string(inet_ntoa(mreq.imr_multiaddr),
741 16, QUOTE_0_TERMINATED);
742 tprints("), imr_interface=inet_addr(");
743 print_quoted_string(inet_ntoa(mreq.imr_interface),
744 16, QUOTE_0_TERMINATED);
745 tprints(")}");
746}
747#endif /* IP_ADD_MEMBERSHIP */
748
749#ifdef IPV6_ADD_MEMBERSHIP
750static void
751print_mreq6(struct tcb *tcp, long addr, unsigned int len)
752{
753 struct ipv6_mreq mreq;
754
755 if (len < sizeof(mreq))
756 goto fail;
757
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000758 if (umove_or_printaddr(tcp, addr, &mreq))
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000759 return;
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000760
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000761 const struct in6_addr *in6 = &mreq.ipv6mr_multiaddr;
762 char address[INET6_ADDRSTRLEN];
763
764 if (!inet_ntop(AF_INET6, in6, address, sizeof(address)))
765 goto fail;
766
767 tprints("{ipv6mr_multiaddr=inet_pton(");
768 print_quoted_string(address, sizeof(address), QUOTE_0_TERMINATED);
769 tprints("), ipv6mr_interface=");
770 print_ifindex(mreq.ipv6mr_interface);
771 tprints("}");
772 return;
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000773
774fail:
775 printstr(tcp, addr, len);
776}
777#endif /* IPV6_ADD_MEMBERSHIP */
778
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000779#ifdef MCAST_JOIN_GROUP
780static void
781print_group_req(struct tcb *tcp, long addr, int len)
782{
783 struct group_req greq;
784
785 if (len != sizeof(greq) ||
786 umove(tcp, addr, &greq) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000787 printaddr(addr);
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000788 return;
789 }
790
Dmitry V. Levin1019f002015-11-21 02:38:59 +0000791 tprintf("{gr_interface=%u, gr_group=", greq.gr_interface);
Dmitry V. Levin3bf9c192016-06-21 16:45:40 +0000792 print_sockaddr(tcp, &greq.gr_group, sizeof(greq.gr_group));
Dmitry V. Levin1019f002015-11-21 02:38:59 +0000793 tprintf("}");
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000794
795}
796#endif /* MCAST_JOIN_GROUP */
797
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000798#ifdef PACKET_RX_RING
799static void
800print_tpacket_req(struct tcb *tcp, long addr, int len)
801{
802 struct tpacket_req req;
803
804 if (len != sizeof(req) ||
805 umove(tcp, addr, &req) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000806 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000807 } else {
808 tprintf("{block_size=%u, block_nr=%u, "
809 "frame_size=%u, frame_nr=%u}",
810 req.tp_block_size,
811 req.tp_block_nr,
812 req.tp_frame_size,
813 req.tp_frame_nr);
814 }
815}
816#endif /* PACKET_RX_RING */
817
Dmitry V. Levin02f2f092015-01-29 03:26:53 +0000818#ifdef PACKET_ADD_MEMBERSHIP
819# include "xlat/packet_mreq_type.h"
820
821static void
822print_packet_mreq(struct tcb *tcp, long addr, int len)
823{
824 struct packet_mreq mreq;
825
826 if (len != sizeof(mreq) ||
827 umove(tcp, addr, &mreq) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000828 printaddr(addr);
Dmitry V. Levin02f2f092015-01-29 03:26:53 +0000829 } else {
830 unsigned int i;
831
832 tprintf("{mr_ifindex=%u, mr_type=", mreq.mr_ifindex);
833 printxval(packet_mreq_type, mreq.mr_type, "PACKET_MR_???");
834 tprintf(", mr_alen=%u, mr_address=", mreq.mr_alen);
835 if (mreq.mr_alen > ARRAY_SIZE(mreq.mr_address))
836 mreq.mr_alen = ARRAY_SIZE(mreq.mr_address);
837 for (i = 0; i < mreq.mr_alen; ++i)
838 tprintf("%02x", mreq.mr_address[i]);
839 tprints("}");
840 }
841}
842#endif /* PACKET_ADD_MEMBERSHIP */
843
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000844static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +0000845print_setsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
846 long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000847{
848 if (addr && verbose(tcp))
849 switch (level) {
850 case SOL_SOCKET:
851 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000852 case SO_LINGER:
853 print_linger(tcp, addr, len);
854 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000855 }
856 break;
857
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000858 case SOL_IP:
859 switch (name) {
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000860#ifdef IP_ADD_MEMBERSHIP
861 case IP_ADD_MEMBERSHIP:
862 case IP_DROP_MEMBERSHIP:
863 print_mreq(tcp, addr, len);
864 goto done;
865#endif /* IP_ADD_MEMBERSHIP */
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000866#ifdef MCAST_JOIN_GROUP
867 case MCAST_JOIN_GROUP:
868 case MCAST_LEAVE_GROUP:
869 print_group_req(tcp, addr, len);
870 goto done;
871#endif /* MCAST_JOIN_GROUP */
872 }
Dmitry V. Levin3910d0f2015-02-08 01:19:06 +0000873 break;
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000874
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000875 case SOL_IPV6:
876 switch (name) {
877#ifdef IPV6_ADD_MEMBERSHIP
878 case IPV6_ADD_MEMBERSHIP:
879 case IPV6_DROP_MEMBERSHIP:
880# ifdef IPV6_JOIN_ANYCAST
881 case IPV6_JOIN_ANYCAST:
882# endif
883# ifdef IPV6_LEAVE_ANYCAST
884 case IPV6_LEAVE_ANYCAST:
885# endif
886 print_mreq6(tcp, addr, len);
887 goto done;
888#endif /* IPV6_ADD_MEMBERSHIP */
889 }
890 break;
891
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000892 case SOL_PACKET:
893 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000894#ifdef PACKET_RX_RING
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000895 case PACKET_RX_RING:
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000896# ifdef PACKET_TX_RING
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000897 case PACKET_TX_RING:
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000898# endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000899 print_tpacket_req(tcp, addr, len);
900 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000901#endif /* PACKET_RX_RING */
902#ifdef PACKET_ADD_MEMBERSHIP
Dmitry V. Levin02f2f092015-01-29 03:26:53 +0000903 case PACKET_ADD_MEMBERSHIP:
904 case PACKET_DROP_MEMBERSHIP:
905 print_packet_mreq(tcp, addr, len);
906 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000907#endif /* PACKET_ADD_MEMBERSHIP */
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000908 }
909 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000910
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000911 case SOL_RAW:
912 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000913 case ICMP_FILTER:
914 print_icmp_filter(tcp, addr, len);
915 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000916 }
917 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000918 }
919
920 /* default arg printing */
921
922 if (verbose(tcp)) {
923 if (len == sizeof(int)) {
924 printnum_int(tcp, addr, "%d");
925 } else {
926 printstr(tcp, addr, len);
927 }
928 } else {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000929 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000930 }
931done:
932 tprintf(", %d", len);
933}
934
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000935SYS_FUNC(setsockopt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000936{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000937 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
Mike Frysinger54646b82015-08-19 13:29:27 -0400938 tcp->u_arg[1], tcp->u_arg[2], false);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000939 print_setsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
940 tcp->u_arg[3], tcp->u_arg[4]);
941
942 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000943}