MFC r328015:
Decode msghdr argument of sendmsg() and recvmsg().
This commit is contained in:
parent
ecccab8667
commit
f4f87ff118
@ -81,7 +81,7 @@ enum Argtype { None = 1, Hex, Octal, Int, UInt, LongHex, Name, Ptr, Stat, Ioctl,
|
|||||||
Sockoptname, Msgflags, CapRights, PUInt, PQuadHex, Acltype,
|
Sockoptname, Msgflags, CapRights, PUInt, PQuadHex, Acltype,
|
||||||
Extattrnamespace, Minherit, Mlockall, Mountflags, Msync, Priowhich,
|
Extattrnamespace, Minherit, Mlockall, Mountflags, Msync, Priowhich,
|
||||||
Ptraceop, Quotactlcmd, Reboothowto, Rtpriofunc, Schedpolicy, Schedparam,
|
Ptraceop, Quotactlcmd, Reboothowto, Rtpriofunc, Schedpolicy, Schedparam,
|
||||||
PSig, Siginfo, Kevent11, Iovec, Sctpsndrcvinfo,
|
PSig, Siginfo, Kevent11, Iovec, Sctpsndrcvinfo, Msghdr,
|
||||||
|
|
||||||
CloudABIAdvice, CloudABIClockID, ClouduABIFDSFlags,
|
CloudABIAdvice, CloudABIClockID, ClouduABIFDSFlags,
|
||||||
CloudABIFDStat, CloudABIFileStat, CloudABIFileType,
|
CloudABIFDStat, CloudABIFileStat, CloudABIFileType,
|
||||||
|
@ -385,7 +385,7 @@ static struct syscall decoded_syscalls[] = {
|
|||||||
{ Msgflags, 3 }, { Sockaddr | OUT, 4 },
|
{ Msgflags, 3 }, { Sockaddr | OUT, 4 },
|
||||||
{ Ptr | OUT, 5 } } },
|
{ Ptr | OUT, 5 } } },
|
||||||
{ .name = "recvmsg", .ret_type = 1, .nargs = 3,
|
{ .name = "recvmsg", .ret_type = 1, .nargs = 3,
|
||||||
.args = { { Int, 0 }, { Ptr, 1 }, { Msgflags, 2 } } },
|
.args = { { Int, 0 }, { Msghdr | OUT, 1 }, { Msgflags, 2 } } },
|
||||||
{ .name = "rename", .ret_type = 1, .nargs = 2,
|
{ .name = "rename", .ret_type = 1, .nargs = 2,
|
||||||
.args = { { Name, 0 }, { Name, 1 } } },
|
.args = { { Name, 0 }, { Name, 1 } } },
|
||||||
{ .name = "renameat", .ret_type = 1, .nargs = 4,
|
{ .name = "renameat", .ret_type = 1, .nargs = 4,
|
||||||
@ -428,7 +428,7 @@ static struct syscall decoded_syscalls[] = {
|
|||||||
.args = { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 },
|
.args = { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 },
|
||||||
{ Timeval, 4 } } },
|
{ Timeval, 4 } } },
|
||||||
{ .name = "sendmsg", .ret_type = 1, .nargs = 3,
|
{ .name = "sendmsg", .ret_type = 1, .nargs = 3,
|
||||||
.args = { { Int, 0 }, { Ptr, 1 }, { Msgflags, 2 } } },
|
.args = { { Int, 0 }, { Msghdr | IN, 1 }, { Msgflags, 2 } } },
|
||||||
{ .name = "sendto", .ret_type = 1, .nargs = 6,
|
{ .name = "sendto", .ret_type = 1, .nargs = 6,
|
||||||
.args = { { Int, 0 }, { BinString | IN, 1 }, { Sizet, 2 },
|
.args = { { Int, 0 }, { BinString | IN, 1 }, { Sizet, 2 },
|
||||||
{ Msgflags, 3 }, { Sockaddr | IN, 4 },
|
{ Msgflags, 3 }, { Sockaddr | IN, 4 },
|
||||||
@ -1142,6 +1142,378 @@ print_utrace(FILE *fp, void *utrace_addr, size_t len)
|
|||||||
fprintf(fp, " }");
|
fprintf(fp, " }");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_sockaddr(FILE *fp, struct trussinfo *trussinfo, void *arg, socklen_t len)
|
||||||
|
{
|
||||||
|
char addr[64];
|
||||||
|
struct sockaddr_in *lsin;
|
||||||
|
struct sockaddr_in6 *lsin6;
|
||||||
|
struct sockaddr_un *sun;
|
||||||
|
struct sockaddr *sa;
|
||||||
|
u_char *q;
|
||||||
|
pid_t pid = trussinfo->curthread->proc->pid;
|
||||||
|
|
||||||
|
if (arg == NULL) {
|
||||||
|
fputs("NULL", fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* If the length is too small, just bail. */
|
||||||
|
if (len < sizeof(*sa)) {
|
||||||
|
fprintf(fp, "0x%p", arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sa = calloc(1, len);
|
||||||
|
if (get_struct(pid, arg, sa, len) == -1) {
|
||||||
|
free(sa);
|
||||||
|
fprintf(fp, "0x%p", arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (sa->sa_family) {
|
||||||
|
case AF_INET:
|
||||||
|
if (len < sizeof(*lsin))
|
||||||
|
goto sockaddr_short;
|
||||||
|
lsin = (struct sockaddr_in *)(void *)sa;
|
||||||
|
inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof(addr));
|
||||||
|
fprintf(fp, "{ AF_INET %s:%d }", addr,
|
||||||
|
htons(lsin->sin_port));
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
if (len < sizeof(*lsin6))
|
||||||
|
goto sockaddr_short;
|
||||||
|
lsin6 = (struct sockaddr_in6 *)(void *)sa;
|
||||||
|
inet_ntop(AF_INET6, &lsin6->sin6_addr, addr,
|
||||||
|
sizeof(addr));
|
||||||
|
fprintf(fp, "{ AF_INET6 [%s]:%d }", addr,
|
||||||
|
htons(lsin6->sin6_port));
|
||||||
|
break;
|
||||||
|
case AF_UNIX:
|
||||||
|
sun = (struct sockaddr_un *)sa;
|
||||||
|
fprintf(fp, "{ AF_UNIX \"%.*s\" }",
|
||||||
|
(int)(len - offsetof(struct sockaddr_un, sun_path)),
|
||||||
|
sun->sun_path);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sockaddr_short:
|
||||||
|
fprintf(fp,
|
||||||
|
"{ sa_len = %d, sa_family = %d, sa_data = {",
|
||||||
|
(int)sa->sa_len, (int)sa->sa_family);
|
||||||
|
for (q = (u_char *)sa->sa_data;
|
||||||
|
q < (u_char *)sa + len; q++)
|
||||||
|
fprintf(fp, "%s 0x%02x",
|
||||||
|
q == (u_char *)sa->sa_data ? "" : ",",
|
||||||
|
*q);
|
||||||
|
fputs(" } }", fp);
|
||||||
|
}
|
||||||
|
free(sa);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IOV_LIMIT 16
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_iovec(FILE *fp, struct trussinfo *trussinfo, void *arg, int iovcnt)
|
||||||
|
{
|
||||||
|
struct iovec iov[IOV_LIMIT];
|
||||||
|
size_t max_string = trussinfo->strsize;
|
||||||
|
char tmp2[max_string + 1], *tmp3;
|
||||||
|
size_t len;
|
||||||
|
pid_t pid = trussinfo->curthread->proc->pid;
|
||||||
|
int i;
|
||||||
|
bool buf_truncated, iov_truncated;
|
||||||
|
|
||||||
|
if (iovcnt <= 0) {
|
||||||
|
fprintf(fp, "0x%p", arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (iovcnt > IOV_LIMIT) {
|
||||||
|
iovcnt = IOV_LIMIT;
|
||||||
|
iov_truncated = true;
|
||||||
|
} else {
|
||||||
|
iov_truncated = false;
|
||||||
|
}
|
||||||
|
if (get_struct(pid, arg, &iov, iovcnt * sizeof(struct iovec)) == -1) {
|
||||||
|
fprintf(fp, "0x%p", arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs("[", fp);
|
||||||
|
for (i = 0; i < iovcnt; i++) {
|
||||||
|
len = iov[i].iov_len;
|
||||||
|
if (len > max_string) {
|
||||||
|
len = max_string;
|
||||||
|
buf_truncated = true;
|
||||||
|
} else {
|
||||||
|
buf_truncated = false;
|
||||||
|
}
|
||||||
|
fprintf(fp, "%s{", (i > 0) ? "," : "");
|
||||||
|
if (len && get_struct(pid, iov[i].iov_base, &tmp2, len) != -1) {
|
||||||
|
tmp3 = malloc(len * 4 + 1);
|
||||||
|
while (len) {
|
||||||
|
if (strvisx(tmp3, tmp2, len,
|
||||||
|
VIS_CSTYLE|VIS_TAB|VIS_NL) <=
|
||||||
|
(int)max_string)
|
||||||
|
break;
|
||||||
|
len--;
|
||||||
|
buf_truncated = true;
|
||||||
|
}
|
||||||
|
fprintf(fp, "\"%s\"%s", tmp3,
|
||||||
|
buf_truncated ? "..." : "");
|
||||||
|
free(tmp3);
|
||||||
|
} else {
|
||||||
|
fprintf(fp, "0x%p", iov[i].iov_base);
|
||||||
|
}
|
||||||
|
fprintf(fp, ",%zu}", iov[i].iov_len);
|
||||||
|
}
|
||||||
|
fprintf(fp, "%s%s", iov_truncated ? ",..." : "", "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_gen_cmsg(FILE *fp, struct cmsghdr *cmsghdr)
|
||||||
|
{
|
||||||
|
u_char *q;
|
||||||
|
|
||||||
|
fputs("{", fp);
|
||||||
|
for (q = CMSG_DATA(cmsghdr);
|
||||||
|
q < (u_char *)cmsghdr + cmsghdr->cmsg_len; q++) {
|
||||||
|
fprintf(fp, "%s0x%02x", q == CMSG_DATA(cmsghdr) ? "" : ",", *q);
|
||||||
|
}
|
||||||
|
fputs("}", fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_sctp_initmsg(FILE *fp, struct sctp_initmsg *init)
|
||||||
|
{
|
||||||
|
fprintf(fp, "{out=%u,", init->sinit_num_ostreams);
|
||||||
|
fprintf(fp, "in=%u,", init->sinit_max_instreams);
|
||||||
|
fprintf(fp, "max_rtx=%u,", init->sinit_max_attempts);
|
||||||
|
fprintf(fp, "max_rto=%u}", init->sinit_max_init_timeo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_sctp_sndrcvinfo(FILE *fp, bool recv, struct sctp_sndrcvinfo *info)
|
||||||
|
{
|
||||||
|
fprintf(fp, "{sid=%u,", info->sinfo_stream);
|
||||||
|
if (recv) {
|
||||||
|
fprintf(fp, "ssn=%u,", info->sinfo_ssn);
|
||||||
|
}
|
||||||
|
fputs("flgs=", fp);
|
||||||
|
sysdecode_sctp_sinfo_flags(fp, info->sinfo_flags);
|
||||||
|
fprintf(fp, ",ppid=%u,", ntohl(info->sinfo_ppid));
|
||||||
|
if (!recv) {
|
||||||
|
fprintf(fp, "ctx=%u,", info->sinfo_context);
|
||||||
|
fprintf(fp, "ttl=%u,", info->sinfo_timetolive);
|
||||||
|
}
|
||||||
|
if (recv) {
|
||||||
|
fprintf(fp, "tsn=%u,", info->sinfo_tsn);
|
||||||
|
fprintf(fp, "cumtsn=%u,", info->sinfo_cumtsn);
|
||||||
|
}
|
||||||
|
fprintf(fp, "id=%u}", info->sinfo_assoc_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_sctp_sndinfo(FILE *fp, struct sctp_sndinfo *info)
|
||||||
|
{
|
||||||
|
fprintf(fp, "{sid=%u,", info->snd_sid);
|
||||||
|
fputs("flgs=", fp);
|
||||||
|
print_mask_arg(sysdecode_sctp_snd_flags, fp, info->snd_flags);
|
||||||
|
fprintf(fp, ",ppid=%u,", ntohl(info->snd_ppid));
|
||||||
|
fprintf(fp, "ctx=%u,", info->snd_context);
|
||||||
|
fprintf(fp, "id=%u}", info->snd_assoc_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_sctp_rcvinfo(FILE *fp, struct sctp_rcvinfo *info)
|
||||||
|
{
|
||||||
|
fprintf(fp, "{sid=%u,", info->rcv_sid);
|
||||||
|
fprintf(fp, "ssn=%u,", info->rcv_ssn);
|
||||||
|
fputs("flgs=", fp);
|
||||||
|
print_mask_arg(sysdecode_sctp_rcv_flags, fp, info->rcv_flags);
|
||||||
|
fprintf(fp, ",ppid=%u,", ntohl(info->rcv_ppid));
|
||||||
|
fprintf(fp, "tsn=%u,", info->rcv_tsn);
|
||||||
|
fprintf(fp, "cumtsn=%u,", info->rcv_cumtsn);
|
||||||
|
fprintf(fp, "ctx=%u,", info->rcv_context);
|
||||||
|
fprintf(fp, "id=%u}", info->rcv_assoc_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_sctp_nxtinfo(FILE *fp, struct sctp_nxtinfo *info)
|
||||||
|
{
|
||||||
|
fprintf(fp, "{sid=%u,", info->nxt_sid);
|
||||||
|
fputs("flgs=", fp);
|
||||||
|
print_mask_arg(sysdecode_sctp_nxt_flags, fp, info->nxt_flags);
|
||||||
|
fprintf(fp, ",ppid=%u,", ntohl(info->nxt_ppid));
|
||||||
|
fprintf(fp, "len=%u,", info->nxt_length);
|
||||||
|
fprintf(fp, "id=%u}", info->nxt_assoc_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_sctp_prinfo(FILE *fp, struct sctp_prinfo *info)
|
||||||
|
{
|
||||||
|
fputs("{pol=", fp);
|
||||||
|
print_integer_arg(sysdecode_sctp_pr_policy, fp, info->pr_policy);
|
||||||
|
fprintf(fp, ",val=%u}", info->pr_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_sctp_authinfo(FILE *fp, struct sctp_authinfo *info)
|
||||||
|
{
|
||||||
|
fprintf(fp, "{num=%u}", info->auth_keynumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_sctp_ipv4_addr(FILE *fp, struct in_addr *addr)
|
||||||
|
{
|
||||||
|
char buf[INET_ADDRSTRLEN];
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
s = inet_ntop(AF_INET, addr, buf, INET_ADDRSTRLEN);
|
||||||
|
if (s != NULL)
|
||||||
|
fprintf(fp, "{addr=%s}", s);
|
||||||
|
else
|
||||||
|
fputs("{addr=???}", fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_sctp_ipv6_addr(FILE *fp, struct in6_addr *addr)
|
||||||
|
{
|
||||||
|
char buf[INET6_ADDRSTRLEN];
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
s = inet_ntop(AF_INET6, addr, buf, INET6_ADDRSTRLEN);
|
||||||
|
if (s != NULL)
|
||||||
|
fprintf(fp, "{addr=%s}", s);
|
||||||
|
else
|
||||||
|
fputs("{addr=???}", fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_sctp_cmsg(FILE *fp, bool recv, struct cmsghdr *cmsghdr)
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
socklen_t len;
|
||||||
|
|
||||||
|
len = cmsghdr->cmsg_len;
|
||||||
|
data = CMSG_DATA(cmsghdr);
|
||||||
|
switch (cmsghdr->cmsg_type) {
|
||||||
|
case SCTP_INIT:
|
||||||
|
if (len == CMSG_LEN(sizeof(struct sctp_initmsg)))
|
||||||
|
print_sctp_initmsg(fp, (struct sctp_initmsg *)data);
|
||||||
|
else
|
||||||
|
print_gen_cmsg(fp, cmsghdr);
|
||||||
|
break;
|
||||||
|
case SCTP_SNDRCV:
|
||||||
|
if (len == CMSG_LEN(sizeof(struct sctp_sndrcvinfo)))
|
||||||
|
print_sctp_sndrcvinfo(fp, recv,
|
||||||
|
(struct sctp_sndrcvinfo *)data);
|
||||||
|
else
|
||||||
|
print_gen_cmsg(fp, cmsghdr);
|
||||||
|
break;
|
||||||
|
#if 0
|
||||||
|
case SCTP_EXTRCV:
|
||||||
|
if (len == CMSG_LEN(sizeof(struct sctp_extrcvinfo)))
|
||||||
|
print_sctp_extrcvinfo(fp,
|
||||||
|
(struct sctp_extrcvinfo *)data);
|
||||||
|
else
|
||||||
|
print_gen_cmsg(fp, cmsghdr);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case SCTP_SNDINFO:
|
||||||
|
if (len == CMSG_LEN(sizeof(struct sctp_sndinfo)))
|
||||||
|
print_sctp_sndinfo(fp, (struct sctp_sndinfo *)data);
|
||||||
|
else
|
||||||
|
print_gen_cmsg(fp, cmsghdr);
|
||||||
|
break;
|
||||||
|
case SCTP_RCVINFO:
|
||||||
|
if (len == CMSG_LEN(sizeof(struct sctp_rcvinfo)))
|
||||||
|
print_sctp_rcvinfo(fp, (struct sctp_rcvinfo *)data);
|
||||||
|
else
|
||||||
|
print_gen_cmsg(fp, cmsghdr);
|
||||||
|
break;
|
||||||
|
case SCTP_NXTINFO:
|
||||||
|
if (len == CMSG_LEN(sizeof(struct sctp_nxtinfo)))
|
||||||
|
print_sctp_nxtinfo(fp, (struct sctp_nxtinfo *)data);
|
||||||
|
else
|
||||||
|
print_gen_cmsg(fp, cmsghdr);
|
||||||
|
break;
|
||||||
|
case SCTP_PRINFO:
|
||||||
|
if (len == CMSG_LEN(sizeof(struct sctp_prinfo)))
|
||||||
|
print_sctp_prinfo(fp, (struct sctp_prinfo *)data);
|
||||||
|
else
|
||||||
|
print_gen_cmsg(fp, cmsghdr);
|
||||||
|
break;
|
||||||
|
case SCTP_AUTHINFO:
|
||||||
|
if (len == CMSG_LEN(sizeof(struct sctp_authinfo)))
|
||||||
|
print_sctp_authinfo(fp, (struct sctp_authinfo *)data);
|
||||||
|
else
|
||||||
|
print_gen_cmsg(fp, cmsghdr);
|
||||||
|
break;
|
||||||
|
case SCTP_DSTADDRV4:
|
||||||
|
if (len == CMSG_LEN(sizeof(struct in_addr)))
|
||||||
|
print_sctp_ipv4_addr(fp, (struct in_addr *)data);
|
||||||
|
else
|
||||||
|
print_gen_cmsg(fp, cmsghdr);
|
||||||
|
break;
|
||||||
|
case SCTP_DSTADDRV6:
|
||||||
|
if (len == CMSG_LEN(sizeof(struct in6_addr)))
|
||||||
|
print_sctp_ipv6_addr(fp, (struct in6_addr *)data);
|
||||||
|
else
|
||||||
|
print_gen_cmsg(fp, cmsghdr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_gen_cmsg(fp, cmsghdr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_cmsgs(FILE *fp, pid_t pid, bool recv, struct msghdr *msghdr)
|
||||||
|
{
|
||||||
|
struct cmsghdr *cmsghdr;
|
||||||
|
char *cmsgbuf;
|
||||||
|
const char *temp;
|
||||||
|
socklen_t len;
|
||||||
|
int level, type;
|
||||||
|
bool first;
|
||||||
|
|
||||||
|
len = msghdr->msg_controllen;
|
||||||
|
cmsgbuf = calloc(1, len);
|
||||||
|
if (get_struct(pid, msghdr->msg_control, cmsgbuf, len) == -1) {
|
||||||
|
fprintf(fp, "0x%p", msghdr);
|
||||||
|
free(cmsgbuf);
|
||||||
|
}
|
||||||
|
msghdr->msg_control = cmsgbuf;
|
||||||
|
first = true;
|
||||||
|
fputs("{", fp);
|
||||||
|
for (cmsghdr = CMSG_FIRSTHDR(msghdr);
|
||||||
|
cmsghdr != NULL;
|
||||||
|
cmsghdr = CMSG_NXTHDR(msghdr, cmsghdr)) {
|
||||||
|
level = cmsghdr->cmsg_level;
|
||||||
|
type = cmsghdr->cmsg_type;
|
||||||
|
len = cmsghdr->cmsg_len;
|
||||||
|
fprintf(fp, "%s{level=", first ? "" : ",");
|
||||||
|
print_integer_arg(sysdecode_sockopt_level, fp, level);
|
||||||
|
fputs(",type=", fp);
|
||||||
|
temp = sysdecode_cmsg_type(level, type);
|
||||||
|
if (temp) {
|
||||||
|
fputs(temp, fp);
|
||||||
|
} else {
|
||||||
|
fprintf(fp, "%d", type);
|
||||||
|
}
|
||||||
|
fputs(",data=", fp);
|
||||||
|
switch (level) {
|
||||||
|
case IPPROTO_SCTP:
|
||||||
|
print_sctp_cmsg(fp, recv, cmsghdr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_gen_cmsg(fp, cmsghdr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fputs("}", fp);
|
||||||
|
}
|
||||||
|
fputs("}", fp);
|
||||||
|
free(cmsgbuf);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Converts a syscall argument into a string. Said string is
|
* Converts a syscall argument into a string. Said string is
|
||||||
* allocated via malloc(), so needs to be free()'d. sc is
|
* allocated via malloc(), so needs to be free()'d. sc is
|
||||||
@ -1596,13 +1968,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long *retval,
|
|||||||
print_mask_arg(sysdecode_rfork_flags, fp, args[sc->offset]);
|
print_mask_arg(sysdecode_rfork_flags, fp, args[sc->offset]);
|
||||||
break;
|
break;
|
||||||
case Sockaddr: {
|
case Sockaddr: {
|
||||||
char addr[64];
|
|
||||||
struct sockaddr_in *lsin;
|
|
||||||
struct sockaddr_in6 *lsin6;
|
|
||||||
struct sockaddr_un *sun;
|
|
||||||
struct sockaddr *sa;
|
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
u_char *q;
|
|
||||||
|
|
||||||
if (args[sc->offset] == 0) {
|
if (args[sc->offset] == 0) {
|
||||||
fputs("NULL", fp);
|
fputs("NULL", fp);
|
||||||
@ -1624,56 +1990,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long *retval,
|
|||||||
} else
|
} else
|
||||||
len = args[sc->offset + 1];
|
len = args[sc->offset + 1];
|
||||||
|
|
||||||
/* If the length is too small, just bail. */
|
print_sockaddr(fp, trussinfo, (void *)args[sc->offset], len);
|
||||||
if (len < sizeof(*sa)) {
|
|
||||||
fprintf(fp, "0x%lx", args[sc->offset]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sa = calloc(1, len);
|
|
||||||
if (get_struct(pid, (void *)args[sc->offset], sa, len) == -1) {
|
|
||||||
free(sa);
|
|
||||||
fprintf(fp, "0x%lx", args[sc->offset]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (sa->sa_family) {
|
|
||||||
case AF_INET:
|
|
||||||
if (len < sizeof(*lsin))
|
|
||||||
goto sockaddr_short;
|
|
||||||
lsin = (struct sockaddr_in *)(void *)sa;
|
|
||||||
inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof(addr));
|
|
||||||
fprintf(fp, "{ AF_INET %s:%d }", addr,
|
|
||||||
htons(lsin->sin_port));
|
|
||||||
break;
|
|
||||||
case AF_INET6:
|
|
||||||
if (len < sizeof(*lsin6))
|
|
||||||
goto sockaddr_short;
|
|
||||||
lsin6 = (struct sockaddr_in6 *)(void *)sa;
|
|
||||||
inet_ntop(AF_INET6, &lsin6->sin6_addr, addr,
|
|
||||||
sizeof(addr));
|
|
||||||
fprintf(fp, "{ AF_INET6 [%s]:%d }", addr,
|
|
||||||
htons(lsin6->sin6_port));
|
|
||||||
break;
|
|
||||||
case AF_UNIX:
|
|
||||||
sun = (struct sockaddr_un *)sa;
|
|
||||||
fprintf(fp, "{ AF_UNIX \"%.*s\" }",
|
|
||||||
(int)(len - offsetof(struct sockaddr_un, sun_path)),
|
|
||||||
sun->sun_path);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sockaddr_short:
|
|
||||||
fprintf(fp,
|
|
||||||
"{ sa_len = %d, sa_family = %d, sa_data = {",
|
|
||||||
(int)sa->sa_len, (int)sa->sa_family);
|
|
||||||
for (q = (u_char *)sa->sa_data;
|
|
||||||
q < (u_char *)sa + len; q++)
|
|
||||||
fprintf(fp, "%s 0x%02x",
|
|
||||||
q == (u_char *)sa->sa_data ? "" : ",",
|
|
||||||
*q);
|
|
||||||
fputs(" } }", fp);
|
|
||||||
}
|
|
||||||
free(sa);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Sigaction: {
|
case Sigaction: {
|
||||||
@ -2073,68 +2390,15 @@ print_arg(struct syscall_args *sc, unsigned long *args, long *retval,
|
|||||||
fprintf(fp, "0x%lx", args[sc->offset]);
|
fprintf(fp, "0x%lx", args[sc->offset]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#define IOV_LIMIT 16
|
case Iovec:
|
||||||
case Iovec: {
|
|
||||||
/*
|
/*
|
||||||
* Print argument as an array of struct iovec, where the next
|
* Print argument as an array of struct iovec, where the next
|
||||||
* syscall argument is the number of elements of the array.
|
* syscall argument is the number of elements of the array.
|
||||||
*/
|
*/
|
||||||
struct iovec iov[IOV_LIMIT];
|
|
||||||
size_t max_string = trussinfo->strsize;
|
|
||||||
char tmp2[max_string + 1], *tmp3;
|
|
||||||
size_t len;
|
|
||||||
int i, iovcnt;
|
|
||||||
bool buf_truncated, iov_truncated;
|
|
||||||
|
|
||||||
iovcnt = args[sc->offset + 1];
|
print_iovec(fp, trussinfo, (void *)args[sc->offset],
|
||||||
if (iovcnt <= 0) {
|
(int)args[sc->offset + 1]);
|
||||||
fprintf(fp, "0x%lx", args[sc->offset]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (iovcnt > IOV_LIMIT) {
|
|
||||||
iovcnt = IOV_LIMIT;
|
|
||||||
iov_truncated = true;
|
|
||||||
} else {
|
|
||||||
iov_truncated = false;
|
|
||||||
}
|
|
||||||
if (get_struct(pid, (void *)args[sc->offset],
|
|
||||||
&iov, iovcnt * sizeof(struct iovec)) == -1) {
|
|
||||||
fprintf(fp, "0x%lx", args[sc->offset]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(fp, "%s", "[");
|
|
||||||
for (i = 0; i < iovcnt; i++) {
|
|
||||||
len = iov[i].iov_len;
|
|
||||||
if (len > max_string) {
|
|
||||||
len = max_string;
|
|
||||||
buf_truncated = true;
|
|
||||||
} else {
|
|
||||||
buf_truncated = false;
|
|
||||||
}
|
|
||||||
fprintf(fp, "%s{", (i > 0) ? "," : "");
|
|
||||||
if (len && get_struct(pid, iov[i].iov_base, &tmp2, len)
|
|
||||||
!= -1) {
|
|
||||||
tmp3 = malloc(len * 4 + 1);
|
|
||||||
while (len) {
|
|
||||||
if (strvisx(tmp3, tmp2, len,
|
|
||||||
VIS_CSTYLE|VIS_TAB|VIS_NL) <=
|
|
||||||
(int)max_string)
|
|
||||||
break;
|
|
||||||
len--;
|
|
||||||
buf_truncated = true;
|
|
||||||
}
|
|
||||||
fprintf(fp, "\"%s\"%s", tmp3,
|
|
||||||
buf_truncated ? "..." : "");
|
|
||||||
free(tmp3);
|
|
||||||
} else {
|
|
||||||
fprintf(fp, "0x%p", iov[i].iov_base);
|
|
||||||
}
|
|
||||||
fprintf(fp, ",%zu}", iov[i].iov_len);
|
|
||||||
}
|
|
||||||
fprintf(fp, "%s%s", iov_truncated ? ",..." : "", "]");
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case Sctpsndrcvinfo: {
|
case Sctpsndrcvinfo: {
|
||||||
struct sctp_sndrcvinfo info;
|
struct sctp_sndrcvinfo info;
|
||||||
|
|
||||||
@ -2143,23 +2407,26 @@ print_arg(struct syscall_args *sc, unsigned long *args, long *retval,
|
|||||||
fprintf(fp, "0x%lx", args[sc->offset]);
|
fprintf(fp, "0x%lx", args[sc->offset]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(fp, "{sid=%u,", info.sinfo_stream);
|
print_sctp_sndrcvinfo(fp, sc->type & OUT, &info);
|
||||||
if (sc->type & OUT) {
|
break;
|
||||||
fprintf(fp, "ssn=%u,", info.sinfo_ssn);
|
}
|
||||||
|
case Msghdr: {
|
||||||
|
struct msghdr msghdr;
|
||||||
|
|
||||||
|
if (get_struct(pid, (void *)args[sc->offset],
|
||||||
|
&msghdr, sizeof(struct msghdr)) == -1) {
|
||||||
|
fprintf(fp, "0x%lx", args[sc->offset]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
fputs("flgs=", fp);
|
fputs("{", fp);
|
||||||
sysdecode_sctp_sinfo_flags(fp, info.sinfo_flags);
|
print_sockaddr(fp, trussinfo, msghdr.msg_name, msghdr.msg_namelen);
|
||||||
fprintf(fp, ",ppid=%u,", ntohl(info.sinfo_ppid));
|
fprintf(fp, ",%d,", msghdr.msg_namelen);
|
||||||
/* Can't use IN here, since IN is 0 */
|
print_iovec(fp, trussinfo, msghdr.msg_iov, msghdr.msg_iovlen);
|
||||||
if ((sc->type & OUT) == 0) {
|
fprintf(fp, ",%d,", msghdr.msg_iovlen);
|
||||||
fprintf(fp, "ctx=%u,", info.sinfo_context);
|
print_cmsgs(fp, pid, sc->type & OUT, &msghdr);
|
||||||
fprintf(fp, "ttl=%u,", info.sinfo_timetolive);
|
fprintf(fp, ",%u,", msghdr.msg_controllen);
|
||||||
}
|
print_mask_arg(sysdecode_msg_flags, fp, msghdr.msg_flags);
|
||||||
if (sc->type & OUT) {
|
fputs("}", fp);
|
||||||
fprintf(fp, "tsn=%u,", info.sinfo_tsn);
|
|
||||||
fprintf(fp, "cumtsn=%u,", info.sinfo_cumtsn);
|
|
||||||
}
|
|
||||||
fprintf(fp, "id=%u}", info.sinfo_assoc_id);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user