net.c revision e96aee7ebbc23e602664ec1487e62d0885167111
1/* 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> 5 * Copyright (c) 1996-2000 Wichert Akkerman <wichert@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/uio.h> 35#include <sys/un.h> 36#include <netinet/in.h> 37#ifdef HAVE_NETINET_TCP_H 38# include <netinet/tcp.h> 39#endif 40#ifdef HAVE_NETINET_UDP_H 41# include <netinet/udp.h> 42#endif 43#ifdef HAVE_NETINET_SCTP_H 44# include <netinet/sctp.h> 45#endif 46#include <arpa/inet.h> 47#include <net/if.h> 48#include <asm/types.h> 49#ifdef HAVE_NETIPX_IPX_H 50# include <netipx/ipx.h> 51#else 52# include <linux/ipx.h> 53#endif 54 55#if defined(HAVE_LINUX_IP_VS_H) 56# include <linux/ip_vs.h> 57#endif 58#include <linux/netlink.h> 59#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 71#include <linux/if_packet.h> 72#include <linux/icmp.h> 73 74#include "xlat/socktypes.h" 75#include "xlat/sock_type_flags.h" 76#ifndef SOCK_TYPE_MASK 77# define SOCK_TYPE_MASK 0xf 78#endif 79 80#include "xlat/socketlayers.h" 81 82#include "xlat/inet_protocols.h" 83 84#if !defined NETLINK_SOCK_DIAG && defined NETLINK_INET_DIAG 85# define NETLINK_SOCK_DIAG NETLINK_INET_DIAG 86#endif 87#include "xlat/netlink_protocols.h" 88 89#ifdef HAVE_BLUETOOTH_BLUETOOTH_H 90# include <bluetooth/bluetooth.h> 91# include "xlat/bt_protocols.h" 92#endif 93 94#include "xlat/msg_flags.h" 95 96void 97print_ifindex(unsigned int ifindex) 98{ 99#ifdef HAVE_IF_INDEXTONAME 100 char buf[IFNAMSIZ + 1]; 101 102 if (if_indextoname(ifindex, buf)) { 103 tprints("if_nametoindex("); 104 print_quoted_string(buf, sizeof(buf), QUOTE_0_TERMINATED); 105 tprints(")"); 106 return; 107 } 108#endif 109 tprintf("%u", ifindex); 110} 111 112#include "xlat/scmvals.h" 113#include "xlat/ip_cmsg_types.h" 114 115#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 116struct cmsghdr32 { 117 uint32_t cmsg_len; 118 int cmsg_level; 119 int cmsg_type; 120}; 121#endif 122 123typedef union { 124 char *ptr; 125 struct cmsghdr *cmsg; 126#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 127 struct cmsghdr32 *cmsg32; 128#endif 129} union_cmsghdr; 130 131static void 132print_scm_rights(struct tcb *tcp, const void *cmsg_data, 133 const size_t data_len) 134{ 135 const int *fds = cmsg_data; 136 const char *end = (const char *) cmsg_data + data_len; 137 bool seen = false; 138 139 if (sizeof(*fds) > data_len) 140 return; 141 142 tprints(", ["); 143 while ((const char *) fds < end) { 144 if (seen) 145 tprints(", "); 146 else 147 seen = true; 148 printfd(tcp, *fds++); 149 } 150 tprints("]"); 151} 152 153static void 154print_scm_creds(struct tcb *tcp, const void *cmsg_data, 155 const size_t data_len) 156{ 157 const struct ucred *uc = cmsg_data; 158 159 if (sizeof(*uc) > data_len) 160 return; 161 162 tprintf(", {pid=%u, uid=%u, gid=%u}", 163 (unsigned) uc->pid, (unsigned) uc->uid, (unsigned) uc->gid); 164} 165 166static void 167print_scm_security(struct tcb *tcp, const void *cmsg_data, 168 const size_t data_len) 169{ 170 if (!data_len) 171 return; 172 173 tprints(", "); 174 print_quoted_string(cmsg_data, data_len, 0); 175} 176 177static void 178print_cmsg_ip_pktinfo(struct tcb *tcp, const void *cmsg_data, 179 const size_t data_len) 180{ 181 const struct in_pktinfo *info = cmsg_data; 182 183 if (sizeof(*info) > data_len) 184 return; 185 186 tprints(", {ipi_ifindex="); 187 print_ifindex(info->ipi_ifindex); 188 tprintf(", ipi_spec_dst=inet_addr(\"%s\"), ipi_addr=inet_addr(\"%s\")}", 189 inet_ntoa(info->ipi_spec_dst), inet_ntoa(info->ipi_addr)); 190} 191 192static void 193print_cmsg_ip_ttl(struct tcb *tcp, const void *cmsg_data, 194 const size_t data_len) 195{ 196 const unsigned int *ttl = cmsg_data; 197 198 if (sizeof(*ttl) > data_len) 199 return; 200 201 tprintf(", {ttl=%u}", *ttl); 202} 203 204static void 205print_cmsg_ip_tos(struct tcb *tcp, const void *cmsg_data, 206 const size_t data_len) 207{ 208 const uint8_t *tos = cmsg_data; 209 210 if (sizeof(*tos) > data_len) 211 return; 212 213 tprintf(", {tos=%x}", *tos); 214} 215 216static void 217print_cmsg_ip_checksum(struct tcb *tcp, const void *cmsg_data, 218 const size_t data_len) 219{ 220 const uint32_t *csum = cmsg_data; 221 222 if (sizeof(*csum) > data_len) 223 return; 224 225 tprintf(", {csum=%u}", *csum); 226} 227 228static void 229print_cmsg_ip_opts(struct tcb *tcp, const void *cmsg_data, 230 const size_t data_len) 231{ 232 const unsigned char *opts = cmsg_data; 233 size_t i; 234 235 if (!data_len) 236 return; 237 238 tprints(", {opts=0x"); 239 for (i = 0; i < data_len; ++i) 240 tprintf("%02x", opts[i]); 241 tprints("}"); 242} 243 244static void 245print_cmsg_ip_recverr(struct tcb *tcp, const void *cmsg_data, 246 const size_t data_len) 247{ 248 const struct { 249 uint32_t ee_errno; 250 uint8_t ee_origin; 251 uint8_t ee_type; 252 uint8_t ee_code; 253 uint8_t ee_pad; 254 uint32_t ee_info; 255 uint32_t ee_data; 256 struct sockaddr_in offender; 257 } *err = cmsg_data; 258 259 if (sizeof(*err) > data_len) 260 return; 261 262 tprintf(", {ee_errno=%u, ee_origin=%u, ee_type=%u, ee_code=%u" 263 ", ee_info=%u, ee_data=%u, offender=", 264 err->ee_errno, err->ee_origin, err->ee_type, 265 err->ee_code, err->ee_info, err->ee_data); 266 print_sockaddr(tcp, &err->offender, sizeof(err->offender)); 267 tprints("}"); 268} 269 270static void 271print_cmsg_ip_origdstaddr(struct tcb *tcp, const void *cmsg_data, 272 const size_t data_len) 273{ 274 if (sizeof(struct sockaddr_in) > data_len) 275 return; 276 277 tprints(", "); 278 print_sockaddr(tcp, cmsg_data, data_len); 279} 280 281static void 282print_cmsg_type_data(struct tcb *tcp, const int cmsg_level, const int cmsg_type, 283 const void *cmsg_data, const size_t data_len) 284{ 285 switch (cmsg_level) { 286 case SOL_SOCKET: 287 printxval(scmvals, cmsg_type, "SCM_???"); 288 switch (cmsg_type) { 289 case SCM_RIGHTS: 290 print_scm_rights(tcp, cmsg_data, data_len); 291 break; 292 case SCM_CREDENTIALS: 293 print_scm_creds(tcp, cmsg_data, data_len); 294 break; 295 case SCM_SECURITY: 296 print_scm_security(tcp, cmsg_data, data_len); 297 break; 298 } 299 break; 300 case SOL_IP: 301 printxval(ip_cmsg_types, cmsg_type, "IP_???"); 302 switch (cmsg_type) { 303 case IP_PKTINFO: 304 print_cmsg_ip_pktinfo(tcp, cmsg_data, data_len); 305 break; 306 case IP_TTL: 307 print_cmsg_ip_ttl(tcp, cmsg_data, data_len); 308 break; 309 case IP_TOS: 310 print_cmsg_ip_tos(tcp, cmsg_data, data_len); 311 break; 312 case IP_RECVOPTS: 313 case IP_RETOPTS: 314 print_cmsg_ip_opts(tcp, cmsg_data, data_len); 315 break; 316 case IP_RECVERR: 317 print_cmsg_ip_recverr(tcp, cmsg_data, data_len); 318 break; 319 case IP_ORIGDSTADDR: 320 print_cmsg_ip_origdstaddr(tcp, cmsg_data, data_len); 321 break; 322 case IP_CHECKSUM: 323 print_cmsg_ip_checksum(tcp, cmsg_data, data_len); 324 break; 325 case SCM_SECURITY: 326 print_scm_security(tcp, cmsg_data, data_len); 327 break; 328 } 329 break; 330 default: 331 tprintf("%u", cmsg_type); 332 } 333} 334 335static void 336printcmsghdr(struct tcb *tcp, unsigned long addr, size_t len) 337{ 338 const size_t cmsg_size = 339#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 340 (current_wordsize < sizeof(long)) ? sizeof(struct cmsghdr32) : 341#endif 342 sizeof(struct cmsghdr); 343 344 char *buf = len < cmsg_size ? NULL : malloc(len); 345 if (!buf || umoven(tcp, addr, len, buf) < 0) { 346 tprints(", msg_control="); 347 printaddr(addr); 348 free(buf); 349 return; 350 } 351 352 union_cmsghdr u = { .ptr = buf }; 353 354 tprints(", ["); 355 while (len >= cmsg_size) { 356 size_t cmsg_len = 357#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 358 (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_len : 359#endif 360 u.cmsg->cmsg_len; 361 int cmsg_level = 362#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 363 (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_level : 364#endif 365 u.cmsg->cmsg_level; 366 int cmsg_type = 367#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 368 (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_type : 369#endif 370 u.cmsg->cmsg_type; 371 372 if (u.ptr != buf) 373 tprints(", "); 374 tprintf("{cmsg_len=%lu, cmsg_level=", (unsigned long) cmsg_len); 375 printxval(socketlayers, cmsg_level, "SOL_???"); 376 tprints(", cmsg_type="); 377 378 if (cmsg_len > len) 379 cmsg_len = len; 380 381 print_cmsg_type_data(tcp, cmsg_level, cmsg_type, 382 (const void *) (u.ptr + cmsg_size), 383 cmsg_len > cmsg_size ? cmsg_len - cmsg_size: 0); 384 tprints("}"); 385 386 if (cmsg_len < cmsg_size) { 387 len -= cmsg_size; 388 break; 389 } 390 cmsg_len = (cmsg_len + current_wordsize - 1) & 391 (size_t) ~(current_wordsize - 1); 392 if (cmsg_len >= len) { 393 len = 0; 394 break; 395 } 396 u.ptr += cmsg_len; 397 len -= cmsg_len; 398 } 399 if (len) 400 tprints(", ..."); 401 tprints("]"); 402 free(buf); 403} 404 405static void 406do_msghdr(struct tcb *tcp, struct msghdr *msg, unsigned long data_size) 407{ 408 tprintf("{msg_name(%d)=", msg->msg_namelen); 409 decode_sockaddr(tcp, (long)msg->msg_name, msg->msg_namelen); 410 411 tprintf(", msg_iov(%lu)=", (unsigned long)msg->msg_iovlen); 412 413 tprint_iov_upto(tcp, (unsigned long)msg->msg_iovlen, 414 (unsigned long)msg->msg_iov, IOV_DECODE_STR, data_size); 415 416#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL 417 tprintf(", msg_controllen=%lu", (unsigned long)msg->msg_controllen); 418 if (msg->msg_controllen) 419 printcmsghdr(tcp, (unsigned long) msg->msg_control, 420 msg->msg_controllen); 421 tprints(", msg_flags="); 422 printflags(msg_flags, msg->msg_flags, "MSG_???"); 423#else /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */ 424 tprintf("msg_accrights=%#lx, msg_accrightslen=%u", 425 (unsigned long) msg->msg_accrights, msg->msg_accrightslen); 426#endif /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */ 427 tprints("}"); 428} 429 430struct msghdr32 { 431 uint32_t /* void* */ msg_name; 432 uint32_t /* socklen_t */msg_namelen; 433 uint32_t /* iovec* */ msg_iov; 434 uint32_t /* size_t */ msg_iovlen; 435 uint32_t /* void* */ msg_control; 436 uint32_t /* size_t */ msg_controllen; 437 uint32_t /* int */ msg_flags; 438}; 439struct mmsghdr32 { 440 struct msghdr32 msg_hdr; 441 uint32_t /* unsigned */ msg_len; 442}; 443 444#ifndef HAVE_STRUCT_MMSGHDR 445struct mmsghdr { 446 struct msghdr msg_hdr; 447 unsigned msg_len; 448}; 449#endif 450 451#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 452static void 453copy_from_msghdr32(struct msghdr *to_msg, struct msghdr32 *from_msg32) 454{ 455 to_msg->msg_name = (void*)(long)from_msg32->msg_name; 456 to_msg->msg_namelen = from_msg32->msg_namelen; 457 to_msg->msg_iov = (void*)(long)from_msg32->msg_iov; 458 to_msg->msg_iovlen = from_msg32->msg_iovlen; 459 to_msg->msg_control = (void*)(long)from_msg32->msg_control; 460 to_msg->msg_controllen = from_msg32->msg_controllen; 461 to_msg->msg_flags = from_msg32->msg_flags; 462} 463#endif 464 465static bool 466extractmsghdr(struct tcb *tcp, long addr, struct msghdr *msg) 467{ 468#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 469 if (current_wordsize == 4) { 470 struct msghdr32 msg32; 471 472 if (umove(tcp, addr, &msg32) < 0) 473 return false; 474 copy_from_msghdr32(msg, &msg32); 475 } else 476#endif 477 if (umove(tcp, addr, msg) < 0) 478 return false; 479 return true; 480} 481 482static bool 483extractmmsghdr(struct tcb *tcp, long addr, unsigned int idx, struct mmsghdr *mmsg) 484{ 485#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 486 if (current_wordsize == 4) { 487 struct mmsghdr32 mmsg32; 488 489 addr += sizeof(struct mmsghdr32) * idx; 490 if (umove(tcp, addr, &mmsg32) < 0) 491 return false; 492 493 copy_from_msghdr32(&mmsg->msg_hdr, &mmsg32.msg_hdr); 494 mmsg->msg_len = mmsg32.msg_len; 495 } else 496#endif 497 { 498 addr += sizeof(*mmsg) * idx; 499 if (umove(tcp, addr, mmsg) < 0) 500 return false; 501 } 502 return true; 503} 504 505static void 506printmsghdr(struct tcb *tcp, long addr, unsigned long data_size) 507{ 508 struct msghdr msg; 509 510 if (verbose(tcp) && extractmsghdr(tcp, addr, &msg)) 511 do_msghdr(tcp, &msg, data_size); 512 else 513 printaddr(addr); 514} 515 516void 517dumpiov_in_msghdr(struct tcb *tcp, long addr, unsigned long data_size) 518{ 519 struct msghdr msg; 520 521 if (extractmsghdr(tcp, addr, &msg)) 522 dumpiov_upto(tcp, msg.msg_iovlen, (long)msg.msg_iov, data_size); 523} 524 525static void 526printmmsghdr(struct tcb *tcp, long addr, unsigned int idx, unsigned long msg_len) 527{ 528 struct mmsghdr mmsg; 529 530 if (extractmmsghdr(tcp, addr, idx, &mmsg)) { 531 tprints("{"); 532 do_msghdr(tcp, &mmsg.msg_hdr, msg_len ? msg_len : mmsg.msg_len); 533 tprintf(", %u}", mmsg.msg_len); 534 } 535 else 536 printaddr(addr); 537} 538 539static void 540decode_mmsg(struct tcb *tcp, unsigned long msg_len) 541{ 542 /* mmsgvec */ 543 if (syserror(tcp)) { 544 printaddr(tcp->u_arg[1]); 545 } else { 546 unsigned int len = tcp->u_rval; 547 unsigned int i; 548 549 tprints("{"); 550 for (i = 0; i < len; ++i) { 551 if (i) 552 tprints(", "); 553 printmmsghdr(tcp, tcp->u_arg[1], i, msg_len); 554 } 555 tprints("}"); 556 } 557 /* vlen */ 558 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]); 559 /* flags */ 560 printflags(msg_flags, tcp->u_arg[3], "MSG_???"); 561} 562 563void 564dumpiov_in_mmsghdr(struct tcb *tcp, long addr) 565{ 566 unsigned int len = tcp->u_rval; 567 unsigned int i; 568 struct mmsghdr mmsg; 569 570 for (i = 0; i < len; ++i) { 571 if (extractmmsghdr(tcp, addr, i, &mmsg)) { 572 tprintf(" = %lu buffers in vector %u\n", 573 (unsigned long)mmsg.msg_hdr.msg_iovlen, i); 574 dumpiov_upto(tcp, mmsg.msg_hdr.msg_iovlen, 575 (long)mmsg.msg_hdr.msg_iov, mmsg.msg_len); 576 } 577 } 578} 579 580/* 581 * low bits of the socket type define real socket type, 582 * other bits are socket type flags. 583 */ 584static void 585tprint_sock_type(unsigned int flags) 586{ 587 const char *str = xlookup(socktypes, flags & SOCK_TYPE_MASK); 588 589 if (str) { 590 tprints(str); 591 flags &= ~SOCK_TYPE_MASK; 592 if (!flags) 593 return; 594 tprints("|"); 595 } 596 printflags(sock_type_flags, flags, "SOCK_???"); 597} 598 599SYS_FUNC(socket) 600{ 601 printxval(addrfams, tcp->u_arg[0], "AF_???"); 602 tprints(", "); 603 tprint_sock_type(tcp->u_arg[1]); 604 tprints(", "); 605 switch (tcp->u_arg[0]) { 606 case AF_INET: 607 case AF_INET6: 608 printxval(inet_protocols, tcp->u_arg[2], "IPPROTO_???"); 609 break; 610 611 case AF_NETLINK: 612 printxval(netlink_protocols, tcp->u_arg[2], "NETLINK_???"); 613 break; 614 615#ifdef HAVE_BLUETOOTH_BLUETOOTH_H 616 case AF_BLUETOOTH: 617 printxval(bt_protocols, tcp->u_arg[2], "BTPROTO_???"); 618 break; 619#endif 620 621 default: 622 tprintf("%lu", tcp->u_arg[2]); 623 break; 624 } 625 626 return RVAL_DECODED | RVAL_FD; 627} 628 629SYS_FUNC(bind) 630{ 631 printfd(tcp, tcp->u_arg[0]); 632 tprints(", "); 633 decode_sockaddr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 634 tprintf(", %lu", tcp->u_arg[2]); 635 636 return RVAL_DECODED; 637} 638 639SYS_FUNC(listen) 640{ 641 printfd(tcp, tcp->u_arg[0]); 642 tprints(", "); 643 tprintf("%lu", tcp->u_arg[1]); 644 645 return RVAL_DECODED; 646} 647 648static int 649do_sockname(struct tcb *tcp, int flags_arg) 650{ 651 if (entering(tcp)) { 652 printfd(tcp, tcp->u_arg[0]); 653 tprints(", "); 654 return 0; 655 } 656 657 int len; 658 if (!tcp->u_arg[2] || !verbose(tcp) || syserror(tcp) || 659 umove(tcp, tcp->u_arg[2], &len) < 0) { 660 printaddr(tcp->u_arg[1]); 661 tprints(", "); 662 printaddr(tcp->u_arg[2]); 663 } else { 664 decode_sockaddr(tcp, tcp->u_arg[1], len); 665 tprintf(", [%d]", len); 666 } 667 668 if (flags_arg >= 0) { 669 tprints(", "); 670 printflags(sock_type_flags, tcp->u_arg[flags_arg], 671 "SOCK_???"); 672 } 673 return 0; 674} 675 676SYS_FUNC(accept) 677{ 678 do_sockname(tcp, -1); 679 return RVAL_FD; 680} 681 682SYS_FUNC(accept4) 683{ 684 do_sockname(tcp, 3); 685 return RVAL_FD; 686} 687 688SYS_FUNC(send) 689{ 690 printfd(tcp, tcp->u_arg[0]); 691 tprints(", "); 692 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 693 tprintf(", %lu, ", tcp->u_arg[2]); 694 /* flags */ 695 printflags(msg_flags, tcp->u_arg[3], "MSG_???"); 696 697 return RVAL_DECODED; 698} 699 700SYS_FUNC(sendto) 701{ 702 printfd(tcp, tcp->u_arg[0]); 703 tprints(", "); 704 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 705 tprintf(", %lu, ", tcp->u_arg[2]); 706 /* flags */ 707 printflags(msg_flags, tcp->u_arg[3], "MSG_???"); 708 /* to address */ 709 tprints(", "); 710 decode_sockaddr(tcp, tcp->u_arg[4], tcp->u_arg[5]); 711 /* to length */ 712 tprintf(", %lu", tcp->u_arg[5]); 713 714 return RVAL_DECODED; 715} 716 717SYS_FUNC(sendmsg) 718{ 719 printfd(tcp, tcp->u_arg[0]); 720 tprints(", "); 721 printmsghdr(tcp, tcp->u_arg[1], (unsigned long) -1L); 722 /* flags */ 723 tprints(", "); 724 printflags(msg_flags, tcp->u_arg[2], "MSG_???"); 725 726 return RVAL_DECODED; 727} 728 729SYS_FUNC(sendmmsg) 730{ 731 if (entering(tcp)) { 732 /* sockfd */ 733 printfd(tcp, tcp->u_arg[0]); 734 tprints(", "); 735 if (!verbose(tcp)) { 736 printaddr(tcp->u_arg[1]); 737 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]); 738 printflags(msg_flags, tcp->u_arg[3], "MSG_???"); 739 } 740 } else { 741 if (verbose(tcp)) 742 decode_mmsg(tcp, (unsigned long) -1L); 743 } 744 return 0; 745} 746 747SYS_FUNC(recv) 748{ 749 if (entering(tcp)) { 750 printfd(tcp, tcp->u_arg[0]); 751 tprints(", "); 752 } else { 753 if (syserror(tcp)) 754 printaddr(tcp->u_arg[1]); 755 else 756 printstr(tcp, tcp->u_arg[1], tcp->u_rval); 757 758 tprintf(", %lu, ", tcp->u_arg[2]); 759 printflags(msg_flags, tcp->u_arg[3], "MSG_???"); 760 } 761 return 0; 762} 763 764SYS_FUNC(recvfrom) 765{ 766 int fromlen; 767 768 if (entering(tcp)) { 769 printfd(tcp, tcp->u_arg[0]); 770 tprints(", "); 771 } else { 772 /* buf */ 773 if (syserror(tcp)) { 774 printaddr(tcp->u_arg[1]); 775 } else { 776 printstr(tcp, tcp->u_arg[1], tcp->u_rval); 777 } 778 /* len */ 779 tprintf(", %lu, ", tcp->u_arg[2]); 780 /* flags */ 781 printflags(msg_flags, tcp->u_arg[3], "MSG_???"); 782 tprints(", "); 783 if (syserror(tcp) || !tcp->u_arg[4] || !tcp->u_arg[5] || 784 umove(tcp, tcp->u_arg[5], &fromlen) < 0) { 785 /* from address, len */ 786 printaddr(tcp->u_arg[4]); 787 tprints(", "); 788 printaddr(tcp->u_arg[5]); 789 return 0; 790 } 791 /* from address */ 792 decode_sockaddr(tcp, tcp->u_arg[4], fromlen); 793 /* from length */ 794 tprintf(", [%u]", fromlen); 795 } 796 return 0; 797} 798 799SYS_FUNC(recvmsg) 800{ 801 if (entering(tcp)) { 802 printfd(tcp, tcp->u_arg[0]); 803 tprints(", "); 804 } else { 805 if (syserror(tcp)) 806 printaddr(tcp->u_arg[1]); 807 else 808 printmsghdr(tcp, tcp->u_arg[1], tcp->u_rval); 809 /* flags */ 810 tprints(", "); 811 printflags(msg_flags, tcp->u_arg[2], "MSG_???"); 812 } 813 return 0; 814} 815 816SYS_FUNC(recvmmsg) 817{ 818 static char str[sizeof("left") + TIMESPEC_TEXT_BUFSIZE]; 819 820 if (entering(tcp)) { 821 printfd(tcp, tcp->u_arg[0]); 822 tprints(", "); 823 if (verbose(tcp)) { 824 /* Abusing tcp->auxstr as temp storage. 825 * Will be used and cleared on syscall exit. 826 */ 827 tcp->auxstr = sprint_timespec(tcp, tcp->u_arg[4]); 828 } else { 829 printaddr(tcp->u_arg[1]); 830 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]); 831 printflags(msg_flags, tcp->u_arg[3], "MSG_???"); 832 tprints(", "); 833 print_timespec(tcp, tcp->u_arg[4]); 834 } 835 return 0; 836 } else { 837 if (verbose(tcp)) { 838 decode_mmsg(tcp, 0); 839 tprints(", "); 840 /* timeout on entrance */ 841 tprints(tcp->auxstr); 842 tcp->auxstr = NULL; 843 } 844 if (syserror(tcp)) 845 return 0; 846 if (tcp->u_rval == 0) { 847 tcp->auxstr = "Timeout"; 848 return RVAL_STR; 849 } 850 if (!verbose(tcp)) 851 return 0; 852 /* timeout on exit */ 853 snprintf(str, sizeof(str), "left %s", 854 sprint_timespec(tcp, tcp->u_arg[4])); 855 tcp->auxstr = str; 856 return RVAL_STR; 857 } 858} 859 860#include "xlat/shutdown_modes.h" 861 862SYS_FUNC(shutdown) 863{ 864 printfd(tcp, tcp->u_arg[0]); 865 tprints(", "); 866 printxval(shutdown_modes, tcp->u_arg[1], "SHUT_???"); 867 868 return RVAL_DECODED; 869} 870 871SYS_FUNC(getsockname) 872{ 873 return do_sockname(tcp, -1); 874} 875 876static void 877printpair_fd(struct tcb *tcp, const int i0, const int i1) 878{ 879 tprints("["); 880 printfd(tcp, i0); 881 tprints(", "); 882 printfd(tcp, i1); 883 tprints("]"); 884} 885 886static void 887decode_pair_fd(struct tcb *tcp, const long addr) 888{ 889 int pair[2]; 890 891 if (umove_or_printaddr(tcp, addr, &pair)) 892 return; 893 894 printpair_fd(tcp, pair[0], pair[1]); 895} 896 897static int 898do_pipe(struct tcb *tcp, int flags_arg) 899{ 900 if (exiting(tcp)) { 901 decode_pair_fd(tcp, tcp->u_arg[0]); 902 if (flags_arg >= 0) { 903 tprints(", "); 904 printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???"); 905 } 906 } 907 return 0; 908} 909 910SYS_FUNC(pipe) 911{ 912#ifdef HAVE_GETRVAL2 913 if (exiting(tcp) && !syserror(tcp)) 914 printpair_fd(tcp, tcp->u_rval, getrval2(tcp)); 915 return 0; 916#else 917 return do_pipe(tcp, -1); 918#endif 919} 920 921SYS_FUNC(pipe2) 922{ 923 return do_pipe(tcp, 1); 924} 925 926SYS_FUNC(socketpair) 927{ 928 if (entering(tcp)) { 929 printxval(addrfams, tcp->u_arg[0], "AF_???"); 930 tprints(", "); 931 tprint_sock_type(tcp->u_arg[1]); 932 tprintf(", %lu", tcp->u_arg[2]); 933 } else { 934 tprints(", "); 935 decode_pair_fd(tcp, tcp->u_arg[3]); 936 } 937 return 0; 938} 939 940#include "xlat/sockoptions.h" 941#include "xlat/sockipoptions.h" 942#include "xlat/getsockipoptions.h" 943#include "xlat/setsockipoptions.h" 944#include "xlat/sockipv6options.h" 945#include "xlat/getsockipv6options.h" 946#include "xlat/setsockipv6options.h" 947#include "xlat/sockipxoptions.h" 948#include "xlat/sockrawoptions.h" 949#include "xlat/sockpacketoptions.h" 950#include "xlat/socksctpoptions.h" 951#include "xlat/socktcpoptions.h" 952 953static void 954print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level, 955 unsigned int name, bool is_getsockopt) 956{ 957 printfd(tcp, fd); 958 tprints(", "); 959 printxval(socketlayers, level, "SOL_??"); 960 tprints(", "); 961 962 switch (level) { 963 case SOL_SOCKET: 964 printxval(sockoptions, name, "SO_???"); 965 break; 966 case SOL_IP: 967 printxvals(name, "IP_???", sockipoptions, 968 is_getsockopt ? getsockipoptions : setsockipoptions, NULL); 969 break; 970 case SOL_IPV6: 971 printxvals(name, "IPV6_???", sockipv6options, 972 is_getsockopt ? getsockipv6options : setsockipv6options, NULL); 973 break; 974 case SOL_IPX: 975 printxval(sockipxoptions, name, "IPX_???"); 976 break; 977 case SOL_PACKET: 978 printxval(sockpacketoptions, name, "PACKET_???"); 979 break; 980 case SOL_TCP: 981 printxval(socktcpoptions, name, "TCP_???"); 982 break; 983 case SOL_SCTP: 984 printxval(socksctpoptions, name, "SCTP_???"); 985 break; 986 case SOL_RAW: 987 printxval(sockrawoptions, name, "RAW_???"); 988 break; 989 990 /* Other SOL_* protocol levels still need work. */ 991 992 default: 993 tprintf("%u", name); 994 } 995 996 tprints(", "); 997} 998 999static void 1000print_linger(struct tcb *tcp, long addr, int len) 1001{ 1002 struct linger linger; 1003 1004 if (len != sizeof(linger) || 1005 umove(tcp, addr, &linger) < 0) { 1006 printaddr(addr); 1007 return; 1008 } 1009 1010 tprintf("{onoff=%d, linger=%d}", 1011 linger.l_onoff, 1012 linger.l_linger); 1013} 1014 1015#ifdef SO_PEERCRED 1016static void 1017print_ucred(struct tcb *tcp, long addr, int len) 1018{ 1019 struct ucred uc; 1020 1021 if (len != sizeof(uc) || 1022 umove(tcp, addr, &uc) < 0) { 1023 printaddr(addr); 1024 } else { 1025 tprintf("{pid=%u, uid=%u, gid=%u}", 1026 (unsigned) uc.pid, 1027 (unsigned) uc.uid, 1028 (unsigned) uc.gid); 1029 } 1030} 1031#endif /* SO_PEERCRED */ 1032 1033#ifdef PACKET_STATISTICS 1034static void 1035print_tpacket_stats(struct tcb *tcp, long addr, int len) 1036{ 1037 struct tpacket_stats stats; 1038 1039 if (len != sizeof(stats) || 1040 umove(tcp, addr, &stats) < 0) { 1041 printaddr(addr); 1042 } else { 1043 tprintf("{packets=%u, drops=%u}", 1044 stats.tp_packets, 1045 stats.tp_drops); 1046 } 1047} 1048#endif /* PACKET_STATISTICS */ 1049 1050#include "xlat/icmpfilterflags.h" 1051 1052static void 1053print_icmp_filter(struct tcb *tcp, const long addr, int len) 1054{ 1055 struct icmp_filter filter = {}; 1056 1057 if (len > (int) sizeof(filter)) 1058 len = sizeof(filter); 1059 else if (len <= 0) { 1060 printaddr(addr); 1061 return; 1062 } 1063 1064 if (umoven_or_printaddr(tcp, addr, len, &filter)) 1065 return; 1066 1067 tprints("~("); 1068 printflags(icmpfilterflags, ~filter.data, "ICMP_???"); 1069 tprints(")"); 1070} 1071 1072static void 1073print_getsockopt(struct tcb *tcp, unsigned int level, unsigned int name, 1074 long addr, int len) 1075{ 1076 if (addr && verbose(tcp)) 1077 switch (level) { 1078 case SOL_SOCKET: 1079 switch (name) { 1080 case SO_LINGER: 1081 print_linger(tcp, addr, len); 1082 goto done; 1083#ifdef SO_PEERCRED 1084 case SO_PEERCRED: 1085 print_ucred(tcp, addr, len); 1086 goto done; 1087#endif 1088 } 1089 break; 1090 1091 case SOL_PACKET: 1092 switch (name) { 1093#ifdef PACKET_STATISTICS 1094 case PACKET_STATISTICS: 1095 print_tpacket_stats(tcp, addr, len); 1096 goto done; 1097#endif 1098 } 1099 break; 1100 1101 case SOL_RAW: 1102 switch (name) { 1103 case ICMP_FILTER: 1104 print_icmp_filter(tcp, addr, len); 1105 goto done; 1106 } 1107 break; 1108 } 1109 1110 /* default arg printing */ 1111 1112 if (verbose(tcp)) { 1113 if (len == sizeof(int)) { 1114 printnum_int(tcp, addr, "%d"); 1115 } else { 1116 printstr(tcp, addr, len); 1117 } 1118 } else { 1119 printaddr(addr); 1120 } 1121done: 1122 tprintf(", [%d]", len); 1123} 1124 1125SYS_FUNC(getsockopt) 1126{ 1127 if (entering(tcp)) { 1128 print_sockopt_fd_level_name(tcp, tcp->u_arg[0], 1129 tcp->u_arg[1], tcp->u_arg[2], true); 1130 } else { 1131 int len; 1132 1133 if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &len) < 0) { 1134 printaddr(tcp->u_arg[3]); 1135 tprints(", "); 1136 printaddr(tcp->u_arg[4]); 1137 } else { 1138 print_getsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2], 1139 tcp->u_arg[3], len); 1140 } 1141 } 1142 return 0; 1143} 1144 1145#ifdef IP_ADD_MEMBERSHIP 1146static void 1147print_mreq(struct tcb *tcp, long addr, unsigned int len) 1148{ 1149 struct ip_mreq mreq; 1150 1151 if (len < sizeof(mreq)) { 1152 printstr(tcp, addr, len); 1153 return; 1154 } 1155 if (umove_or_printaddr(tcp, addr, &mreq)) 1156 return; 1157 1158 tprints("{imr_multiaddr=inet_addr("); 1159 print_quoted_string(inet_ntoa(mreq.imr_multiaddr), 1160 16, QUOTE_0_TERMINATED); 1161 tprints("), imr_interface=inet_addr("); 1162 print_quoted_string(inet_ntoa(mreq.imr_interface), 1163 16, QUOTE_0_TERMINATED); 1164 tprints(")}"); 1165} 1166#endif /* IP_ADD_MEMBERSHIP */ 1167 1168#ifdef IPV6_ADD_MEMBERSHIP 1169static void 1170print_mreq6(struct tcb *tcp, long addr, unsigned int len) 1171{ 1172 struct ipv6_mreq mreq; 1173 1174 if (len < sizeof(mreq)) 1175 goto fail; 1176 1177 if (umove_or_printaddr(tcp, addr, &mreq)) 1178 return; 1179 1180 const struct in6_addr *in6 = &mreq.ipv6mr_multiaddr; 1181 char address[INET6_ADDRSTRLEN]; 1182 1183 if (!inet_ntop(AF_INET6, in6, address, sizeof(address))) 1184 goto fail; 1185 1186 tprints("{ipv6mr_multiaddr=inet_pton("); 1187 print_quoted_string(address, sizeof(address), QUOTE_0_TERMINATED); 1188 tprints("), ipv6mr_interface="); 1189 print_ifindex(mreq.ipv6mr_interface); 1190 tprints("}"); 1191 return; 1192 1193fail: 1194 printstr(tcp, addr, len); 1195} 1196#endif /* IPV6_ADD_MEMBERSHIP */ 1197 1198#ifdef MCAST_JOIN_GROUP 1199static void 1200print_group_req(struct tcb *tcp, long addr, int len) 1201{ 1202 struct group_req greq; 1203 1204 if (len != sizeof(greq) || 1205 umove(tcp, addr, &greq) < 0) { 1206 printaddr(addr); 1207 return; 1208 } 1209 1210 tprintf("{gr_interface=%u, gr_group=", greq.gr_interface); 1211 print_sockaddr(tcp, &greq.gr_group, sizeof(greq.gr_group)); 1212 tprintf("}"); 1213 1214} 1215#endif /* MCAST_JOIN_GROUP */ 1216 1217#ifdef PACKET_RX_RING 1218static void 1219print_tpacket_req(struct tcb *tcp, long addr, int len) 1220{ 1221 struct tpacket_req req; 1222 1223 if (len != sizeof(req) || 1224 umove(tcp, addr, &req) < 0) { 1225 printaddr(addr); 1226 } else { 1227 tprintf("{block_size=%u, block_nr=%u, " 1228 "frame_size=%u, frame_nr=%u}", 1229 req.tp_block_size, 1230 req.tp_block_nr, 1231 req.tp_frame_size, 1232 req.tp_frame_nr); 1233 } 1234} 1235#endif /* PACKET_RX_RING */ 1236 1237#ifdef PACKET_ADD_MEMBERSHIP 1238# include "xlat/packet_mreq_type.h" 1239 1240static void 1241print_packet_mreq(struct tcb *tcp, long addr, int len) 1242{ 1243 struct packet_mreq mreq; 1244 1245 if (len != sizeof(mreq) || 1246 umove(tcp, addr, &mreq) < 0) { 1247 printaddr(addr); 1248 } else { 1249 unsigned int i; 1250 1251 tprintf("{mr_ifindex=%u, mr_type=", mreq.mr_ifindex); 1252 printxval(packet_mreq_type, mreq.mr_type, "PACKET_MR_???"); 1253 tprintf(", mr_alen=%u, mr_address=", mreq.mr_alen); 1254 if (mreq.mr_alen > ARRAY_SIZE(mreq.mr_address)) 1255 mreq.mr_alen = ARRAY_SIZE(mreq.mr_address); 1256 for (i = 0; i < mreq.mr_alen; ++i) 1257 tprintf("%02x", mreq.mr_address[i]); 1258 tprints("}"); 1259 } 1260} 1261#endif /* PACKET_ADD_MEMBERSHIP */ 1262 1263static void 1264print_setsockopt(struct tcb *tcp, unsigned int level, unsigned int name, 1265 long addr, int len) 1266{ 1267 if (addr && verbose(tcp)) 1268 switch (level) { 1269 case SOL_SOCKET: 1270 switch (name) { 1271 case SO_LINGER: 1272 print_linger(tcp, addr, len); 1273 goto done; 1274 } 1275 break; 1276 1277 case SOL_IP: 1278 switch (name) { 1279#ifdef IP_ADD_MEMBERSHIP 1280 case IP_ADD_MEMBERSHIP: 1281 case IP_DROP_MEMBERSHIP: 1282 print_mreq(tcp, addr, len); 1283 goto done; 1284#endif /* IP_ADD_MEMBERSHIP */ 1285#ifdef MCAST_JOIN_GROUP 1286 case MCAST_JOIN_GROUP: 1287 case MCAST_LEAVE_GROUP: 1288 print_group_req(tcp, addr, len); 1289 goto done; 1290#endif /* MCAST_JOIN_GROUP */ 1291 } 1292 break; 1293 1294 case SOL_IPV6: 1295 switch (name) { 1296#ifdef IPV6_ADD_MEMBERSHIP 1297 case IPV6_ADD_MEMBERSHIP: 1298 case IPV6_DROP_MEMBERSHIP: 1299# ifdef IPV6_JOIN_ANYCAST 1300 case IPV6_JOIN_ANYCAST: 1301# endif 1302# ifdef IPV6_LEAVE_ANYCAST 1303 case IPV6_LEAVE_ANYCAST: 1304# endif 1305 print_mreq6(tcp, addr, len); 1306 goto done; 1307#endif /* IPV6_ADD_MEMBERSHIP */ 1308 } 1309 break; 1310 1311 case SOL_PACKET: 1312 switch (name) { 1313#ifdef PACKET_RX_RING 1314 case PACKET_RX_RING: 1315# ifdef PACKET_TX_RING 1316 case PACKET_TX_RING: 1317# endif 1318 print_tpacket_req(tcp, addr, len); 1319 goto done; 1320#endif /* PACKET_RX_RING */ 1321#ifdef PACKET_ADD_MEMBERSHIP 1322 case PACKET_ADD_MEMBERSHIP: 1323 case PACKET_DROP_MEMBERSHIP: 1324 print_packet_mreq(tcp, addr, len); 1325 goto done; 1326#endif /* PACKET_ADD_MEMBERSHIP */ 1327 } 1328 break; 1329 1330 case SOL_RAW: 1331 switch (name) { 1332 case ICMP_FILTER: 1333 print_icmp_filter(tcp, addr, len); 1334 goto done; 1335 } 1336 break; 1337 } 1338 1339 /* default arg printing */ 1340 1341 if (verbose(tcp)) { 1342 if (len == sizeof(int)) { 1343 printnum_int(tcp, addr, "%d"); 1344 } else { 1345 printstr(tcp, addr, len); 1346 } 1347 } else { 1348 printaddr(addr); 1349 } 1350done: 1351 tprintf(", %d", len); 1352} 1353 1354SYS_FUNC(setsockopt) 1355{ 1356 print_sockopt_fd_level_name(tcp, tcp->u_arg[0], 1357 tcp->u_arg[1], tcp->u_arg[2], false); 1358 print_setsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2], 1359 tcp->u_arg[3], tcp->u_arg[4]); 1360 1361 return RVAL_DECODED; 1362} 1363