Skip to content

Commit

Permalink
Modify the code according to chenhengqi's suggestion
Browse files Browse the repository at this point in the history
No more support timestamp and COMM, procedure as follows:
1. startup UNIX socket server:
```bash
[rongtao@bogon ~]$ nc --unixsock ./unix-sock -l
```
2. start UNIX socket client:
```bash
[rongtao@bogon ~]$ nc --unixsock ./unix-sock
```
3. startup undump.py script
```
[rongtao@bogon study]$ sudo ./undump2.py -p 41147
Tracing PID=41147 UNIX socket packets ... Hit Ctrl-C to end
```
4. send some packets
```
[rongtao@bogon ~]$ nc --unixsock ./unix-sock
abcdefg
1234567890
```

5. capture these packets
server recv:
```
[rongtao@bogon ~]$ nc --unixsock ./unix-sock -l
abcdefg
1234567890
```
undump.py capture
```
[rongtao@bogon study]$ sudo ./undump2.py -p 41147
Tracing PID=41147 UNIX socket packets ... Hit Ctrl-C to end
PID 41147 Recv 8 bytes
    61 62 63 64 65 66 67 0a 
PID 41147 Recv 11 bytes
    31 32 33 34 35 36 37 38 39 30 0a
```
  • Loading branch information
Rtoax committed Sep 17, 2021
1 parent 4d13c17 commit 4615a3f
Showing 1 changed file with 15 additions and 77 deletions.
92 changes: 15 additions & 77 deletions examples/tracing/undump.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
# Licensed under the GPL License, Version 2.0
#
# 27-Aug-2021 Rong Tao Created this.
# 17-Sep-2021 Rong Tao Simplify according to chenhengqi's suggestion
# https://github.com/iovisor/bcc/pull/3615
#
from __future__ import print_function
from bcc import BPF
Expand All @@ -27,16 +29,13 @@
# arguments
examples = """examples:
./undump # trace/dump all UNIX packets
./undump -t # include timestamps
./undump -p 181 # only trace/dump PID 181
"""
parser = argparse.ArgumentParser(
description="Dump UNIX socket packets",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=examples)

parser.add_argument("-t", "--timestamp",
action="store_true", help="include timestamp on output")
parser.add_argument("-p", "--pid",
help="trace this PID only")
args = parser.parse_args()
Expand All @@ -55,66 +54,17 @@
#include <net/sock.h>
#include <net/af_unix.h>
// separate data structs for ipv4 and ipv6
struct stream_data_t {
u64 ts_us;
u32 pid;
u32 uid;
u32 sock_state;
u32 sock_type; //type of socket[STREAM|DRGMA]
u64 sock_flags;
char task[TASK_COMM_LEN];
char *unix_sock_path;
int msg_namelen;
};
BPF_PERF_OUTPUT(stream_recvmsg_events);
#define MAX_PKT 512
struct recv_data_t {
u32 recv_len;
u8 pkt[MAX_PKT];
};
// single element per-cpu array to hold the current event off the stack
BPF_PERCPU_ARRAY(unix_data, struct recv_data_t,1);
BPF_PERCPU_ARRAY(unix_data, struct recv_data_t, 1);
BPF_PERF_OUTPUT(unix_recv_events);
//static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
// size_t size, int flags)
int trace_stream_entry(struct pt_regs *ctx)
{
int ret = PT_REGS_RC(ctx);
u64 pid_tgid = bpf_get_current_pid_tgid();
u32 pid = pid_tgid >> 32;
u32 tid = pid_tgid;
FILTER_PID
struct stream_data_t data4 = {.pid = pid,};
data4.uid = bpf_get_current_uid_gid();
data4.ts_us = bpf_ktime_get_ns() / 1000;
struct socket *sock = (struct socket *)PT_REGS_PARM1(ctx);
struct msghdr *msg = (struct msghdr *)PT_REGS_PARM2(ctx);
data4.sock_state = sock->state;
data4.sock_type = sock->type;
data4.sock_flags = sock->flags;
data4.msg_namelen = msg->msg_namelen;
bpf_get_current_comm(&data4.task, sizeof(data4.task));
struct unix_sock *unsock = (struct unix_sock *)sock->sk;
data4.unix_sock_path = (char *)unsock->path.dentry->d_name.name;
stream_recvmsg_events.perf_submit(ctx, &data4, sizeof(data4));
return 0;
};
int trace_unix_stream_read_actor(struct pt_regs *ctx)
{
u32 zero = 0;
Expand Down Expand Up @@ -151,50 +101,38 @@

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

# process event
def print_stream_event(cpu, data, size):
event = b["stream_recvmsg_events"].event(data)
global start_ts
if args.timestamp:
if start_ts == 0:
start_ts = event.ts_us
printb(b"%-9.3f" % ((float(event.ts_us) - start_ts) / 1000000), nl="")
printb(b"%-6s %-12s" % (event.pid, event.task))

# process event
def print_recv_pkg(cpu, data, size):
event = b["unix_recv_events"].event(data)
print("----------------", end="")
if args.pid:
print("PID \033[1;31m%s\033[m " % args.pid, end="")
print("Recv \033[1;31m%d\033[m bytes" % event.recv_len)

print(" ", end="")
for i in range(0, event.recv_len):
print("%02x " % event.pkt[i], end="")
sys.stdout.flush()
if (i+1)%16 == 0:
print("")
print("----------------", end="")
print("\n----------------recv %d bytes" % event.recv_len)
print(" ", end="")
print("")

# initialize BPF
b = BPF(text=bpf_text)
b.attach_kprobe(event="unix_stream_recvmsg", fn_name="trace_stream_entry")
b.attach_kprobe(event="unix_stream_read_actor", fn_name="trace_unix_stream_read_actor")

print("Tracing UNIX socket packets ... Hit Ctrl-C to end")

# header
if args.timestamp:
print("%-9s" % ("TIME(s)"), end="")

print("%-6s %-12s" % ("PID", "COMM"), end="")
if args.pid:
print("Tracing \033[1;31mPID=%s\033[m UNIX socket packets ... Hit Ctrl-C to end" % args.pid)
else:
print("Tracing UNIX socket packets ... Hit Ctrl-C to end")

start_ts = 0

# read events
b["stream_recvmsg_events"].open_perf_buffer(print_stream_event)
b["unix_recv_events"].open_perf_buffer(print_recv_pkg)

while True:
try:
b.perf_buffer_poll()
except KeyboardInterrupt:
exit()

0 comments on commit 4615a3f

Please sign in to comment.