Skip to content

Commit

Permalink
[tcpconnect] filter traced connection based on destination ports
Browse files Browse the repository at this point in the history
Test:
While running:
while [ 1 ]; do nc -w 1 100.127.0.1 80; nc -w 1 100.127.0.1 81; done

root@vagrant:/mnt/bcc# ./tools/tcpconnect.py
PID    COMM         IP SADDR            DADDR            DPORT
19978  nc           4  10.0.2.15        100.127.0.1      80
19979  nc           4  10.0.2.15        100.127.0.1      81
19980  nc           4  10.0.2.15        100.127.0.1      80
19981  nc           4  10.0.2.15        100.127.0.1      81
root@vagrant:/mnt/bcc# ./tools/tcpconnect.py  -P 80
PID    COMM         IP SADDR            DADDR            DPORT
19987  nc           4  10.0.2.15        100.127.0.1      80
19989  nc           4  10.0.2.15        100.127.0.1      80
19991  nc           4  10.0.2.15        100.127.0.1      80
19993  nc           4  10.0.2.15        100.127.0.1      80
19995  nc           4  10.0.2.15        100.127.0.1      80
root@vagrant:/mnt/bcc# ./tools/tcpconnect.py  -P 80,81
PID    COMM         IP SADDR            DADDR            DPORT
8725   nc           4  10.0.2.15        100.127.0.1      80
8726   nc           4  10.0.2.15        100.127.0.1      81
8727   nc           4  10.0.2.15        100.127.0.1      80
8728   nc           4  10.0.2.15        100.127.0.1      81
8729   nc           4  10.0.2.15        100.127.0.1      80

Fixes #681
  • Loading branch information
chantra committed Sep 16, 2016
1 parent 1298998 commit 5293805
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 8 deletions.
9 changes: 8 additions & 1 deletion man/man8/tcpconnect.8
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.SH NAME
tcpconnect \- Trace TCP active connections (connect()). Uses Linux eBPF/bcc.
.SH SYNOPSIS
.B tcpconnect [\-h] [\-t] [\-x] [\-p PID]
.B tcpconnect [\-h] [\-t] [\-x] [\-p PID] [-P PORT]
.SH DESCRIPTION
This tool traces active TCP connections (eg, via a connect() syscall;
accept() are passive connections). This can be useful for general
Expand All @@ -27,6 +27,9 @@ Include a timestamp column.
.TP
\-p PID
Trace this process ID only (filtered in-kernel).
.TP
\-P PORT
Comma-separated list of destination ports to trace (filtered in-kernel).
.SH EXAMPLES
.TP
Trace all active TCP connections:
Expand All @@ -40,6 +43,10 @@ Trace all TCP connects, and include timestamps:
Trace PID 181 only:
#
.B tcpconnect \-p 181
.TP
Trace ports 80 and 81 only:
#
.B tcpconnect \-P 80,81
.SH FIELDS
.TP
TIME(s)
Expand Down
25 changes: 19 additions & 6 deletions tools/tcpconnect.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# tcpconnect Trace TCP connect()s.
# For Linux, uses BCC, eBPF. Embedded C.
#
# USAGE: tcpconnect [-h] [-t] [-p PID]
# USAGE: tcpconnect [-h] [-t] [-p PID] [-P PORT [PORT ...]]
#
# All connection attempts are traced, even if they ultimately fail.
#
Expand All @@ -20,7 +20,7 @@
from __future__ import print_function
from bcc import BPF
import argparse
from socket import inet_ntop, AF_INET, AF_INET6
from socket import inet_ntop, ntohs, AF_INET, AF_INET6
from struct import pack
import ctypes as ct

Expand All @@ -29,6 +29,8 @@
./tcpconnect # trace all TCP connect()s
./tcpconnect -t # include timestamps
./tcpconnect -p 181 # only trace PID 181
./tcpconnect -P 80 # only trace port 80
./tcpconnect -P 80,81 # only trace port 80 and 81
"""
parser = argparse.ArgumentParser(
description="Trace TCP connects",
Expand All @@ -38,6 +40,8 @@
help="include timestamp on output")
parser.add_argument("-p", "--pid",
help="trace this PID only")
parser.add_argument("-P", "--port",
help="comma-separated list of destination ports to trace.")
args = parser.parse_args()
debug = 0

Expand Down Expand Up @@ -76,7 +80,7 @@
int trace_connect_entry(struct pt_regs *ctx, struct sock *sk)
{
u32 pid = bpf_get_current_pid_tgid();
FILTER
FILTER_PID
// stash the sock ptr for lookup on return
currsock.update(&pid, &sk);
Expand Down Expand Up @@ -107,6 +111,8 @@
u16 dport = 0;
bpf_probe_read(&dport, sizeof(dport), &skp->__sk_common.skc_dport);
FILTER_PORT
if (ipver == 4) {
struct ipv4_data_t data4 = {.pid = pid, .ip = ipver};
data4.ts_us = bpf_ktime_get_ns() / 1000;
Expand Down Expand Up @@ -148,10 +154,17 @@

# code substitutions
if args.pid:
bpf_text = bpf_text.replace('FILTER',
bpf_text = bpf_text.replace('FILTER_PID',
'if (pid != %s) { return 0; }' % args.pid)
else:
bpf_text = bpf_text.replace('FILTER', '')
if args.port:
dports = [int(dport) for dport in args.port.split(',')]
dports_if = ' && '.join(['dport != %d' % ntohs(dport) for dport in dports])
bpf_text = bpf_text.replace('FILTER_PORT',
'if (%s) { currsock.delete(&pid); return 0; }' % dports_if)

bpf_text = bpf_text.replace('FILTER_PID', '')
bpf_text = bpf_text.replace('FILTER_PORT', '')

if debug:
print(bpf_text)

Expand Down
6 changes: 5 additions & 1 deletion tools/tcpconnect_example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,20 @@ process to various other addresses. A few connections occur every minute.
USAGE message:

# ./tcpconnect -h
usage: tcpconnect [-h] [-t] [-p PID]
usage: tcpconnect [-h] [-t] [-p PID] [-P PORT]

Trace TCP connects

optional arguments:
-h, --help show this help message and exit
-t, --timestamp include timestamp on output
-p PID, --pid PID trace this PID only
-P PORT, --port PORT
comma-separated list of destination ports to trace.

examples:
./tcpconnect # trace all TCP connect()s
./tcpconnect -t # include timestamps
./tcpconnect -p 181 # only trace PID 181
./tcpconnect -P 80 # only trace port 80
./tcpconnect -P 80,81 # only trace port 80 and 81

4 comments on commit 5293805

@Murulidhar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi,
Please let me know how to solve import bcc error.

@chantra
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Murulidhar what does this diff has to do with your issue? You should open an issue with the content of the backtrace if you want people to be able to help you.

@Murulidhar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I didn't know this. So I asked you directly.
Anyways I just now solved it.
Thanks

@Murulidhar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,
Is there any ways to filter destination address also ? like if I mention destination address then only connections going to that IP only should be displayed.

Please sign in to comment.