#!/usr/bin/env python
# @lint-avoid-python-3-compatibility-imports
#
# tcpsubnet   Summarize TCP bytes sent to different subnets.
#             For Linux, uses BCC, eBPF. Embedded C.
#
# USAGE: tcpsubnet [-h] [-v] [-J] [-f FORMAT] [-i INTERVAL] [subnets]
#
# This uses dynamic tracing of kernel functions, and will need to be updated
# to match kernel changes.
#
# This is an adaptation of tcptop from written by Brendan Gregg.
#
# WARNING: This traces all send at the TCP level, and while it
# summarizes data in-kernel to reduce overhead, there may still be some
# overhead at high TCP send/receive rates (eg, ~13% of one CPU at 100k TCP
# events/sec. This is not the same as packet rate: funccount can be used to
# count the kprobes below to find out the TCP rate). Test in a lab environment
# first. If your send rate is low (eg, <1k/sec) then the overhead is
# expected to be negligible.
#
# Copyright 2017 Rodrigo Manyari
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 03-Oct-2017   Rodrigo Manyari   Created this based on tcptop.
# 13-Feb-2018   Rodrigo Manyari   Fix pep8 errors, some refactoring.
# 05-Mar-2018   Rodrigo Manyari   Add date time to output.

import argparse
import json
import logging
import struct
import socket
from bcc import BPF
from datetime import datetime as dt
from time import sleep

# arguments
examples = """examples:
    ./tcpsubnet                 # Trace TCP sent to the default subnets:
                                # 127.0.0.1/32,10.0.0.0/8,172.16.0.0/12,
                                # 192.168.0.0/16,0.0.0.0/0
    ./tcpsubnet -f K            # Trace TCP sent to the default subnets
                                # aggregated in KBytes.
    ./tcpsubnet 10.80.0.0/24    # Trace TCP sent to 10.80.0.0/24 only
    ./tcpsubnet -J              # Format the output in JSON.
"""

default_subnets = "127.0.0.1/32,10.0.0.0/8," \
    "172.16.0.0/12,192.168.0.0/16,0.0.0.0/0"

parser = argparse.ArgumentParser(
    description="Summarize TCP send and aggregate by subnet",
    formatter_class=argparse.RawDescriptionHelpFormatter,
    epilog=examples)
parser.add_argument("subnets", help="comma separated list of subnets",
    type=str, nargs="?", default=default_subnets)
parser.add_argument("-v", "--verbose", action="store_true",
    help="output debug statements")
parser.add_argument("-J", "--json", action="store_true",
    help="format output in JSON")
parser.add_argument("--ebpf", action="store_true",
    help=argparse.SUPPRESS)
parser.add_argument("-f", "--format", default="B",
    help="[bkmBKM] format to report: bits, Kbits, Mbits, bytes, " +
    "KBytes, MBytes (default B)", choices=["b", "k", "m", "B", "K", "M"])
parser.add_argument("-i", "--interval", default=1, type=int,
    help="output interval, in seconds (default 1)")
args = parser.parse_args()

level = logging.INFO
if args.verbose:
    level = logging.DEBUG

logging.basicConfig(level=level)

logging.debug("Starting with the following args:")
logging.debug(args)

# args checking
if int(args.interval) <= 0:
    logging.error("Invalid interval, must be > 0. Exiting.")
    exit(1)
else:
    args.interval = int(args.interval)

# map of supported formats
formats = {
    "b": lambda x: (x * 8),
    "k": lambda x: ((x * 8) / 1024),
    "m": lambda x: ((x * 8) / pow(1024, 2)),
    "B": lambda x: x,
    "K": lambda x: x / 1024,
    "M": lambda x: x / pow(1024, 2)
}

# Let's swap the string with the actual numeric value
# once here so we don't have to do it on every interval
formatFn = formats[args.format]

# define the basic structure of the BPF program
bpf_text = """
#include <uapi/linux/ptrace.h>
#include <net/sock.h>
#include <bcc/proto.h>

struct index_key_t {
  u32 index;
};

BPF_HASH(ipv4_send_bytes, struct index_key_t);

int kprobe__tcp_sendmsg(struct pt_regs *ctx, struct sock *sk,
    struct msghdr *msg, size_t size)
{
    u16 family = sk->__sk_common.skc_family;

    if (family == AF_INET) {
        u32 dst = sk->__sk_common.skc_daddr;
        unsigned categorized = 0;
        __SUBNETS__
    }
    return 0;
}
"""


