#!/usr/bin/env python
#
# solisten      Trace TCP listen events
#               For Linux, uses BCC, eBPF. Embedded C.
#
# USAGE: solisten.py [-h] [-p PID] [--show-netns]
#
# This is provided as a basic example of TCP connection & socket tracing.
# It could be useful in scenarios where load balancers needs to be updated
# dynamically as application is fully initialized.
#
# All IPv4 and IPv6 listen attempts are traced, even if they ultimately fail
# or the the listening program is not willing to accept().
#
# Copyright (c) 2016 Jean-Tiare Le Bigot.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 04-Mar-2016	Jean-Tiare Le Bigot	Created this.

import os
from socket import inet_ntop, AF_INET, AF_INET6, SOCK_STREAM, SOCK_DGRAM
from struct import pack
import argparse
from bcc import BPF
from bcc.utils import printb

# Arguments
examples = """Examples:
    ./solisten.py              # Stream socket listen
    ./solisten.py -p 1234      # Stream socket listen for specified PID only
    ./solisten.py --netns 4242 # " for the specified network namespace ID only
    ./solisten.py --show-netns # Show network ns ID (useful for containers)
"""

parser = argparse.ArgumentParser(
    description="Stream sockets listen",
    formatter_class=argparse.RawDescriptionHelpFormatter,
    epilog=examples)
parser.add_argument("--show-netns", action="store_true",
    help="show network namespace")
parser.add_argument("-p", "--pid", default=0, type=int,
    help="trace this PID only")
parser.add_argument("-n", "--netns", default=0, type=int,
    help="trace this Network Namespace only")
parser.add_argument("--ebpf", action="store_true",
    help=argparse.SUPPRESS)


# BPF Program
bpf_text = """
#include <net/net_namespace.h>
#include <bcc/proto.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wenum-conversion"
#include <net/inet_sock.h>
#pragma clang diagnostic pop

// Common structure for UDP/TCP IPv4/IPv6
struct listen_evt_t {
    u64 ts_us;
    u32 pid;
    int backlog;
    u64 netns;
    u64 proto;    // familiy << 16 | type
    u64 lport;    // use only 16 bits
    u64 laddr[2]; // IPv4: store in laddr[0]
    char task[TASK_COMM_LEN];
};
BPF_PERF_OUTPUT(listen_evt);

// Send an event for each IPv4 listen with PID, bound address and port
int kprobe__inet_listen(struct pt_regs *ctx, struct socket *sock, int backlog)
{
        // cast types. Intermediate cast not needed, kept for readability
        struct sock *sk = sock->sk;
        struct inet_sock *inet = (struct inet_sock *)sk;

        // Built event for userland
        struct listen_evt_t evt = {
            .ts_us = bpf_ktime_get_ns() / 1000,
            .backlog = backlog,
        };

        // Get process comm. Needs LLVM >= 3.7.1
        // see https://github.com/iovisor/bcc/issues/393
        bpf_get_current_comm(evt.task, TASK_COMM_LEN);

        // Get socket IP family
        u16 family = sk->__sk_common.skc_family;
        evt.proto = family << 16 | SOCK_STREAM;

        // Get PID
        evt.pid = bpf_get_current_pid_tgid() >> 32;

        ##FILTER_PID##

        // Get port
        evt.lport = inet->inet_sport;
        evt.lport = ntohs(evt.lport);

        // Get network namespace id, if kernel supports it
#ifdef CONFIG_NET_NS
        evt.netns = sk->__sk_common.skc_net.net->ns.inum;
#else
        evt.netns = 0;
#endif

        ##FILTER_NETNS##

        // Get IP
        if (family == AF_INET) {
            evt.laddr[0] = inet->inet_rcv_saddr;
        } else if (family == AF_INET6) {
            bpf_probe_read_kernel(evt.laddr, sizeof(evt.laddr),
                           sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
        }

        // Send event to userland
        listen_evt.perf_submit(ctx, &evt, sizeof(evt));

        return 0;
};
"""

    # TODO: properties to unpack protocol / ip / pid / tgid ...

# Format output
def event_printer(show_netns):
    def print_event(cpu, data, size):
        # Decode event
        event = b["listen_evt"].event(data)

        pid = event.pid
        proto_family = event.proto & 0xff
        proto_type = event.proto >> 16 & 0xff

        if proto_family == SOCK_STREAM:
            protocol = "TCP"
        elif proto_family == SOCK_DGRAM:
            protocol = "UDP"
        else:
            protocol = "UNK"

        address = ""
        if proto_type == AF_INET:
            protocol += "v4"
            address = inet_ntop(AF_INET, pack("I", event.laddr[0]))
        elif proto_type == AF_INET6:
            address = inet_ntop(AF_INET6, event.laddr)
            protocol += "v6"

        # Display
        if show_netns:
            printb(b"%-7d %-12.12s %-12d %-6s %-8d %-5d %-39s" % (
                pid, event.task, event.netns, protocol.encode(), event.backlog,
                event.lport, address.encode(),
            ))
        else:
            printb(b"%-7d %-12.12s %-6s %-8d %-5d %-39s" % (
                pid, event.task, protocol.encode(), event.backlog,
                event.lport, address.encode(),
            ))

    return print_event

if __name__ == "__main__":
    # Parse arguments
    args = parser.parse_args()

    pid_filter = ""
    netns_filter = ""

    if args.pid:
        pid_filter = "if (evt.pid != %d) return 0;" % args.pid
    if args.netns:
        netns_filter = "if (evt.netns != %d) return 0;" % args.netns

    bpf_text = bpf_text.replace("##FILTER_PID##", pid_filter)
    bpf_text = bpf_text.replace("##FILTER_NETNS##", netns_filter)

    if args.ebpf:
        print(bpf_text)
        exit()

    # Initialize BPF
    b = BPF(text=bpf_text)
    b["listen_evt"].open_perf_buffer(event_printer(args.show_netns))

    # Print headers
    if args.show_netns:
        print("%-7s %-12s %-12s %-6s %-8s %-5s %-39s" %
              ("PID", "COMM", "NETNS", "PROTO", "BACKLOG", "PORT", "ADDR"))
    else:
        print("%-7s %-12s %-6s %-8s %-5s %-39s" %
              ("PID", "COMM", "PROTO", "BACKLOG", "PORT", "ADDR"))

    # Read events
    while 1:
        try:
            b.perf_buffer_poll()
        except KeyboardInterrupt:
            exit()
