blob: 16b42b5b89729e0fad6d8bdb10ef44836faa711b [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. Levin7acde9e2016-07-12 09:17:30 +0000177 const int addrlen = tcp->u_arg[2];
178 decode_sockaddr(tcp, tcp->u_arg[1], addrlen);
179 tprintf(", %d", addrlen);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000180
181 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000182}
183
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000184SYS_FUNC(listen)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000185{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000186 printfd(tcp, tcp->u_arg[0]);
187 tprints(", ");
188 tprintf("%lu", tcp->u_arg[1]);
189
190 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000191}
192
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000193static bool
194fetch_socklen(struct tcb *tcp, int *plen,
195 const unsigned long sockaddr, const unsigned long socklen)
196{
197 return verbose(tcp) && sockaddr && socklen
198 && umove(tcp, socklen, plen) == 0;
199}
200
Paolo Bonzini705ff102009-08-14 12:34:05 +0200201static int
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000202decode_sockname(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000203{
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000204 int ulen, rlen;
205
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000206 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800207 printfd(tcp, tcp->u_arg[0]);
208 tprints(", ");
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000209 if (fetch_socklen(tcp, &ulen, tcp->u_arg[1], tcp->u_arg[2])) {
210 /* abuse of auxstr to retain state */
211 tcp->auxstr = (void *) (long) ulen;
212 return 0;
213 } else {
214 printaddr(tcp->u_arg[1]);
215 tprints(", ");
216 printaddr(tcp->u_arg[2]);
217 return RVAL_DECODED;
218 }
Paolo Bonzini705ff102009-08-14 12:34:05 +0200219 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000220
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000221 ulen = (long) tcp->auxstr;
222 tcp->auxstr = NULL;
223
224 if (syserror(tcp) || umove(tcp, tcp->u_arg[2], &rlen) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000225 printaddr(tcp->u_arg[1]);
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000226 tprintf(", [%d]", ulen);
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000227 } else {
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000228 decode_sockaddr(tcp, tcp->u_arg[1], ulen > rlen ? rlen : ulen);
Dmitry V. Levineca8b5b2016-07-09 21:52:58 +0000229 if (ulen != rlen)
Dmitry V. Levin36df8222016-07-09 21:52:51 +0000230 tprintf(", [%d->%d]", ulen, rlen);
231 else
232 tprintf(", [%d]", rlen);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000233 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000234
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000235 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000236}
237
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000238SYS_FUNC(accept)
Paolo Bonzini705ff102009-08-14 12:34:05 +0200239{
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000240 return decode_sockname(tcp) | RVAL_FD;
Paolo Bonzini705ff102009-08-14 12:34:05 +0200241}
242
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000243SYS_FUNC(accept4)
Paolo Bonzini705ff102009-08-14 12:34:05 +0200244{
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000245 int rc = decode_sockname(tcp);
246
247 if (rc & RVAL_DECODED) {
248 tprints(", ");
249 printflags(sock_type_flags, tcp->u_arg[3], "SOCK_???");
250 }
251
252 return rc | RVAL_FD;
Paolo Bonzini705ff102009-08-14 12:34:05 +0200253}
Paolo Bonzini705ff102009-08-14 12:34:05 +0200254
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000255SYS_FUNC(send)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000256{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000257 printfd(tcp, tcp->u_arg[0]);
258 tprints(", ");
Fabien Siron2850f742016-07-06 15:49:22 +0000259 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000260 tprintf(", %lu, ", tcp->u_arg[2]);
261 /* flags */
262 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
263
264 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000265}
266
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000267SYS_FUNC(sendto)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000268{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000269 printfd(tcp, tcp->u_arg[0]);
270 tprints(", ");
Fabien Siron2850f742016-07-06 15:49:22 +0000271 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000272 tprintf(", %lu, ", tcp->u_arg[2]);
273 /* flags */
274 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
275 /* to address */
Dmitry V. Levin7acde9e2016-07-12 09:17:30 +0000276 const int addrlen = tcp->u_arg[5];
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000277 tprints(", ");
Dmitry V. Levin7acde9e2016-07-12 09:17:30 +0000278 decode_sockaddr(tcp, tcp->u_arg[4], addrlen);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000279 /* to length */
Dmitry V. Levin7acde9e2016-07-12 09:17:30 +0000280 tprintf(", %d", addrlen);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000281
282 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000283}
284
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000285SYS_FUNC(sendmsg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000286{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000287 printfd(tcp, tcp->u_arg[0]);
288 tprints(", ");
Dmitry V. Levin3e514c02016-06-26 23:57:29 +0000289 decode_msghdr(tcp, tcp->u_arg[1], (unsigned long) -1L);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000290 /* flags */
291 tprints(", ");
292 printflags(msg_flags, tcp->u_arg[2], "MSG_???");
293
294 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000295}
296
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000297SYS_FUNC(sendmmsg)
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000298{
299 if (entering(tcp)) {
300 /* sockfd */
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800301 printfd(tcp, tcp->u_arg[0]);
302 tprints(", ");
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000303 if (!verbose(tcp)) {
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000304 printaddr(tcp->u_arg[1]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000305 /* vlen */
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000306 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000307 /* flags */
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000308 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000309 return RVAL_DECODED;
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000310 }
311 } else {
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000312 decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval, false);
313 /* vlen */
314 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
315 /* flags */
316 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000317 }
318 return 0;
319}
320
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000321SYS_FUNC(recv)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000322{
323 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800324 printfd(tcp, tcp->u_arg[0]);
325 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000326 } else {
Fabien Siron2850f742016-07-06 15:49:22 +0000327 if (syserror(tcp)) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000328 printaddr(tcp->u_arg[1]);
Fabien Siron2850f742016-07-06 15:49:22 +0000329 } else {
330 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
331 tcp->u_rval);
332 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000333
334 tprintf(", %lu, ", tcp->u_arg[2]);
Roland McGrathb2dee132005-06-01 19:02:36 +0000335 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000336 }
337 return 0;
338}
339
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000340SYS_FUNC(recvfrom)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000341{
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000342 int ulen, rlen;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000343
344 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800345 printfd(tcp, tcp->u_arg[0]);
346 tprints(", ");
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000347 if (fetch_socklen(tcp, &ulen, tcp->u_arg[4], tcp->u_arg[5])) {
348 /* abuse of auxstr to retain state */
349 tcp->auxstr = (void *) (long) ulen;
350 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000351 } else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000352 /* buf */
Denys Vlasenko383386d2015-07-30 13:29:20 +0200353 if (syserror(tcp)) {
Dmitry V. Levin52dc1502015-07-30 13:53:42 +0000354 printaddr(tcp->u_arg[1]);
Denys Vlasenko383386d2015-07-30 13:29:20 +0200355 } else {
Fabien Siron2850f742016-07-06 15:49:22 +0000356 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
357 tcp->u_rval);
Denys Vlasenko383386d2015-07-30 13:29:20 +0200358 }
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000359 /* size */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000360 tprintf(", %lu, ", tcp->u_arg[2]);
361 /* flags */
Roland McGrathb2dee132005-06-01 19:02:36 +0000362 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200363 tprints(", ");
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000364
365 ulen = (long) tcp->auxstr;
366 tcp->auxstr = NULL;
367
368 if (!fetch_socklen(tcp, &rlen, tcp->u_arg[4], tcp->u_arg[5])) {
369 /* from address */
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000370 printaddr(tcp->u_arg[4]);
371 tprints(", ");
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000372 /* from length */
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000373 printaddr(tcp->u_arg[5]);
374 return 0;
375 }
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000376 if (syserror(tcp)) {
377 /* from address */
378 printaddr(tcp->u_arg[4]);
379 /* from length */
380 tprintf(", [%d]", ulen);
381 return 0;
382 }
Denys Vlasenko383386d2015-07-30 13:29:20 +0200383 /* from address */
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000384 decode_sockaddr(tcp, tcp->u_arg[4], ulen > rlen ? rlen : ulen);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000385 /* from length */
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000386 if (ulen != rlen)
387 tprintf(", [%d->%d]", ulen, rlen);
388 else
389 tprintf(", [%d]", rlen);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000390 }
391 return 0;
392}
393
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000394SYS_FUNC(recvmsg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000395{
396 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800397 printfd(tcp, tcp->u_arg[0]);
398 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000399 } else {
Dmitry V. Levin00244b92015-01-28 01:52:25 +0000400 if (syserror(tcp))
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000401 printaddr(tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000402 else
Dmitry V. Levin3e514c02016-06-26 23:57:29 +0000403 decode_msghdr(tcp, tcp->u_arg[1], tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000404 /* flags */
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200405 tprints(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +0000406 printflags(msg_flags, tcp->u_arg[2], "MSG_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000407 }
408 return 0;
409}
410
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000411SYS_FUNC(recvmmsg)
Andreas Schwab0873f292010-02-12 21:39:12 +0100412{
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000413 static char str[sizeof("left") + TIMESPEC_TEXT_BUFSIZE];
Dmitry V. Levine6591032010-03-29 20:45:48 +0400414
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100415 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800416 printfd(tcp, tcp->u_arg[0]);
417 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +0400418 if (verbose(tcp)) {
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100419 /* Abusing tcp->auxstr as temp storage.
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000420 * Will be used and cleared on syscall exit.
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +0100421 */
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000422 tcp->auxstr = sprint_timespec(tcp, tcp->u_arg[4]);
Dmitry V. Levine6591032010-03-29 20:45:48 +0400423 } else {
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000424 printaddr(tcp->u_arg[1]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000425 /* vlen */
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000426 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000427 /* flags */
Dmitry V. Levine6591032010-03-29 20:45:48 +0400428 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200429 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +0400430 print_timespec(tcp, tcp->u_arg[4]);
431 }
432 return 0;
433 } else {
434 if (verbose(tcp)) {
Dmitry V. Levin9a8216e2016-06-27 00:02:50 +0000435 decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval, true);
436 /* vlen */
437 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
438 /* flags */
439 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000440 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +0400441 /* timeout on entrance */
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000442 tprints(tcp->auxstr);
Dmitry V. Levine6591032010-03-29 20:45:48 +0400443 tcp->auxstr = NULL;
444 }
445 if (syserror(tcp))
446 return 0;
447 if (tcp->u_rval == 0) {
448 tcp->auxstr = "Timeout";
449 return RVAL_STR;
450 }
451 if (!verbose(tcp))
452 return 0;
453 /* timeout on exit */
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000454 snprintf(str, sizeof(str), "left %s",
455 sprint_timespec(tcp, tcp->u_arg[4]));
Dmitry V. Levine6591032010-03-29 20:45:48 +0400456 tcp->auxstr = str;
457 return RVAL_STR;
Andreas Schwab0873f292010-02-12 21:39:12 +0100458 }
Andreas Schwab0873f292010-02-12 21:39:12 +0100459}
Andreas Schwab0873f292010-02-12 21:39:12 +0100460
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000461#include "xlat/shutdown_modes.h"
Sebastian Pipping9cd38502011-03-03 01:12:25 +0100462
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000463SYS_FUNC(shutdown)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000464{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000465 printfd(tcp, tcp->u_arg[0]);
466 tprints(", ");
467 printxval(shutdown_modes, tcp->u_arg[1], "SHUT_???");
468
469 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000470}
471
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000472SYS_FUNC(getsockname)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000473{
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000474 return decode_sockname(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000475}
476
Dmitry V. Levin2a4f0522015-08-02 01:54:48 +0000477static void
478printpair_fd(struct tcb *tcp, const int i0, const int i1)
479{
480 tprints("[");
481 printfd(tcp, i0);
482 tprints(", ");
483 printfd(tcp, i1);
484 tprints("]");
485}
486
487static void
488decode_pair_fd(struct tcb *tcp, const long addr)
489{
490 int pair[2];
491
492 if (umove_or_printaddr(tcp, addr, &pair))
493 return;
494
495 printpair_fd(tcp, pair[0], pair[1]);
496}
497
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000498static int
499do_pipe(struct tcb *tcp, int flags_arg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000500{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000501 if (exiting(tcp)) {
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000502 decode_pair_fd(tcp, tcp->u_arg[0]);
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000503 if (flags_arg >= 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200504 tprints(", ");
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000505 printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
506 }
507 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000508 return 0;
509}
510
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000511SYS_FUNC(pipe)
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000512{
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000513#ifdef HAVE_GETRVAL2
514 if (exiting(tcp) && !syserror(tcp))
515 printpair_fd(tcp, tcp->u_rval, getrval2(tcp));
516 return 0;
517#else
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000518 return do_pipe(tcp, -1);
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000519#endif
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000520}
521
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000522SYS_FUNC(pipe2)
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000523{
524 return do_pipe(tcp, 1);
525}
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000526
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000527SYS_FUNC(socketpair)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000528{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000529 if (entering(tcp)) {
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000530 printxval(addrfams, tcp->u_arg[0], "AF_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200531 tprints(", ");
Dmitry V. Levin1e42f2d2014-09-10 17:48:28 +0000532 tprint_sock_type(tcp->u_arg[1]);
Dmitry V. Levin033fb912014-03-11 22:50:39 +0000533 tprintf(", %lu", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000534 } else {
Dmitry V. Levinb6795082015-07-06 22:33:39 +0000535 tprints(", ");
Dmitry V. Levin2a4f0522015-08-02 01:54:48 +0000536 decode_pair_fd(tcp, tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000537 }
538 return 0;
539}
540
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000541#include "xlat/sockoptions.h"
542#include "xlat/sockipoptions.h"
Mike Frysinger54646b82015-08-19 13:29:27 -0400543#include "xlat/getsockipoptions.h"
544#include "xlat/setsockipoptions.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000545#include "xlat/sockipv6options.h"
Mike Frysinger54646b82015-08-19 13:29:27 -0400546#include "xlat/getsockipv6options.h"
547#include "xlat/setsockipv6options.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000548#include "xlat/sockipxoptions.h"
549#include "xlat/sockrawoptions.h"
550#include "xlat/sockpacketoptions.h"
551#include "xlat/socksctpoptions.h"
552#include "xlat/socktcpoptions.h"
553
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000554static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +0000555print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
556 unsigned int name, bool is_getsockopt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000557{
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000558 printfd(tcp, fd);
559 tprints(", ");
John Hughes38ae88d2002-05-23 11:48:58 +0000560 printxval(socketlayers, level, "SOL_??");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200561 tprints(", ");
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000562
John Hughes38ae88d2002-05-23 11:48:58 +0000563 switch (level) {
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100564 case SOL_SOCKET:
John Hughes38ae88d2002-05-23 11:48:58 +0000565 printxval(sockoptions, name, "SO_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000566 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100567 case SOL_IP:
Mike Frysinger54646b82015-08-19 13:29:27 -0400568 printxvals(name, "IP_???", sockipoptions,
569 is_getsockopt ? getsockipoptions : setsockipoptions, NULL);
John Hughes38ae88d2002-05-23 11:48:58 +0000570 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100571 case SOL_IPV6:
Mike Frysinger54646b82015-08-19 13:29:27 -0400572 printxvals(name, "IPV6_???", sockipv6options,
573 is_getsockopt ? getsockipv6options : setsockipv6options, NULL);
Roland McGrath4f6ba692004-08-31 07:01:26 +0000574 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100575 case SOL_IPX:
John Hughes38ae88d2002-05-23 11:48:58 +0000576 printxval(sockipxoptions, name, "IPX_???");
577 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100578 case SOL_PACKET:
John Hughes38ae88d2002-05-23 11:48:58 +0000579 printxval(sockpacketoptions, name, "PACKET_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000580 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100581 case SOL_TCP:
John Hughes38ae88d2002-05-23 11:48:58 +0000582 printxval(socktcpoptions, name, "TCP_???");
583 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100584 case SOL_SCTP:
Holger Hans Peter Freyther7fea79b2011-01-14 11:08:12 +0100585 printxval(socksctpoptions, name, "SCTP_???");
586 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100587 case SOL_RAW:
John Hughes38ae88d2002-05-23 11:48:58 +0000588 printxval(sockrawoptions, name, "RAW_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000589 break;
John Hughes38ae88d2002-05-23 11:48:58 +0000590
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000591 /* Other SOL_* protocol levels still need work. */
John Hughes38ae88d2002-05-23 11:48:58 +0000592
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100593 default:
John Hughes38ae88d2002-05-23 11:48:58 +0000594 tprintf("%u", name);
595 }
596
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000597 tprints(", ");
598}
599
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000600static void
601print_linger(struct tcb *tcp, long addr, int len)
602{
603 struct linger linger;
604
605 if (len != sizeof(linger) ||
606 umove(tcp, addr, &linger) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000607 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000608 return;
609 }
610
611 tprintf("{onoff=%d, linger=%d}",
612 linger.l_onoff,
613 linger.l_linger);
614}
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000615
616#ifdef SO_PEERCRED
617static void
618print_ucred(struct tcb *tcp, long addr, int len)
619{
620 struct ucred uc;
621
622 if (len != sizeof(uc) ||
623 umove(tcp, addr, &uc) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000624 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000625 } else {
626 tprintf("{pid=%u, uid=%u, gid=%u}",
627 (unsigned) uc.pid,
628 (unsigned) uc.uid,
629 (unsigned) uc.gid);
630 }
631}
632#endif /* SO_PEERCRED */
633
634#ifdef PACKET_STATISTICS
635static void
636print_tpacket_stats(struct tcb *tcp, long addr, int len)
637{
638 struct tpacket_stats stats;
639
640 if (len != sizeof(stats) ||
641 umove(tcp, addr, &stats) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000642 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000643 } else {
644 tprintf("{packets=%u, drops=%u}",
645 stats.tp_packets,
646 stats.tp_drops);
647 }
648}
649#endif /* PACKET_STATISTICS */
650
Dmitry V. Levinfba9db22016-06-15 21:29:07 +0000651#include "xlat/icmpfilterflags.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000652
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000653static void
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000654print_icmp_filter(struct tcb *tcp, const long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000655{
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000656 struct icmp_filter filter = {};
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000657
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000658 if (len > (int) sizeof(filter))
659 len = sizeof(filter);
660 else if (len <= 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000661 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000662 return;
663 }
664
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000665 if (umoven_or_printaddr(tcp, addr, len, &filter))
666 return;
667
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000668 tprints("~(");
669 printflags(icmpfilterflags, ~filter.data, "ICMP_???");
670 tprints(")");
671}
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000672
673static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +0000674print_getsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
675 long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000676{
677 if (addr && verbose(tcp))
678 switch (level) {
679 case SOL_SOCKET:
680 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000681 case SO_LINGER:
682 print_linger(tcp, addr, len);
683 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000684#ifdef SO_PEERCRED
685 case SO_PEERCRED:
686 print_ucred(tcp, addr, len);
687 goto done;
688#endif
689 }
690 break;
691
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000692 case SOL_PACKET:
693 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000694#ifdef PACKET_STATISTICS
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000695 case PACKET_STATISTICS:
696 print_tpacket_stats(tcp, addr, len);
697 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000698#endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000699 }
700 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000701
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000702 case SOL_RAW:
703 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000704 case ICMP_FILTER:
705 print_icmp_filter(tcp, addr, len);
706 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000707 }
708 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000709 }
710
John Hughes38ae88d2002-05-23 11:48:58 +0000711 /* default arg printing */
712
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000713 if (verbose(tcp)) {
714 if (len == sizeof(int)) {
715 printnum_int(tcp, addr, "%d");
716 } else {
717 printstr(tcp, addr, len);
718 }
719 } else {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000720 printaddr(addr);
John Hughes38ae88d2002-05-23 11:48:58 +0000721 }
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000722done:
723 tprintf(", [%d]", len);
724}
725
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000726SYS_FUNC(getsockopt)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000727{
728 if (entering(tcp)) {
729 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
Mike Frysinger54646b82015-08-19 13:29:27 -0400730 tcp->u_arg[1], tcp->u_arg[2], true);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000731 } else {
732 int len;
733
734 if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &len) < 0) {
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000735 printaddr(tcp->u_arg[3]);
736 tprints(", ");
737 printaddr(tcp->u_arg[4]);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000738 } else {
739 print_getsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
740 tcp->u_arg[3], len);
741 }
John Hughes38ae88d2002-05-23 11:48:58 +0000742 }
743 return 0;
744}
745
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000746#ifdef IP_ADD_MEMBERSHIP
747static void
748print_mreq(struct tcb *tcp, long addr, unsigned int len)
749{
750 struct ip_mreq mreq;
751
752 if (len < sizeof(mreq)) {
753 printstr(tcp, addr, len);
754 return;
755 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000756 if (umove_or_printaddr(tcp, addr, &mreq))
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000757 return;
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000758
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000759 tprints("{imr_multiaddr=inet_addr(");
760 print_quoted_string(inet_ntoa(mreq.imr_multiaddr),
761 16, QUOTE_0_TERMINATED);
762 tprints("), imr_interface=inet_addr(");
763 print_quoted_string(inet_ntoa(mreq.imr_interface),
764 16, QUOTE_0_TERMINATED);
765 tprints(")}");
766}
767#endif /* IP_ADD_MEMBERSHIP */
768
769#ifdef IPV6_ADD_MEMBERSHIP
770static void
771print_mreq6(struct tcb *tcp, long addr, unsigned int len)
772{
773 struct ipv6_mreq mreq;
774
775 if (len < sizeof(mreq))
776 goto fail;
777
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000778 if (umove_or_printaddr(tcp, addr, &mreq))
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000779 return;
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000780
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000781 const struct in6_addr *in6 = &mreq.ipv6mr_multiaddr;
782 char address[INET6_ADDRSTRLEN];
783
784 if (!inet_ntop(AF_INET6, in6, address, sizeof(address)))
785 goto fail;
786
787 tprints("{ipv6mr_multiaddr=inet_pton(");
788 print_quoted_string(address, sizeof(address), QUOTE_0_TERMINATED);
789 tprints("), ipv6mr_interface=");
790 print_ifindex(mreq.ipv6mr_interface);
791 tprints("}");
792 return;
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000793
794fail:
795 printstr(tcp, addr, len);
796}
797#endif /* IPV6_ADD_MEMBERSHIP */
798
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000799#ifdef MCAST_JOIN_GROUP
800static void
801print_group_req(struct tcb *tcp, long addr, int len)
802{
803 struct group_req greq;
804
805 if (len != sizeof(greq) ||
806 umove(tcp, addr, &greq) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000807 printaddr(addr);
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000808 return;
809 }
810
Dmitry V. Levin1019f002015-11-21 02:38:59 +0000811 tprintf("{gr_interface=%u, gr_group=", greq.gr_interface);
Dmitry V. Levin3bf9c192016-06-21 16:45:40 +0000812 print_sockaddr(tcp, &greq.gr_group, sizeof(greq.gr_group));
Dmitry V. Levin1019f002015-11-21 02:38:59 +0000813 tprintf("}");
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000814
815}
816#endif /* MCAST_JOIN_GROUP */
817
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000818#ifdef PACKET_RX_RING
819static void
820print_tpacket_req(struct tcb *tcp, long addr, int len)
821{
822 struct tpacket_req req;
823
824 if (len != sizeof(req) ||
825 umove(tcp, addr, &req) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000826 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000827 } else {
828 tprintf("{block_size=%u, block_nr=%u, "
829 "frame_size=%u, frame_nr=%u}",
830 req.tp_block_size,
831 req.tp_block_nr,
832 req.tp_frame_size,
833 req.tp_frame_nr);
834 }
835}
836#endif /* PACKET_RX_RING */
837
Dmitry V. Levin02f2f092015-01-29 03:26:53 +0000838#ifdef PACKET_ADD_MEMBERSHIP
839# include "xlat/packet_mreq_type.h"
840
841static void
842print_packet_mreq(struct tcb *tcp, long addr, int len)
843{
844 struct packet_mreq mreq;
845
846 if (len != sizeof(mreq) ||
847 umove(tcp, addr, &mreq) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000848 printaddr(addr);
Dmitry V. Levin02f2f092015-01-29 03:26:53 +0000849 } else {
850 unsigned int i;
851
852 tprintf("{mr_ifindex=%u, mr_type=", mreq.mr_ifindex);
853 printxval(packet_mreq_type, mreq.mr_type, "PACKET_MR_???");
854 tprintf(", mr_alen=%u, mr_address=", mreq.mr_alen);
855 if (mreq.mr_alen > ARRAY_SIZE(mreq.mr_address))
856 mreq.mr_alen = ARRAY_SIZE(mreq.mr_address);
857 for (i = 0; i < mreq.mr_alen; ++i)
858 tprintf("%02x", mreq.mr_address[i]);
859 tprints("}");
860 }
861}
862#endif /* PACKET_ADD_MEMBERSHIP */
863
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000864static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +0000865print_setsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
866 long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000867{
868 if (addr && verbose(tcp))
869 switch (level) {
870 case SOL_SOCKET:
871 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000872 case SO_LINGER:
873 print_linger(tcp, addr, len);
874 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000875 }
876 break;
877
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000878 case SOL_IP:
879 switch (name) {
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000880#ifdef IP_ADD_MEMBERSHIP
881 case IP_ADD_MEMBERSHIP:
882 case IP_DROP_MEMBERSHIP:
883 print_mreq(tcp, addr, len);
884 goto done;
885#endif /* IP_ADD_MEMBERSHIP */
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000886#ifdef MCAST_JOIN_GROUP
887 case MCAST_JOIN_GROUP:
888 case MCAST_LEAVE_GROUP:
889 print_group_req(tcp, addr, len);
890 goto done;
891#endif /* MCAST_JOIN_GROUP */
892 }
Dmitry V. Levin3910d0f2015-02-08 01:19:06 +0000893 break;
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000894
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000895 case SOL_IPV6:
896 switch (name) {
897#ifdef IPV6_ADD_MEMBERSHIP
898 case IPV6_ADD_MEMBERSHIP:
899 case IPV6_DROP_MEMBERSHIP:
900# ifdef IPV6_JOIN_ANYCAST
901 case IPV6_JOIN_ANYCAST:
902# endif
903# ifdef IPV6_LEAVE_ANYCAST
904 case IPV6_LEAVE_ANYCAST:
905# endif
906 print_mreq6(tcp, addr, len);
907 goto done;
908#endif /* IPV6_ADD_MEMBERSHIP */
909 }
910 break;
911
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000912 case SOL_PACKET:
913 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000914#ifdef PACKET_RX_RING
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000915 case PACKET_RX_RING:
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000916# ifdef PACKET_TX_RING
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000917 case PACKET_TX_RING:
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000918# endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000919 print_tpacket_req(tcp, addr, len);
920 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000921#endif /* PACKET_RX_RING */
922#ifdef PACKET_ADD_MEMBERSHIP
Dmitry V. Levin02f2f092015-01-29 03:26:53 +0000923 case PACKET_ADD_MEMBERSHIP:
924 case PACKET_DROP_MEMBERSHIP:
925 print_packet_mreq(tcp, addr, len);
926 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000927#endif /* PACKET_ADD_MEMBERSHIP */
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000928 }
929 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000930
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000931 case SOL_RAW:
932 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000933 case ICMP_FILTER:
934 print_icmp_filter(tcp, addr, len);
935 goto done;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000936 }
937 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000938 }
939
940 /* default arg printing */
941
942 if (verbose(tcp)) {
943 if (len == sizeof(int)) {
944 printnum_int(tcp, addr, "%d");
945 } else {
946 printstr(tcp, addr, len);
947 }
948 } else {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000949 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000950 }
951done:
952 tprintf(", %d", len);
953}
954
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000955SYS_FUNC(setsockopt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000956{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000957 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
Mike Frysinger54646b82015-08-19 13:29:27 -0400958 tcp->u_arg[1], tcp->u_arg[2], false);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000959 print_setsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
960 tcp->u_arg[3], tcp->u_arg[4]);
961
962 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000963}