tools: add option to include 'LPORT' in tcpconnect otuput (#3301)
authorsuresh2514 <64078451+suresh2514@users.noreply.github.com>
Fri, 12 Mar 2021 04:05:14 +0000 (09:35 +0530)
committerGitHub <noreply@github.com>
Fri, 12 Mar 2021 04:05:14 +0000 (20:05 -0800)
add option to include 'LPORT' in tcpconnect otuput and
update man page for tcpconnect and add examples

man/man8/tcpconnect.8
tools/tcpconnect.py
tools/tcpconnect_example.txt

index e298dec4e6269c2ac3df20664e7d95e68882945c..55105709e41befc39780391844c6f509846d27b3 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 tcpconnect \- Trace TCP active connections (connect()). Uses Linux eBPF/bcc.
 .SH SYNOPSIS
-.B tcpconnect [\-h] [\-c] [\-t] [\-p PID] [-P PORT] [-u UID] [-U] [\-\-cgroupmap MAPPATH] [\-\-mntnsmap MAPPATH] [\-d]
+.B tcpconnect [\-h] [\-c] [\-t] [\-p PID] [-P PORT] [\-L] [-u UID] [-U] [\-\-cgroupmap MAPPATH] [\-\-mntnsmap MAPPATH] [\-d]
 .SH DESCRIPTION
 This tool traces active TCP connections (eg, via a connect() syscall;
 accept() are passive connections). This can be useful for general
@@ -43,6 +43,9 @@ Trace this process ID only (filtered in-kernel).
 \-P PORT
 Comma-separated list of destination ports to trace (filtered in-kernel).
 .TP
+\-L
+Include a LPORT column.
+.TP
 \-U
 Include a UID column.
 .TP
@@ -96,6 +99,10 @@ Trace ports 80 and 81 only:
 #
 .B tcpconnect \-P 80,81
 .TP
+Trace all TCP connects, and include LPORT:
+#
+.B tcpconnect \-L
+.TP
 Trace all TCP connects, and include UID:
 #
 .B tcpconnect \-U
@@ -135,6 +142,9 @@ IP address family (4 or 6)
 SADDR
 Source IP address.
 .TP
+LPORT
+Source port
+.TP
 DADDR
 Destination IP address.
 .TP
index acdf176723dc158b7e6e5a365fdcfb75b2ac28bb..0d204ea5c69fc95151d08fbc488c9301dedc9ed6 100755 (executable)
@@ -19,6 +19,7 @@
 # 09-Jan-2019   Takuma Kume     Support filtering by UID
 # 30-Jul-2019   Xiaozhou Liu    Count connects.
 # 07-Oct-2020   Nabil Schear    Correlate connects with DNS responses
+# 08-Mar-2021   Suresh Kumar    Added LPORT option
 
 from __future__ import print_function
 from bcc import BPF
@@ -41,6 +42,7 @@ examples = """examples:
     ./tcpconnect -U        # include UID
     ./tcpconnect -u 1000   # only trace UID 1000
     ./tcpconnect -c        # count connects per src ip and dest ip/port
+    ./tcpconnect -L        # include LPORT while printing outputs
     ./tcpconnect --cgroupmap mappath  # only trace cgroups in this BPF map
     ./tcpconnect --mntnsmap mappath   # only trace mount namespaces in the map
 """
@@ -54,6 +56,8 @@ parser.add_argument("-p", "--pid",
     help="trace this PID only")
 parser.add_argument("-P", "--port",
     help="comma-separated list of destination ports to trace.")
+parser.add_argument("-L", "--lport", action="store_true",
+    help="include LPORT on output")
 parser.add_argument("-U", "--print-uid", action="store_true",
     help="include UID on output")
 parser.add_argument("-u", "--uid",
@@ -87,6 +91,7 @@ struct ipv4_data_t {
     u32 saddr;
     u32 daddr;
     u64 ip;
+    u16 lport;
     u16 dport;
     char task[TASK_COMM_LEN];
 };
@@ -99,6 +104,7 @@ struct ipv6_data_t {
     unsigned __int128 saddr;
     unsigned __int128 daddr;
     u64 ip;
+    u16 lport;
     u16 dport;
     char task[TASK_COMM_LEN];
 };
@@ -161,6 +167,7 @@ static int trace_connect_return(struct pt_regs *ctx, short ipver)
 
     // pull in details
     struct sock *skp = *skpp;
+    u16 lport = skp->__sk_common.skc_num;
     u16 dport = skp->__sk_common.skc_dport;
 
     FILTER_PORT
@@ -202,6 +209,7 @@ struct_init = {'ipv4':
                data4.ts_us = bpf_ktime_get_ns() / 1000;
                data4.saddr = skp->__sk_common.skc_rcv_saddr;
                data4.daddr = skp->__sk_common.skc_daddr;
+               data4.lport = lport;
                data4.dport = ntohs(dport);
                bpf_get_current_comm(&data4.task, sizeof(data4.task));
                ipv4_events.perf_submit(ctx, &data4, sizeof(data4));"""
@@ -225,6 +233,7 @@ struct_init = {'ipv4':
                    skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
                bpf_probe_read_kernel(&data6.daddr, sizeof(data6.daddr),
                    skp->__sk_common.skc_v6_daddr.in6_u.u6_addr32);
+               data6.lport = lport;
                data6.dport = ntohs(dport);
                bpf_get_current_comm(&data6.task, sizeof(data6.task));
                ipv6_events.perf_submit(ctx, &data6, sizeof(data6));"""
@@ -354,10 +363,16 @@ def print_ipv4_event(cpu, data, size):
     if args.print_uid:
         printb(b"%-6d" % event.uid, nl="")
     dest_ip = inet_ntop(AF_INET, pack("I", event.daddr)).encode()
-    printb(b"%-6d %-12.12s %-2d %-16s %-16s %-6d %s" % (event.pid,
-        event.task, event.ip,
-        inet_ntop(AF_INET, pack("I", event.saddr)).encode(),
-        dest_ip, event.dport, print_dns(dest_ip)))
+    if args.lport:
+        printb(b"%-6d %-12.12s %-2d %-16s %-6d %-16s %-6d %s" % (event.pid,
+            event.task, event.ip,
+            inet_ntop(AF_INET, pack("I", event.saddr)).encode(), event.lport,
+            dest_ip, event.dport, print_dns(dest_ip)))
+    else:
+        printb(b"%-6d %-12.12s %-2d %-16s %-16s %-6d %s" % (event.pid,
+            event.task, event.ip,
+            inet_ntop(AF_INET, pack("I", event.saddr)).encode(),
+            dest_ip, event.dport, print_dns(dest_ip)))
 
 def print_ipv6_event(cpu, data, size):
     event = b["ipv6_events"].event(data)
@@ -369,10 +384,16 @@ def print_ipv6_event(cpu, data, size):
     if args.print_uid:
         printb(b"%-6d" % event.uid, nl="")
     dest_ip = inet_ntop(AF_INET6, event.daddr).encode()
-    printb(b"%-6d %-12.12s %-2d %-16s %-16s %-6d %s" % (event.pid,
-        event.task, event.ip,
-        inet_ntop(AF_INET6, event.saddr).encode(), dest_ip,
-        event.dport, print_dns(dest_ip)))
+    if args.lport:
+        printb(b"%-6d %-12.12s %-2d %-16s %-6d %-16s %-6d %s" % (event.pid,
+            event.task, event.ip,
+            inet_ntop(AF_INET6, event.saddr).encode(), event.lport,
+            dest_ip, event.dport, print_dns(dest_ip)))
+    else:
+        printb(b"%-6d %-12.12s %-2d %-16s %-16s %-6d %s" % (event.pid,
+            event.task, event.ip,
+            inet_ntop(AF_INET6, event.saddr).encode(),
+            dest_ip, event.dport, print_dns(dest_ip)))
 
 def depict_cnt(counts_tab, l3prot='ipv4'):
     for k, v in sorted(counts_tab.items(),
@@ -490,8 +511,12 @@ else:
         print("%-9s" % ("TIME(s)"), end="")
     if args.print_uid:
         print("%-6s" % ("UID"), end="")
-    print("%-6s %-12s %-2s %-16s %-16s %-6s" % ("PID", "COMM", "IP", "SADDR",
-        "DADDR", "DPORT"), end="")
+    if args.lport:
+        print("%-6s %-12s %-2s %-16s %-6s %-16s %-6s" % ("PID", "COMM", "IP", "SADDR",
+            "LPORT", "DADDR", "DPORT"), end="")
+    else:
+        print("%-6s %-12s %-2s %-16s %-16s %-6s" % ("PID", "COMM", "IP", "SADDR",
+            "DADDR", "DPORT"), end="")
     if args.dns:
         print(" QUERY")
     else:
index b8ad22d1326d7e20ff797204ce73505728334b08..f2e6d72f3e502d1bd300b269f26041e8121da0d0 100644 (file)
@@ -55,6 +55,15 @@ PID    COMM         IP SADDR            DADDR            DPORT QUERY
 2015   ssh          6  fe80::2000:bff:fe82:3ac fe80::2000:bff:fe82:3ac 22    anotherhost.org
 
 
+The -L option prints a LPORT column:
+
+# ./tcpconnect -L
+PID    COMM         IP SADDR            LPORT  DADDR            DPORT
+3706   nc           4  192.168.122.205  57266  192.168.122.150  5000
+3722   ssh          4  192.168.122.205  50966  192.168.122.150  22
+3779   ssh          6  fe80::1          52328  fe80::2          22
+
+
 The -U option prints a UID column:
 
 # ./tcpconnect -U
@@ -97,7 +106,7 @@ USAGE message:
 
 # ./tcpconnect -h
 
-usage: tcpconnect.py [-h] [-t] [-p PID] [-P PORT] [-U] [-u UID] [-c]
+usage: tcpconnect.py [-h] [-t] [-p PID] [-P PORT] [-L] [-U] [-u UID] [-c]
                      [--cgroupmap CGROUPMAP] [--mntnsmap MNTNSMAP] [-d]
 
 Trace TCP connects
@@ -107,6 +116,7 @@ optional arguments:
   -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.
+  -L, --lport           include LPORT on output
   -U, --print-uid       include UID on output
   -u UID, --uid UID     trace this UID only
   -c, --count           count connects per src ip and dest ip/port
@@ -118,11 +128,13 @@ optional arguments:
 examples:
     ./tcpconnect           # trace all TCP connect()s
     ./tcpconnect -t        # include timestamps
+    ./tcpconnect -d        # include DNS queries associated with connects
     ./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
     ./tcpconnect -c        # count connects per src ip and dest ip/port
+    ./tcpconnect -L        # include LPORT while printing outputs
     ./tcpconnect --cgroupmap mappath  # only trace cgroups in this BPF map
-    ./tcpconnect --mntnsmap mappath   # only trace mount namespaces in the map
\ No newline at end of file
+    ./tcpconnect --mntnsmap mappath   # only trace mount namespaces in the map