- tprints("sa_data=");
- print_quoted_string(addrbuf.sa.sa_data,
- sizeof(addrbuf.sa.sa_data), 0);
- break;
- }
- tprints("}");
-}
-
-#ifdef HAVE_SENDMSG
-# ifndef SCM_SECURITY
-# define SCM_SECURITY 0x03
-# endif
-# include "xlat/scmvals.h"
-
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
-struct cmsghdr32 {
- uint32_t cmsg_len;
- int cmsg_level;
- int cmsg_type;
-};
-#endif
-
-typedef union {
- char *ptr;
- struct cmsghdr *cmsg;
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
- struct cmsghdr32 *cmsg32;
-#endif
-} union_cmsghdr;
-
-static bool
-print_scm_rights(struct tcb *tcp, size_t cmsg_size, char *ptr, size_t cmsg_len)
-{
- if (cmsg_size + sizeof(int) > cmsg_len)
- return false;
-
- int *fds = (int *) (ptr + cmsg_size);
- bool seen = false;
-
- tprints(", [");
- while ((char *) fds < (ptr + cmsg_len)) {
- if (seen)
- tprints(", ");
- else
- seen = true;
- printfd(tcp, *fds++);
- }
- tprints("]}");
- return true;
-}
-
-static bool
-print_scm_creds(struct tcb *tcp, size_t cmsg_size, char *ptr, size_t cmsg_len)
-{
- if (cmsg_size + sizeof(struct ucred) > cmsg_len)
- return false;
-
- const struct ucred *uc = (void *) (ptr + cmsg_size);
-
- tprintf(", {pid=%u, uid=%u, gid=%u}}",
- (unsigned) uc->pid, (unsigned) uc->uid, (unsigned) uc->gid);
- return true;
-}
-
-static bool
-print_scm_security(struct tcb *tcp, size_t cmsg_size, char *ptr, size_t cmsg_len)
-{
- if (cmsg_size + sizeof(char) > cmsg_len)
- return false;
-
- const char *label = (const char *) (ptr + cmsg_size);
- const size_t label_len = cmsg_len - cmsg_size;
-
- tprints(", ");
- print_quoted_string(label, label_len, 0);
- tprints("}");
-
- return true;
-}
-
-static void
-printcmsghdr(struct tcb *tcp, unsigned long addr, size_t len)
-{
- const size_t cmsg_size =
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
- (current_wordsize < sizeof(long)) ? sizeof(struct cmsghdr32) :
-#endif
- sizeof(struct cmsghdr);
-
- char *buf = len < cmsg_size ? NULL : malloc(len);
- if (!buf || umoven(tcp, addr, len, buf) < 0) {
- tprints(", msg_control=");
- printaddr(addr);
- free(buf);
- return;
- }
-
- union_cmsghdr u = { .ptr = buf };
-
- tprints(", [");
- while (len >= cmsg_size) {
- size_t cmsg_len =
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
- (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_len :
-#endif
- u.cmsg->cmsg_len;
- int cmsg_level =
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
- (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_level :
-#endif
- u.cmsg->cmsg_level;
- int cmsg_type =
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
- (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_type :
-#endif
- u.cmsg->cmsg_type;
-
- if (u.ptr != buf)
- tprints(", ");
- tprintf("{cmsg_len=%lu, cmsg_level=", (unsigned long) cmsg_len);
- printxval(socketlayers, cmsg_level, "SOL_???");
- tprints(", cmsg_type=");
-
- if (cmsg_len > len)
- cmsg_len = len;
-
- if (cmsg_level == SOL_SOCKET) {
- printxval(scmvals, cmsg_type, "SCM_???");
- switch (cmsg_type) {
- case SCM_RIGHTS:
- if (print_scm_rights(tcp, cmsg_size, u.ptr, cmsg_len))
- goto next_cmsg;
- break;
- case SCM_CREDENTIALS:
- if (print_scm_creds(tcp, cmsg_size, u.ptr, cmsg_len))
- goto next_cmsg;
- break;
- case SCM_SECURITY:
- if (print_scm_security(tcp, cmsg_size, u.ptr, cmsg_len))
- goto next_cmsg;
- break;
- }
- } else {
- tprintf("%u", cmsg_type);
- }
- tprints(", ...}");
-next_cmsg:
- if (cmsg_len < cmsg_size) {
- len -= cmsg_size;
- break;
- }
- cmsg_len = (cmsg_len + current_wordsize - 1) &
- (size_t) ~(current_wordsize - 1);
- if (cmsg_len >= len) {
- len = 0;
- break;
- }
- u.ptr += cmsg_len;
- len -= cmsg_len;
- }
- if (len)
- tprints(", ...");
- tprints("]");
- free(buf);
-}
-
-static void
-do_msghdr(struct tcb *tcp, struct msghdr *msg, unsigned long data_size)
-{
- tprintf("{msg_name(%d)=", msg->msg_namelen);
- printsock(tcp, (long)msg->msg_name, msg->msg_namelen);
-
- tprintf(", msg_iov(%lu)=", (unsigned long)msg->msg_iovlen);
- tprint_iov_upto(tcp, (unsigned long)msg->msg_iovlen,
- (unsigned long)msg->msg_iov, 1, data_size);
-
-#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
- tprintf(", msg_controllen=%lu", (unsigned long)msg->msg_controllen);
- if (msg->msg_controllen)
- printcmsghdr(tcp, (unsigned long) msg->msg_control,
- msg->msg_controllen);
- tprints(", msg_flags=");
- printflags(msg_flags, msg->msg_flags, "MSG_???");
-#else /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
- tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
- (unsigned long) msg->msg_accrights, msg->msg_accrightslen);
-#endif /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
- tprints("}");
-}
-
-struct msghdr32 {
- uint32_t /* void* */ msg_name;
- uint32_t /* socklen_t */msg_namelen;
- uint32_t /* iovec* */ msg_iov;
- uint32_t /* size_t */ msg_iovlen;
- uint32_t /* void* */ msg_control;
- uint32_t /* size_t */ msg_controllen;
- uint32_t /* int */ msg_flags;
-};
-struct mmsghdr32 {
- struct msghdr32 msg_hdr;
- uint32_t /* unsigned */ msg_len;
-};
-
-#ifndef HAVE_STRUCT_MMSGHDR
-struct mmsghdr {
- struct msghdr msg_hdr;
- unsigned msg_len;
-};
-#endif
-
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
-static void
-copy_from_msghdr32(struct msghdr *to_msg, struct msghdr32 *from_msg32)
-{
- to_msg->msg_name = (void*)(long)from_msg32->msg_name;
- to_msg->msg_namelen = from_msg32->msg_namelen;
- to_msg->msg_iov = (void*)(long)from_msg32->msg_iov;
- to_msg->msg_iovlen = from_msg32->msg_iovlen;
- to_msg->msg_control = (void*)(long)from_msg32->msg_control;
- to_msg->msg_controllen = from_msg32->msg_controllen;
- to_msg->msg_flags = from_msg32->msg_flags;
-}
-#endif
-
-static bool
-extractmsghdr(struct tcb *tcp, long addr, struct msghdr *msg)
-{
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
- if (current_wordsize == 4) {
- struct msghdr32 msg32;
-
- if (umove(tcp, addr, &msg32) < 0)
- return false;
- copy_from_msghdr32(msg, &msg32);
- } else
-#endif
- if (umove(tcp, addr, msg) < 0)
- return false;
- return true;
-}
-
-static bool
-extractmmsghdr(struct tcb *tcp, long addr, unsigned int idx, struct mmsghdr *mmsg)
-{
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
- if (current_wordsize == 4) {
- struct mmsghdr32 mmsg32;
-
- addr += sizeof(struct mmsghdr32) * idx;
- if (umove(tcp, addr, &mmsg32) < 0)
- return false;
-
- copy_from_msghdr32(&mmsg->msg_hdr, &mmsg32.msg_hdr);
- mmsg->msg_len = mmsg32.msg_len;
- } else
-#endif
- {
- addr += sizeof(*mmsg) * idx;
- if (umove(tcp, addr, mmsg) < 0)
- return false;
- }
- return true;
-}
-
-static void
-printmsghdr(struct tcb *tcp, long addr, unsigned long data_size)
-{
- struct msghdr msg;
-
- if (verbose(tcp) && extractmsghdr(tcp, addr, &msg))
- do_msghdr(tcp, &msg, data_size);
- else
- printaddr(addr);
-}
-
-void
-dumpiov_in_msghdr(struct tcb *tcp, long addr)
-{
- struct msghdr msg;
-
- if (extractmsghdr(tcp, addr, &msg))
- dumpiov(tcp, msg.msg_iovlen, (long)msg.msg_iov);
-}
-
-static void
-printmmsghdr(struct tcb *tcp, long addr, unsigned int idx, unsigned long msg_len)
-{
- struct mmsghdr mmsg;
-
- if (extractmmsghdr(tcp, addr, idx, &mmsg)) {
- tprints("{");
- do_msghdr(tcp, &mmsg.msg_hdr, msg_len ? msg_len : mmsg.msg_len);
- tprintf(", %u}", mmsg.msg_len);
- }
- else
- printaddr(addr);
-}
-
-static void
-decode_mmsg(struct tcb *tcp, unsigned long msg_len)
-{
- /* mmsgvec */
- if (syserror(tcp)) {
- printaddr(tcp->u_arg[1]);
- } else {
- unsigned int len = tcp->u_rval;
- unsigned int i;
-
- tprints("{");
- for (i = 0; i < len; ++i) {
- if (i)
- tprints(", ");
- printmmsghdr(tcp, tcp->u_arg[1], i, msg_len);
- }
- tprints("}");