Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tcpconnect: supported UID options #2118

Merged
merged 2 commits into from
Jan 9, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
tcpconnect: support uid option
  • Loading branch information
takumakume committed Jan 9, 2019
commit 1ae580918832302c29e028b3ce1ee00e103ee257
19 changes: 19 additions & 0 deletions man/man8/tcpconnect.8
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ Trace this process ID only (filtered in-kernel).
Comma-separated list of destination ports to trace (filtered in-kernel).
.SH EXAMPLES
.TP
\-U
Include a UID column.
.TP
\-u UID
Trace this UID only (filtered in-kernel).
.TP
Trace all active TCP connections:
#
.B tcpconnect
Expand All @@ -49,9 +55,22 @@ Trace ports 80 and 81 only:
.B tcpconnect \-P 80,81
.SH FIELDS
.TP
Trace all TCP connects, and include UID:
#
.B tcpconnect \-U
.SH FIELDS
.TP
Trace UID 1000 only:
#
.B tcpconnect \-u 1000
.SH FIELDS
.TP
TIME(s)
Time of the call, in seconds.
.TP
UID
User ID
.TP
PID
Process ID
.TP
Expand Down
26 changes: 26 additions & 0 deletions tools/tcpconnect.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#
# 25-Sep-2015 Brendan Gregg Created this.
# 14-Feb-2016 " " Switch to bpf_perf_output.
# 09-Jan-2019 Takuma Kume Support filtering by UID

from __future__ import print_function
from bcc import BPF
Expand All @@ -31,6 +32,8 @@
./tcpconnect -p 181 # only trace PID 181
./tcpconnect -P 80 # only trace port 80
./tcpconnect -P 80,81 # only trace port 80 and 81
./tcpconnect -U # include UID
./tcpconnect -u 1000 # only trace UID 1000
"""
parser = argparse.ArgumentParser(
description="Trace TCP connects",
Expand All @@ -42,6 +45,10 @@
help="trace this PID only")
parser.add_argument("-P", "--port",
help="comma-separated list of destination ports to trace.")
parser.add_argument("-U", "--print-uid", action="store_true",
help="include UID on output")
parser.add_argument("-u", "--uid",
help="trace this UID only")
parser.add_argument("--ebpf", action="store_true",
help=argparse.SUPPRESS)
args = parser.parse_args()
Expand All @@ -59,6 +66,7 @@
struct ipv4_data_t {
u64 ts_us;
u32 pid;
u32 uid;
u32 saddr;
u32 daddr;
u64 ip;
Expand All @@ -70,6 +78,7 @@
struct ipv6_data_t {
u64 ts_us;
u32 pid;
u32 uid;
unsigned __int128 saddr;
unsigned __int128 daddr;
u64 ip;
Expand All @@ -83,6 +92,9 @@
u32 pid = bpf_get_current_pid_tgid();
FILTER_PID

u32 uid = bpf_get_current_uid_gid();
FILTER_UID

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

Expand Down Expand Up @@ -115,6 +127,7 @@

if (ipver == 4) {
struct ipv4_data_t data4 = {.pid = pid, .ip = ipver};
data4.uid = bpf_get_current_uid_gid();
data4.ts_us = bpf_ktime_get_ns() / 1000;
data4.saddr = skp->__sk_common.skc_rcv_saddr;
data4.daddr = skp->__sk_common.skc_daddr;
Expand All @@ -124,6 +137,7 @@

} else /* 6 */ {
struct ipv6_data_t data6 = {.pid = pid, .ip = ipver};
data6.uid = bpf_get_current_uid_gid();
data6.ts_us = bpf_ktime_get_ns() / 1000;
bpf_probe_read(&data6.saddr, sizeof(data6.saddr),
skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
Expand Down Expand Up @@ -159,9 +173,13 @@
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)
if args.uid:
bpf_text = bpf_text.replace('FILTER_UID',
'if (uid != %s) { return 0; }' % args.uid)

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

if debug or args.ebpf:
print(bpf_text)
Expand All @@ -175,6 +193,7 @@ class Data_ipv4(ct.Structure):
_fields_ = [
("ts_us", ct.c_ulonglong),
("pid", ct.c_uint),
("uid", ct.c_uint),
("saddr", ct.c_uint),
("daddr", ct.c_uint),
("ip", ct.c_ulonglong),
Expand All @@ -186,6 +205,7 @@ class Data_ipv6(ct.Structure):
_fields_ = [
("ts_us", ct.c_ulonglong),
("pid", ct.c_uint),
("uid", ct.c_uint),
("saddr", (ct.c_ulonglong * 2)),
("daddr", (ct.c_ulonglong * 2)),
("ip", ct.c_ulonglong),
Expand All @@ -201,6 +221,8 @@ def print_ipv4_event(cpu, data, size):
if start_ts == 0:
start_ts = event.ts_us
print("%-9.3f" % ((float(event.ts_us) - start_ts) / 1000000), end="")
if args.print_uid:
print("%-6d" % event.uid, end="")
print("%-6d %-12.12s %-2d %-16s %-16s %-4d" % (event.pid,
event.task.decode('utf-8', 'replace'), event.ip,
inet_ntop(AF_INET, pack("I", event.saddr)),
Expand All @@ -213,6 +235,8 @@ def print_ipv6_event(cpu, data, size):
if start_ts == 0:
start_ts = event.ts_us
print("%-9.3f" % ((float(event.ts_us) - start_ts) / 1000000), end="")
if args.print_uid:
print("%-6d" % event.uid, end="")
print("%-6d %-12.12s %-2d %-16s %-16s %-4d" % (event.pid,
event.task.decode('utf-8', 'replace'), event.ip,
inet_ntop(AF_INET6, event.saddr), inet_ntop(AF_INET6, event.daddr),
Expand All @@ -228,6 +252,8 @@ def print_ipv6_event(cpu, data, size):
# header
if args.timestamp:
print("%-9s" % ("TIME(s)"), end="")
if args.print_uid:
print("%-6s" % ("UID"), end="")
print("%-6s %-12s %-2s %-16s %-16s %-4s" % ("PID", "COMM", "IP", "SADDR",
"DADDR", "DPORT"))

Expand Down
22 changes: 22 additions & 0 deletions tools/tcpconnect_example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,24 @@ The output shows some periodic connections (or attempts) from a "local_agent"
process to various other addresses. A few connections occur every minute.


The -U option prints a UID column:

# ./tcpconnect -U
UID PID COMM IP SADDR DADDR DPORT
0 31333 telnet 6 ::1 ::1 23
0 31333 telnet 4 127.0.0.1 127.0.0.1 23
1000 31322 curl 4 127.0.0.1 127.0.0.1 80
1000 31322 curl 6 ::1 ::1 80


The -u option filtering UID:

# ./tcpconnect -Uu 1000
UID PID COMM IP SADDR DADDR DPORT
1000 31338 telnet 6 ::1 ::1 23
1000 31338 telnet 4 127.0.0.1 127.0.0.1 23


USAGE message:

# ./tcpconnect -h
Expand All @@ -51,10 +69,14 @@ optional arguments:
-p PID, --pid PID trace this PID only
-P PORT, --port PORT
comma-separated list of destination ports to trace.
-U, --print-uid include UID on output
-u UID, --uid UID trace this UID only

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
./tcpconnect -U # include UID
./tcpconnect -u 1000 # only trace UID 1000