-
-
Save StoneMoe/cdd6ea110cbbfbcb29a7ef91bc5c9469 to your computer and use it in GitHub Desktop.
ICMP packet tracer using BCC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
bpf_text = """ | |
#include <linux/ptrace.h> | |
#include <linux/sched.h> /* For TASK_COMM_LEN */ | |
#include <linux/icmp.h> | |
#include <linux/netdevice.h> | |
struct probe_icmp_data_t | |
{ | |
u64 timestamp_ns; | |
u32 tgid; | |
u32 pid; | |
char comm[TASK_COMM_LEN]; | |
u16 v0; | |
}; | |
BPF_PERF_OUTPUT(probe_icmp_events); | |
static inline unsigned char *my_skb_transport_header(const struct sk_buff *skb) | |
{ | |
unsigned char *head; | |
u16 ts; | |
bpf_probe_read(&ts, sizeof(ts), &skb->transport_header); | |
bpf_probe_read(&head, sizeof(head), &skb->head); | |
return (unsigned char*)(head + ts); | |
} | |
static inline struct icmphdr *my_icmp_hdr(const struct sk_buff *skb) | |
{ | |
return (struct icmphdr *)my_skb_transport_header(skb); | |
} | |
int probe_icmp(struct pt_regs *ctx, struct sk_buff *skb) | |
{ | |
u64 __pid_tgid = bpf_get_current_pid_tgid(); | |
u32 __tgid = __pid_tgid >> 32; | |
u32 __pid = __pid_tgid; // implicit cast to u32 for bottom half | |
struct probe_icmp_data_t __data = {0}; | |
__data.timestamp_ns = bpf_ktime_get_ns(); | |
__data.tgid = __tgid; | |
__data.pid = __pid; | |
bpf_get_current_comm(&__data.comm, sizeof(__data.comm)); | |
__be16 seq; | |
bpf_probe_read(&seq, sizeof(seq), &my_icmp_hdr(skb)->un.echo.sequence); | |
__data.v0 = ntohs(seq); | |
probe_icmp_events.perf_submit(ctx, &__data, sizeof(__data)); | |
return 0; | |
} | |
""" | |
from bcc import BPF | |
import ctypes as ct | |
class Data_icmp(ct.Structure): | |
_fields_ = [ | |
("timestamp_ns", ct.c_ulonglong), | |
("tgid", ct.c_uint), | |
("pid", ct.c_uint), | |
("comm", ct.c_char * 16), # TASK_COMM_LEN | |
('v0', ct.c_ushort), | |
] | |
b = BPF(text=bpf_text) | |
rtt = 0 | |
def print_icmp_event(cpu, data, size): | |
global rtt | |
#event = b["probe_icmp_events"].event(data) | |
event = ct.cast(data, ct.POINTER(Data_icmp)).contents | |
print("%-7d %-7d %-15s %s --\t\t %-16d" % | |
(event.tgid, event.pid, | |
event.comm.decode('utf-8', 'replace'), | |
event.v0, (event.timestamp_ns - rtt)/1000000)) | |
rtt = event.timestamp_ns | |
b.attach_kprobe(event="icmp_echo", fn_name="probe_icmp") | |
b["probe_icmp_events"].open_perf_buffer(print_icmp_event) | |
while 1: | |
try: | |
b.kprobe_poll() | |
except KeyboardInterrupt: | |
exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment