#!/usr/bin/env python
# @lint-avoid-python-3-compatibility-imports
#
# sofdsnoop traces file descriptors passed via socket
#           For Linux, uses BCC, eBPF. Embedded C.
#
# USAGE: sofdsnoop
#
# Copyright (c) 2018 Jiri Olsa.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 30-Jul-2018   Jiri Olsa   Created this.

from __future__ import print_function
from bcc import ArgString, BPF
import os
import argparse
from datetime import datetime, timedelta

# arguments
examples = """examples:
    ./sofdsnoop           # trace passed file descriptors
    ./sofdsnoop -T        # include timestamps
    ./sofdsnoop -p 181    # only trace PID 181
    ./sofdsnoop -t 123    # only trace TID 123
    ./sofdsnoop -d 10     # trace for 10 seconds only
    ./sofdsnoop -n main   # only print process names containing "main"

"""
parser = argparse.ArgumentParser(
    description="Trace file descriptors passed via socket",
    formatter_class=argparse.RawDescriptionHelpFormatter,
    epilog=examples)
parser.add_argument("-T", "--timestamp", action="store_true",
    help="include timestamp on output")
parser.add_argument("-p", "--pid",
    help="trace this PID only")
parser.add_argument("-t", "--tid",
    help="trace this TID only")
parser.add_argument("-n", "--name",
    type=ArgString,
    help="only print process names containing this name")
parser.add_argument("-d", "--duration",
    help="total duration of trace in seconds")
args = parser.parse_args()
debug = 0

ACTION_SEND=0
ACTION_RECV=1
MAX_FD=10

if args.duration:
    args.duration = timedelta(seconds=int(args.duration))

# define BPF program
bpf_text = """
#include <uapi/linux/ptrace.h>
#include <uapi/linux/limits.h>
#include <linux/sched.h>
#include <linux/socket.h>
#include <net/sock.h>

#define MAX_FD 10
#define ACTION_SEND   0
#define ACTION_RECV   1

struct val_t {
    u64  id;
    u64  ts;
    int  action;
    int  sock_fd;
    int  fd_cnt;
    int  fd[MAX_FD];
    char comm[TASK_COMM_LEN];
};

BPF_HASH(detach_ptr, u64, struct cmsghdr *);
BPF_HASH(sock_fd, u64, int);
BPF_PERF_OUTPUT(events);

static void set_fd(int fd)
{
    u64 id = bpf_get_current_pid_tgid();

    sock_fd.update(&id, &fd);
}

static int get_fd(void)
{
    u64 id = bpf_get_current_pid_tgid();
    int *fd;

    fd = sock_fd.lookup(&id);
    return fd ? *fd : -1;
}

static void put_fd(void)
{
    u64 id = bpf_get_current_pid_tgid();

    sock_fd.delete(&id);
}

static int sent_1(struct pt_regs *ctx, struct val_t *val, int num, void *data)
{
    val->fd_cnt = min(num, MAX_FD);

    if (bpf_probe_read_kernel(&val->fd[0], MAX_FD * sizeof(int), data))
        return -1;

    events.perf_submit(ctx, val, sizeof(*val));
    return 0;
}

#define SEND_1                                  \
    if (sent_1(ctx, &val, num, (void *) data))  \
        return 0;                               \
                                                \
    num -= MAX_FD;                              \
    if (num < 0)                                \
        return 0;                               \
                                                \
    data += MAX_FD;

#define SEND_2   SEND_1 SEND_1
#define SEND_4   SEND_2 SEND_2
#define SEND_8   SEND_4 SEND_4
#define SEND_260 SEND_8 SEND_8 SEND_8 SEND_2

static int send(struct pt_regs *ctx, struct cmsghdr *cmsg, int action)
{
    struct val_t val = { 0 };
    int *data, num, fd;
    u64 tsp = bpf_ktime_get_ns();

    data = (void *) ((char *) cmsg + sizeof(struct cmsghdr));
    num  = (cmsg->cmsg_len - sizeof(struct cmsghdr)) / sizeof(int);

    val.id      = bpf_get_current_pid_tgid();
    val.action  = action;
    val.sock_fd = get_fd();
    val.ts      = tsp / 1000;

    if (bpf_get_current_comm(&val.comm, sizeof(val.comm)) != 0)
        return 0;

    SEND_260
    return 0;
}

static bool allow_pid(u64 id)
{
    u32 pid = id >> 32; // PID is higher part
    u32 tid = id;       // Cast and get the lower part

    FILTER

    return 1;
}

int trace_scm_send_entry(struct pt_regs *ctx, struct socket *sock, struct msghdr *hdr)
{
    struct cmsghdr *cmsg = NULL;

    if (!allow_pid(bpf_get_current_pid_tgid()))
        return 0;

    if (hdr->msg_controllen >= sizeof(struct cmsghdr))
        cmsg = hdr->msg_control;

    if (!cmsg || (cmsg->cmsg_type != SCM_RIGHTS))
        return 0;

    return send(ctx, cmsg, ACTION_SEND);
};

int trace_scm_detach_fds_entry(struct pt_regs *ctx, struct msghdr *hdr)
{
    struct cmsghdr *cmsg = NULL;
    u64 id = bpf_get_current_pid_tgid();

    if (!allow_pid(id))
        return 0;

    if (hdr->msg_controllen >= sizeof(struct cmsghdr))
        cmsg = hdr->msg_control;

    if (!cmsg)
        return 0;

    detach_ptr.update(&id, &cmsg);
    return 0;
};

int trace_scm_detach_fds_return(struct pt_regs *ctx)
{
    struct cmsghdr **cmsgp;
    u64 id = bpf_get_current_pid_tgid();

    if (!allow_pid(id))
        return 0;

    cmsgp = detach_ptr.lookup(&id);

    if (!cmsgp)
        return 0;

    return send(ctx, *cmsgp, ACTION_RECV);
}

int syscall__sendmsg(struct pt_regs *ctx, u64 fd, u64 msg, u64 flags)
{
    struct pt_regs p;

    if (!allow_pid(bpf_get_current_pid_tgid()))
        return 0;

    set_fd(fd);
    return 0;
}

int trace_sendmsg_return(struct pt_regs *ctx)
{
    if (!allow_pid(bpf_get_current_pid_tgid()))
        return 0;

    put_fd();
    return 0;
}

int syscall__recvmsg(struct pt_regs *ctx, u64 fd, u64 msg, u64 flags)
{
    struct pt_regs p;

    if (!allow_pid(bpf_get_current_pid_tgid()))
        return 0;

    fd = fd;

    set_fd(fd);
    return 0;
}

int trace_recvmsg_return(struct pt_regs *ctx)
{
    if (!allow_pid(bpf_get_current_pid_tgid()))
        return 0;

    put_fd();
    return 0;
}

"""

