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