Question

I tried to dump all data sent by a specific process on Linux by hooking a handler to the Kernel's function sock_sendmsg() defined in linux/socket.c. I could do that by writing a systemtap probe handler for probe kernel.function("sock_sendmsg@net/socket.c") that dumps all data blocks passed with the 2nd argument struct msghdr *msg.

Here's the excerpt from net/socket.c:

int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
{
    struct kiocb iocb;
    struct sock_iocb siocb;
    int ret;

    init_sync_kiocb(&iocb, NULL);
    iocb.private = &siocb;
    ret = __sock_sendmsg(&iocb, sock, msg, size);
    if (-EIOCBQUEUED == ret)
            ret = wait_on_sync_kiocb(&iocb);
    return ret;
}

I tested my systemtap script hook_sendmsg.stp. First I ran hook_sendmsg.stp in one terminal. Then I opened another terminal and invoked telnet command to connect to stackoverflow.com and typed HEAD / HTTP/1.0<Enter twice> in the terminal. I got the following output from hook_sendmsg.stp:

root@debian:~# stap -g hook_sendmsg.stp
message block [0]; type=3(raw); state=1(unconnected)
14 00 00 00 16 00 01 03 ec 95 f4 52 00 00 00 00 |...........R....|
00 00 00 00                                     |................|
message block [0]; type=3(raw); state=1(unconnected)
14 00 00 00 16 00 01 03 ec 95 f4 52 00 00 00 00 |...........R....|
00 00 00 00                                     |................|
message block [0]; type=2(udp); state=1(unconnected)
4d 0d 01 00 00 01 00 00 00 00 00 00 0d 73 74 61 |M............sta|
63 6b 6f 76 65 72 66 6c 6f 77 03 63 6f 6d 00 00 |ckoverflow.com..|
01 00 01                                        |................|
message block [0]; type=2(udp); state=1(unconnected)
0f 1e 01 00 00 01 00 00 00 00 00 00 0d 73 74 61 |.............sta|
63 6b 6f 76 65 72 66 6c 6f 77 03 63 6f 6d 00 00 |ckoverflow.com..|
1c 00 01                                        |................|
message block [0]; type=1(tcp); state=3(connected)
48 45 41 44 20 2f 20 48 54 54 50 2f 31 2e 30 0d |HEAD / HTTP/1.0.|
0a                                              |................|
message block [0]; type=1(tcp); state=3(connected)
0d 0a                                           |................|

This shows that totally sock_sendmsg() were called 6 times in the context of telnet. Obviously the 3rd and 4th are DNS queries to Google's public DNS servers 8.8.8.8 and 8.8.4.4. The 5th and 6th are the two lines of HTTP request sent from telnet. But what were the 1st and 2nd called for? Did they called internally by the Kernel?

Thanks in advance.

Was it helpful?

Solution

They are NETLINK messages, as you can see if you monitor the telnet command from userspace with strace (check the socket family):

sendto(3, "\24\0\0\0\26\0\1\3?\254\364R\0\0\0\0\0\0\0\0", 20, 0, {sa_family=AF_NETLINK,  pid=0, groups=00000000}, 12) = 20
sendto(3, "\24\0\0\0\26\0\1\3?\254\364R\0\0\0\0\0\0\0\0", 20, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20
send(3, "\212\355\1\0\0\1\0\0\0\0\0\0\rstackoverflow\3com\0\0"..., 35, MSG_NOSIGNAL) = 35
send(3, "\241\353\1\0\0\1\0\0\0\0\0\0\rstackoverflow\3com\10i"..., 50, MSG_NOSIGNAL) = 50
send(3, "|\341\1\0\0\1\0\0\0\0\0\0\rstackoverflow\3com\0\0"..., 35, MSG_NOSIGNAL) = 35
send(3, "HEAD / HTTP/1.0\r\n", 17, 0)   = 17
send(3, "\r\n", 2, 0)                   = 2

Netlink is an interface used by the userspace processes to communicate with kernel (so, they are send by the telnet), usually for routing, firewalling... pourposes [1]. Some usual network C functions (i.e. getsockname) works internally with this kind of NETLINK messages.

If you want to investigate a bit more you should translate the payload of the send_message to the netlink header structure and check what type of messages are.:

       struct nlmsghdr {
           __u32 nlmsg_len;    /* Length of message including header. */
           __u16 nlmsg_type;   /* Type of message content. */
           __u16 nlmsg_flags;  /* Additional flags. */
           __u32 nlmsg_seq;    /* Sequence number. */
           __u32 nlmsg_pid;    /* Sender port ID. */
       };

[1]http://man7.org/linux/man-pages/man7/netlink.7.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top