*/
#include "defs.h"
-#include "msghdr.h"
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include "xlat/socketlayers.h"
#include "xlat/inet_protocols.h"
-
-#if !defined NETLINK_SOCK_DIAG && defined NETLINK_INET_DIAG
-# define NETLINK_SOCK_DIAG NETLINK_INET_DIAG
-#endif
#include "xlat/netlink_protocols.h"
#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
}
static void
-decode_sockbuf(struct tcb *tcp, int fd, long addr, long addrlen)
+decode_sockbuf(struct tcb *const tcp, const int fd, const kernel_ureg_t addr,
+ const long addrlen)
{
switch (verbose(tcp) ? getfdproto(tcp, fd) : SOCK_PROTO_UNKNOWN) {
decode_netlink(tcp, addr, addrlen);
break;
default:
- printstr(tcp, addr, addrlen);
+ printstrn(tcp, addr, addrlen);
}
}
{
printfd(tcp, tcp->u_arg[0]);
tprints(", ");
- decode_sockaddr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
- tprintf(", %lu", tcp->u_arg[2]);
+ const int addrlen = tcp->u_arg[2];
+ decode_sockaddr(tcp, tcp->u_arg[1], addrlen);
+ tprintf(", %d", addrlen);
return RVAL_DECODED;
}
return RVAL_DECODED;
}
+static bool
+fetch_socklen(struct tcb *const tcp, int *const plen,
+ const kernel_ureg_t sockaddr, const kernel_ureg_t socklen)
+{
+ return verbose(tcp) && sockaddr && socklen
+ && umove(tcp, socklen, plen) == 0;
+}
+
static int
decode_sockname(struct tcb *tcp)
{
+ int ulen, rlen;
+
if (entering(tcp)) {
printfd(tcp, tcp->u_arg[0]);
tprints(", ");
- return 0;
+ if (fetch_socklen(tcp, &ulen, tcp->u_arg[1], tcp->u_arg[2])) {
+ set_tcb_priv_ulong(tcp, ulen);
+ return 0;
+ } else {
+ printaddr(tcp->u_arg[1]);
+ tprints(", ");
+ printaddr(tcp->u_arg[2]);
+ return RVAL_DECODED;
+ }
}
- int len;
- if (!tcp->u_arg[2] || !verbose(tcp) || syserror(tcp) ||
- umove(tcp, tcp->u_arg[2], &len) < 0) {
+ ulen = get_tcb_priv_ulong(tcp);
+
+ if (syserror(tcp) || umove(tcp, tcp->u_arg[2], &rlen) < 0) {
printaddr(tcp->u_arg[1]);
- tprints(", ");
- printaddr(tcp->u_arg[2]);
+ tprintf(", [%d]", ulen);
} else {
- decode_sockaddr(tcp, tcp->u_arg[1], len);
- tprintf(", [%d]", len);
+ decode_sockaddr(tcp, tcp->u_arg[1], ulen > rlen ? rlen : ulen);
+ if (ulen != rlen)
+ tprintf(", [%d->%d]", ulen, rlen);
+ else
+ tprintf(", [%d]", rlen);
}
return RVAL_DECODED;
/* flags */
printflags(msg_flags, tcp->u_arg[3], "MSG_???");
/* to address */
+ const int addrlen = tcp->u_arg[5];
tprints(", ");
- decode_sockaddr(tcp, tcp->u_arg[4], tcp->u_arg[5]);
+ decode_sockaddr(tcp, tcp->u_arg[4], addrlen);
/* to length */
- tprintf(", %lu", tcp->u_arg[5]);
-
- return RVAL_DECODED;
-}
-
-SYS_FUNC(sendmsg)
-{
- printfd(tcp, tcp->u_arg[0]);
- tprints(", ");
- decode_msghdr(tcp, tcp->u_arg[1], (unsigned long) -1L);
- /* flags */
- tprints(", ");
- printflags(msg_flags, tcp->u_arg[2], "MSG_???");
+ tprintf(", %d", addrlen);
return RVAL_DECODED;
}
-SYS_FUNC(sendmmsg)
-{
- if (entering(tcp)) {
- /* sockfd */
- printfd(tcp, tcp->u_arg[0]);
- tprints(", ");
- if (!verbose(tcp)) {
- printaddr(tcp->u_arg[1]);
- /* vlen */
- tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
- /* flags */
- printflags(msg_flags, tcp->u_arg[3], "MSG_???");
- return RVAL_DECODED;
- }
- } else {
- decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval, false);
- /* vlen */
- tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
- /* flags */
- printflags(msg_flags, tcp->u_arg[3], "MSG_???");
- }
- return 0;
-}
-
SYS_FUNC(recv)
{
if (entering(tcp)) {
SYS_FUNC(recvfrom)
{
- int fromlen;
+ int ulen, rlen;
if (entering(tcp)) {
printfd(tcp, tcp->u_arg[0]);
tprints(", ");
+ if (fetch_socklen(tcp, &ulen, tcp->u_arg[4], tcp->u_arg[5])) {
+ set_tcb_priv_ulong(tcp, ulen);
+ }
} else {
/* buf */
if (syserror(tcp)) {
decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
tcp->u_rval);
}
- /* len */
+ /* size */
tprintf(", %lu, ", tcp->u_arg[2]);
/* flags */
printflags(msg_flags, tcp->u_arg[3], "MSG_???");
tprints(", ");
- if (syserror(tcp) || !tcp->u_arg[4] || !tcp->u_arg[5] ||
- umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
- /* from address, len */
+
+ ulen = get_tcb_priv_ulong(tcp);
+
+ if (!fetch_socklen(tcp, &rlen, tcp->u_arg[4], tcp->u_arg[5])) {
+ /* from address */
printaddr(tcp->u_arg[4]);
tprints(", ");
+ /* from length */
printaddr(tcp->u_arg[5]);
return 0;
}
+ if (syserror(tcp)) {
+ /* from address */
+ printaddr(tcp->u_arg[4]);
+ /* from length */
+ tprintf(", [%d]", ulen);
+ return 0;
+ }
/* from address */
- decode_sockaddr(tcp, tcp->u_arg[4], fromlen);
+ decode_sockaddr(tcp, tcp->u_arg[4], ulen > rlen ? rlen : ulen);
/* from length */
- tprintf(", [%u]", fromlen);
- }
- return 0;
-}
-
-SYS_FUNC(recvmsg)
-{
- if (entering(tcp)) {
- printfd(tcp, tcp->u_arg[0]);
- tprints(", ");
- } else {
- if (syserror(tcp))
- printaddr(tcp->u_arg[1]);
+ if (ulen != rlen)
+ tprintf(", [%d->%d]", ulen, rlen);
else
- decode_msghdr(tcp, tcp->u_arg[1], tcp->u_rval);
- /* flags */
- tprints(", ");
- printflags(msg_flags, tcp->u_arg[2], "MSG_???");
+ tprintf(", [%d]", rlen);
}
return 0;
}
-SYS_FUNC(recvmmsg)
-{
- static char str[sizeof("left") + TIMESPEC_TEXT_BUFSIZE];
-
- if (entering(tcp)) {
- printfd(tcp, tcp->u_arg[0]);
- tprints(", ");
- if (verbose(tcp)) {
- /* Abusing tcp->auxstr as temp storage.
- * Will be used and cleared on syscall exit.
- */
- tcp->auxstr = sprint_timespec(tcp, tcp->u_arg[4]);
- } else {
- printaddr(tcp->u_arg[1]);
- /* vlen */
- tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
- /* flags */
- printflags(msg_flags, tcp->u_arg[3], "MSG_???");
- tprints(", ");
- print_timespec(tcp, tcp->u_arg[4]);
- }
- return 0;
- } else {
- if (verbose(tcp)) {
- decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval, true);
- /* vlen */
- tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
- /* flags */
- printflags(msg_flags, tcp->u_arg[3], "MSG_???");
- tprints(", ");
- /* timeout on entrance */
- tprints(tcp->auxstr);
- tcp->auxstr = NULL;
- }
- if (syserror(tcp))
- return 0;
- if (tcp->u_rval == 0) {
- tcp->auxstr = "Timeout";
- return RVAL_STR;
- }
- if (!verbose(tcp))
- return 0;
- /* timeout on exit */
- snprintf(str, sizeof(str), "left %s",
- sprint_timespec(tcp, tcp->u_arg[4]));
- tcp->auxstr = str;
- return RVAL_STR;
- }
-}
-
#include "xlat/shutdown_modes.h"
SYS_FUNC(shutdown)
}
static void
-decode_pair_fd(struct tcb *tcp, const long addr)
+decode_pair_fd(struct tcb *const tcp, const kernel_ureg_t addr)
{
int pair[2];
}
static void
-print_linger(struct tcb *tcp, long addr, int len)
+print_linger(struct tcb *const tcp, const kernel_ureg_t addr, const int len)
{
struct linger linger;
#ifdef SO_PEERCRED
static void
-print_ucred(struct tcb *tcp, long addr, int len)
+print_ucred(struct tcb *const tcp, const kernel_ureg_t addr, const int len)
{
struct ucred uc;
#ifdef PACKET_STATISTICS
static void
-print_tpacket_stats(struct tcb *tcp, long addr, int len)
+print_tpacket_stats(struct tcb *const tcp, const kernel_ureg_t addr,
+ const int len)
{
struct tpacket_stats stats;
#include "xlat/icmpfilterflags.h"
static void
-print_icmp_filter(struct tcb *tcp, const long addr, int len)
+print_icmp_filter(struct tcb *const tcp, const kernel_ureg_t addr, int len)
{
struct icmp_filter filter = {};
}
static void
-print_getsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
- long addr, int len)
+print_getsockopt(struct tcb *const tcp, const unsigned int level,
+ const unsigned int name, const kernel_ureg_t addr,
+ const int len)
{
if (addr && verbose(tcp))
switch (level) {
if (len == sizeof(int)) {
printnum_int(tcp, addr, "%d");
} else {
- printstr(tcp, addr, len);
+ printstrn(tcp, addr, len);
}
} else {
printaddr(addr);
#ifdef IP_ADD_MEMBERSHIP
static void
-print_mreq(struct tcb *tcp, long addr, unsigned int len)
+print_mreq(struct tcb *const tcp, const kernel_ureg_t addr,
+ const unsigned int len)
{
struct ip_mreq mreq;
if (len < sizeof(mreq)) {
- printstr(tcp, addr, len);
+ printstrn(tcp, addr, len);
return;
}
if (umove_or_printaddr(tcp, addr, &mreq))
#ifdef IPV6_ADD_MEMBERSHIP
static void
-print_mreq6(struct tcb *tcp, long addr, unsigned int len)
+print_mreq6(struct tcb *const tcp, const kernel_ureg_t addr,
+ const unsigned int len)
{
struct ipv6_mreq mreq;
return;
fail:
- printstr(tcp, addr, len);
+ printstrn(tcp, addr, len);
}
#endif /* IPV6_ADD_MEMBERSHIP */
#ifdef MCAST_JOIN_GROUP
static void
-print_group_req(struct tcb *tcp, long addr, int len)
+print_group_req(struct tcb *const tcp, const kernel_ureg_t addr, const int len)
{
struct group_req greq;
tprintf("{gr_interface=%u, gr_group=", greq.gr_interface);
print_sockaddr(tcp, &greq.gr_group, sizeof(greq.gr_group));
- tprintf("}");
+ tprints("}");
}
#endif /* MCAST_JOIN_GROUP */
#ifdef PACKET_RX_RING
static void
-print_tpacket_req(struct tcb *tcp, long addr, int len)
+print_tpacket_req(struct tcb *const tcp, const kernel_ureg_t addr, const int len)
{
struct tpacket_req req;
# include "xlat/packet_mreq_type.h"
static void
-print_packet_mreq(struct tcb *tcp, long addr, int len)
+print_packet_mreq(struct tcb *const tcp, const kernel_ureg_t addr, const int len)
{
struct packet_mreq mreq;
#endif /* PACKET_ADD_MEMBERSHIP */
static void
-print_setsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
- long addr, int len)
+print_setsockopt(struct tcb *const tcp, const unsigned int level,
+ const unsigned int name, const kernel_ureg_t addr,
+ const int len)
{
if (addr && verbose(tcp))
switch (level) {
if (len == sizeof(int)) {
printnum_int(tcp, addr, "%d");
} else {
- printstr(tcp, addr, len);
+ printstrn(tcp, addr, len);
}
} else {
printaddr(addr);