# Takes in a mask and returns the integer equivalent
# e.g.
# mask_to_int(8) returns 4278190080
def mask_to_int(n):
    return ((1 << n) - 1) << (32 - n)

# Takes in a list of subnets and returns a list
# of tuple-3 containing:
# - The subnet info at index 0
# - The addr portion as an int at index 1
# - The mask portion as an int at index 2
#
# e.g.
# parse_subnets([10.10.0.0/24]) returns
# [
#   ['10.10.0.0/24', 168427520, 4294967040],
# ]
def parse_subnets(subnets):
    m = []
    for s in subnets:
        parts = s.split("/")
        if len(parts) != 2:
            msg = "Subnet [%s] is invalid, please refer to the examples." % s
            raise ValueError(msg)
        netaddr_int = 0
        mask_int = 0
        try:
            netaddr_int = struct.unpack("!I", socket.inet_aton(parts[0]))[0]
        except:
            msg = ("Invalid net address in subnet [%s], " +
                "please refer to the examples.") % s
            raise ValueError(msg)
        try:
            mask_int = int(parts[1])
        except:
            msg = "Invalid mask in subnet [%s]. Mask must be an int" % s
            raise ValueError(msg)
        if mask_int < 0 or mask_int > 32:
            msg = ("Invalid mask in subnet [%s]. Must be an " +
                "int between 0 and 32.") % s
            raise ValueError(msg)
        mask_int = mask_to_int(int(parts[1]))
        m.append([s, netaddr_int, mask_int])
    return m

def generate_bpf_subnets(subnets):
    template = """
        if (!categorized && (__NET_ADDR__ & __NET_MASK__) ==
             (dst & __NET_MASK__)) {
          struct index_key_t key = {.index = __POS__};
          ipv4_send_bytes.increment(key, size);
          categorized = 1;
        }
    """
    bpf = ''
    for i, s in enumerate(subnets):
        branch = template
        branch = branch.replace("__NET_ADDR__", str(socket.htonl(s[1])))
        branch = branch.replace("__NET_MASK__", str(socket.htonl(s[2])))
        branch = branch.replace("__POS__", str(i))
        bpf += branch
    return bpf

subnets = []
if args.subnets:
    subnets = args.subnets.split(",")

subnets = parse_subnets(subnets)

logging.debug("Packets are going to be categorized in the following subnets:")
logging.debug(subnets)

bpf_subnets = generate_bpf_subnets(subnets)

# initialize BPF
bpf_text = bpf_text.replace("__SUBNETS__", bpf_subnets)

logging.debug("Done preprocessing the BPF program, " +
        "this is what will actually get executed:")
logging.debug(bpf_text)

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

b = BPF(text=bpf_text)

ipv4_send_bytes = b["ipv4_send_bytes"]

if not args.json:
    print("Tracing... Output every %d secs. Hit Ctrl-C to end" % args.interval)

# output
exiting = 0
while (1):

    try:
        sleep(args.interval)
    except KeyboardInterrupt:
        exiting = 1

    # IPv4:  build dict of all seen keys
    keys = ipv4_send_bytes
    for k, v in ipv4_send_bytes.items():
        if k not in keys:
            keys[k] = v

    # to hold json data
    data = {}

    # output
    now = dt.now()
    data['date'] = now.strftime('%x')
    data['time'] = now.strftime('%X')
    data['entries'] = {}
    if not args.json:
        print(now.strftime('[%x %X]'))
    for k, v in reversed(sorted(keys.items(), key=lambda keys: keys[1].value)):
        send_bytes = 0
        if k in ipv4_send_bytes:
            send_bytes = int(ipv4_send_bytes[k].value)
        subnet = subnets[k.index][0]
        send = formatFn(send_bytes)
        if args.json:
            data['entries'][subnet] = send
        else:
            print("%-21s %6d" % (subnet, send))

    if args.json:
        print(json.dumps(data))

    ipv4_send_bytes.clear()

    if exiting:
        exit(0)
