blob: 9c4af0d584158f7ae2d369decfbe7d200efc6dcd [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"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000032#include <sys/stat.h>
33#include <sys/socket.h>
Dmitry V. Levinb2fa2be2014-11-21 20:46:16 +000034#include <sys/uio.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000035#include <sys/un.h>
36#include <netinet/in.h>
Wichert Akkerman8c7122c2001-02-16 19:59:55 +000037#ifdef HAVE_NETINET_TCP_H
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010038# include <netinet/tcp.h>
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000039#endif
Wichert Akkerman8c7122c2001-02-16 19:59:55 +000040#ifdef HAVE_NETINET_UDP_H
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010041# include <netinet/udp.h>
Wichert Akkerman8c7122c2001-02-16 19:59:55 +000042#endif
Holger Hans Peter Freyther7fea79b2011-01-14 11:08:12 +010043#ifdef HAVE_NETINET_SCTP_H
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010044# include <netinet/sctp.h>
Holger Hans Peter Freyther7fea79b2011-01-14 11:08:12 +010045#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000046#include <arpa/inet.h>
Wichert Akkermanf1850652001-02-16 20:29:03 +000047#include <net/if.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000048#include <asm/types.h>
Denys Vlasenko99aa1812013-02-08 18:49:06 +010049#if defined(__GLIBC__)
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010050# include <netipx/ipx.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000051#else
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010052# include <linux/ipx.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000053#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000054
Mike Frysinger54646b82015-08-19 13:29:27 -040055#if defined(HAVE_LINUX_IP_VS_H)
56# include <linux/ip_vs.h>
57#endif
Dmitry V. Levinb10ee4e2016-06-14 13:53:47 +000058#include <linux/netlink.h>
Mike Frysinger54646b82015-08-19 13:29:27 -040059#if defined(HAVE_LINUX_NETFILTER_ARP_ARP_TABLES_H)
60# include <linux/netfilter_arp/arp_tables.h>
61#endif
62#if defined(HAVE_LINUX_NETFILTER_BRIDGE_EBTABLES_H)
63# include <linux/netfilter_bridge/ebtables.h>
64#endif
65#if defined(HAVE_LINUX_NETFILTER_IPV4_IP_TABLES_H)
66# include <linux/netfilter_ipv4/ip_tables.h>
67#endif
68#if defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H)
69# include <linux/netfilter_ipv6/ip6_tables.h>
70#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +000071#if defined(HAVE_LINUX_IF_PACKET_H)
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010072# include <linux/if_packet.h>
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +000073#endif
Dmitry V. Levind06010b2016-06-15 21:27:41 +000074#include <linux/icmp.h>
Lubomir Rintelc400a1c2014-10-03 11:40:28 +020075#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
76# include <bluetooth/bluetooth.h>
77# include <bluetooth/hci.h>
78# include <bluetooth/l2cap.h>
79# include <bluetooth/rfcomm.h>
80# include <bluetooth/sco.h>
81#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000082
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000083#include "xlat/addrfams.h"
84#include "xlat/socktypes.h"
85#include "xlat/sock_type_flags.h"
Dmitry V. Levin8a550d72008-11-10 17:21:23 +000086#ifndef SOCK_TYPE_MASK
87# define SOCK_TYPE_MASK 0xf
88#endif
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +000089
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000090#include "xlat/socketlayers.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +000091
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000092#include "xlat/inet_protocols.h"
Masatake YAMATO2394a3d2014-03-11 23:37:37 +090093
Dmitry V. Levin94573042016-06-14 13:53:47 +000094#if !defined NETLINK_SOCK_DIAG && defined NETLINK_INET_DIAG
95# define NETLINK_SOCK_DIAG NETLINK_INET_DIAG
Masatake YAMATO2394a3d2014-03-11 23:37:37 +090096#endif
Dmitry V. Levin94573042016-06-14 13:53:47 +000097#include "xlat/netlink_protocols.h"
Masatake YAMATO2394a3d2014-03-11 23:37:37 +090098
Lubomir Rintelc400a1c2014-10-03 11:40:28 +020099#if defined(HAVE_BLUETOOTH_BLUETOOTH_H)
100# include "xlat/bt_protocols.h"
101#endif
102
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000103#include "xlat/msg_flags.h"
Wichert Akkerman7987cdf2000-07-05 16:05:39 +0000104
Wichert Akkermanb0c598f2002-04-01 12:48:06 +0000105#if defined(AF_PACKET) /* from e.g. linux/if_packet.h */
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +0000106# include "xlat/af_packet_types.h"
107#endif
Wichert Akkermanb0c598f2002-04-01 12:48:06 +0000108
Dmitry V. Levinae280932015-06-05 20:13:21 +0000109static void
110print_ifindex(unsigned int ifindex)
111{
112#ifdef HAVE_IF_INDEXTONAME
113 char buf[IFNAMSIZ + 1];
114
115 if (if_indextoname(ifindex, buf)) {
116 tprints("if_nametoindex(");
117 print_quoted_string(buf, sizeof(buf), QUOTE_0_TERMINATED);
118 tprints(")");
119 return;
120 }
121#endif
122 tprintf("%u", ifindex);
123}
124
Dmitry V. Levin1019f002015-11-21 02:38:59 +0000125typedef union {
126 char pad[128];
127 struct sockaddr sa;
128 struct sockaddr_in sin;
129 struct sockaddr_un sau;
130#ifdef HAVE_INET_NTOP
131 struct sockaddr_in6 sa6;
132#endif
133#if defined(AF_IPX)
134 struct sockaddr_ipx sipx;
135#endif
136#ifdef AF_PACKET
137 struct sockaddr_ll ll;
138#endif
Dmitry V. Levin1019f002015-11-21 02:38:59 +0000139 struct sockaddr_nl nl;
Dmitry V. Levin1019f002015-11-21 02:38:59 +0000140#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
141 struct sockaddr_hci hci;
142 struct sockaddr_l2 l2;
143 struct sockaddr_rc rc;
144 struct sockaddr_sco sco;
145#endif
146} sockaddr_buf_t;
147
148static void
149print_sockaddr(struct tcb *tcp, const sockaddr_buf_t *addr, const int addrlen)
150{
151 tprints("{sa_family=");
152 printxval(addrfams, addr->sa.sa_family, "AF_???");
153 tprints(", ");
154
155 switch (addr->sa.sa_family) {
156 case AF_UNIX:
157 if (addrlen == 2) {
158 tprints("NULL");
159 } else if (addr->sau.sun_path[0]) {
160 tprints("sun_path=");
161 print_quoted_string(addr->sau.sun_path,
162 sizeof(addr->sau.sun_path) + 1,
163 QUOTE_0_TERMINATED);
164 } else {
165 tprints("sun_path=@");
166 print_quoted_string(addr->sau.sun_path + 1,
167 sizeof(addr->sau.sun_path),
168 QUOTE_0_TERMINATED);
169 }
170 break;
171 case AF_INET:
172 tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")",
173 ntohs(addr->sin.sin_port), inet_ntoa(addr->sin.sin_addr));
174 break;
175#ifdef HAVE_INET_NTOP
176 case AF_INET6:
177 {
178 char string_addr[100];
179 inet_ntop(AF_INET6, &addr->sa6.sin6_addr,
180 string_addr, sizeof(string_addr));
181 tprintf("sin6_port=htons(%u), inet_pton(AF_INET6"
182 ", \"%s\", &sin6_addr), sin6_flowinfo=%u",
183 ntohs(addr->sa6.sin6_port), string_addr,
184 addr->sa6.sin6_flowinfo);
185# ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
186 tprints(", sin6_scope_id=");
187# if defined IN6_IS_ADDR_LINKLOCAL && defined IN6_IS_ADDR_MC_LINKLOCAL
188 if (IN6_IS_ADDR_LINKLOCAL(&addr->sa6.sin6_addr)
189 || IN6_IS_ADDR_MC_LINKLOCAL(&addr->sa6.sin6_addr))
190 print_ifindex(addr->sa6.sin6_scope_id);
191 else
192# endif
193 tprintf("%u", addr->sa6.sin6_scope_id);
194# endif /* HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID */
195 }
196 break;
197#endif
198#if defined(AF_IPX)
199 case AF_IPX:
200 {
201 int i;
202 tprintf("sipx_port=htons(%u), ",
203 ntohs(addr->sipx.sipx_port));
204 /* Yes, I know, this does not look too
205 * strace-ish, but otherwise the IPX
206 * addresses just look monstrous...
207 * Anyways, feel free if you don't like
208 * this way.. :)
209 */
210 tprintf("%08lx:", (unsigned long)ntohl(addr->sipx.sipx_network));
211 for (i = 0; i < IPX_NODE_LEN; i++)
212 tprintf("%02x", addr->sipx.sipx_node[i]);
213 tprintf("/[%02x]", addr->sipx.sipx_type);
214 }
215 break;
216#endif /* AF_IPX */
217#ifdef AF_PACKET
218 case AF_PACKET:
219 {
220 int i;
221 tprintf("proto=%#04x, if%d, pkttype=",
222 ntohs(addr->ll.sll_protocol),
223 addr->ll.sll_ifindex);
224 printxval(af_packet_types, addr->ll.sll_pkttype, "PACKET_???");
225 tprintf(", addr(%d)={%d, ",
226 addr->ll.sll_halen,
227 addr->ll.sll_hatype);
228 for (i = 0; i < addr->ll.sll_halen; i++)
229 tprintf("%02x", addr->ll.sll_addr[i]);
230 }
231 break;
232
233#endif /* AF_PACKET */
Dmitry V. Levin1019f002015-11-21 02:38:59 +0000234 case AF_NETLINK:
235 tprintf("pid=%d, groups=%08x", addr->nl.nl_pid, addr->nl.nl_groups);
236 break;
Dmitry V. Levin1019f002015-11-21 02:38:59 +0000237#if defined(AF_BLUETOOTH) && defined(HAVE_BLUETOOTH_BLUETOOTH_H)
238 case AF_BLUETOOTH:
239 tprintf("{sco_bdaddr=%02X:%02X:%02X:%02X:%02X:%02X} or "
240 "{rc_bdaddr=%02X:%02X:%02X:%02X:%02X:%02X, rc_channel=%d} or "
241 "{l2_psm=htobs(%d), l2_bdaddr=%02X:%02X:%02X:%02X:%02X:%02X, l2_cid=htobs(%d)} or "
242 "{hci_dev=htobs(%d)}",
243 addr->sco.sco_bdaddr.b[0], addr->sco.sco_bdaddr.b[1],
244 addr->sco.sco_bdaddr.b[2], addr->sco.sco_bdaddr.b[3],
245 addr->sco.sco_bdaddr.b[4], addr->sco.sco_bdaddr.b[5],
246 addr->rc.rc_bdaddr.b[0], addr->rc.rc_bdaddr.b[1],
247 addr->rc.rc_bdaddr.b[2], addr->rc.rc_bdaddr.b[3],
248 addr->rc.rc_bdaddr.b[4], addr->rc.rc_bdaddr.b[5],
249 addr->rc.rc_channel,
250 btohs(addr->l2.l2_psm), addr->l2.l2_bdaddr.b[0],
251 addr->l2.l2_bdaddr.b[1], addr->l2.l2_bdaddr.b[2],
252 addr->l2.l2_bdaddr.b[3], addr->l2.l2_bdaddr.b[4],
253 addr->l2.l2_bdaddr.b[5], btohs(addr->l2.l2_cid),
254 btohs(addr->hci.hci_dev));
255 break;
256#endif /* AF_BLUETOOTH && HAVE_BLUETOOTH_BLUETOOTH_H */
257 /* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
258 AF_X25 AF_ROSE etc. still need to be done */
259
260 default:
261 tprints("sa_data=");
262 print_quoted_string(addr->sa.sa_data,
263 sizeof(addr->sa.sa_data), 0);
264 break;
265 }
266 tprints("}");
267}
268
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000269void
Dmitry V. Levinb6c32f42007-10-08 23:31:19 +0000270printsock(struct tcb *tcp, long addr, int addrlen)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000271{
Dmitry V. Levin1019f002015-11-21 02:38:59 +0000272 sockaddr_buf_t addrbuf;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000273
Denys Vlasenko383386d2015-07-30 13:29:20 +0200274 if (addrlen < 2) {
Dmitry V. Levin52dc1502015-07-30 13:53:42 +0000275 printaddr(addr);
Denys Vlasenko383386d2015-07-30 13:29:20 +0200276 return;
277 }
278
279 if (addrlen > (int) sizeof(addrbuf))
Dmitry V. Levinb6c32f42007-10-08 23:31:19 +0000280 addrlen = sizeof(addrbuf);
281
282 memset(&addrbuf, 0, sizeof(addrbuf));
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000283 if (umoven_or_printaddr(tcp, addr, addrlen, addrbuf.pad))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000284 return;
Dmitry V. Levinb6c32f42007-10-08 23:31:19 +0000285 addrbuf.pad[sizeof(addrbuf.pad) - 1] = '\0';
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000286
Dmitry V. Levin1019f002015-11-21 02:38:59 +0000287 print_sockaddr(tcp, &addrbuf, addrlen);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000288}
289
Dmitry V. Levinb36d1322015-11-18 23:18:17 +0000290#include "xlat/scmvals.h"
Dmitry V. Levin1f111cf2015-11-21 03:03:54 +0300291#include "xlat/ip_cmsg_types.h"
Roland McGrath50770822004-10-06 22:11:51 +0000292
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000293#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
294struct cmsghdr32 {
295 uint32_t cmsg_len;
296 int cmsg_level;
297 int cmsg_type;
298};
299#endif
300
301typedef union {
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000302 char *ptr;
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000303 struct cmsghdr *cmsg;
304#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
305 struct cmsghdr32 *cmsg32;
306#endif
307} union_cmsghdr;
308
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000309static void
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000310print_scm_rights(struct tcb *tcp, const void *cmsg_data,
311 const size_t data_len)
Roland McGrath50770822004-10-06 22:11:51 +0000312{
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000313 const int *fds = cmsg_data;
314 const char *end = (const char *) cmsg_data + data_len;
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000315 bool seen = false;
316
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000317 if (sizeof(*fds) > data_len)
318 return;
319
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000320 tprints(", [");
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000321 while ((const char *) fds < end) {
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000322 if (seen)
323 tprints(", ");
324 else
325 seen = true;
326 printfd(tcp, *fds++);
327 }
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000328 tprints("]");
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000329}
330
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000331static void
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000332print_scm_creds(struct tcb *tcp, const void *cmsg_data,
333 const size_t data_len)
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000334{
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000335 const struct ucred *uc = cmsg_data;
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000336
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000337 if (sizeof(*uc) > data_len)
338 return;
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000339
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000340 tprintf(", {pid=%u, uid=%u, gid=%u}",
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000341 (unsigned) uc->pid, (unsigned) uc->uid, (unsigned) uc->gid);
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000342}
343
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000344static void
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000345print_scm_security(struct tcb *tcp, const void *cmsg_data,
346 const size_t data_len)
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000347{
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000348 if (!data_len)
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000349 return;
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000350
Dmitry V. Levin513e96e2015-01-26 01:17:08 +0000351 tprints(", ");
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000352 print_quoted_string(cmsg_data, data_len, 0);
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000353}
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000354
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000355static void
Dmitry V. Levin1f111cf2015-11-21 03:03:54 +0300356print_cmsg_ip_pktinfo(struct tcb *tcp, const void *cmsg_data,
357 const size_t data_len)
358{
359 const struct in_pktinfo *info = cmsg_data;
360
361 if (sizeof(*info) > data_len)
362 return;
363
364 tprints(", {ipi_ifindex=");
365 print_ifindex(info->ipi_ifindex);
366 tprintf(", ipi_spec_dst=inet_addr(\"%s\"), ipi_addr=inet_addr(\"%s\")}",
367 inet_ntoa(info->ipi_spec_dst), inet_ntoa(info->ipi_addr));
368}
369
370static void
371print_cmsg_ip_ttl(struct tcb *tcp, const void *cmsg_data,
372 const size_t data_len)
373{
374 const unsigned int *ttl = cmsg_data;
375
376 if (sizeof(*ttl) > data_len)
377 return;
378
379 tprintf(", {ttl=%u}", *ttl);
380}
381
382static void
383print_cmsg_ip_tos(struct tcb *tcp, const void *cmsg_data,
384 const size_t data_len)
385{
386 const uint8_t *tos = cmsg_data;
387
388 if (sizeof(*tos) > data_len)
389 return;
390
391 tprintf(", {tos=%x}", *tos);
392}
393
394static void
395print_cmsg_ip_checksum(struct tcb *tcp, const void *cmsg_data,
396 const size_t data_len)
397{
398 const uint32_t *csum = cmsg_data;
399
400 if (sizeof(*csum) > data_len)
401 return;
402
403 tprintf(", {csum=%u}", *csum);
404}
405
406static void
407print_cmsg_ip_opts(struct tcb *tcp, const void *cmsg_data,
408 const size_t data_len)
409{
Dmitry V. Levina17f5932015-11-22 23:07:52 +0000410 const unsigned char *opts = cmsg_data;
Dmitry V. Levin1f111cf2015-11-21 03:03:54 +0300411 size_t i;
412
413 if (!data_len)
414 return;
415
416 tprints(", {opts=0x");
417 for (i = 0; i < data_len; ++i)
418 tprintf("%02x", opts[i]);
419 tprints("}");
420}
421
422static void
423print_cmsg_ip_recverr(struct tcb *tcp, const void *cmsg_data,
424 const size_t data_len)
425{
426 const struct {
427 uint32_t ee_errno;
428 uint8_t ee_origin;
429 uint8_t ee_type;
430 uint8_t ee_code;
431 uint8_t ee_pad;
432 uint32_t ee_info;
433 uint32_t ee_data;
434 struct sockaddr_in offender;
435 } *err = cmsg_data;
436
437 if (sizeof(*err) > data_len)
438 return;
439
440 tprintf(", {ee_errno=%u, ee_origin=%u, ee_type=%u, ee_code=%u"
441 ", ee_info=%u, ee_data=%u, offender=",
442 err->ee_errno, err->ee_origin, err->ee_type,
443 err->ee_code, err->ee_info, err->ee_data);
444 print_sockaddr(tcp, (const void *) &err->offender,
445 sizeof(err->offender));
446 tprints("}");
447}
448
449static void
450print_cmsg_ip_origdstaddr(struct tcb *tcp, const void *cmsg_data,
451 const size_t data_len)
452{
453 if (sizeof(struct sockaddr_in) > data_len)
454 return;
455
456 tprints(", ");
457 print_sockaddr(tcp, cmsg_data, data_len);
458}
459
460static void
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000461print_cmsg_type_data(struct tcb *tcp, const int cmsg_level, const int cmsg_type,
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000462 const void *cmsg_data, const size_t data_len)
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000463{
464 switch (cmsg_level) {
465 case SOL_SOCKET:
466 printxval(scmvals, cmsg_type, "SCM_???");
467 switch (cmsg_type) {
468 case SCM_RIGHTS:
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000469 print_scm_rights(tcp, cmsg_data, data_len);
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000470 break;
471 case SCM_CREDENTIALS:
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000472 print_scm_creds(tcp, cmsg_data, data_len);
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000473 break;
474 case SCM_SECURITY:
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000475 print_scm_security(tcp, cmsg_data, data_len);
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000476 break;
477 }
478 break;
Dmitry V. Levin1f111cf2015-11-21 03:03:54 +0300479 case SOL_IP:
480 printxval(ip_cmsg_types, cmsg_type, "IP_???");
481 switch (cmsg_type) {
482 case IP_PKTINFO:
483 print_cmsg_ip_pktinfo(tcp, cmsg_data, data_len);
484 break;
485 case IP_TTL:
486 print_cmsg_ip_ttl(tcp, cmsg_data, data_len);
487 break;
488 case IP_TOS:
489 print_cmsg_ip_tos(tcp, cmsg_data, data_len);
490 break;
491 case IP_RECVOPTS:
492 case IP_RETOPTS:
493 print_cmsg_ip_opts(tcp, cmsg_data, data_len);
494 break;
495 case IP_RECVERR:
496 print_cmsg_ip_recverr(tcp, cmsg_data, data_len);
497 break;
498 case IP_ORIGDSTADDR:
499 print_cmsg_ip_origdstaddr(tcp, cmsg_data, data_len);
500 break;
501 case IP_CHECKSUM:
502 print_cmsg_ip_checksum(tcp, cmsg_data, data_len);
503 break;
504 case SCM_SECURITY:
505 print_scm_security(tcp, cmsg_data, data_len);
506 break;
507 }
508 break;
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000509 default:
510 tprintf("%u", cmsg_type);
511 }
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000512}
513
514static void
515printcmsghdr(struct tcb *tcp, unsigned long addr, size_t len)
516{
517 const size_t cmsg_size =
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000518#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
519 (current_wordsize < sizeof(long)) ? sizeof(struct cmsghdr32) :
520#endif
521 sizeof(struct cmsghdr);
522
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000523 char *buf = len < cmsg_size ? NULL : malloc(len);
524 if (!buf || umoven(tcp, addr, len, buf) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000525 tprints(", msg_control=");
526 printaddr(addr);
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000527 free(buf);
Roland McGrath50770822004-10-06 22:11:51 +0000528 return;
529 }
530
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000531 union_cmsghdr u = { .ptr = buf };
532
533 tprints(", [");
534 while (len >= cmsg_size) {
535 size_t cmsg_len =
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000536#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000537 (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_len :
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000538#endif
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000539 u.cmsg->cmsg_len;
540 int cmsg_level =
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000541#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000542 (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_level :
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000543#endif
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000544 u.cmsg->cmsg_level;
545 int cmsg_type =
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000546#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000547 (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_type :
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000548#endif
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000549 u.cmsg->cmsg_type;
Dmitry V. Levin05884d82015-01-24 01:08:57 +0000550
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000551 if (u.ptr != buf)
552 tprints(", ");
553 tprintf("{cmsg_len=%lu, cmsg_level=", (unsigned long) cmsg_len);
554 printxval(socketlayers, cmsg_level, "SOL_???");
555 tprints(", cmsg_type=");
Roland McGrath50770822004-10-06 22:11:51 +0000556
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000557 if (cmsg_len > len)
558 cmsg_len = len;
Roland McGrath96ad7b82005-02-02 03:11:32 +0000559
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000560 print_cmsg_type_data(tcp, cmsg_level, cmsg_type,
Dmitry V. Levin1103b4e2015-11-21 03:59:09 +0000561 (const void *) (u.ptr + cmsg_size),
562 cmsg_len > cmsg_size ? cmsg_len - cmsg_size: 0);
Dmitry V. Levinf54cb962015-11-19 00:29:19 +0000563 tprints("}");
564
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000565 if (cmsg_len < cmsg_size) {
566 len -= cmsg_size;
567 break;
Roland McGrath50770822004-10-06 22:11:51 +0000568 }
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000569 cmsg_len = (cmsg_len + current_wordsize - 1) &
570 (size_t) ~(current_wordsize - 1);
571 if (cmsg_len >= len) {
572 len = 0;
573 break;
574 }
575 u.ptr += cmsg_len;
576 len -= cmsg_len;
Roland McGrath50770822004-10-06 22:11:51 +0000577 }
Dmitry V. Levinb85a7f32015-01-24 15:20:31 +0000578 if (len)
579 tprints(", ...");
580 tprints("]");
581 free(buf);
Roland McGrath50770822004-10-06 22:11:51 +0000582}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000583
584static void
Denys Vlasenkoe0bc2222012-04-28 14:26:18 +0200585do_msghdr(struct tcb *tcp, struct msghdr *msg, unsigned long data_size)
Andreas Schwab0873f292010-02-12 21:39:12 +0100586{
587 tprintf("{msg_name(%d)=", msg->msg_namelen);
588 printsock(tcp, (long)msg->msg_name, msg->msg_namelen);
589
590 tprintf(", msg_iov(%lu)=", (unsigned long)msg->msg_iovlen);
Denys Vlasenkoe0bc2222012-04-28 14:26:18 +0200591 tprint_iov_upto(tcp, (unsigned long)msg->msg_iovlen,
592 (unsigned long)msg->msg_iov, 1, data_size);
Andreas Schwab0873f292010-02-12 21:39:12 +0100593
594#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
595 tprintf(", msg_controllen=%lu", (unsigned long)msg->msg_controllen);
596 if (msg->msg_controllen)
597 printcmsghdr(tcp, (unsigned long) msg->msg_control,
598 msg->msg_controllen);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200599 tprints(", msg_flags=");
Andreas Schwab0873f292010-02-12 21:39:12 +0100600 printflags(msg_flags, msg->msg_flags, "MSG_???");
601#else /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
602 tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
603 (unsigned long) msg->msg_accrights, msg->msg_accrightslen);
604#endif /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200605 tprints("}");
Andreas Schwab0873f292010-02-12 21:39:12 +0100606}
607
Denys Vlasenko3e759d42013-02-12 11:57:48 +0100608struct msghdr32 {
609 uint32_t /* void* */ msg_name;
610 uint32_t /* socklen_t */msg_namelen;
611 uint32_t /* iovec* */ msg_iov;
612 uint32_t /* size_t */ msg_iovlen;
613 uint32_t /* void* */ msg_control;
614 uint32_t /* size_t */ msg_controllen;
615 uint32_t /* int */ msg_flags;
616};
617struct mmsghdr32 {
618 struct msghdr32 msg_hdr;
619 uint32_t /* unsigned */ msg_len;
620};
621
Masatake YAMATOcaf6a432014-11-07 01:23:25 +0900622#ifndef HAVE_STRUCT_MMSGHDR
623struct mmsghdr {
624 struct msghdr msg_hdr;
625 unsigned msg_len;
626};
627#endif
628
Masatake YAMATOb2485432014-11-07 01:23:24 +0900629#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
630static void
631copy_from_msghdr32(struct msghdr *to_msg, struct msghdr32 *from_msg32)
632{
633 to_msg->msg_name = (void*)(long)from_msg32->msg_name;
634 to_msg->msg_namelen = from_msg32->msg_namelen;
635 to_msg->msg_iov = (void*)(long)from_msg32->msg_iov;
636 to_msg->msg_iovlen = from_msg32->msg_iovlen;
637 to_msg->msg_control = (void*)(long)from_msg32->msg_control;
638 to_msg->msg_controllen = from_msg32->msg_controllen;
639 to_msg->msg_flags = from_msg32->msg_flags;
640}
641#endif
642
Masatake YAMATO02f9f6b2014-10-15 22:11:43 +0900643static bool
644extractmsghdr(struct tcb *tcp, long addr, struct msghdr *msg)
645{
646#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
647 if (current_wordsize == 4) {
648 struct msghdr32 msg32;
649
650 if (umove(tcp, addr, &msg32) < 0)
651 return false;
Masatake YAMATOb2485432014-11-07 01:23:24 +0900652 copy_from_msghdr32(msg, &msg32);
Masatake YAMATO02f9f6b2014-10-15 22:11:43 +0900653 } else
654#endif
655 if (umove(tcp, addr, msg) < 0)
656 return false;
657 return true;
658}
659
Masatake YAMATOa807dce2014-11-07 01:23:26 +0900660static bool
661extractmmsghdr(struct tcb *tcp, long addr, unsigned int idx, struct mmsghdr *mmsg)
662{
663#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
664 if (current_wordsize == 4) {
665 struct mmsghdr32 mmsg32;
666
667 addr += sizeof(struct mmsghdr32) * idx;
668 if (umove(tcp, addr, &mmsg32) < 0)
669 return false;
670
671 copy_from_msghdr32(&mmsg->msg_hdr, &mmsg32.msg_hdr);
672 mmsg->msg_len = mmsg32.msg_len;
673 } else
674#endif
675 {
676 addr += sizeof(*mmsg) * idx;
677 if (umove(tcp, addr, mmsg) < 0)
678 return false;
679 }
680 return true;
681}
682
Andreas Schwab0873f292010-02-12 21:39:12 +0100683static void
Denys Vlasenkoe0bc2222012-04-28 14:26:18 +0200684printmsghdr(struct tcb *tcp, long addr, unsigned long data_size)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000685{
686 struct msghdr msg;
687
Dmitry V. Levin00244b92015-01-28 01:52:25 +0000688 if (verbose(tcp) && extractmsghdr(tcp, addr, &msg))
Masatake YAMATO02f9f6b2014-10-15 22:11:43 +0900689 do_msghdr(tcp, &msg, data_size);
690 else
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000691 printaddr(addr);
Masatake YAMATO02f9f6b2014-10-15 22:11:43 +0900692}
693
694void
Dmitry V. Levin93c9d1c2016-01-20 03:26:37 +0000695dumpiov_in_msghdr(struct tcb *tcp, long addr, unsigned long data_size)
Masatake YAMATO02f9f6b2014-10-15 22:11:43 +0900696{
697 struct msghdr msg;
698
699 if (extractmsghdr(tcp, addr, &msg))
Dmitry V. Levin93c9d1c2016-01-20 03:26:37 +0000700 dumpiov_upto(tcp, msg.msg_iovlen, (long)msg.msg_iov, data_size);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000701}
702
Andreas Schwab0873f292010-02-12 21:39:12 +0100703static void
Dmitry V. Levin5ea97652012-05-01 20:41:40 +0000704printmmsghdr(struct tcb *tcp, long addr, unsigned int idx, unsigned long msg_len)
Andreas Schwab0873f292010-02-12 21:39:12 +0100705{
Masatake YAMATOcaf6a432014-11-07 01:23:25 +0900706 struct mmsghdr mmsg;
Andreas Schwab0873f292010-02-12 21:39:12 +0100707
Masatake YAMATOa807dce2014-11-07 01:23:26 +0900708 if (extractmmsghdr(tcp, addr, idx, &mmsg)) {
709 tprints("{");
710 do_msghdr(tcp, &mmsg.msg_hdr, msg_len ? msg_len : mmsg.msg_len);
711 tprintf(", %u}", mmsg.msg_len);
Andreas Schwab0873f292010-02-12 21:39:12 +0100712 }
Masatake YAMATOa807dce2014-11-07 01:23:26 +0900713 else
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000714 printaddr(addr);
Andreas Schwab0873f292010-02-12 21:39:12 +0100715}
Andreas Schwab0873f292010-02-12 21:39:12 +0100716
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000717static void
Dmitry V. Levin5ea97652012-05-01 20:41:40 +0000718decode_mmsg(struct tcb *tcp, unsigned long msg_len)
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000719{
720 /* mmsgvec */
721 if (syserror(tcp)) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000722 printaddr(tcp->u_arg[1]);
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000723 } else {
724 unsigned int len = tcp->u_rval;
725 unsigned int i;
726
727 tprints("{");
728 for (i = 0; i < len; ++i) {
729 if (i)
730 tprints(", ");
Dmitry V. Levin5ea97652012-05-01 20:41:40 +0000731 printmmsghdr(tcp, tcp->u_arg[1], i, msg_len);
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000732 }
733 tprints("}");
734 }
735 /* vlen */
736 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
737 /* flags */
738 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
739}
740
Masatake YAMATOa807dce2014-11-07 01:23:26 +0900741void
742dumpiov_in_mmsghdr(struct tcb *tcp, long addr)
743{
744 unsigned int len = tcp->u_rval;
745 unsigned int i;
746 struct mmsghdr mmsg;
747
748 for (i = 0; i < len; ++i) {
749 if (extractmmsghdr(tcp, addr, i, &mmsg)) {
750 tprintf(" = %lu buffers in vector %u\n",
751 (unsigned long)mmsg.msg_hdr.msg_iovlen, i);
Dmitry V. Levind44707d2016-01-20 04:56:25 +0000752 dumpiov_upto(tcp, mmsg.msg_hdr.msg_iovlen,
753 (long)mmsg.msg_hdr.msg_iov, mmsg.msg_len);
Masatake YAMATOa807dce2014-11-07 01:23:26 +0900754 }
755 }
756}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000757
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000758/*
759 * low bits of the socket type define real socket type,
760 * other bits are socket type flags.
761 */
762static void
Dmitry V. Levin9134aab2016-05-14 21:46:05 +0000763tprint_sock_type(unsigned int flags)
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000764{
765 const char *str = xlookup(socktypes, flags & SOCK_TYPE_MASK);
766
Denys Vlasenko7b609d52011-06-22 14:32:43 +0200767 if (str) {
Denys Vlasenko5940e652011-09-01 09:55:05 +0200768 tprints(str);
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000769 flags &= ~SOCK_TYPE_MASK;
770 if (!flags)
771 return;
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200772 tprints("|");
Dmitry V. Levin8a550d72008-11-10 17:21:23 +0000773 }
774 printflags(sock_type_flags, flags, "SOCK_???");
775}
776
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000777SYS_FUNC(socket)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000778{
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000779 printxval(addrfams, tcp->u_arg[0], "AF_???");
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000780 tprints(", ");
781 tprint_sock_type(tcp->u_arg[1]);
782 tprints(", ");
783 switch (tcp->u_arg[0]) {
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000784 case AF_INET:
785#ifdef AF_INET6
786 case AF_INET6:
Roland McGrath8758e542003-06-23 23:39:59 +0000787#endif
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000788 printxval(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
789 break;
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000790#ifdef AF_IPX
791 case AF_IPX:
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000792 /* BTW: I don't believe this.. */
793 tprints("[");
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000794 printxval(addrfams, tcp->u_arg[2], "AF_???");
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000795 tprints("]");
796 break;
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000797#endif /* AF_IPX */
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000798 case AF_NETLINK:
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000799 printxval(netlink_protocols, tcp->u_arg[2], "NETLINK_???");
800 break;
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +0000801#if defined(AF_BLUETOOTH) && defined(HAVE_BLUETOOTH_BLUETOOTH_H)
802 case AF_BLUETOOTH:
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000803 printxval(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
804 break;
Lubomir Rintelc400a1c2014-10-03 11:40:28 +0200805#endif
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000806 default:
807 tprintf("%lu", tcp->u_arg[2]);
808 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000809 }
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000810
Dmitry V. Levin3d463be2015-08-02 01:41:26 +0000811 return RVAL_DECODED | RVAL_FD;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000812}
813
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000814SYS_FUNC(bind)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000815{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000816 printfd(tcp, tcp->u_arg[0]);
817 tprints(", ");
818 printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
819 tprintf(", %lu", tcp->u_arg[2]);
820
821 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000822}
823
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000824SYS_FUNC(listen)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000825{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000826 printfd(tcp, tcp->u_arg[0]);
827 tprints(", ");
828 tprintf("%lu", tcp->u_arg[1]);
829
830 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000831}
832
Paolo Bonzini705ff102009-08-14 12:34:05 +0200833static int
Dmitry V. Levin15114ec2014-08-06 16:46:13 +0000834do_sockname(struct tcb *tcp, int flags_arg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000835{
836 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800837 printfd(tcp, tcp->u_arg[0]);
838 tprints(", ");
Paolo Bonzini705ff102009-08-14 12:34:05 +0200839 return 0;
840 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000841
842 int len;
843 if (!tcp->u_arg[2] || !verbose(tcp) || syserror(tcp) ||
844 umove(tcp, tcp->u_arg[2], &len) < 0) {
845 printaddr(tcp->u_arg[1]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200846 tprints(", ");
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000847 printaddr(tcp->u_arg[2]);
848 } else {
849 printsock(tcp, tcp->u_arg[1], len);
850 tprintf(", [%d]", len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000851 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000852
Paolo Bonzini705ff102009-08-14 12:34:05 +0200853 if (flags_arg >= 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200854 tprints(", ");
Paolo Bonzini705ff102009-08-14 12:34:05 +0200855 printflags(sock_type_flags, tcp->u_arg[flags_arg],
856 "SOCK_???");
857 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000858 return 0;
859}
860
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000861SYS_FUNC(accept)
Paolo Bonzini705ff102009-08-14 12:34:05 +0200862{
Dmitry V. Levin15114ec2014-08-06 16:46:13 +0000863 do_sockname(tcp, -1);
864 return RVAL_FD;
Paolo Bonzini705ff102009-08-14 12:34:05 +0200865}
866
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000867SYS_FUNC(accept4)
Paolo Bonzini705ff102009-08-14 12:34:05 +0200868{
Dmitry V. Levin15114ec2014-08-06 16:46:13 +0000869 do_sockname(tcp, 3);
870 return RVAL_FD;
Paolo Bonzini705ff102009-08-14 12:34:05 +0200871}
Paolo Bonzini705ff102009-08-14 12:34:05 +0200872
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000873SYS_FUNC(send)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000874{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000875 printfd(tcp, tcp->u_arg[0]);
876 tprints(", ");
877 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
878 tprintf(", %lu, ", tcp->u_arg[2]);
879 /* flags */
880 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
881
882 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000883}
884
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000885SYS_FUNC(sendto)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000886{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000887 printfd(tcp, tcp->u_arg[0]);
888 tprints(", ");
889 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
890 tprintf(", %lu, ", tcp->u_arg[2]);
891 /* flags */
892 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
893 /* to address */
894 tprints(", ");
895 printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
896 /* to length */
897 tprintf(", %lu", tcp->u_arg[5]);
898
899 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000900}
901
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000902SYS_FUNC(sendmsg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000903{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +0000904 printfd(tcp, tcp->u_arg[0]);
905 tprints(", ");
906 printmsghdr(tcp, tcp->u_arg[1], (unsigned long) -1L);
907 /* flags */
908 tprints(", ");
909 printflags(msg_flags, tcp->u_arg[2], "MSG_???");
910
911 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000912}
913
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000914SYS_FUNC(sendmmsg)
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000915{
916 if (entering(tcp)) {
917 /* sockfd */
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800918 printfd(tcp, tcp->u_arg[0]);
919 tprints(", ");
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000920 if (!verbose(tcp)) {
Dmitry V. Levin484326d2016-06-11 01:28:21 +0000921 printaddr(tcp->u_arg[1]);
922 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000923 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
924 }
925 } else {
926 if (verbose(tcp))
Dmitry V. Levin5ea97652012-05-01 20:41:40 +0000927 decode_mmsg(tcp, (unsigned long) -1L);
Dmitry V. Levin7af9f352012-03-11 23:59:29 +0000928 }
929 return 0;
930}
931
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000932SYS_FUNC(recv)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000933{
934 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800935 printfd(tcp, tcp->u_arg[0]);
936 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000937 } else {
938 if (syserror(tcp))
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000939 printaddr(tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000940 else
941 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
942
943 tprintf(", %lu, ", tcp->u_arg[2]);
Roland McGrathb2dee132005-06-01 19:02:36 +0000944 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000945 }
946 return 0;
947}
948
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000949SYS_FUNC(recvfrom)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000950{
951 int fromlen;
952
953 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800954 printfd(tcp, tcp->u_arg[0]);
955 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000956 } else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000957 /* buf */
Denys Vlasenko383386d2015-07-30 13:29:20 +0200958 if (syserror(tcp)) {
Dmitry V. Levin52dc1502015-07-30 13:53:42 +0000959 printaddr(tcp->u_arg[1]);
Denys Vlasenko383386d2015-07-30 13:29:20 +0200960 } else {
961 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
962 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000963 /* len */
964 tprintf(", %lu, ", tcp->u_arg[2]);
965 /* flags */
Roland McGrathb2dee132005-06-01 19:02:36 +0000966 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200967 tprints(", ");
Dmitry V. Levin52dc1502015-07-30 13:53:42 +0000968 if (syserror(tcp) || !tcp->u_arg[4] || !tcp->u_arg[5] ||
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000969 umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
Denys Vlasenko383386d2015-07-30 13:29:20 +0200970 /* from address, len */
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000971 printaddr(tcp->u_arg[4]);
972 tprints(", ");
973 printaddr(tcp->u_arg[5]);
974 return 0;
975 }
Denys Vlasenko383386d2015-07-30 13:29:20 +0200976 /* from address */
977 printsock(tcp, tcp->u_arg[4], fromlen);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000978 /* from length */
979 tprintf(", [%u]", fromlen);
980 }
981 return 0;
982}
983
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000984SYS_FUNC(recvmsg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000985{
986 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -0800987 printfd(tcp, tcp->u_arg[0]);
988 tprints(", ");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000989 } else {
Dmitry V. Levin00244b92015-01-28 01:52:25 +0000990 if (syserror(tcp))
Dmitry V. Levin6c277da2015-07-19 22:36:46 +0000991 printaddr(tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000992 else
Denys Vlasenkoe0bc2222012-04-28 14:26:18 +0200993 printmsghdr(tcp, tcp->u_arg[1], tcp->u_rval);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000994 /* flags */
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200995 tprints(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +0000996 printflags(msg_flags, tcp->u_arg[2], "MSG_???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000997 }
998 return 0;
999}
1000
Dmitry V. Levina0bd3742015-04-07 01:36:50 +00001001SYS_FUNC(recvmmsg)
Andreas Schwab0873f292010-02-12 21:39:12 +01001002{
Dmitry V. Levin2950de32015-09-18 17:44:16 +00001003 static char str[sizeof("left") + TIMESPEC_TEXT_BUFSIZE];
Dmitry V. Levine6591032010-03-29 20:45:48 +04001004
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +01001005 if (entering(tcp)) {
Philippe Ombredanne894c7e32014-02-01 09:57:45 -08001006 printfd(tcp, tcp->u_arg[0]);
1007 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +04001008 if (verbose(tcp)) {
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +01001009 /* Abusing tcp->auxstr as temp storage.
Dmitry V. Levin2950de32015-09-18 17:44:16 +00001010 * Will be used and cleared on syscall exit.
Denys Vlasenkoa1d541e2012-01-20 11:04:04 +01001011 */
Dmitry V. Levin2950de32015-09-18 17:44:16 +00001012 tcp->auxstr = sprint_timespec(tcp, tcp->u_arg[4]);
Dmitry V. Levine6591032010-03-29 20:45:48 +04001013 } else {
Dmitry V. Levin484326d2016-06-11 01:28:21 +00001014 printaddr(tcp->u_arg[1]);
1015 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
Dmitry V. Levine6591032010-03-29 20:45:48 +04001016 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001017 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +04001018 print_timespec(tcp, tcp->u_arg[4]);
1019 }
1020 return 0;
1021 } else {
1022 if (verbose(tcp)) {
Dmitry V. Levin5ea97652012-05-01 20:41:40 +00001023 decode_mmsg(tcp, 0);
Dmitry V. Levin2950de32015-09-18 17:44:16 +00001024 tprints(", ");
Dmitry V. Levine6591032010-03-29 20:45:48 +04001025 /* timeout on entrance */
Dmitry V. Levin2950de32015-09-18 17:44:16 +00001026 tprints(tcp->auxstr);
Dmitry V. Levine6591032010-03-29 20:45:48 +04001027 tcp->auxstr = NULL;
1028 }
1029 if (syserror(tcp))
1030 return 0;
1031 if (tcp->u_rval == 0) {
1032 tcp->auxstr = "Timeout";
1033 return RVAL_STR;
1034 }
1035 if (!verbose(tcp))
1036 return 0;
1037 /* timeout on exit */
Dmitry V. Levin2950de32015-09-18 17:44:16 +00001038 snprintf(str, sizeof(str), "left %s",
1039 sprint_timespec(tcp, tcp->u_arg[4]));
Dmitry V. Levine6591032010-03-29 20:45:48 +04001040 tcp->auxstr = str;
1041 return RVAL_STR;
Andreas Schwab0873f292010-02-12 21:39:12 +01001042 }
Andreas Schwab0873f292010-02-12 21:39:12 +01001043}
Andreas Schwab0873f292010-02-12 21:39:12 +01001044
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +00001045#include "xlat/shutdown_modes.h"
Sebastian Pipping9cd38502011-03-03 01:12:25 +01001046
Dmitry V. Levina0bd3742015-04-07 01:36:50 +00001047SYS_FUNC(shutdown)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001048{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +00001049 printfd(tcp, tcp->u_arg[0]);
1050 tprints(", ");
1051 printxval(shutdown_modes, tcp->u_arg[1], "SHUT_???");
1052
1053 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001054}
1055
Dmitry V. Levina0bd3742015-04-07 01:36:50 +00001056SYS_FUNC(getsockname)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001057{
Dmitry V. Levin15114ec2014-08-06 16:46:13 +00001058 return do_sockname(tcp, -1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001059}
1060
Dmitry V. Levin2a4f0522015-08-02 01:54:48 +00001061static void
1062printpair_fd(struct tcb *tcp, const int i0, const int i1)
1063{
1064 tprints("[");
1065 printfd(tcp, i0);
1066 tprints(", ");
1067 printfd(tcp, i1);
1068 tprints("]");
1069}
1070
1071static void
1072decode_pair_fd(struct tcb *tcp, const long addr)
1073{
1074 int pair[2];
1075
1076 if (umove_or_printaddr(tcp, addr, &pair))
1077 return;
1078
1079 printpair_fd(tcp, pair[0], pair[1]);
1080}
1081
Dmitry V. Levin4371b102008-11-10 22:53:02 +00001082static int
1083do_pipe(struct tcb *tcp, int flags_arg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001084{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001085 if (exiting(tcp)) {
Dmitry V. Levin9b388852016-02-12 16:37:31 +00001086 decode_pair_fd(tcp, tcp->u_arg[0]);
Dmitry V. Levin4371b102008-11-10 22:53:02 +00001087 if (flags_arg >= 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001088 tprints(", ");
Dmitry V. Levin4371b102008-11-10 22:53:02 +00001089 printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
1090 }
1091 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001092 return 0;
1093}
1094
Dmitry V. Levina0bd3742015-04-07 01:36:50 +00001095SYS_FUNC(pipe)
Dmitry V. Levin4371b102008-11-10 22:53:02 +00001096{
Dmitry V. Levin9b388852016-02-12 16:37:31 +00001097#ifdef HAVE_GETRVAL2
1098 if (exiting(tcp) && !syserror(tcp))
1099 printpair_fd(tcp, tcp->u_rval, getrval2(tcp));
1100 return 0;
1101#else
Dmitry V. Levin4371b102008-11-10 22:53:02 +00001102 return do_pipe(tcp, -1);
Dmitry V. Levin9b388852016-02-12 16:37:31 +00001103#endif
Dmitry V. Levin4371b102008-11-10 22:53:02 +00001104}
1105
Dmitry V. Levina0bd3742015-04-07 01:36:50 +00001106SYS_FUNC(pipe2)
Dmitry V. Levin4371b102008-11-10 22:53:02 +00001107{
1108 return do_pipe(tcp, 1);
1109}
Dmitry V. Levin4371b102008-11-10 22:53:02 +00001110
Dmitry V. Levina0bd3742015-04-07 01:36:50 +00001111SYS_FUNC(socketpair)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001112{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001113 if (entering(tcp)) {
Dmitry V. Levin71fe62e2016-04-04 01:35:28 +00001114 printxval(addrfams, tcp->u_arg[0], "AF_???");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001115 tprints(", ");
Dmitry V. Levin1e42f2d2014-09-10 17:48:28 +00001116 tprint_sock_type(tcp->u_arg[1]);
Dmitry V. Levin033fb912014-03-11 22:50:39 +00001117 tprintf(", %lu", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001118 } else {
Dmitry V. Levinb6795082015-07-06 22:33:39 +00001119 tprints(", ");
Dmitry V. Levin2a4f0522015-08-02 01:54:48 +00001120 decode_pair_fd(tcp, tcp->u_arg[3]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001121 }
1122 return 0;
1123}
1124
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001125#include "xlat/sockoptions.h"
1126#include "xlat/sockipoptions.h"
Mike Frysinger54646b82015-08-19 13:29:27 -04001127#include "xlat/getsockipoptions.h"
1128#include "xlat/setsockipoptions.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001129#include "xlat/sockipv6options.h"
Mike Frysinger54646b82015-08-19 13:29:27 -04001130#include "xlat/getsockipv6options.h"
1131#include "xlat/setsockipv6options.h"
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001132#include "xlat/sockipxoptions.h"
1133#include "xlat/sockrawoptions.h"
1134#include "xlat/sockpacketoptions.h"
1135#include "xlat/socksctpoptions.h"
1136#include "xlat/socktcpoptions.h"
1137
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001138static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +00001139print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
1140 unsigned int name, bool is_getsockopt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001141{
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001142 printfd(tcp, fd);
1143 tprints(", ");
John Hughes38ae88d2002-05-23 11:48:58 +00001144 printxval(socketlayers, level, "SOL_??");
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02001145 tprints(", ");
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001146
John Hughes38ae88d2002-05-23 11:48:58 +00001147 switch (level) {
Denys Vlasenko989ebc92012-03-17 04:42:07 +01001148 case SOL_SOCKET:
John Hughes38ae88d2002-05-23 11:48:58 +00001149 printxval(sockoptions, name, "SO_???");
John Hughes38ae88d2002-05-23 11:48:58 +00001150 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +01001151 case SOL_IP:
Mike Frysinger54646b82015-08-19 13:29:27 -04001152 printxvals(name, "IP_???", sockipoptions,
1153 is_getsockopt ? getsockipoptions : setsockipoptions, NULL);
John Hughes38ae88d2002-05-23 11:48:58 +00001154 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +01001155 case SOL_IPV6:
Mike Frysinger54646b82015-08-19 13:29:27 -04001156 printxvals(name, "IPV6_???", sockipv6options,
1157 is_getsockopt ? getsockipv6options : setsockipv6options, NULL);
Roland McGrath4f6ba692004-08-31 07:01:26 +00001158 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +01001159 case SOL_IPX:
John Hughes38ae88d2002-05-23 11:48:58 +00001160 printxval(sockipxoptions, name, "IPX_???");
1161 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +01001162 case SOL_PACKET:
John Hughes38ae88d2002-05-23 11:48:58 +00001163 printxval(sockpacketoptions, name, "PACKET_???");
John Hughes38ae88d2002-05-23 11:48:58 +00001164 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +01001165 case SOL_TCP:
John Hughes38ae88d2002-05-23 11:48:58 +00001166 printxval(socktcpoptions, name, "TCP_???");
1167 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +01001168 case SOL_SCTP:
Holger Hans Peter Freyther7fea79b2011-01-14 11:08:12 +01001169 printxval(socksctpoptions, name, "SCTP_???");
1170 break;
Denys Vlasenko989ebc92012-03-17 04:42:07 +01001171 case SOL_RAW:
John Hughes38ae88d2002-05-23 11:48:58 +00001172 printxval(sockrawoptions, name, "RAW_???");
John Hughes38ae88d2002-05-23 11:48:58 +00001173 break;
John Hughes38ae88d2002-05-23 11:48:58 +00001174
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001175 /* Other SOL_* protocol levels still need work. */
John Hughes38ae88d2002-05-23 11:48:58 +00001176
Denys Vlasenko989ebc92012-03-17 04:42:07 +01001177 default:
John Hughes38ae88d2002-05-23 11:48:58 +00001178 tprintf("%u", name);
1179 }
1180
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001181 tprints(", ");
1182}
1183
1184#ifdef SO_LINGER
1185static void
1186print_linger(struct tcb *tcp, long addr, int len)
1187{
1188 struct linger linger;
1189
1190 if (len != sizeof(linger) ||
1191 umove(tcp, addr, &linger) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001192 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001193 return;
1194 }
1195
1196 tprintf("{onoff=%d, linger=%d}",
1197 linger.l_onoff,
1198 linger.l_linger);
1199}
1200#endif /* SO_LINGER */
1201
1202#ifdef SO_PEERCRED
1203static void
1204print_ucred(struct tcb *tcp, long addr, int len)
1205{
1206 struct ucred uc;
1207
1208 if (len != sizeof(uc) ||
1209 umove(tcp, addr, &uc) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001210 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001211 } else {
1212 tprintf("{pid=%u, uid=%u, gid=%u}",
1213 (unsigned) uc.pid,
1214 (unsigned) uc.uid,
1215 (unsigned) uc.gid);
1216 }
1217}
1218#endif /* SO_PEERCRED */
1219
1220#ifdef PACKET_STATISTICS
1221static void
1222print_tpacket_stats(struct tcb *tcp, long addr, int len)
1223{
1224 struct tpacket_stats stats;
1225
1226 if (len != sizeof(stats) ||
1227 umove(tcp, addr, &stats) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001228 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001229 } else {
1230 tprintf("{packets=%u, drops=%u}",
1231 stats.tp_packets,
1232 stats.tp_drops);
1233 }
1234}
1235#endif /* PACKET_STATISTICS */
1236
1237#ifdef ICMP_FILTER
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001238# include "xlat/icmpfilterflags.h"
1239
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001240static void
Dmitry V. Levineb5c2332016-05-06 00:06:15 +00001241print_icmp_filter(struct tcb *tcp, const long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001242{
Dmitry V. Levineb5c2332016-05-06 00:06:15 +00001243 struct icmp_filter filter = {};
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001244
Dmitry V. Levineb5c2332016-05-06 00:06:15 +00001245 if (len > (int) sizeof(filter))
1246 len = sizeof(filter);
1247 else if (len <= 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001248 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001249 return;
1250 }
1251
Dmitry V. Levineb5c2332016-05-06 00:06:15 +00001252 if (umoven_or_printaddr(tcp, addr, len, &filter))
1253 return;
1254
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001255 tprints("~(");
1256 printflags(icmpfilterflags, ~filter.data, "ICMP_???");
1257 tprints(")");
1258}
1259#endif /* ICMP_FILTER */
1260
1261static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +00001262print_getsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
1263 long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001264{
1265 if (addr && verbose(tcp))
1266 switch (level) {
1267 case SOL_SOCKET:
1268 switch (name) {
1269#ifdef SO_LINGER
1270 case SO_LINGER:
1271 print_linger(tcp, addr, len);
1272 goto done;
1273#endif
1274#ifdef SO_PEERCRED
1275 case SO_PEERCRED:
1276 print_ucred(tcp, addr, len);
1277 goto done;
1278#endif
1279 }
1280 break;
1281
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001282 case SOL_PACKET:
1283 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001284#ifdef PACKET_STATISTICS
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001285 case PACKET_STATISTICS:
1286 print_tpacket_stats(tcp, addr, len);
1287 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001288#endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001289 }
1290 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001291
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001292 case SOL_RAW:
1293 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001294#ifdef ICMP_FILTER
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001295 case ICMP_FILTER:
1296 print_icmp_filter(tcp, addr, len);
1297 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001298#endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001299 }
1300 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001301 }
1302
John Hughes38ae88d2002-05-23 11:48:58 +00001303 /* default arg printing */
1304
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001305 if (verbose(tcp)) {
1306 if (len == sizeof(int)) {
1307 printnum_int(tcp, addr, "%d");
1308 } else {
1309 printstr(tcp, addr, len);
1310 }
1311 } else {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001312 printaddr(addr);
John Hughes38ae88d2002-05-23 11:48:58 +00001313 }
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001314done:
1315 tprintf(", [%d]", len);
1316}
1317
Dmitry V. Levina0bd3742015-04-07 01:36:50 +00001318SYS_FUNC(getsockopt)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001319{
1320 if (entering(tcp)) {
1321 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
Mike Frysinger54646b82015-08-19 13:29:27 -04001322 tcp->u_arg[1], tcp->u_arg[2], true);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001323 } else {
1324 int len;
1325
1326 if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &len) < 0) {
Dmitry V. Levin484326d2016-06-11 01:28:21 +00001327 printaddr(tcp->u_arg[3]);
1328 tprints(", ");
1329 printaddr(tcp->u_arg[4]);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001330 } else {
1331 print_getsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
1332 tcp->u_arg[3], len);
1333 }
John Hughes38ae88d2002-05-23 11:48:58 +00001334 }
1335 return 0;
1336}
1337
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001338#ifdef IP_ADD_MEMBERSHIP
1339static void
1340print_mreq(struct tcb *tcp, long addr, unsigned int len)
1341{
1342 struct ip_mreq mreq;
1343
1344 if (len < sizeof(mreq)) {
1345 printstr(tcp, addr, len);
1346 return;
1347 }
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001348 if (umove_or_printaddr(tcp, addr, &mreq))
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001349 return;
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001350
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001351 tprints("{imr_multiaddr=inet_addr(");
1352 print_quoted_string(inet_ntoa(mreq.imr_multiaddr),
1353 16, QUOTE_0_TERMINATED);
1354 tprints("), imr_interface=inet_addr(");
1355 print_quoted_string(inet_ntoa(mreq.imr_interface),
1356 16, QUOTE_0_TERMINATED);
1357 tprints(")}");
1358}
1359#endif /* IP_ADD_MEMBERSHIP */
1360
1361#ifdef IPV6_ADD_MEMBERSHIP
1362static void
1363print_mreq6(struct tcb *tcp, long addr, unsigned int len)
1364{
1365 struct ipv6_mreq mreq;
1366
1367 if (len < sizeof(mreq))
1368 goto fail;
1369
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001370 if (umove_or_printaddr(tcp, addr, &mreq))
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001371 return;
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001372
1373#ifdef HAVE_INET_NTOP
1374 const struct in6_addr *in6 = &mreq.ipv6mr_multiaddr;
1375 char address[INET6_ADDRSTRLEN];
1376
1377 if (!inet_ntop(AF_INET6, in6, address, sizeof(address)))
1378 goto fail;
1379
1380 tprints("{ipv6mr_multiaddr=inet_pton(");
1381 print_quoted_string(address, sizeof(address), QUOTE_0_TERMINATED);
1382 tprints("), ipv6mr_interface=");
1383 print_ifindex(mreq.ipv6mr_interface);
1384 tprints("}");
1385 return;
1386#endif /* HAVE_INET_NTOP */
1387
1388fail:
1389 printstr(tcp, addr, len);
1390}
1391#endif /* IPV6_ADD_MEMBERSHIP */
1392
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001393#ifdef MCAST_JOIN_GROUP
1394static void
1395print_group_req(struct tcb *tcp, long addr, int len)
1396{
1397 struct group_req greq;
1398
1399 if (len != sizeof(greq) ||
1400 umove(tcp, addr, &greq) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001401 printaddr(addr);
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001402 return;
1403 }
1404
Dmitry V. Levin1019f002015-11-21 02:38:59 +00001405 tprintf("{gr_interface=%u, gr_group=", greq.gr_interface);
1406 print_sockaddr(tcp, (const void *) &greq.gr_group,
1407 sizeof(greq.gr_group));
1408 tprintf("}");
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001409
1410}
1411#endif /* MCAST_JOIN_GROUP */
1412
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001413#ifdef PACKET_RX_RING
1414static void
1415print_tpacket_req(struct tcb *tcp, long addr, int len)
1416{
1417 struct tpacket_req req;
1418
1419 if (len != sizeof(req) ||
1420 umove(tcp, addr, &req) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001421 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001422 } else {
1423 tprintf("{block_size=%u, block_nr=%u, "
1424 "frame_size=%u, frame_nr=%u}",
1425 req.tp_block_size,
1426 req.tp_block_nr,
1427 req.tp_frame_size,
1428 req.tp_frame_nr);
1429 }
1430}
1431#endif /* PACKET_RX_RING */
1432
Dmitry V. Levin02f2f092015-01-29 03:26:53 +00001433#ifdef PACKET_ADD_MEMBERSHIP
1434# include "xlat/packet_mreq_type.h"
1435
1436static void
1437print_packet_mreq(struct tcb *tcp, long addr, int len)
1438{
1439 struct packet_mreq mreq;
1440
1441 if (len != sizeof(mreq) ||
1442 umove(tcp, addr, &mreq) < 0) {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001443 printaddr(addr);
Dmitry V. Levin02f2f092015-01-29 03:26:53 +00001444 } else {
1445 unsigned int i;
1446
1447 tprintf("{mr_ifindex=%u, mr_type=", mreq.mr_ifindex);
1448 printxval(packet_mreq_type, mreq.mr_type, "PACKET_MR_???");
1449 tprintf(", mr_alen=%u, mr_address=", mreq.mr_alen);
1450 if (mreq.mr_alen > ARRAY_SIZE(mreq.mr_address))
1451 mreq.mr_alen = ARRAY_SIZE(mreq.mr_address);
1452 for (i = 0; i < mreq.mr_alen; ++i)
1453 tprintf("%02x", mreq.mr_address[i]);
1454 tprints("}");
1455 }
1456}
1457#endif /* PACKET_ADD_MEMBERSHIP */
1458
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001459static void
Dmitry V. Levinf40ea792016-04-01 01:03:20 +00001460print_setsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
1461 long addr, int len)
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001462{
1463 if (addr && verbose(tcp))
1464 switch (level) {
1465 case SOL_SOCKET:
1466 switch (name) {
1467#ifdef SO_LINGER
1468 case SO_LINGER:
1469 print_linger(tcp, addr, len);
1470 goto done;
1471#endif
1472 }
1473 break;
1474
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001475 case SOL_IP:
1476 switch (name) {
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001477#ifdef IP_ADD_MEMBERSHIP
1478 case IP_ADD_MEMBERSHIP:
1479 case IP_DROP_MEMBERSHIP:
1480 print_mreq(tcp, addr, len);
1481 goto done;
1482#endif /* IP_ADD_MEMBERSHIP */
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001483#ifdef MCAST_JOIN_GROUP
1484 case MCAST_JOIN_GROUP:
1485 case MCAST_LEAVE_GROUP:
1486 print_group_req(tcp, addr, len);
1487 goto done;
1488#endif /* MCAST_JOIN_GROUP */
1489 }
Dmitry V. Levin3910d0f2015-02-08 01:19:06 +00001490 break;
Dmitry V. Levina0a49092015-01-30 01:55:20 +00001491
Dmitry V. Levin7bee4622015-06-08 14:19:46 +00001492 case SOL_IPV6:
1493 switch (name) {
1494#ifdef IPV6_ADD_MEMBERSHIP
1495 case IPV6_ADD_MEMBERSHIP:
1496 case IPV6_DROP_MEMBERSHIP:
1497# ifdef IPV6_JOIN_ANYCAST
1498 case IPV6_JOIN_ANYCAST:
1499# endif
1500# ifdef IPV6_LEAVE_ANYCAST
1501 case IPV6_LEAVE_ANYCAST:
1502# endif
1503 print_mreq6(tcp, addr, len);
1504 goto done;
1505#endif /* IPV6_ADD_MEMBERSHIP */
1506 }
1507 break;
1508
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001509 case SOL_PACKET:
1510 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001511#ifdef PACKET_RX_RING
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001512 case PACKET_RX_RING:
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001513# ifdef PACKET_TX_RING
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001514 case PACKET_TX_RING:
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001515# endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001516 print_tpacket_req(tcp, addr, len);
1517 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001518#endif /* PACKET_RX_RING */
1519#ifdef PACKET_ADD_MEMBERSHIP
Dmitry V. Levin02f2f092015-01-29 03:26:53 +00001520 case PACKET_ADD_MEMBERSHIP:
1521 case PACKET_DROP_MEMBERSHIP:
1522 print_packet_mreq(tcp, addr, len);
1523 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001524#endif /* PACKET_ADD_MEMBERSHIP */
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001525 }
1526 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001527
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001528 case SOL_RAW:
1529 switch (name) {
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001530#ifdef ICMP_FILTER
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001531 case ICMP_FILTER:
1532 print_icmp_filter(tcp, addr, len);
1533 goto done;
Dmitry V. Levin6d31c7a2015-01-29 04:42:37 +00001534#endif
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001535 }
1536 break;
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001537 }
1538
1539 /* default arg printing */
1540
1541 if (verbose(tcp)) {
1542 if (len == sizeof(int)) {
1543 printnum_int(tcp, addr, "%d");
1544 } else {
1545 printstr(tcp, addr, len);
1546 }
1547 } else {
Dmitry V. Levin6c277da2015-07-19 22:36:46 +00001548 printaddr(addr);
Dmitry V. Levin0509c8e2015-01-29 03:11:41 +00001549 }
1550done:
1551 tprintf(", %d", len);
1552}
1553
Dmitry V. Levina0bd3742015-04-07 01:36:50 +00001554SYS_FUNC(setsockopt)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001555{
Dmitry V. Levin219b3a72015-07-19 22:52:47 +00001556 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
Mike Frysinger54646b82015-08-19 13:29:27 -04001557 tcp->u_arg[1], tcp->u_arg[2], false);
Dmitry V. Levin219b3a72015-07-19 22:52:47 +00001558 print_setsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
1559 tcp->u_arg[3], tcp->u_arg[4]);
1560
1561 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001562}