Add a general netlink socket parser
Introduce a general socket netlink parser which prints the header and a string for the remaining part of the buffer. It doesn't handle all the netlink flags and types yet because the parser needs more information, this will be implemented later. * net.c (decode_sockbuf): New function. (SYS_FUNC(send), SYS_FUNC(sendto), SYS_FUNC(recv), SYS_FUNC(recvfrom)): Use it instead of printstr. * msghdr.c (print_msghdr): Pass IOV_DECODE_NETLINK to tprint_iov_upto() for netlink sockets. * netlink.c: New file. * Makefile.am (strace_SOURCES): Add it. * defs.h (decode_netlink, getfdproto): New prototypes. (iov_decode): Add IOV_DECODER_NETLINK. * io.c (print_iovec): Use decode_netlink(). * util.c (getfdproto): Remove static keyword. * xlat/netlink_flags.in: New file. * xlat/netlink_types.in: New file.
This commit is contained in:
parent
7499ce0244
commit
2850f745ca
@ -160,6 +160,7 @@ strace_SOURCES = \
|
||||
mtd.c \
|
||||
native_defs.h \
|
||||
net.c \
|
||||
netlink.c \
|
||||
numa.c \
|
||||
open.c \
|
||||
or1k_atomic.c \
|
||||
|
5
defs.h
5
defs.h
@ -452,7 +452,8 @@ extern enum sock_proto get_proto_by_name(const char *);
|
||||
|
||||
enum iov_decode {
|
||||
IOV_DECODE_ADDR,
|
||||
IOV_DECODE_STR
|
||||
IOV_DECODE_STR,
|
||||
IOV_DECODE_NETLINK
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@ -567,6 +568,7 @@ extern const char *signame(const int);
|
||||
extern void pathtrace_select(const char *);
|
||||
extern int pathtrace_match(struct tcb *);
|
||||
extern int getfdpath(struct tcb *, int, char *, unsigned);
|
||||
extern enum sock_proto getfdproto(struct tcb *, int);
|
||||
|
||||
extern const char *xlookup(const struct xlat *, const uint64_t);
|
||||
extern const char *xlat_search(const struct xlat *, const size_t, const uint64_t);
|
||||
@ -679,6 +681,7 @@ extern void printsignal(int);
|
||||
extern void tprint_iov(struct tcb *, unsigned long, unsigned long, enum iov_decode);
|
||||
extern void tprint_iov_upto(struct tcb *, unsigned long, unsigned long,
|
||||
enum iov_decode, unsigned long);
|
||||
extern void decode_netlink(struct tcb *, unsigned long, unsigned long);
|
||||
extern void tprint_open_modes(unsigned int);
|
||||
extern const char *sprint_open_modes(unsigned int);
|
||||
extern void print_seccomp_filter(struct tcb *, unsigned long);
|
||||
|
6
io.c
6
io.c
@ -88,6 +88,12 @@ print_iovec(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
|
||||
c->data_size -= len;
|
||||
printstr(tcp, iov[0], len);
|
||||
break;
|
||||
case IOV_DECODE_NETLINK:
|
||||
if (len > c->data_size)
|
||||
len = c->data_size;
|
||||
c->data_size -= len;
|
||||
decode_netlink(tcp, iov[0], iov[1]);
|
||||
break;
|
||||
default:
|
||||
printaddr(iov[0]);
|
||||
break;
|
||||
|
13
msghdr.c
13
msghdr.c
@ -335,13 +335,22 @@ decode_msg_control(struct tcb *tcp, unsigned long addr,
|
||||
static void
|
||||
print_msghdr(struct tcb *tcp, struct msghdr *msg, unsigned long data_size)
|
||||
{
|
||||
int family;
|
||||
enum iov_decode decode;
|
||||
|
||||
tprints("{msg_name=");
|
||||
decode_sockaddr(tcp, (long)msg->msg_name, msg->msg_namelen);
|
||||
family = decode_sockaddr(tcp, (long)msg->msg_name, msg->msg_namelen);
|
||||
tprintf(", msg_namelen=%d", msg->msg_namelen);
|
||||
|
||||
tprints(", msg_iov=");
|
||||
|
||||
if (family == AF_NETLINK)
|
||||
decode = IOV_DECODE_NETLINK;
|
||||
else
|
||||
decode = IOV_DECODE_STR;
|
||||
|
||||
tprint_iov_upto(tcp, (unsigned long) msg->msg_iovlen,
|
||||
(unsigned long) msg->msg_iov, IOV_DECODE_STR, data_size);
|
||||
(unsigned long) msg->msg_iov, decode, data_size);
|
||||
tprintf(", msg_iovlen=%lu", (unsigned long) msg->msg_iovlen);
|
||||
|
||||
decode_msg_control(tcp, (unsigned long) msg->msg_control,
|
||||
|
28
net.c
28
net.c
@ -108,6 +108,19 @@ print_ifindex(unsigned int ifindex)
|
||||
tprintf("%u", ifindex);
|
||||
}
|
||||
|
||||
static void
|
||||
decode_sockbuf(struct tcb *tcp, int fd, long addr, long addrlen)
|
||||
{
|
||||
|
||||
switch (verbose(tcp) ? getfdproto(tcp, fd) : SOCK_PROTO_UNKNOWN) {
|
||||
case SOCK_PROTO_NETLINK:
|
||||
decode_netlink(tcp, addr, addrlen);
|
||||
break;
|
||||
default:
|
||||
printstr(tcp, addr, addrlen);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* low bits of the socket type define real socket type,
|
||||
* other bits are socket type flags.
|
||||
@ -220,7 +233,7 @@ SYS_FUNC(send)
|
||||
{
|
||||
printfd(tcp, tcp->u_arg[0]);
|
||||
tprints(", ");
|
||||
printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
|
||||
decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
|
||||
tprintf(", %lu, ", tcp->u_arg[2]);
|
||||
/* flags */
|
||||
printflags(msg_flags, tcp->u_arg[3], "MSG_???");
|
||||
@ -232,7 +245,7 @@ SYS_FUNC(sendto)
|
||||
{
|
||||
printfd(tcp, tcp->u_arg[0]);
|
||||
tprints(", ");
|
||||
printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
|
||||
decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
|
||||
tprintf(", %lu, ", tcp->u_arg[2]);
|
||||
/* flags */
|
||||
printflags(msg_flags, tcp->u_arg[3], "MSG_???");
|
||||
@ -287,10 +300,12 @@ SYS_FUNC(recv)
|
||||
printfd(tcp, tcp->u_arg[0]);
|
||||
tprints(", ");
|
||||
} else {
|
||||
if (syserror(tcp))
|
||||
if (syserror(tcp)) {
|
||||
printaddr(tcp->u_arg[1]);
|
||||
else
|
||||
printstr(tcp, tcp->u_arg[1], tcp->u_rval);
|
||||
} else {
|
||||
decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
|
||||
tcp->u_rval);
|
||||
}
|
||||
|
||||
tprintf(", %lu, ", tcp->u_arg[2]);
|
||||
printflags(msg_flags, tcp->u_arg[3], "MSG_???");
|
||||
@ -310,7 +325,8 @@ SYS_FUNC(recvfrom)
|
||||
if (syserror(tcp)) {
|
||||
printaddr(tcp->u_arg[1]);
|
||||
} else {
|
||||
printstr(tcp, tcp->u_arg[1], tcp->u_rval);
|
||||
decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
|
||||
tcp->u_rval);
|
||||
}
|
||||
/* len */
|
||||
tprintf(", %lu, ", tcp->u_arg[2]);
|
||||
|
64
netlink.c
Normal file
64
netlink.c
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
#include <sys/socket.h>
|
||||
#include <linux/netlink.h>
|
||||
#include "xlat/netlink_flags.h"
|
||||
#include "xlat/netlink_types.h"
|
||||
|
||||
void
|
||||
decode_netlink(struct tcb *tcp, unsigned long addr, unsigned long size)
|
||||
{
|
||||
struct nlmsghdr nlmsghdr;
|
||||
|
||||
if (size < sizeof(struct nlmsghdr)) {
|
||||
printstr(tcp, addr, size);
|
||||
return;
|
||||
}
|
||||
if (umove_or_printaddr(tcp, addr, &nlmsghdr))
|
||||
return;
|
||||
|
||||
tprintf("{{len=%u, type=", nlmsghdr.nlmsg_len);
|
||||
|
||||
printxval(netlink_types, nlmsghdr.nlmsg_type, "NLMSG_???");
|
||||
|
||||
tprints(", flags=");
|
||||
printflags(netlink_flags, nlmsghdr.nlmsg_flags, "NLM_F_???");
|
||||
/* manage get/new requests */
|
||||
|
||||
tprintf(", seq=%u, pid=%u}", nlmsghdr.nlmsg_seq,
|
||||
nlmsghdr.nlmsg_pid);
|
||||
|
||||
if (size - sizeof(struct nlmsghdr) > 0) {
|
||||
tprints(", ");
|
||||
printstr(tcp, addr + sizeof(struct nlmsghdr),
|
||||
size - sizeof(struct nlmsghdr));
|
||||
}
|
||||
|
||||
tprints("}");
|
||||
}
|
2
util.c
2
util.c
@ -472,7 +472,7 @@ sprinttime(time_t t)
|
||||
return buf;
|
||||
}
|
||||
|
||||
static enum sock_proto
|
||||
enum sock_proto
|
||||
getfdproto(struct tcb *tcp, int fd)
|
||||
{
|
||||
#ifdef HAVE_SYS_XATTR_H
|
||||
|
6
xlat/netlink_flags.in
Normal file
6
xlat/netlink_flags.in
Normal file
@ -0,0 +1,6 @@
|
||||
NLM_F_REQUEST 0x1
|
||||
NLM_F_MULTI 0x2
|
||||
NLM_F_ACK 0x4
|
||||
NLM_F_ECHO 0x8
|
||||
NLM_F_DUMP_INTR 0x10
|
||||
NLM_F_DUMP_FILTERED 0x20
|
4
xlat/netlink_types.in
Normal file
4
xlat/netlink_types.in
Normal file
@ -0,0 +1,4 @@
|
||||
NLMSG_NOOP 0x1
|
||||
NLMSG_ERROR 0x2
|
||||
NLMSG_DONE 0x3
|
||||
NLMSG_OVERRUN 0x4
|
Loading…
x
Reference in New Issue
Block a user