Module ImportFrom alias ImportFrom alias Import alias Assign NameStore Str Assign NameStore Call AttributeLoad NameLoad attr keyword Str keyword AttributeLoad NameLoad attr keyword NameLoad Expr Call AttributeLoad NameLoad attr Str Str keyword Str keyword Str Expr Call AttributeLoad NameLoad attr Str Str keyword Str Assign NameStore Call AttributeLoad NameLoad attr Assign NameStore Num Assign NameStore Str If AttributeLoad NameLoad attr body Assign NameStore Call AttributeLoad NameLoad attr Str BinOpMod Str AttributeLoad NameLoad attr orelse Assign NameStore Call AttributeLoad NameLoad attr Str Str If NameLoad body Expr Call NameLoad NameLoad Assign NameStore Call NameLoad keyword NameLoad Expr Call AttributeLoad NameLoad attr keyword Str keyword Str Expr Call AttributeLoad NameLoad attr keyword Str keyword Str Expr Call AttributeLoad NameLoad attr keyword Str keyword Str Expr Call AttributeLoad NameLoad attr keyword Str keyword Str If AttributeLoad NameLoad attr body Expr Call NameLoad BinOpMod Str Str keyword Str Expr Call NameLoad BinOpMod Str TupleLoad Str Str Str Str Str Str Assign NameStore Num FunctionDef arguments args NameParam defaults body Assign NameStore Str For NameStore Call NameLoad Num Num body Assign NameStore BinOpAdd NameLoad Call NameLoad BinOpBitAnd NameLoad Num If CompareNotEq NameLoad Num body Assign NameStore BinOpAdd NameLoad Str Assign NameStore BinOpRShift NameLoad Num Return NameLoad decorator_list While Num body Assign TupleStore NameStore NameStore NameStore NameStore NameStore NameStore Call AttributeLoad NameLoad attr Assign TupleStore NameStore NameStore NameStore NameStore Call AttributeLoad NameLoad attr Str If AttributeLoad NameLoad attr body If CompareEq NameLoad Num body Assign NameStore NameLoad Expr Call NameLoad BinOpMod Str BinOpSub NameLoad NameLoad keyword Str Expr Call NameLoad BinOpMod Str TupleLoad NameLoad NameLoad NameLoad IfExp CompareEq NameLoad Str Call NameLoad Call NameLoad NameLoad Num BinOpAdd Str NameLoad IfExp CompareEq NameLoad Str Call NameLoad Call NameLoad NameLoad Num BinOpAdd Str NameLoad NameLoad
N/A __future__ print_function bcc BPF N/A argparse N/A examples examples:
    ./tcpconnect           # trace all TCP connect()s
    ./tcpconnect -t        # include timestamps
    ./tcpconnect -p 181    # only trace PID 181
 N/A parser N/A N/A argparse ArgumentParser description Trace TCP connects formatter_class N/A argparse RawDescriptionHelpFormatter epilog examples N/A N/A N/A parser add_argument -t --timestamp action store_true help include timestamp on output N/A N/A N/A parser add_argument -p --pid help trace this PID only N/A args N/A N/A parser parse_args N/A debug 0 N/A bpf_text 
#include <uapi/linux/ptrace.h>
#include <net/sock.h>
#include <bcc/proto.h>

BPF_HASH(currsock, u32, struct sock *);

int trace_connect_entry(struct pt_regs *ctx, struct sock *sk)
{
    u32 pid = bpf_get_current_pid_tgid();
    FILTER

    // stash the sock ptr for lookup on return
    currsock.update(&pid, &sk);

    return 0;
};

static int trace_connect_return(struct pt_regs *ctx, short ipver)
{
    int ret = ctx->ax;
    u32 pid = bpf_get_current_pid_tgid();

    struct sock **skpp;
    skpp = currsock.lookup(&pid);
    if (skpp == 0) {
        return 0;   // missed entry
    }

    if (ret != 0) {
        // failed to send SYNC packet, may not have populated
        // socket __sk_common.{skc_rcv_saddr, ...}
        currsock.delete(&pid);
        return 0;
    }

    // pull in details
    struct sock *skp = *skpp;
    u32 saddr = 0, daddr = 0;
    u16 dport = 0;
    bpf_probe_read(&dport, sizeof(dport), &skp->__sk_common.skc_dport);
    if (ipver == 4) {
        bpf_probe_read(&saddr, sizeof(saddr),
            &skp->__sk_common.skc_rcv_saddr);
        bpf_probe_read(&daddr, sizeof(daddr),
            &skp->__sk_common.skc_daddr);

        // output
        bpf_trace_printk("4 %x %x %d\n", saddr, daddr, ntohs(dport));
    } else /* 6 */ {
        // just grab the last 4 bytes for now
        bpf_probe_read(&saddr, sizeof(saddr),
            &skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32[3]);
        bpf_probe_read(&daddr, sizeof(daddr),
            &skp->__sk_common.skc_v6_daddr.in6_u.u6_addr32[3]);

        // output and flip byte order of addresses
        bpf_trace_printk("6 %x %x %d\n", bpf_ntohl(saddr),
            bpf_ntohl(daddr), ntohs(dport));
    }

    currsock.delete(&pid);

    return 0;
}

int trace_connect_v4_return(struct pt_regs *ctx)
{
    return trace_connect_return(ctx, 4);
}

int trace_connect_v6_return(struct pt_regs *ctx)
{
    return trace_connect_return(ctx, 6);
}
 N/A N/A args pid N/A N/A bpf_text N/A N/A bpf_text replace FILTER N/A if (pid != %s) { return 0; } N/A args pid N/A N/A bpf_text N/A N/A bpf_text replace FILTER N/A debug N/A N/A N/A print bpf_text N/A b N/A BPF text bpf_text N/A N/A N/A b attach_kprobe event tcp_v4_connect fn_name trace_connect_entry N/A N/A N/A b attach_kprobe event tcp_v6_connect fn_name trace_connect_entry N/A N/A N/A b attach_kretprobe event tcp_v4_connect fn_name trace_connect_v4_return N/A N/A N/A b attach_kretprobe event tcp_v6_connect fn_name trace_connect_v6_return N/A N/A args timestamp N/A N/A N/A print N/A %-9s TIME(s) end N/A N/A print N/A %-6s %-12s %-2s %-16s %-16s %-4s N/A PID COMM IP SADDR DADDR DPORT N/A start_ts 0 inet_ntoa N/A N/A addr N/A N/A N/A dq N/A i N/A range 0 4 N/A N/A dq N/A dq N/A str N/A addr 255 N/A N/A i 3 N/A N/A dq N/A dq . N/A addr N/A addr 8 N/A dq N/A N/A 1 N/A N/A N/A task pid cpu flags ts msg N/A N/A b trace_fields N/A N/A ip_s saddr_hs daddr_hs dport_s N/A N/A msg split N/A N/A args timestamp N/A N/A N/A start_ts 0 N/A N/A start_ts ts N/A N/A print N/A %-9.3f N/A ts start_ts end N/A N/A print N/A %-6d %-12.12s %-2s %-16s %-16s %-4s N/A pid task ip_s N/A N/A ip_s 4 N/A inet_ntoa N/A int saddr_hs 16 N/A ... saddr_hs N/A N/A ip_s 4 N/A inet_ntoa N/A int daddr_hs 16 N/A ... daddr_hs dport_s