blob: 775e14caa705d606f98d042e8c6a7aa4672c641f [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>
Elliott Hughesb7556142018-02-20 17:03:16 -08006 * Copyright (c) 1999-2018 The strace developers.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00007 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000030 */
31
32#include "defs.h"
Elliott Hughes77c3ff82017-09-08 17:11:00 -070033#include "print_fields.h"
34
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000035#include <sys/stat.h>
36#include <sys/socket.h>
Dmitry V. Levinb2fa2be2014-11-21 20:46:16 +000037#include <sys/uio.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000038#include <sys/un.h>
39#include <netinet/in.h>
Wichert Akkerman8c7122c2001-02-16 19:59:55 +000040#ifdef HAVE_NETINET_TCP_H
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010041# include <netinet/tcp.h>
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000042#endif
Wichert Akkerman8c7122c2001-02-16 19:59:55 +000043#ifdef HAVE_NETINET_UDP_H
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010044# include <netinet/udp.h>
Wichert Akkerman8c7122c2001-02-16 19:59:55 +000045#endif
Holger Hans Peter Freyther7fea79b2011-01-14 11:08:12 +010046#ifdef HAVE_NETINET_SCTP_H
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010047# include <netinet/sctp.h>
Holger Hans Peter Freyther7fea79b2011-01-14 11:08:12 +010048#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000049#include <arpa/inet.h>
Wichert Akkermanf1850652001-02-16 20:29:03 +000050#include <net/if.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000051#include <asm/types.h>
Dmitry V. Levinebda41a2016-06-19 22:02:45 +000052#ifdef HAVE_NETIPX_IPX_H
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010053# include <netipx/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
Elliott Hughesdc75b012017-07-05 13:54:44 -070059#include "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
Elliott Hughes03a418e2018-06-15 13:11:40 -070085#define XLAT_MACROS_ONLY
86# include "xlat/addrfams.h"
Elliott Hughesc1873762018-12-19 15:13:36 -080087# include "xlat/ethernet_protocols.h"
Elliott Hughes03a418e2018-06-15 13:11:40 -070088#undef XLAT_MACROS_ONLY
Elliott Hughesc1873762018-12-19 15:13:36 -080089#include "xlat/ax25_protocols.h"
Elliott Hughes03a418e2018-06-15 13:11:40 -070090#include "xlat/irda_protocols.h"
91#include "xlat/can_protocols.h"
92#include "xlat/bt_protocols.h"
93#include "xlat/isdn_protocols.h"
94#include "xlat/phonet_protocols.h"
95#include "xlat/caif_protocols.h"
96#include "xlat/nfc_protocols.h"
97#include "xlat/kcm_protocols.h"
98#include "xlat/smc_protocols.h"
99
100const size_t inet_protocols_size = ARRAY_SIZE(inet_protocols) - 1;
Lubomir Rintelc400a1c2014-10-03 11:40:28 +0200101
Fabien Siron2850f742016-07-06 15:49:22 +0000102static void
Elliott Hughesd35df492017-02-15 15:19:05 -0800103decode_sockbuf(struct tcb *const tcp, const int fd, const kernel_ulong_t addr,
104 const kernel_ulong_t addrlen)
Fabien Siron2850f742016-07-06 15:49:22 +0000105{
106
107 switch (verbose(tcp) ? getfdproto(tcp, fd) : SOCK_PROTO_UNKNOWN) {
108 case SOCK_PROTO_NETLINK:
Elliott Hughesdc75b012017-07-05 13:54:44 -0700109 decode_netlink(tcp, fd, addr, addrlen);
Fabien Siron2850f742016-07-06 15:49:22 +0000110 break;
111 default:
Elliott Hughesd35df492017-02-15 15:19:05 -0800112 printstrn(tcp, addr, addrlen);
Fabien Siron2850f742016-07-06 15:49:22 +0000113 }
114}
115
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000116/*
117 * low bits of the socket type define real socket type,
118 * other bits are socket type flags.
119 */
120static void
Dmitry V. Levin9134aab2016-05-14 21:46:05 +0000121tprint_sock_type(unsigned int flags)
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000122{
123 const char *str = xlookup(socktypes, flags & SOCK_TYPE_MASK);
124
Denys Vlasenko7b609d52011-06-22 14:32:43 +0200125 if (str) {
Elliott Hughes03a418e2018-06-15 13:11:40 -0700126 print_xlat_ex(flags & SOCK_TYPE_MASK, str, XLAT_STYLE_DEFAULT);
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000127 flags &= ~SOCK_TYPE_MASK;
128 if (!flags)
129 return;
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200130 tprints("|");
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000131 }
132 printflags(sock_type_flags, flags, "SOCK_???");
133}
134
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000135SYS_FUNC(socket)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000136{
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000137 printxval(addrfams, tcp->u_arg[0], "AF_???");
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000138 tprints(", ");
139 tprint_sock_type(tcp->u_arg[1]);
140 tprints(", ");
141 switch (tcp->u_arg[0]) {
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000142 case AF_INET:
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000143 case AF_INET6:
Elliott Hughes03a418e2018-06-15 13:11:40 -0700144 printxval_search(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000145 break;
Dmitry V. Levineb1c22b2016-06-19 22:02:45 +0000146
Elliott Hughesc1873762018-12-19 15:13:36 -0800147 case AF_AX25:
148 /* Those are not available in public headers. */
149 printxval_searchn_ex(ARRSZ_PAIR(ax25_protocols), tcp->u_arg[2],
150 "AX25_P_???", XLAT_STYLE_VERBOSE);
151 break;
152
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000153 case AF_NETLINK:
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000154 printxval(netlink_protocols, tcp->u_arg[2], "NETLINK_???");
155 break;
Dmitry V. Levinbc4102e2016-06-19 22:02:45 +0000156
Elliott Hughesc1873762018-12-19 15:13:36 -0800157 case AF_PACKET:
158 tprints("htons(");
159 printxval_searchn(ethernet_protocols, ethernet_protocols_size,
160 ntohs(tcp->u_arg[2]), "ETH_P_???");
161 tprints(")");
162 break;
163
Elliott Hughes03a418e2018-06-15 13:11:40 -0700164 case AF_IRDA:
165 printxval_index(can_protocols, tcp->u_arg[2], "IRDAPROTO_???");
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000166 break;
Elliott Hughes03a418e2018-06-15 13:11:40 -0700167
168 case AF_CAN:
169 printxval_index(can_protocols, tcp->u_arg[2], "CAN_???");
170 break;
171
172 case AF_BLUETOOTH:
173 printxval_index(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
174 break;
175
176 case AF_RXRPC:
177 printxval(addrfams, tcp->u_arg[2], "AF_???");
178 break;
179
180 case AF_ISDN:
181 printxval(isdn_protocols, tcp->u_arg[2], "ISDN_P_???");
182 break;
183
184 case AF_PHONET:
185 printxval_index(phonet_protocols, tcp->u_arg[2], "PN_PROTO_???");
186 break;
187
188 case AF_CAIF:
189 printxval_index(caif_protocols, tcp->u_arg[2], "CAIFPROTO_???");
190 break;
191
192 case AF_NFC:
193 printxval_index(nfc_protocols, tcp->u_arg[2],
194 "NFC_SOCKPROTO_???");
195 break;
196
197 case AF_KCM:
198 printxval_index(kcm_protocols, tcp->u_arg[2], "KCMPROTO_???");
199 break;
200
201 case AF_SMC:
202 printxval_index(smc_protocols, tcp->u_arg[2], "SMCPROTO_???");
203 break;
Dmitry V. Levinbc4102e2016-06-19 22:02:45 +0000204
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000205 default:
Elliott Hughesd35df492017-02-15 15:19:05 -0800206 tprintf("%" PRI_klu, tcp->u_arg[2]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000207 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000208 }
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000209
Dmitry V. Levin3d463be2015-08-02 01:41:26 +0000210 return RVAL_DECODED | RVAL_FD;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000211}
212
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000213static bool
Elliott Hughesd35df492017-02-15 15:19:05 -0800214fetch_socklen(struct tcb *const tcp, int *const plen,
215 const kernel_ulong_t sockaddr, const kernel_ulong_t socklen)
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000216{
217 return verbose(tcp) && sockaddr && socklen
218 && umove(tcp, socklen, plen) == 0;
219}
220
Paolo Bonzini705ff102009-08-14 12:34:05 +0200221static int
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000222decode_sockname(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000223{
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000224 int ulen, rlen;
225
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000226 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800227 printfd(tcp, tcp->u_arg[0]);
228 tprints(", ");
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000229 if (fetch_socklen(tcp, &ulen, tcp->u_arg[1], tcp->u_arg[2])) {
Dmitry V. Levinb759d272016-07-15 16:08:19 +0000230 set_tcb_priv_ulong(tcp, ulen);
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000231 return 0;
232 } else {
233 printaddr(tcp->u_arg[1]);
234 tprints(", ");
235 printaddr(tcp->u_arg[2]);
236 return RVAL_DECODED;
237 }
Paolo Bonzini705ff102009-08-14 12:34:05 +0200238 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000239
Dmitry V. Levinb759d272016-07-15 16:08:19 +0000240 ulen = get_tcb_priv_ulong(tcp);
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000241
242 if (syserror(tcp) || umove(tcp, tcp->u_arg[2], &rlen) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000243 printaddr(tcp->u_arg[1]);
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000244 tprintf(", [%d]", ulen);
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000245 } else {
Dmitry V. Levind07eac32016-07-09 21:52:43 +0000246 decode_sockaddr(tcp, tcp->u_arg[1], ulen > rlen ? rlen : ulen);
Dmitry V. Levineca8b5b2016-07-09 21:52:58 +0000247 if (ulen != rlen)
Dmitry V. Levin36df8222016-07-09 21:52:51 +0000248 tprintf(", [%d->%d]", ulen, rlen);
249 else
250 tprintf(", [%d]", rlen);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000251 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000252
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000253 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000254}
255
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000256SYS_FUNC(accept)
Paolo Bonzini705ff102009-08-14 12:34:05 +0200257{
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000258 return decode_sockname(tcp) | RVAL_FD;
Paolo Bonzini705ff102009-08-14 12:34:05 +0200259}
260
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000261SYS_FUNC(accept4)
Paolo Bonzini705ff102009-08-14 12:34:05 +0200262{
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000263 int rc = decode_sockname(tcp);
264
265 if (rc & RVAL_DECODED) {
266 tprints(", ");
267 printflags(sock_type_flags, tcp->u_arg[3], "SOCK_???");
268 }
269
270 return rc | RVAL_FD;
Paolo Bonzini705ff102009-08-14 12:34:05 +0200271}
Paolo Bonzini705ff102009-08-14 12:34:05 +0200272
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000273SYS_FUNC(send)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000274{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000275 printfd(tcp, tcp->u_arg[0]);
276 tprints(", ");
Fabien Siron2850f742016-07-06 15:49:22 +0000277 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
Elliott Hughesd35df492017-02-15 15:19:05 -0800278 tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000279 /* flags */
280 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
281
282 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000283}
284
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000285SYS_FUNC(sendto)
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(", ");
Fabien Siron2850f742016-07-06 15:49:22 +0000289 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
Elliott Hughesd35df492017-02-15 15:19:05 -0800290 tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000291 /* flags */
292 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
293 /* to address */
Dmitry V. Levin7acde9e2016-07-12 09:17:30 +0000294 const int addrlen = tcp->u_arg[5];
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000295 tprints(", ");
Dmitry V. Levin7acde9e2016-07-12 09:17:30 +0000296 decode_sockaddr(tcp, tcp->u_arg[4], addrlen);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000297 /* to length */
Dmitry V. Levin7acde9e2016-07-12 09:17:30 +0000298 tprintf(", %d", addrlen);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000299
300 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000301}
302
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000303SYS_FUNC(recv)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000304{
305 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800306 printfd(tcp, tcp->u_arg[0]);
307 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000308 } else {
Fabien Siron2850f742016-07-06 15:49:22 +0000309 if (syserror(tcp)) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000310 printaddr(tcp->u_arg[1]);
Fabien Siron2850f742016-07-06 15:49:22 +0000311 } else {
312 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
313 tcp->u_rval);
314 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000315
Elliott Hughesd35df492017-02-15 15:19:05 -0800316 tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
Roland McGrathb2dee132005-06-01 19:02:36 +0000317 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000318 }
319 return 0;
320}
321
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000322SYS_FUNC(recvfrom)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000323{
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000324 int ulen, rlen;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000325
326 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800327 printfd(tcp, tcp->u_arg[0]);
328 tprints(", ");
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000329 if (fetch_socklen(tcp, &ulen, tcp->u_arg[4], tcp->u_arg[5])) {
Dmitry V. Levinb759d272016-07-15 16:08:19 +0000330 set_tcb_priv_ulong(tcp, ulen);
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000331 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000332 } else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000333 /* buf */
Denys Vlasenko383386d2015-07-30 13:29:20 +0200334 if (syserror(tcp)) {
Dmitry V. Levin52dc1502015-07-30 13:53:42 +0000335 printaddr(tcp->u_arg[1]);
Denys Vlasenko383386d2015-07-30 13:29:20 +0200336 } else {
Fabien Siron2850f742016-07-06 15:49:22 +0000337 decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
338 tcp->u_rval);
Denys Vlasenko383386d2015-07-30 13:29:20 +0200339 }
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000340 /* size */
Elliott Hughesd35df492017-02-15 15:19:05 -0800341 tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000342 /* flags */
Roland McGrathb2dee132005-06-01 19:02:36 +0000343 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200344 tprints(", ");
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000345
Dmitry V. Levinb759d272016-07-15 16:08:19 +0000346 ulen = get_tcb_priv_ulong(tcp);
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000347
348 if (!fetch_socklen(tcp, &rlen, tcp->u_arg[4], tcp->u_arg[5])) {
349 /* from address */
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000350 printaddr(tcp->u_arg[4]);
351 tprints(", ");
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000352 /* from length */
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000353 printaddr(tcp->u_arg[5]);
354 return 0;
355 }
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000356 if (syserror(tcp)) {
357 /* from address */
358 printaddr(tcp->u_arg[4]);
359 /* from length */
360 tprintf(", [%d]", ulen);
361 return 0;
362 }
Denys Vlasenko383386d2015-07-30 13:29:20 +0200363 /* from address */
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000364 decode_sockaddr(tcp, tcp->u_arg[4], ulen > rlen ? rlen : ulen);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000365 /* from length */
Dmitry V. Levin802f2642016-07-12 07:46:19 +0000366 if (ulen != rlen)
367 tprintf(", [%d->%d]", ulen, rlen);
368 else
369 tprintf(", [%d]", rlen);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000370 }
371 return 0;
372}
373
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000374SYS_FUNC(getsockname)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000375{
Dmitry V. Levind1cedf02016-07-09 21:52:34 +0000376 return decode_sockname(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000377}
378
Dmitry V. Levin2a4f0522015-08-02 01:54:48 +0000379static void
380printpair_fd(struct tcb *tcp, const int i0, const int i1)
381{
382 tprints("[");
383 printfd(tcp, i0);
384 tprints(", ");
385 printfd(tcp, i1);
386 tprints("]");
387}
388
389static void
Elliott Hughesd35df492017-02-15 15:19:05 -0800390decode_pair_fd(struct tcb *const tcp, const kernel_ulong_t addr)
Dmitry V. Levin2a4f0522015-08-02 01:54:48 +0000391{
392 int pair[2];
393
394 if (umove_or_printaddr(tcp, addr, &pair))
395 return;
396
397 printpair_fd(tcp, pair[0], pair[1]);
398}
399
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000400static int
401do_pipe(struct tcb *tcp, int flags_arg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000402{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000403 if (exiting(tcp)) {
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000404 decode_pair_fd(tcp, tcp->u_arg[0]);
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000405 if (flags_arg >= 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200406 tprints(", ");
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000407 printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
408 }
409 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000410 return 0;
411}
412
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000413SYS_FUNC(pipe)
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000414{
Elliott Hughesb7556142018-02-20 17:03:16 -0800415#if HAVE_ARCH_GETRVAL2
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000416 if (exiting(tcp) && !syserror(tcp))
417 printpair_fd(tcp, tcp->u_rval, getrval2(tcp));
418 return 0;
419#else
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000420 return do_pipe(tcp, -1);
Dmitry V. Levin9b388852016-02-12 16:37:31 +0000421#endif
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000422}
423
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000424SYS_FUNC(pipe2)
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000425{
426 return do_pipe(tcp, 1);
427}
Dmitry V. Levin4371b102008-11-10 22:53:02 +0000428
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000429SYS_FUNC(socketpair)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000430{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000431 if (entering(tcp)) {
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000432 printxval(addrfams, tcp->u_arg[0], "AF_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200433 tprints(", ");
Dmitry V. Levin1e42f2d2014-09-10 17:48:28 +0000434 tprint_sock_type(tcp->u_arg[1]);
Elliott Hughesd35df492017-02-15 15:19:05 -0800435 tprintf(", %" PRI_klu, tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000436 } else {
Dmitry V. Levinb6795082015-07-06 22:33:39 +0000437 tprints(", ");
Dmitry V. Levin2a4f0522015-08-02 01:54:48 +0000438 decode_pair_fd(tcp, tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000439 }
440 return 0;
441}
442
Elliott Hughes03a418e2018-06-15 13:11:40 -0700443#include "xlat/sock_options.h"
444#include "xlat/getsock_options.h"
445#include "xlat/setsock_options.h"
446#include "xlat/sock_ip_options.h"
447#include "xlat/getsock_ip_options.h"
448#include "xlat/setsock_ip_options.h"
449#include "xlat/sock_ipv6_options.h"
450#include "xlat/getsock_ipv6_options.h"
451#include "xlat/setsock_ipv6_options.h"
452#include "xlat/sock_ipx_options.h"
Elliott Hughesc1873762018-12-19 15:13:36 -0800453#include "xlat/sock_ax25_options.h"
Elliott Hughes03a418e2018-06-15 13:11:40 -0700454#include "xlat/sock_netlink_options.h"
455#include "xlat/sock_packet_options.h"
456#include "xlat/sock_raw_options.h"
457#include "xlat/sock_sctp_options.h"
458#include "xlat/sock_tcp_options.h"
459#include "xlat/sock_udp_options.h"
460#include "xlat/sock_irda_options.h"
461#include "xlat/sock_llc_options.h"
462#include "xlat/sock_dccp_options.h"
463#include "xlat/sock_tipc_options.h"
464#include "xlat/sock_rxrpc_options.h"
465#include "xlat/sock_pppol2tp_options.h"
466#include "xlat/sock_bluetooth_options.h"
467#include "xlat/sock_pnp_options.h"
468#include "xlat/sock_rds_options.h"
469#include "xlat/sock_iucv_options.h"
470#include "xlat/sock_caif_options.h"
471#include "xlat/sock_alg_options.h"
472#include "xlat/sock_nfcllcp_options.h"
473#include "xlat/sock_kcm_options.h"
474#include "xlat/sock_tls_options.h"
Elliott Hughesc1873762018-12-19 15:13:36 -0800475#include "xlat/sock_xdp_options.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000476
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000477static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +0000478print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
479 unsigned int name, bool is_getsockopt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000480{
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000481 printfd(tcp, fd);
482 tprints(", ");
Elliott Hughes03a418e2018-06-15 13:11:40 -0700483 printxval_search(socketlayers, level, "SOL_??");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200484 tprints(", ");
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000485
John Hughes38ae88d2002-05-23 11:48:58 +0000486 switch (level) {
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100487 case SOL_SOCKET:
Elliott Hughes03a418e2018-06-15 13:11:40 -0700488 printxvals(name, "SO_???", sock_options,
489 is_getsockopt ? getsock_options :
490 setsock_options, NULL);
John Hughes38ae88d2002-05-23 11:48:58 +0000491 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100492 case SOL_IP:
Elliott Hughes03a418e2018-06-15 13:11:40 -0700493 printxvals(name, "IP_???", sock_ip_options,
494 is_getsockopt ? getsock_ip_options :
495 setsock_ip_options, NULL);
John Hughes38ae88d2002-05-23 11:48:58 +0000496 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100497 case SOL_IPV6:
Elliott Hughes03a418e2018-06-15 13:11:40 -0700498 printxvals(name, "IPV6_???", sock_ipv6_options,
499 is_getsockopt ? getsock_ipv6_options :
500 setsock_ipv6_options, NULL);
Roland McGrath4f6ba692004-08-31 07:01:26 +0000501 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100502 case SOL_IPX:
Elliott Hughes03a418e2018-06-15 13:11:40 -0700503 printxval(sock_ipx_options, name, "IPX_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000504 break;
Elliott Hughesc1873762018-12-19 15:13:36 -0800505 case SOL_AX25:
506 printxval_search(sock_ax25_options, name, "AX25_???");
507 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100508 case SOL_PACKET:
Elliott Hughes03a418e2018-06-15 13:11:40 -0700509 printxval(sock_packet_options, name, "PACKET_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000510 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100511 case SOL_TCP:
Elliott Hughesc1873762018-12-19 15:13:36 -0800512 printxval_index(sock_tcp_options, name, "TCP_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000513 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100514 case SOL_SCTP:
Elliott Hughes03a418e2018-06-15 13:11:40 -0700515 printxval(sock_sctp_options, name, "SCTP_???");
Holger Hans Peter Freyther7fea79b2011-01-14 11:08:12 +0100516 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100517 case SOL_RAW:
Elliott Hughes03a418e2018-06-15 13:11:40 -0700518 printxval(sock_raw_options, name, "RAW_???");
John Hughes38ae88d2002-05-23 11:48:58 +0000519 break;
Elliott Hughesb7556142018-02-20 17:03:16 -0800520 case SOL_NETLINK:
Elliott Hughes03a418e2018-06-15 13:11:40 -0700521 printxval(sock_netlink_options, name, "NETLINK_???");
522 break;
523 case SOL_UDP:
524 printxval(sock_udp_options, name, "UDP_???");
525 break;
526 case SOL_IRDA:
527 printxval_index(sock_irda_options, name, "IRLMP_???");
528 break;
529 case SOL_LLC:
530 printxval_index(sock_llc_options, name, "LLC_OPT_???");
531 break;
532 case SOL_DCCP:
533 printxval_search(sock_dccp_options, name, "DCCP_SOCKOPT_???");
534 break;
535 case SOL_TIPC:
536 printxval_search(sock_tipc_options, name, "TIPC_???");
537 break;
538 case SOL_RXRPC:
539 printxval_index(sock_rxrpc_options, name, "RXRPC_???");
540 break;
541 case SOL_PPPOL2TP:
542 printxval_index(sock_pppol2tp_options, name, "PPPOL2TP_SO_???");
543 break;
544 case SOL_BLUETOOTH:
545 printxval_search(sock_bluetooth_options, name, "BT_???");
546 break;
547 case SOL_PNPIPE:
548 printxval(sock_pnp_options, name, "PNPIPE_???");
549 break;
550 case SOL_RDS:
551 printxval_search(sock_rds_options, name, "RDS_???");
552 break;
553 case SOL_IUCV:
554 printxval(sock_iucv_options, name, "SO_???");
555 break;
556 case SOL_CAIF:
557 printxval(sock_caif_options, name, "CAIFSO_???");
558 break;
559 case SOL_ALG:
560 printxval_index(sock_alg_options, name, "ALG_???");
561 break;
562 case SOL_NFC:
563 printxval_index(sock_nfcllcp_options, name, "NFC_LLCP_???");
564 break;
565 case SOL_KCM:
566 printxval(sock_kcm_options, name, "KCM_???");
567 break;
568 case SOL_TLS:
569 printxval(sock_tls_options, name, "TLS_???");
Elliott Hughesb7556142018-02-20 17:03:16 -0800570 break;
Elliott Hughesc1873762018-12-19 15:13:36 -0800571 case SOL_XDP:
572 printxval_index(sock_xdp_options, name, "XDP_???");
573 break;
John Hughes38ae88d2002-05-23 11:48:58 +0000574
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000575 /* Other SOL_* protocol levels still need work. */
John Hughes38ae88d2002-05-23 11:48:58 +0000576
Denys Vlasenko989ebc92012-03-17 04:42:07 +0100577 default:
John Hughes38ae88d2002-05-23 11:48:58 +0000578 tprintf("%u", name);
579 }
580
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000581 tprints(", ");
582}
583
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000584static void
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700585print_get_linger(struct tcb *const tcp, const kernel_ulong_t addr,
586 unsigned int len)
587{
588 struct linger linger;
589
Elliott Hughesc1873762018-12-19 15:13:36 -0800590 /*
591 * The kernel cannot return len > sizeof(linger) because struct linger
592 * cannot change, but extra safety won't harm either.
593 */
594 if (len > sizeof(linger))
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700595 len = sizeof(linger);
Elliott Hughesc1873762018-12-19 15:13:36 -0800596 if (umoven_or_printaddr(tcp, addr, len, &linger))
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000597 return;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000598
Elliott Hughesc1873762018-12-19 15:13:36 -0800599 if (len < sizeof(linger.l_onoff)) {
600 tprints("{l_onoff=");
601 print_quoted_string((void *) &linger.l_onoff,
602 len, QUOTE_FORCE_HEX);
603 } else {
604 PRINT_FIELD_D("{", linger, l_onoff);
605
606 if (len > offsetof(struct linger, l_linger)) {
607 len -= offsetof(struct linger, l_linger);
608 if (len < sizeof(linger.l_linger)) {
609 tprints(", l_linger=");
610 print_quoted_string((void *) &linger.l_linger,
611 len, QUOTE_FORCE_HEX);
612 } else {
613 PRINT_FIELD_D(", ", linger, l_linger);
614 }
615 }
616 }
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700617 tprints("}");
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000618}
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000619
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000620static void
Elliott Hughesc1873762018-12-19 15:13:36 -0800621print_get_ucred(struct tcb *const tcp, const kernel_ulong_t addr,
622 unsigned int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000623{
624 struct ucred uc;
625
Elliott Hughesc1873762018-12-19 15:13:36 -0800626 /*
627 * The kernel is very unlikely to return len > sizeof(uc)
628 * because struct ucred is very unlikely to change,
629 * but extra safety won't harm either.
630 */
631 if (len > sizeof(uc))
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700632 len = sizeof(uc);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700633
Elliott Hughesc1873762018-12-19 15:13:36 -0800634 if (umoven_or_printaddr(tcp, addr, len, &uc))
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700635 return;
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700636
Elliott Hughesc1873762018-12-19 15:13:36 -0800637 if (len < sizeof(uc.pid)) {
638 tprints("{pid=");
639 print_quoted_string((void *) &uc.pid,
640 len, QUOTE_FORCE_HEX);
641 } else {
642 PRINT_FIELD_D("{", uc, pid);
643
644 if (len > offsetof(struct ucred, uid)) {
645 len -= offsetof(struct ucred, uid);
646 if (len < sizeof(uc.uid)) {
647 tprints(", uid=");
648 print_quoted_string((void *) &uc.uid,
649 len, QUOTE_FORCE_HEX);
650 } else {
651 PRINT_FIELD_UID(", ", uc, uid);
652
653 if (len > offsetof(struct ucred, gid) -
654 offsetof(struct ucred, uid)) {
655 len -= offsetof(struct ucred, gid) -
656 offsetof(struct ucred, uid);
657 if (len < sizeof(uc.gid)) {
658 tprints(", gid=");
659 print_quoted_string((void *) &uc.gid,
660 len,
661 QUOTE_FORCE_HEX);
662 } else {
663 PRINT_FIELD_UID(", ", uc, gid);
664 }
665 }
666 }
667 }
668 }
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700669 tprints("}");
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000670}
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000671
672#ifdef PACKET_STATISTICS
673static void
Elliott Hughesd35df492017-02-15 15:19:05 -0800674print_tpacket_stats(struct tcb *const tcp, const kernel_ulong_t addr,
Elliott Hughesc1873762018-12-19 15:13:36 -0800675 unsigned int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000676{
Elliott Hughesc1873762018-12-19 15:13:36 -0800677 struct tp_stats {
678 unsigned int tp_packets, tp_drops, tp_freeze_q_cnt;
679 } stats;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000680
Elliott Hughesc1873762018-12-19 15:13:36 -0800681 /*
682 * The kernel may return len > sizeof(stats) if the kernel structure
683 * grew as it happened when tpacket_stats_v3 was introduced.
684 */
685 if (len > sizeof(stats))
686 len = sizeof(stats);
687
688 if (umoven_or_printaddr(tcp, addr, len, &stats))
689 return;
690
691 if (len < sizeof(stats.tp_packets)) {
692 tprints("{tp_packets=");
693 print_quoted_string((void *) &stats.tp_packets,
694 len, QUOTE_FORCE_HEX);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000695 } else {
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700696 PRINT_FIELD_U("{", stats, tp_packets);
Elliott Hughesc1873762018-12-19 15:13:36 -0800697
698 if (len > offsetof(struct tp_stats, tp_drops)) {
699 len -= offsetof(struct tp_stats, tp_drops);
700 if (len < sizeof(stats.tp_drops)) {
701 tprints(", tp_drops=");
702 print_quoted_string((void *) &stats.tp_drops,
703 len, QUOTE_FORCE_HEX);
704 } else {
705 PRINT_FIELD_U(", ", stats, tp_drops);
706
707 if (len > offsetof(struct tp_stats, tp_freeze_q_cnt) -
708 offsetof(struct tp_stats, tp_drops)) {
709 len -= offsetof(struct tp_stats, tp_freeze_q_cnt) -
710 offsetof(struct tp_stats, tp_drops);
711 if (len < sizeof(stats.tp_freeze_q_cnt)) {
712 tprints(", tp_freeze_q_cnt=");
713 print_quoted_string((void *) &stats.tp_freeze_q_cnt,
714 len,
715 QUOTE_FORCE_HEX);
716 } else {
717 PRINT_FIELD_U(", ", stats, tp_freeze_q_cnt);
718 }
719 }
720 }
721 }
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000722 }
Elliott Hughesc1873762018-12-19 15:13:36 -0800723 tprints("}");
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000724}
725#endif /* PACKET_STATISTICS */
726
Dmitry V. Levinfba9db22016-06-15 21:29:07 +0000727#include "xlat/icmpfilterflags.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000728
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000729static void
Elliott Hughesd35df492017-02-15 15:19:05 -0800730print_icmp_filter(struct tcb *const tcp, const kernel_ulong_t addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000731{
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000732 struct icmp_filter filter = {};
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000733
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000734 if (len > (int) sizeof(filter))
735 len = sizeof(filter);
736 else if (len <= 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000737 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000738 return;
739 }
740
Dmitry V. Levineb5c2332016-05-06 00:06:15 +0000741 if (umoven_or_printaddr(tcp, addr, len, &filter))
742 return;
743
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000744 tprints("~(");
745 printflags(icmpfilterflags, ~filter.data, "ICMP_???");
746 tprints(")");
747}
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000748
Elliott Hughesb7556142018-02-20 17:03:16 -0800749static bool
750print_uint32(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
751{
752 tprintf("%u", *(uint32_t *) elem_buf);
753
754 return true;
755}
756
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000757static void
Elliott Hughesd35df492017-02-15 15:19:05 -0800758print_getsockopt(struct tcb *const tcp, const unsigned int level,
759 const unsigned int name, const kernel_ulong_t addr,
Elliott Hughesb7556142018-02-20 17:03:16 -0800760 const int ulen, const int rlen)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000761{
Elliott Hughesc1873762018-12-19 15:13:36 -0800762 if (ulen <= 0 || rlen <= 0) {
763 /*
764 * As the kernel neither accepts nor returns a negative
765 * length in case of successful getsockopt syscall
766 * invocation, negative values must have been forged
767 * by userspace.
768 */
769 printaddr(addr);
770 return;
771 }
772
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000773 if (addr && verbose(tcp))
774 switch (level) {
775 case SOL_SOCKET:
776 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000777 case SO_LINGER:
Elliott Hughesb7556142018-02-20 17:03:16 -0800778 print_get_linger(tcp, addr, rlen);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700779 return;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000780 case SO_PEERCRED:
Elliott Hughesc1873762018-12-19 15:13:36 -0800781 print_get_ucred(tcp, addr, rlen);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700782 return;
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700783 case SO_ATTACH_FILTER:
Elliott Hughesc1873762018-12-19 15:13:36 -0800784 /*
785 * The length returned by the kernel in case of
786 * successful getsockopt syscall invocation is struct
787 * sock_fprog.len that has type unsigned short,
788 * anything else must have been forged by userspace.
789 */
790 if ((unsigned short) rlen == (unsigned int) rlen)
Elliott Hughesb7556142018-02-20 17:03:16 -0800791 print_sock_fprog(tcp, addr, rlen);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700792 else
793 printaddr(addr);
794 return;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000795 }
796 break;
797
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000798 case SOL_PACKET:
799 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000800#ifdef PACKET_STATISTICS
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000801 case PACKET_STATISTICS:
Elliott Hughesb7556142018-02-20 17:03:16 -0800802 print_tpacket_stats(tcp, addr, rlen);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700803 return;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000804#endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000805 }
806 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000807
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000808 case SOL_RAW:
809 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000810 case ICMP_FILTER:
Elliott Hughesb7556142018-02-20 17:03:16 -0800811 print_icmp_filter(tcp, addr, rlen);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700812 return;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000813 }
814 break;
Elliott Hughesb7556142018-02-20 17:03:16 -0800815
816 case SOL_NETLINK:
Elliott Hughesb7556142018-02-20 17:03:16 -0800817 switch (name) {
818 case NETLINK_LIST_MEMBERSHIPS: {
819 uint32_t buf;
820 print_array(tcp, addr, MIN(ulen, rlen) / sizeof(buf),
821 &buf, sizeof(buf),
Elliott Hughes03a418e2018-06-15 13:11:40 -0700822 tfetch_mem, print_uint32, 0);
Elliott Hughesb7556142018-02-20 17:03:16 -0800823 break;
824 }
825 default:
826 printnum_int(tcp, addr, "%d");
827 break;
828 }
829 return;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000830 }
831
John Hughes38ae88d2002-05-23 11:48:58 +0000832 /* default arg printing */
833
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000834 if (verbose(tcp)) {
Elliott Hughesb7556142018-02-20 17:03:16 -0800835 if (rlen == sizeof(int)) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000836 printnum_int(tcp, addr, "%d");
837 } else {
Elliott Hughesb7556142018-02-20 17:03:16 -0800838 printstrn(tcp, addr, rlen);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000839 }
840 } else {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000841 printaddr(addr);
John Hughes38ae88d2002-05-23 11:48:58 +0000842 }
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000843}
844
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000845SYS_FUNC(getsockopt)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000846{
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700847 int ulen, rlen;
848
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000849 if (entering(tcp)) {
850 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
Mike Frysinger54646b82015-08-19 13:29:27 -0400851 tcp->u_arg[1], tcp->u_arg[2], true);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000852
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700853 if (verbose(tcp) && tcp->u_arg[4]
854 && umove(tcp, tcp->u_arg[4], &ulen) == 0) {
855 set_tcb_priv_ulong(tcp, ulen);
856 return 0;
857 } else {
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000858 printaddr(tcp->u_arg[3]);
859 tprints(", ");
860 printaddr(tcp->u_arg[4]);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700861 return RVAL_DECODED;
862 }
863 } else {
864 ulen = get_tcb_priv_ulong(tcp);
865
866 if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &rlen) < 0) {
867 printaddr(tcp->u_arg[3]);
868 tprintf(", [%d]", ulen);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000869 } else {
870 print_getsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
Elliott Hughesb7556142018-02-20 17:03:16 -0800871 tcp->u_arg[3], ulen, rlen);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700872 if (ulen != rlen)
873 tprintf(", [%d->%d]", ulen, rlen);
874 else
875 tprintf(", [%d]", rlen);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000876 }
John Hughes38ae88d2002-05-23 11:48:58 +0000877 }
878 return 0;
879}
880
Elliott Hughesc1873762018-12-19 15:13:36 -0800881static void
882print_set_linger(struct tcb *const tcp, const kernel_ulong_t addr,
883 const int len)
884{
885 struct linger linger;
886
887 if (len < (int) sizeof(linger)) {
888 printaddr(addr);
889 } else if (!umove_or_printaddr(tcp, addr, &linger)) {
890 PRINT_FIELD_D("{", linger, l_onoff);
891 PRINT_FIELD_D(", ", linger, l_linger);
892 tprints("}");
893 }
894}
895
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000896#ifdef IP_ADD_MEMBERSHIP
897static void
Elliott Hughesd35df492017-02-15 15:19:05 -0800898print_mreq(struct tcb *const tcp, const kernel_ulong_t addr,
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700899 const int len)
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000900{
901 struct ip_mreq mreq;
902
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700903 if (len < (int) sizeof(mreq)) {
904 printaddr(addr);
905 } else if (!umove_or_printaddr(tcp, addr, &mreq)) {
906 PRINT_FIELD_INET4_ADDR("{", mreq, imr_multiaddr);
907 PRINT_FIELD_INET4_ADDR(", ", mreq, imr_interface);
908 tprints("}");
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000909 }
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000910}
911#endif /* IP_ADD_MEMBERSHIP */
912
913#ifdef IPV6_ADD_MEMBERSHIP
914static void
Elliott Hughesd35df492017-02-15 15:19:05 -0800915print_mreq6(struct tcb *const tcp, const kernel_ulong_t addr,
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700916 const int len)
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000917{
918 struct ipv6_mreq mreq;
919
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700920 if (len < (int) sizeof(mreq)) {
921 printaddr(addr);
922 } else if (!umove_or_printaddr(tcp, addr, &mreq)) {
923 PRINT_FIELD_INET_ADDR("{", mreq, ipv6mr_multiaddr, AF_INET6);
924 PRINT_FIELD_IFINDEX(", ", mreq, ipv6mr_interface);
925 tprints("}");
Elliott Hughesdc75b012017-07-05 13:54:44 -0700926 }
Dmitry V. Levin7bee4622015-06-08 14:19:46 +0000927}
928#endif /* IPV6_ADD_MEMBERSHIP */
929
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000930#ifdef PACKET_RX_RING
931static void
Elliott Hughesd35df492017-02-15 15:19:05 -0800932print_tpacket_req(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000933{
934 struct tpacket_req req;
935
936 if (len != sizeof(req) ||
937 umove(tcp, addr, &req) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000938 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000939 } else {
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700940 PRINT_FIELD_U("{", req, tp_block_size);
941 PRINT_FIELD_U(", ", req, tp_block_nr);
942 PRINT_FIELD_U(", ", req, tp_frame_size);
943 PRINT_FIELD_U(", ", req, tp_frame_nr);
944 tprints("}");
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000945 }
946}
947#endif /* PACKET_RX_RING */
948
Dmitry V. Levin02f2f092015-01-29 03:26:53 +0000949#ifdef PACKET_ADD_MEMBERSHIP
950# include "xlat/packet_mreq_type.h"
951
952static void
Elliott Hughesd35df492017-02-15 15:19:05 -0800953print_packet_mreq(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
Dmitry V. Levin02f2f092015-01-29 03:26:53 +0000954{
955 struct packet_mreq mreq;
956
957 if (len != sizeof(mreq) ||
958 umove(tcp, addr, &mreq) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000959 printaddr(addr);
Dmitry V. Levin02f2f092015-01-29 03:26:53 +0000960 } else {
961 unsigned int i;
962
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700963 PRINT_FIELD_IFINDEX("{", mreq, mr_ifindex);
964 PRINT_FIELD_XVAL(", ", mreq, mr_type, packet_mreq_type,
965 "PACKET_MR_???");
966 PRINT_FIELD_U(", ", mreq, mr_alen);
967 tprints(", mr_address=");
Dmitry V. Levin02f2f092015-01-29 03:26:53 +0000968 if (mreq.mr_alen > ARRAY_SIZE(mreq.mr_address))
969 mreq.mr_alen = ARRAY_SIZE(mreq.mr_address);
970 for (i = 0; i < mreq.mr_alen; ++i)
971 tprintf("%02x", mreq.mr_address[i]);
972 tprints("}");
973 }
974}
975#endif /* PACKET_ADD_MEMBERSHIP */
976
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000977static void
Elliott Hughesd35df492017-02-15 15:19:05 -0800978print_setsockopt(struct tcb *const tcp, const unsigned int level,
979 const unsigned int name, const kernel_ulong_t addr,
980 const int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000981{
982 if (addr && verbose(tcp))
983 switch (level) {
984 case SOL_SOCKET:
985 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000986 case SO_LINGER:
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700987 print_set_linger(tcp, addr, len);
988 return;
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700989 case SO_ATTACH_FILTER:
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700990 case SO_ATTACH_REUSEPORT_CBPF:
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700991 if ((unsigned int) len == get_sock_fprog_size())
992 decode_sock_fprog(tcp, addr);
993 else
994 printaddr(addr);
995 return;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +0000996 }
997 break;
998
Dmitry V. Levina0a49092015-01-30 01:55:20 +0000999 case SOL_IP:
1000 switch (name) {
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001001#ifdef IP_ADD_MEMBERSHIP
1002 case IP_ADD_MEMBERSHIP:
1003 case IP_DROP_MEMBERSHIP:
1004 print_mreq(tcp, addr, len);
Elliott Hughes77c3ff82017-09-08 17:11:00 -07001005 return;
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001006#endif /* IP_ADD_MEMBERSHIP */
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001007#ifdef MCAST_JOIN_GROUP
1008 case MCAST_JOIN_GROUP:
1009 case MCAST_LEAVE_GROUP:
1010 print_group_req(tcp, addr, len);
Elliott Hughes77c3ff82017-09-08 17:11:00 -07001011 return;
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001012#endif /* MCAST_JOIN_GROUP */
1013 }
Dmitry V. Levin3910d0f2015-02-08 01:19:06 +00001014 break;
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001015
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001016 case SOL_IPV6:
1017 switch (name) {
1018#ifdef IPV6_ADD_MEMBERSHIP
1019 case IPV6_ADD_MEMBERSHIP:
1020 case IPV6_DROP_MEMBERSHIP:
1021# ifdef IPV6_JOIN_ANYCAST
1022 case IPV6_JOIN_ANYCAST:
1023# endif
1024# ifdef IPV6_LEAVE_ANYCAST
1025 case IPV6_LEAVE_ANYCAST:
1026# endif
1027 print_mreq6(tcp, addr, len);
Elliott Hughes77c3ff82017-09-08 17:11:00 -07001028 return;
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001029#endif /* IPV6_ADD_MEMBERSHIP */
Elliott Hughes77c3ff82017-09-08 17:11:00 -07001030#ifdef MCAST_JOIN_GROUP
1031 case MCAST_JOIN_GROUP:
1032 case MCAST_LEAVE_GROUP:
1033 print_group_req(tcp, addr, len);
1034 return;
1035#endif /* MCAST_JOIN_GROUP */
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001036 }
1037 break;
1038
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001039 case SOL_PACKET:
1040 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001041#ifdef PACKET_RX_RING
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001042 case PACKET_RX_RING:
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001043# ifdef PACKET_TX_RING
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001044 case PACKET_TX_RING:
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001045# endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001046 print_tpacket_req(tcp, addr, len);
Elliott Hughes77c3ff82017-09-08 17:11:00 -07001047 return;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001048#endif /* PACKET_RX_RING */
1049#ifdef PACKET_ADD_MEMBERSHIP
Dmitry V. Levin02f2f092015-01-29 03:26:53 +00001050 case PACKET_ADD_MEMBERSHIP:
1051 case PACKET_DROP_MEMBERSHIP:
1052 print_packet_mreq(tcp, addr, len);
Elliott Hughes77c3ff82017-09-08 17:11:00 -07001053 return;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001054#endif /* PACKET_ADD_MEMBERSHIP */
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001055 }
1056 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001057
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001058 case SOL_RAW:
1059 switch (name) {
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001060 case ICMP_FILTER:
1061 print_icmp_filter(tcp, addr, len);
Elliott Hughes77c3ff82017-09-08 17:11:00 -07001062 return;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001063 }
1064 break;
Elliott Hughesb7556142018-02-20 17:03:16 -08001065
1066 case SOL_NETLINK:
1067 if (len < (int) sizeof(int))
1068 printaddr(addr);
1069 else
1070 printnum_int(tcp, addr, "%d");
1071 return;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001072 }
1073
1074 /* default arg printing */
1075
1076 if (verbose(tcp)) {
1077 if (len == sizeof(int)) {
1078 printnum_int(tcp, addr, "%d");
1079 } else {
Elliott Hughesd35df492017-02-15 15:19:05 -08001080 printstrn(tcp, addr, len);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001081 }
1082 } else {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001083 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001084 }
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001085}
1086
Dmitry V. Levina0bd3742015-04-07 01:36:50 +00001087SYS_FUNC(setsockopt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001088{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +00001089 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
Mike Frysinger54646b82015-08-19 13:29:27 -04001090 tcp->u_arg[1], tcp->u_arg[2], false);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +00001091 print_setsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
1092 tcp->u_arg[3], tcp->u_arg[4]);
Elliott Hughes77c3ff82017-09-08 17:11:00 -07001093 tprintf(", %d", (int) tcp->u_arg[4]);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +00001094
1095 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001096}