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