Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl>
      3  * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl>
      4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com>
      5  * Copyright (c) 1996-2000 Wichert Akkerman <wichert (at) cistron.nl>
      6  * 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.
     29  */
     30 
     31 #include "defs.h"
     32 #include <sys/stat.h>
     33 #include <sys/socket.h>
     34 #include <sys/un.h>
     35 #if defined(HAVE_SIN6_SCOPE_ID_LINUX)
     36 # define in6_addr in6_addr_libc
     37 # define ipv6_mreq ipv6_mreq_libc
     38 # define sockaddr_in6 sockaddr_in6_libc
     39 #endif
     40 #include <netinet/in.h>
     41 #ifdef HAVE_NETINET_TCP_H
     42 # include <netinet/tcp.h>
     43 #endif
     44 #ifdef HAVE_NETINET_UDP_H
     45 # include <netinet/udp.h>
     46 #endif
     47 #ifdef HAVE_NETINET_SCTP_H
     48 # include <netinet/sctp.h>
     49 #endif
     50 #include <arpa/inet.h>
     51 #include <net/if.h>
     52 #include <asm/types.h>
     53 #if defined(__GLIBC__)
     54 # include <netipx/ipx.h>
     55 #else
     56 # include <linux/ipx.h>
     57 #endif
     58 
     59 #if defined(__GLIBC__) && defined(HAVE_SIN6_SCOPE_ID_LINUX)
     60 # if defined(HAVE_LINUX_IN6_H)
     61 #  if defined(HAVE_SIN6_SCOPE_ID_LINUX)
     62 #   undef in6_addr
     63 #   undef ipv6_mreq
     64 #   undef sockaddr_in6
     65 #   define in6_addr in6_addr_kernel
     66 #   define ipv6_mreq ipv6_mreq_kernel
     67 #   define sockaddr_in6 sockaddr_in6_kernel
     68 #  endif
     69 #  include <linux/in6.h>
     70 #  if defined(HAVE_SIN6_SCOPE_ID_LINUX)
     71 #   undef in6_addr
     72 #   undef ipv6_mreq
     73 #   undef sockaddr_in6
     74 #   define in6_addr in6_addr_libc
     75 #   define ipv6_mreq ipv6_mreq_libc
     76 #   define sockaddr_in6 sockaddr_in6_kernel
     77 #  endif
     78 # endif
     79 #endif
     80 
     81 #if defined(HAVE_SYS_UIO_H)
     82 # include <sys/uio.h>
     83 #endif
     84 #if defined(HAVE_LINUX_NETLINK_H)
     85 # include <linux/netlink.h>
     86 #endif
     87 #if defined(HAVE_LINUX_IF_PACKET_H)
     88 # include <linux/if_packet.h>
     89 #endif
     90 #if defined(HAVE_LINUX_ICMP_H)
     91 # include <linux/icmp.h>
     92 #endif
     93 #ifndef PF_UNSPEC
     94 # define PF_UNSPEC AF_UNSPEC
     95 #endif
     96 
     97 #include "xlat/domains.h"
     98 #include "xlat/addrfams.h"
     99 #include "xlat/socktypes.h"
    100 #include "xlat/sock_type_flags.h"
    101 #ifndef SOCK_TYPE_MASK
    102 # define SOCK_TYPE_MASK 0xf
    103 #endif
    104 #include "xlat/socketlayers.h"
    105 /*** WARNING: DANGER WILL ROBINSON: NOTE "socketlayers" array above
    106      falls into "inet_protocols" array below!!!!   This is intended!!! ***/
    107 #include "xlat/inet_protocols.h"
    108 
    109 #ifdef PF_NETLINK
    110 #include "xlat/netlink_protocols.h"
    111 #endif
    112 
    113 #include "xlat/msg_flags.h"
    114 #include "xlat/sockoptions.h"
    115 
    116 #if !defined(SOL_IP) && defined(IPPROTO_IP)
    117 #define SOL_IP IPPROTO_IP
    118 #endif
    119 
    120 #ifdef SOL_IP
    121 #include "xlat/sockipoptions.h"
    122 #endif /* SOL_IP */
    123 
    124 #ifdef SOL_IPV6
    125 #include "xlat/sockipv6options.h"
    126 #endif /* SOL_IPV6 */
    127 
    128 #ifdef SOL_IPX
    129 #include "xlat/sockipxoptions.h"
    130 #endif /* SOL_IPX */
    131 
    132 #ifdef SOL_RAW
    133 #include "xlat/sockrawoptions.h"
    134 #endif /* SOL_RAW */
    135 
    136 #ifdef SOL_PACKET
    137 #include "xlat/sockpacketoptions.h"
    138 #endif /* SOL_PACKET */
    139 
    140 #ifdef SOL_SCTP
    141 #include "xlat/socksctpoptions.h"
    142 #endif
    143 
    144 #if !defined(SOL_TCP) && defined(IPPROTO_TCP)
    145 #define SOL_TCP IPPROTO_TCP
    146 #endif
    147 
    148 #ifdef SOL_TCP
    149 #include "xlat/socktcpoptions.h"
    150 #endif /* SOL_TCP */
    151 
    152 #ifdef SOL_RAW
    153 #include "xlat/icmpfilterflags.h"
    154 #endif /* SOL_RAW */
    155 
    156 #if defined(AF_PACKET) /* from e.g. linux/if_packet.h */
    157 #include "xlat/af_packet_types.h"
    158 #endif /* defined(AF_PACKET) */
    159 
    160 void
    161 printsock(struct tcb *tcp, long addr, int addrlen)
    162 {
    163 	union {
    164 		char pad[128];
    165 		struct sockaddr sa;
    166 		struct sockaddr_in sin;
    167 		struct sockaddr_un sau;
    168 #ifdef HAVE_INET_NTOP
    169 		struct sockaddr_in6 sa6;
    170 #endif
    171 #if defined(AF_IPX)
    172 		struct sockaddr_ipx sipx;
    173 #endif
    174 #ifdef AF_PACKET
    175 		struct sockaddr_ll ll;
    176 #endif
    177 #ifdef AF_NETLINK
    178 		struct sockaddr_nl nl;
    179 #endif
    180 	} addrbuf;
    181 	char string_addr[100];
    182 
    183 	if (addr == 0) {
    184 		tprints("NULL");
    185 		return;
    186 	}
    187 	if (!verbose(tcp)) {
    188 		tprintf("%#lx", addr);
    189 		return;
    190 	}
    191 
    192 	if (addrlen < 2 || addrlen > sizeof(addrbuf))
    193 		addrlen = sizeof(addrbuf);
    194 
    195 	memset(&addrbuf, 0, sizeof(addrbuf));
    196 	if (umoven(tcp, addr, addrlen, addrbuf.pad) < 0) {
    197 		tprints("{...}");
    198 		return;
    199 	}
    200 	addrbuf.pad[sizeof(addrbuf.pad) - 1] = '\0';
    201 
    202 	tprints("{sa_family=");
    203 	printxval(addrfams, addrbuf.sa.sa_family, "AF_???");
    204 	tprints(", ");
    205 
    206 	switch (addrbuf.sa.sa_family) {
    207 	case AF_UNIX:
    208 		if (addrlen == 2) {
    209 			tprints("NULL");
    210 		} else if (addrbuf.sau.sun_path[0]) {
    211 			tprints("sun_path=");
    212 			printpathn(tcp, addr + 2, strlen(addrbuf.sau.sun_path));
    213 		} else {
    214 			tprints("sun_path=@");
    215 			printpathn(tcp, addr + 3, strlen(addrbuf.sau.sun_path + 1));
    216 		}
    217 		break;
    218 	case AF_INET:
    219 		tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")",
    220 			ntohs(addrbuf.sin.sin_port), inet_ntoa(addrbuf.sin.sin_addr));
    221 		break;
    222 #ifdef HAVE_INET_NTOP
    223 	case AF_INET6:
    224 		inet_ntop(AF_INET6, &addrbuf.sa6.sin6_addr, string_addr, sizeof(string_addr));
    225 		tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=%u",
    226 				ntohs(addrbuf.sa6.sin6_port), string_addr,
    227 				addrbuf.sa6.sin6_flowinfo);
    228 #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
    229 		{
    230 #if defined(HAVE_IF_INDEXTONAME) && defined(IN6_IS_ADDR_LINKLOCAL) && defined(IN6_IS_ADDR_MC_LINKLOCAL)
    231 			int numericscope = 0;
    232 			if (IN6_IS_ADDR_LINKLOCAL(&addrbuf.sa6.sin6_addr)
    233 			    || IN6_IS_ADDR_MC_LINKLOCAL(&addrbuf.sa6.sin6_addr)) {
    234 				char scopebuf[IFNAMSIZ + 1];
    235 
    236 				if (if_indextoname(addrbuf.sa6.sin6_scope_id, scopebuf) == NULL)
    237 					numericscope++;
    238 				else
    239 					tprintf(", sin6_scope_id=if_nametoindex(\"%s\")", scopebuf);
    240 			} else
    241 				numericscope++;
    242 
    243 			if (numericscope)
    244 #endif
    245 				tprintf(", sin6_scope_id=%u", addrbuf.sa6.sin6_scope_id);
    246 		}
    247 #endif
    248 		break;
    249 #endif
    250 #if defined(AF_IPX)
    251 	case AF_IPX:
    252 		{
    253 			int i;
    254 			tprintf("sipx_port=htons(%u), ",
    255 					ntohs(addrbuf.sipx.sipx_port));
    256 			/* Yes, I know, this does not look too
    257 			 * strace-ish, but otherwise the IPX
    258 			 * addresses just look monstrous...
    259 			 * Anyways, feel free if you don't like
    260 			 * this way.. :)
    261 			 */
    262 			tprintf("%08lx:", (unsigned long)ntohl(addrbuf.sipx.sipx_network));
    263 			for (i = 0; i < IPX_NODE_LEN; i++)
    264 				tprintf("%02x", addrbuf.sipx.sipx_node[i]);
    265 			tprintf("/[%02x]", addrbuf.sipx.sipx_type);
    266 		}
    267 		break;
    268 #endif /* AF_IPX */
    269 #ifdef AF_PACKET
    270 	case AF_PACKET:
    271 		{
    272 			int i;
    273 			tprintf("proto=%#04x, if%d, pkttype=",
    274 					ntohs(addrbuf.ll.sll_protocol),
    275 					addrbuf.ll.sll_ifindex);
    276 			printxval(af_packet_types, addrbuf.ll.sll_pkttype, "?");
    277 			tprintf(", addr(%d)={%d, ",
    278 					addrbuf.ll.sll_halen,
    279 					addrbuf.ll.sll_hatype);
    280 			for (i = 0; i < addrbuf.ll.sll_halen; i++)
    281 				tprintf("%02x", addrbuf.ll.sll_addr[i]);
    282 		}
    283 		break;
    284 
    285 #endif /* AF_PACKET */
    286 #ifdef AF_NETLINK
    287 	case AF_NETLINK:
    288 		tprintf("pid=%d, groups=%08x", addrbuf.nl.nl_pid, addrbuf.nl.nl_groups);
    289 		break;
    290 #endif /* AF_NETLINK */
    291 	/* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
    292 	AF_X25 AF_ROSE etc. still need to be done */
    293 
    294 	default:
    295 		tprints("sa_data=");
    296 		printstr(tcp, (long) &((struct sockaddr *) addr)->sa_data,
    297 			sizeof addrbuf.sa.sa_data);
    298 		break;
    299 	}
    300 	tprints("}");
    301 }
    302 
    303 #if HAVE_SENDMSG
    304 #include "xlat/scmvals.h"
    305 
    306 static void
    307 printcmsghdr(struct tcb *tcp, unsigned long addr, unsigned long len)
    308 {
    309 	struct cmsghdr *cmsg = len < sizeof(struct cmsghdr) ?
    310 			       NULL : malloc(len);
    311 	if (cmsg == NULL || umoven(tcp, addr, len, (char *) cmsg) < 0) {
    312 		tprintf(", msg_control=%#lx", addr);
    313 		free(cmsg);
    314 		return;
    315 	}
    316 
    317 	tprintf(", {cmsg_len=%u, cmsg_level=", (unsigned) cmsg->cmsg_len);
    318 	printxval(socketlayers, cmsg->cmsg_level, "SOL_???");
    319 	tprints(", cmsg_type=");
    320 
    321 	if (cmsg->cmsg_level == SOL_SOCKET) {
    322 		unsigned long cmsg_len;
    323 
    324 		printxval(scmvals, cmsg->cmsg_type, "SCM_???");
    325 		cmsg_len = (len < cmsg->cmsg_len) ? len : cmsg->cmsg_len;
    326 
    327 		if (cmsg->cmsg_type == SCM_RIGHTS
    328 		    && CMSG_LEN(sizeof(int)) <= cmsg_len) {
    329 			int *fds = (int *) CMSG_DATA(cmsg);
    330 			int first = 1;
    331 
    332 			tprints(", {");
    333 			while ((char *) fds < ((char *) cmsg + cmsg_len)) {
    334 				if (!first)
    335 					tprints(", ");
    336 				printfd(tcp, *fds++);
    337 				first = 0;
    338 			}
    339 			tprints("}}");
    340 			free(cmsg);
    341 			return;
    342 		}
    343 		if (cmsg->cmsg_type == SCM_CREDENTIALS
    344 		    && CMSG_LEN(sizeof(struct ucred)) <= cmsg_len) {
    345 			struct ucred *uc = (struct ucred *) CMSG_DATA(cmsg);
    346 
    347 			tprintf("{pid=%ld, uid=%ld, gid=%ld}}",
    348 				(long)uc->pid, (long)uc->uid, (long)uc->gid);
    349 			free(cmsg);
    350 			return;
    351 		}
    352 	}
    353 	free(cmsg);
    354 	tprints(", ...}");
    355 }
    356 
    357 static void
    358 do_msghdr(struct tcb *tcp, struct msghdr *msg, unsigned long data_size)
    359 {
    360 	tprintf("{msg_name(%d)=", msg->msg_namelen);
    361 	printsock(tcp, (long)msg->msg_name, msg->msg_namelen);
    362 
    363 	tprintf(", msg_iov(%lu)=", (unsigned long)msg->msg_iovlen);
    364 	tprint_iov_upto(tcp, (unsigned long)msg->msg_iovlen,
    365 		   (unsigned long)msg->msg_iov, 1, data_size);
    366 
    367 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
    368 	tprintf(", msg_controllen=%lu", (unsigned long)msg->msg_controllen);
    369 	if (msg->msg_controllen)
    370 		printcmsghdr(tcp, (unsigned long) msg->msg_control,
    371 			     msg->msg_controllen);
    372 	tprints(", msg_flags=");
    373 	printflags(msg_flags, msg->msg_flags, "MSG_???");
    374 #else /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
    375 	tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
    376 		(unsigned long) msg->msg_accrights, msg->msg_accrightslen);
    377 #endif /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
    378 	tprints("}");
    379 }
    380 
    381 struct msghdr32 {
    382 	uint32_t /* void* */    msg_name;
    383 	uint32_t /* socklen_t */msg_namelen;
    384 	uint32_t /* iovec* */   msg_iov;
    385 	uint32_t /* size_t */   msg_iovlen;
    386 	uint32_t /* void* */    msg_control;
    387 	uint32_t /* size_t */   msg_controllen;
    388 	uint32_t /* int */      msg_flags;
    389 };
    390 struct mmsghdr32 {
    391 	struct msghdr32         msg_hdr;
    392 	uint32_t /* unsigned */ msg_len;
    393 };
    394 
    395 static void
    396 printmsghdr(struct tcb *tcp, long addr, unsigned long data_size)
    397 {
    398 	struct msghdr msg;
    399 
    400 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
    401 	if (current_wordsize == 4) {
    402 		struct msghdr32 msg32;
    403 
    404 		if (umove(tcp, addr, &msg32) < 0) {
    405 			tprintf("%#lx", addr);
    406 			return;
    407 		}
    408 		msg.msg_name       = (void*)(long)msg32.msg_name;
    409 		msg.msg_namelen    =              msg32.msg_namelen;
    410 		msg.msg_iov        = (void*)(long)msg32.msg_iov;
    411 		msg.msg_iovlen     =              msg32.msg_iovlen;
    412 		msg.msg_control    = (void*)(long)msg32.msg_control;
    413 		msg.msg_controllen =              msg32.msg_controllen;
    414 		msg.msg_flags      =              msg32.msg_flags;
    415 	} else
    416 #endif
    417 	if (umove(tcp, addr, &msg) < 0) {
    418 		tprintf("%#lx", addr);
    419 		return;
    420 	}
    421 	do_msghdr(tcp, &msg, data_size);
    422 }
    423 
    424 static void
    425 printmmsghdr(struct tcb *tcp, long addr, unsigned int idx, unsigned long msg_len)
    426 {
    427 	struct mmsghdr {
    428 		struct msghdr msg_hdr;
    429 		unsigned msg_len;
    430 	} mmsg;
    431 
    432 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
    433 	if (current_wordsize == 4) {
    434 		struct mmsghdr32 mmsg32;
    435 
    436 		addr += sizeof(mmsg32) * idx;
    437 		if (umove(tcp, addr, &mmsg32) < 0) {
    438 			tprintf("%#lx", addr);
    439 			return;
    440 		}
    441 		mmsg.msg_hdr.msg_name       = (void*)(long)mmsg32.msg_hdr.msg_name;
    442 		mmsg.msg_hdr.msg_namelen    =              mmsg32.msg_hdr.msg_namelen;
    443 		mmsg.msg_hdr.msg_iov        = (void*)(long)mmsg32.msg_hdr.msg_iov;
    444 		mmsg.msg_hdr.msg_iovlen     =              mmsg32.msg_hdr.msg_iovlen;
    445 		mmsg.msg_hdr.msg_control    = (void*)(long)mmsg32.msg_hdr.msg_control;
    446 		mmsg.msg_hdr.msg_controllen =              mmsg32.msg_hdr.msg_controllen;
    447 		mmsg.msg_hdr.msg_flags      =              mmsg32.msg_hdr.msg_flags;
    448 		mmsg.msg_len                =              mmsg32.msg_len;
    449 	} else
    450 #endif
    451 	{
    452 		addr += sizeof(mmsg) * idx;
    453 		if (umove(tcp, addr, &mmsg) < 0) {
    454 			tprintf("%#lx", addr);
    455 			return;
    456 		}
    457 	}
    458 	tprints("{");
    459 	do_msghdr(tcp, &mmsg.msg_hdr, msg_len ? msg_len : mmsg.msg_len);
    460 	tprintf(", %u}", mmsg.msg_len);
    461 }
    462 
    463 static void
    464 decode_mmsg(struct tcb *tcp, unsigned long msg_len)
    465 {
    466 	/* mmsgvec */
    467 	if (syserror(tcp)) {
    468 		tprintf("%#lx", tcp->u_arg[1]);
    469 	} else {
    470 		unsigned int len = tcp->u_rval;
    471 		unsigned int i;
    472 
    473 		tprints("{");
    474 		for (i = 0; i < len; ++i) {
    475 			if (i)
    476 				tprints(", ");
    477 			printmmsghdr(tcp, tcp->u_arg[1], i, msg_len);
    478 		}
    479 		tprints("}");
    480 	}
    481 	/* vlen */
    482 	tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
    483 	/* flags */
    484 	printflags(msg_flags, tcp->u_arg[3], "MSG_???");
    485 }
    486 
    487 #endif /* HAVE_SENDMSG */
    488 
    489 /*
    490  * low bits of the socket type define real socket type,
    491  * other bits are socket type flags.
    492  */
    493 static void
    494 tprint_sock_type(struct tcb *tcp, int flags)
    495 {
    496 	const char *str = xlookup(socktypes, flags & SOCK_TYPE_MASK);
    497 
    498 	if (str) {
    499 		tprints(str);
    500 		flags &= ~SOCK_TYPE_MASK;
    501 		if (!flags)
    502 			return;
    503 		tprints("|");
    504 	}
    505 	printflags(sock_type_flags, flags, "SOCK_???");
    506 }
    507 
    508 int
    509 sys_socket(struct tcb *tcp)
    510 {
    511 	if (entering(tcp)) {
    512 		printxval(domains, tcp->u_arg[0], "PF_???");
    513 		tprints(", ");
    514 		tprint_sock_type(tcp, tcp->u_arg[1]);
    515 		tprints(", ");
    516 		switch (tcp->u_arg[0]) {
    517 		case PF_INET:
    518 #ifdef PF_INET6
    519 		case PF_INET6:
    520 #endif
    521 			printxval(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
    522 			break;
    523 #ifdef PF_IPX
    524 		case PF_IPX:
    525 			/* BTW: I don't believe this.. */
    526 			tprints("[");
    527 			printxval(domains, tcp->u_arg[2], "PF_???");
    528 			tprints("]");
    529 			break;
    530 #endif /* PF_IPX */
    531 #ifdef PF_NETLINK
    532 		case PF_NETLINK:
    533 			printxval(netlink_protocols, tcp->u_arg[2], "NETLINK_???");
    534 			break;
    535 #endif
    536 		default:
    537 			tprintf("%lu", tcp->u_arg[2]);
    538 			break;
    539 		}
    540 	}
    541 	return 0;
    542 }
    543 
    544 int
    545 sys_bind(struct tcb *tcp)
    546 {
    547 	if (entering(tcp)) {
    548 		printfd(tcp, tcp->u_arg[0]);
    549 		tprints(", ");
    550 		printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
    551 		tprintf(", %lu", tcp->u_arg[2]);
    552 	}
    553 	return 0;
    554 }
    555 
    556 int
    557 sys_connect(struct tcb *tcp)
    558 {
    559 	return sys_bind(tcp);
    560 }
    561 
    562 int
    563 sys_listen(struct tcb *tcp)
    564 {
    565 	if (entering(tcp)) {
    566 		printfd(tcp, tcp->u_arg[0]);
    567 		tprints(", ");
    568 		tprintf("%lu", tcp->u_arg[1]);
    569 	}
    570 	return 0;
    571 }
    572 
    573 static int
    574 do_accept(struct tcb *tcp, int flags_arg)
    575 {
    576 	if (entering(tcp)) {
    577 		printfd(tcp, tcp->u_arg[0]);
    578 		tprints(", ");
    579 		return 0;
    580 	}
    581 	if (!tcp->u_arg[2])
    582 		tprintf("%#lx, NULL", tcp->u_arg[1]);
    583 	else {
    584 		int len;
    585 		if (tcp->u_arg[1] == 0 || syserror(tcp)
    586 		    || umove(tcp, tcp->u_arg[2], &len) < 0) {
    587 			tprintf("%#lx", tcp->u_arg[1]);
    588 		} else {
    589 			printsock(tcp, tcp->u_arg[1], len);
    590 		}
    591 		tprints(", ");
    592 		printnum_int(tcp, tcp->u_arg[2], "%u");
    593 	}
    594 	if (flags_arg >= 0) {
    595 		tprints(", ");
    596 		printflags(sock_type_flags, tcp->u_arg[flags_arg],
    597 			   "SOCK_???");
    598 	}
    599 	return 0;
    600 }
    601 
    602 int
    603 sys_accept(struct tcb *tcp)
    604 {
    605 	return do_accept(tcp, -1);
    606 }
    607 
    608 int
    609 sys_accept4(struct tcb *tcp)
    610 {
    611 	return do_accept(tcp, 3);
    612 }
    613 
    614 int
    615 sys_send(struct tcb *tcp)
    616 {
    617 	if (entering(tcp)) {
    618 		printfd(tcp, tcp->u_arg[0]);
    619 		tprints(", ");
    620 		printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
    621 		tprintf(", %lu, ", tcp->u_arg[2]);
    622 		/* flags */
    623 		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
    624 	}
    625 	return 0;
    626 }
    627 
    628 int
    629 sys_sendto(struct tcb *tcp)
    630 {
    631 	if (entering(tcp)) {
    632 		printfd(tcp, tcp->u_arg[0]);
    633 		tprints(", ");
    634 		printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
    635 		tprintf(", %lu, ", tcp->u_arg[2]);
    636 		/* flags */
    637 		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
    638 		/* to address */
    639 		tprints(", ");
    640 		printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
    641 		/* to length */
    642 		tprintf(", %lu", tcp->u_arg[5]);
    643 	}
    644 	return 0;
    645 }
    646 
    647 #ifdef HAVE_SENDMSG
    648 
    649 int
    650 sys_sendmsg(struct tcb *tcp)
    651 {
    652 	if (entering(tcp)) {
    653 		printfd(tcp, tcp->u_arg[0]);
    654 		tprints(", ");
    655 		printmsghdr(tcp, tcp->u_arg[1], (unsigned long) -1L);
    656 		/* flags */
    657 		tprints(", ");
    658 		printflags(msg_flags, tcp->u_arg[2], "MSG_???");
    659 	}
    660 	return 0;
    661 }
    662 
    663 int
    664 sys_sendmmsg(struct tcb *tcp)
    665 {
    666 	if (entering(tcp)) {
    667 		/* sockfd */
    668 		printfd(tcp, tcp->u_arg[0]);
    669 		tprints(", ");
    670 		if (!verbose(tcp)) {
    671 			tprintf("%#lx, %u, ",
    672 				tcp->u_arg[1], (unsigned int) tcp->u_arg[2]);
    673 			printflags(msg_flags, tcp->u_arg[3], "MSG_???");
    674 		}
    675 	} else {
    676 		if (verbose(tcp))
    677 			decode_mmsg(tcp, (unsigned long) -1L);
    678 	}
    679 	return 0;
    680 }
    681 
    682 #endif /* HAVE_SENDMSG */
    683 
    684 int
    685 sys_recv(struct tcb *tcp)
    686 {
    687 	if (entering(tcp)) {
    688 		printfd(tcp, tcp->u_arg[0]);
    689 		tprints(", ");
    690 	} else {
    691 		if (syserror(tcp))
    692 			tprintf("%#lx", tcp->u_arg[1]);
    693 		else
    694 			printstr(tcp, tcp->u_arg[1], tcp->u_rval);
    695 
    696 		tprintf(", %lu, ", tcp->u_arg[2]);
    697 		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
    698 	}
    699 	return 0;
    700 }
    701 
    702 int
    703 sys_recvfrom(struct tcb *tcp)
    704 {
    705 	int fromlen;
    706 
    707 	if (entering(tcp)) {
    708 		printfd(tcp, tcp->u_arg[0]);
    709 		tprints(", ");
    710 	} else {
    711 		if (syserror(tcp)) {
    712 			tprintf("%#lx, %lu, %lu, %#lx, %#lx",
    713 				tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3],
    714 				tcp->u_arg[4], tcp->u_arg[5]);
    715 			return 0;
    716 		}
    717 		/* buf */
    718 		printstr(tcp, tcp->u_arg[1], tcp->u_rval);
    719 		/* len */
    720 		tprintf(", %lu, ", tcp->u_arg[2]);
    721 		/* flags */
    722 		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
    723 		/* from address, len */
    724 		if (!tcp->u_arg[4] || !tcp->u_arg[5]) {
    725 			if (tcp->u_arg[4] == 0)
    726 				tprints(", NULL");
    727 			else
    728 				tprintf(", %#lx", tcp->u_arg[4]);
    729 			if (tcp->u_arg[5] == 0)
    730 				tprints(", NULL");
    731 			else
    732 				tprintf(", %#lx", tcp->u_arg[5]);
    733 			return 0;
    734 		}
    735 		if (umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
    736 			tprints(", {...}, [?]");
    737 			return 0;
    738 		}
    739 		tprints(", ");
    740 		printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
    741 		/* from length */
    742 		tprintf(", [%u]", fromlen);
    743 	}
    744 	return 0;
    745 }
    746 
    747 #ifdef HAVE_SENDMSG
    748 
    749 int
    750 sys_recvmsg(struct tcb *tcp)
    751 {
    752 	if (entering(tcp)) {
    753 		printfd(tcp, tcp->u_arg[0]);
    754 		tprints(", ");
    755 	} else {
    756 		if (syserror(tcp) || !verbose(tcp))
    757 			tprintf("%#lx", tcp->u_arg[1]);
    758 		else
    759 			printmsghdr(tcp, tcp->u_arg[1], tcp->u_rval);
    760 		/* flags */
    761 		tprints(", ");
    762 		printflags(msg_flags, tcp->u_arg[2], "MSG_???");
    763 	}
    764 	return 0;
    765 }
    766 
    767 int
    768 sys_recvmmsg(struct tcb *tcp)
    769 {
    770 	/* +5 chars are for "left " prefix */
    771 	static char str[5 + TIMESPEC_TEXT_BUFSIZE];
    772 
    773 	if (entering(tcp)) {
    774 		printfd(tcp, tcp->u_arg[0]);
    775 		tprints(", ");
    776 		if (verbose(tcp)) {
    777 			sprint_timespec(str, tcp, tcp->u_arg[4]);
    778 			/* Abusing tcp->auxstr as temp storage.
    779 			 * Will be used and freed on syscall exit.
    780 			 */
    781 			tcp->auxstr = strdup(str);
    782 		} else {
    783 			tprintf("%#lx, %ld, ", tcp->u_arg[1], tcp->u_arg[2]);
    784 			printflags(msg_flags, tcp->u_arg[3], "MSG_???");
    785 			tprints(", ");
    786 			print_timespec(tcp, tcp->u_arg[4]);
    787 		}
    788 		return 0;
    789 	} else {
    790 		if (verbose(tcp)) {
    791 			decode_mmsg(tcp, 0);
    792 			/* timeout on entrance */
    793 			tprintf(", %s", tcp->auxstr ? tcp->auxstr : "{...}");
    794 			free((void *) tcp->auxstr);
    795 			tcp->auxstr = NULL;
    796 		}
    797 		if (syserror(tcp))
    798 			return 0;
    799 		if (tcp->u_rval == 0) {
    800 			tcp->auxstr = "Timeout";
    801 			return RVAL_STR;
    802 		}
    803 		if (!verbose(tcp))
    804 			return 0;
    805 		/* timeout on exit */
    806 		sprint_timespec(stpcpy(str, "left "), tcp, tcp->u_arg[4]);
    807 		tcp->auxstr = str;
    808 		return RVAL_STR;
    809 	}
    810 }
    811 
    812 #endif /* HAVE_SENDMSG */
    813 
    814 #include "xlat/shutdown_modes.h"
    815 
    816 int
    817 sys_shutdown(struct tcb *tcp)
    818 {
    819 	if (entering(tcp)) {
    820 		printfd(tcp, tcp->u_arg[0]);
    821 		tprints(", ");
    822 		printxval(shutdown_modes, tcp->u_arg[1], "SHUT_???");
    823 	}
    824 	return 0;
    825 }
    826 
    827 int
    828 sys_getsockname(struct tcb *tcp)
    829 {
    830 	return sys_accept(tcp);
    831 }
    832 
    833 int
    834 sys_getpeername(struct tcb *tcp)
    835 {
    836 	return sys_accept(tcp);
    837 }
    838 
    839 static int
    840 do_pipe(struct tcb *tcp, int flags_arg)
    841 {
    842 	if (exiting(tcp)) {
    843 		if (syserror(tcp)) {
    844 			tprintf("%#lx", tcp->u_arg[0]);
    845 		} else {
    846 #if !defined(SPARC) && !defined(SPARC64) && !defined(SH) && !defined(IA64)
    847 			int fds[2];
    848 
    849 			if (umoven(tcp, tcp->u_arg[0], sizeof fds, (char *) fds) < 0)
    850 				tprints("[...]");
    851 			else
    852 				tprintf("[%u, %u]", fds[0], fds[1]);
    853 #elif defined(SPARC) || defined(SPARC64) || defined(SH) || defined(IA64)
    854 			tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
    855 #else
    856 			tprintf("%#lx", tcp->u_arg[0]);
    857 #endif
    858 		}
    859 		if (flags_arg >= 0) {
    860 			tprints(", ");
    861 			printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
    862 		}
    863 	}
    864 	return 0;
    865 }
    866 
    867 int
    868 sys_pipe(struct tcb *tcp)
    869 {
    870 	return do_pipe(tcp, -1);
    871 }
    872 
    873 int
    874 sys_pipe2(struct tcb *tcp)
    875 {
    876 	return do_pipe(tcp, 1);
    877 }
    878 
    879 int
    880 sys_socketpair(struct tcb *tcp)
    881 {
    882 	int fds[2];
    883 
    884 	if (entering(tcp)) {
    885 		printxval(domains, tcp->u_arg[0], "PF_???");
    886 		tprints(", ");
    887 		tprint_sock_type(tcp, tcp->u_arg[1]);
    888 		tprintf(", %lu", tcp->u_arg[2]);
    889 	} else {
    890 		if (syserror(tcp)) {
    891 			tprintf(", %#lx", tcp->u_arg[3]);
    892 			return 0;
    893 		}
    894 		if (umoven(tcp, tcp->u_arg[3], sizeof fds, (char *) fds) < 0)
    895 			tprints(", [...]");
    896 		else
    897 			tprintf(", [%u, %u]", fds[0], fds[1]);
    898 	}
    899 	return 0;
    900 }
    901 
    902 int
    903 sys_getsockopt(struct tcb *tcp)
    904 {
    905 	if (entering(tcp)) {
    906 		printfd(tcp, tcp->u_arg[0]);
    907 		tprints(", ");
    908 		printxval(socketlayers, tcp->u_arg[1], "SOL_???");
    909 		tprints(", ");
    910 		switch (tcp->u_arg[1]) {
    911 		case SOL_SOCKET:
    912 			printxval(sockoptions, tcp->u_arg[2], "SO_???");
    913 			break;
    914 #ifdef SOL_IP
    915 		case SOL_IP:
    916 			printxval(sockipoptions, tcp->u_arg[2], "IP_???");
    917 			break;
    918 #endif
    919 #ifdef SOL_IPV6
    920 		case SOL_IPV6:
    921 			printxval(sockipv6options, tcp->u_arg[2], "IPV6_???");
    922 			break;
    923 #endif
    924 #ifdef SOL_IPX
    925 		case SOL_IPX:
    926 			printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
    927 			break;
    928 #endif
    929 #ifdef SOL_PACKET
    930 		case SOL_PACKET:
    931 			printxval(sockpacketoptions, tcp->u_arg[2], "PACKET_???");
    932 			break;
    933 #endif
    934 #ifdef SOL_TCP
    935 		case SOL_TCP:
    936 			printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
    937 			break;
    938 #endif
    939 #ifdef SOL_SCTP
    940 		case SOL_SCTP:
    941 			printxval(socksctpoptions, tcp->u_arg[2], "SCTP_???");
    942 			break;
    943 #endif
    944 
    945 		/* SOL_AX25 SOL_ROSE SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
    946 		 * etc. still need work */
    947 		default:
    948 			tprintf("%lu", tcp->u_arg[2]);
    949 			break;
    950 		}
    951 		tprints(", ");
    952 	} else {
    953 		int len;
    954 		if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &len) < 0) {
    955 			tprintf("%#lx, %#lx",
    956 				tcp->u_arg[3], tcp->u_arg[4]);
    957 			return 0;
    958 		}
    959 
    960 		switch (tcp->u_arg[1]) {
    961 		case SOL_SOCKET:
    962 			switch (tcp->u_arg[2]) {
    963 #ifdef SO_LINGER
    964 			case SO_LINGER:
    965 				if (len == sizeof(struct linger)) {
    966 					struct linger linger;
    967 					if (umove(tcp,
    968 						   tcp->u_arg[3],
    969 						   &linger) < 0)
    970 						break;
    971 					tprintf("{onoff=%d, linger=%d}, "
    972 						"[%d]",
    973 						linger.l_onoff,
    974 						linger.l_linger,
    975 						len);
    976 					return 0;
    977 				}
    978 				break;
    979 #endif
    980 #ifdef SO_PEERCRED
    981 			case SO_PEERCRED:
    982 				if (len == sizeof(struct ucred)) {
    983 					struct ucred uc;
    984 					if (umove(tcp,
    985 						   tcp->u_arg[3],
    986 						   &uc) < 0)
    987 						break;
    988 					tprintf("{pid=%ld, uid=%ld, gid=%ld}, "
    989 						"[%d]",
    990 						(long)uc.pid,
    991 						(long)uc.uid,
    992 						(long)uc.gid,
    993 						len);
    994 					return 0;
    995 				}
    996 				break;
    997 #endif
    998 			}
    999 			break;
   1000 		case SOL_PACKET:
   1001 			switch (tcp->u_arg[2]) {
   1002 #ifdef PACKET_STATISTICS
   1003 			case PACKET_STATISTICS:
   1004 				if (len == sizeof(struct tpacket_stats)) {
   1005 					struct tpacket_stats stats;
   1006 					if (umove(tcp,
   1007 						   tcp->u_arg[3],
   1008 						   &stats) < 0)
   1009 						break;
   1010 					tprintf("{packets=%u, drops=%u}, "
   1011 						"[%d]",
   1012 						stats.tp_packets,
   1013 						stats.tp_drops,
   1014 						len);
   1015 					return 0;
   1016 				}
   1017 				break;
   1018 #endif
   1019 			}
   1020 			break;
   1021 		}
   1022 
   1023 		if (len == sizeof(int)) {
   1024 			printnum_int(tcp, tcp->u_arg[3], "%d");
   1025 		}
   1026 		else {
   1027 			printstr(tcp, tcp->u_arg[3], len);
   1028 		}
   1029 		tprintf(", [%d]", len);
   1030 	}
   1031 	return 0;
   1032 }
   1033 
   1034 #if defined(ICMP_FILTER)
   1035 static void printicmpfilter(struct tcb *tcp, long addr)
   1036 {
   1037 	struct icmp_filter	filter;
   1038 
   1039 	if (!addr) {
   1040 		tprints("NULL");
   1041 		return;
   1042 	}
   1043 	if (syserror(tcp) || !verbose(tcp)) {
   1044 		tprintf("%#lx", addr);
   1045 		return;
   1046 	}
   1047 	if (umove(tcp, addr, &filter) < 0) {
   1048 		tprints("{...}");
   1049 		return;
   1050 	}
   1051 
   1052 	tprints("~(");
   1053 	printflags(icmpfilterflags, ~filter.data, "ICMP_???");
   1054 	tprints(")");
   1055 }
   1056 #endif /* ICMP_FILTER */
   1057 
   1058 static int
   1059 printsockopt(struct tcb *tcp, int level, int name, long addr, int len)
   1060 {
   1061 	printxval(socketlayers, level, "SOL_??");
   1062 	tprints(", ");
   1063 	switch (level) {
   1064 	case SOL_SOCKET:
   1065 		printxval(sockoptions, name, "SO_???");
   1066 		switch (name) {
   1067 #if defined(SO_LINGER)
   1068 		case SO_LINGER:
   1069 			if (len == sizeof(struct linger)) {
   1070 				struct linger linger;
   1071 				if (umove(tcp, addr, &linger) < 0)
   1072 					break;
   1073 				tprintf(", {onoff=%d, linger=%d}",
   1074 					linger.l_onoff,
   1075 					linger.l_linger);
   1076 				return 0;
   1077 			}
   1078 			break;
   1079 #endif
   1080 		}
   1081 		break;
   1082 #ifdef SOL_IP
   1083 	case SOL_IP:
   1084 		printxval(sockipoptions, name, "IP_???");
   1085 		break;
   1086 #endif
   1087 #ifdef SOL_IPV6
   1088 	case SOL_IPV6:
   1089 		printxval(sockipv6options, name, "IPV6_???");
   1090 		break;
   1091 #endif
   1092 #ifdef SOL_IPX
   1093 	case SOL_IPX:
   1094 		printxval(sockipxoptions, name, "IPX_???");
   1095 		break;
   1096 #endif
   1097 #ifdef SOL_PACKET
   1098 	case SOL_PACKET:
   1099 		printxval(sockpacketoptions, name, "PACKET_???");
   1100 		/* TODO: decode packate_mreq for PACKET_*_MEMBERSHIP */
   1101 		switch (name) {
   1102 #ifdef PACKET_RX_RING
   1103 		case PACKET_RX_RING:
   1104 #endif
   1105 #ifdef PACKET_TX_RING
   1106 		case PACKET_TX_RING:
   1107 #endif
   1108 #if defined(PACKET_RX_RING) || defined(PACKET_TX_RING)
   1109 			if (len == sizeof(struct tpacket_req)) {
   1110 				struct tpacket_req req;
   1111 				if (umove(tcp, addr, &req) < 0)
   1112 					break;
   1113 				tprintf(", {block_size=%u, block_nr=%u, frame_size=%u, frame_nr=%u}",
   1114 					req.tp_block_size,
   1115 					req.tp_block_nr,
   1116 					req.tp_frame_size,
   1117 					req.tp_frame_nr);
   1118 				return 0;
   1119 			}
   1120 			break;
   1121 #endif /* PACKET_RX_RING || PACKET_TX_RING */
   1122 		}
   1123 		break;
   1124 #endif
   1125 #ifdef SOL_TCP
   1126 	case SOL_TCP:
   1127 		printxval(socktcpoptions, name, "TCP_???");
   1128 		break;
   1129 #endif
   1130 #ifdef SOL_SCTP
   1131 	case SOL_SCTP:
   1132 		printxval(socksctpoptions, name, "SCTP_???");
   1133 		break;
   1134 #endif
   1135 #ifdef SOL_RAW
   1136 	case SOL_RAW:
   1137 		printxval(sockrawoptions, name, "RAW_???");
   1138 		switch (name) {
   1139 #if defined(ICMP_FILTER)
   1140 			case ICMP_FILTER:
   1141 				tprints(", ");
   1142 				printicmpfilter(tcp, addr);
   1143 				return 0;
   1144 #endif
   1145 		}
   1146 		break;
   1147 #endif
   1148 
   1149 		/* SOL_AX25 SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
   1150 		 * etc. still need work  */
   1151 
   1152 	default:
   1153 		tprintf("%u", name);
   1154 	}
   1155 
   1156 	/* default arg printing */
   1157 
   1158 	tprints(", ");
   1159 
   1160 	if (len == sizeof(int)) {
   1161 		printnum_int(tcp, addr, "%d");
   1162 	}
   1163 	else {
   1164 		printstr(tcp, addr, len);
   1165 	}
   1166 	return 0;
   1167 }
   1168 
   1169 int
   1170 sys_setsockopt(struct tcb *tcp)
   1171 {
   1172 	if (entering(tcp)) {
   1173 		printfd(tcp, tcp->u_arg[0]);
   1174 		tprints(", ");
   1175 		printsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
   1176 			      tcp->u_arg[3], tcp->u_arg[4]);
   1177 		tprintf(", %lu", tcp->u_arg[4]);
   1178 	}
   1179 	return 0;
   1180 }
   1181