tcp_mon script

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

tcp_mon script

Hien Nguyen
This script monitors all tcp traffic, it will report the traffic
(snd+rcv) every 2000 jiffies

UID     PID             SIZE    NAME    PORT    SOURCE IP
500     20895           192     sshd    22      9.47.22.138
500     22739           0       sshd    22      9.47.22.138


To run this script
1. download the files to some temp dir
2. create a directory for the tapset (ie tcp_tapset) and copy the
tapset.stp to that directory
3. run the tcp_mon script

stap -I ./tcp_tapset tcp_mon.stp


#! stap
global uids, pidnames, send_bytes, recv_bytes, pid_ports, pid_src_ips

function print_report()
{
        lines = 0;
        log ("UID\tPID\t\tSIZE\tNAME\tPORT\tSOURCE IP")
        for (lines = 0; lines <= 21; lines ++) {
                if (!lines) {
                        foreach (_pid_ in pidnames) {
                                log (string(uids[_pid_]) . "\t" .
                                        string(_pid_) . "\t\t" .
                                        string(send_bytes[_pid_] +
                                        recv_bytes[_pid_]) . "\t" .
                                        pidnames[_pid_]. "\t" .
                                        string(pid_ports[_pid_]). "\t" .
                                        pid_src_ips[_pid_]);
                                lines++
                        }
                } else {
                        print("\n")
                }
        }
}

probe kernel.function("tcp_sendmsg") {
        pid_ports[pid()] = get_local_port($sk)
        pid_src_ips[pid()] = get_ip_source($sk)
}

probe kernel.function("tcp_sendmsg").return {
        size = retval()
        if (size > 0) {
                send_bytes[pid()] += size
                pidnames[pid()] = execname()
                uids[pid()] = uid()
        }
}

probe kernel.function("tcp_recvmsg").return {
        size = retval()
        if (size > 0) {
                recv_bytes[pid()] += size
                pidnames[pid()] = execname()
                uids[pid()] = uid()
        }
}

probe kernel.function("do_exit") {
        delete pidnames[pid()]
}

probe kernel.function("tcp_close_state") {
        delete pidnames[pid()]
}

probe kernel.function("tcp_disconnect") {
        delete pidnames[pid()]
}

probe timer.jiffies(2000) {
        print_report()
        foreach (_pid_ in pidnames) {
                send_bytes[_pid_] = 0
                recv_bytes[_pid_] = 0
        }
}


%{
#include <linux/version.h>
#include <net/sock.h>
#include <net/tcp.h>

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
#define LPORT   (inet->inet.num)
#define DADDR   (&inet->inet.daddr)
#else
#define LPORT   (inet->num)
#define DADDR   (&inet->daddr)
#endif
%}

function get_local_port:long(sock)
%{
        unsigned long ptr = (unsigned long) THIS->sock;
        struct inet_sock *inet = (struct inet_sock *) ptr;

        THIS->__retvalue = (long long) LPORT;
%}

function get_ip_source:string(sock)
%{
        unsigned long ptr = (unsigned long) THIS->sock;
        struct inet_sock *inet = (struct inet_sock *) ptr;
        unsigned char addr[4];

        memcpy(addr, DADDR, sizeof(addr));
        sprintf(THIS->__retvalue, "%d.%d.%d.%d",
                addr[0], addr[1],  addr[2], addr[3]);
%}