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