if args.tid:  # TID trumps PID
    bpf_text = bpf_text.replace('FILTER',
        'if (tid != %s) { return 0; }' % args.tid)
elif args.pid:
    bpf_text = bpf_text.replace('FILTER',
        'if (pid != %s) { return 0; }' % args.pid)
else:
    bpf_text = bpf_text.replace('FILTER', '')

# initialize BPF
b = BPF(text=bpf_text)

syscall_fnname = b.get_syscall_fnname("sendmsg")
if BPF.ksymname(syscall_fnname) != -1:
    b.attach_kprobe(event=syscall_fnname, fn_name="syscall__sendmsg")
    b.attach_kretprobe(event=syscall_fnname, fn_name="trace_sendmsg_return")

syscall_fnname = b.get_syscall_fnname("recvmsg")
if BPF.ksymname(syscall_fnname) != -1:
    b.attach_kprobe(event=syscall_fnname, fn_name="syscall__recvmsg")
    b.attach_kretprobe(event=syscall_fnname, fn_name="trace_recvmsg_return")

b.attach_kprobe(event="__scm_send", fn_name="trace_scm_send_entry")
b.attach_kprobe(event="scm_detach_fds", fn_name="trace_scm_detach_fds_entry")
b.attach_kretprobe(event="scm_detach_fds", fn_name="trace_scm_detach_fds_return")

initial_ts = 0

# header
if args.timestamp:
    print("%-14s" % ("TIME(s)"), end="")
print("%-6s %-6s %-16s %-25s %-5s %s" %
      ("ACTION", "TID", "COMM", "SOCKET", "FD", "NAME"))

def get_file(pid, fd):
    proc = "/proc/%d/fd/%d" % (pid, fd)
    try:
        return os.readlink(proc)
    except OSError as err:
        return "N/A"

# process event
def print_event(cpu, data, size):
    event = b["events"].event(data)
    tid = event.id & 0xffffffff;

    cnt = min(MAX_FD, event.fd_cnt);

    if args.name and bytes(args.name) not in event.comm:
        return

    for i in range(0, cnt):
        global initial_ts

        if not initial_ts:
            initial_ts = event.ts

        if args.timestamp:
            delta = event.ts - initial_ts
            print("%-14.9f" % (float(delta) / 1000000), end="")

        print("%-6s %-6d %-16s " %
              ("SEND" if event.action == ACTION_SEND else "RECV",
               tid, event.comm.decode()), end = '')

        sock = "%d:%s" % (event.sock_fd, get_file(tid, event.sock_fd))
        print("%-25s " % sock, end = '')

        fd = event.fd[i]
        fd_file = get_file(tid, fd) if event.action == ACTION_SEND else ""
        print("%-5d %s" % (fd, fd_file))

# loop with callback to print_event
b["events"].open_perf_buffer(print_event, page_cnt=64)
start_time = datetime.now()
while not args.duration or datetime.now() - start_time < args.duration:
    try:
        b.perf_buffer_poll(timeout=1000)
    except KeyboardInterrupt:
        exit()
