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

net_watcher:添加端口过滤功能、测试 #962

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 5 additions & 1 deletion MagicEyes/src/backend/net/net_watcher/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ foreach(app ${apps})
add_dependencies(${app_stem}_skel libbpf-build bpftool-build)
endforeach()

add_executable(${TOOL_NAME} src/${TOOL_NAME}.c)
# add_executable(${TOOL_NAME} src/${TOOL_NAME}.c)
add_executable(${TOOL_NAME}
src/${TOOL_NAME}.c
src/net_watcher_hepler.c
)
foreach (app ${apps})
get_filename_component(app_stem ${app} NAME_WE)
target_link_libraries(${TOOL_NAME} ${app_stem}_skel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ SEC("kprobe/tcp_enter_loss")
int BPF_KPROBE(tcp_enter_loss, struct sock *sk) { return __tcp_enter_loss(sk); }

/* udp */
//收包 udp_rcv-->__udp_enqueue_schedule_skb(数据包排队)
SEC("kprobe/udp_rcv")
int BPF_KPROBE(udp_rcv, struct sk_buff *skb) {
if (udp_info)
Expand All @@ -242,7 +243,7 @@ int BPF_KPROBE(__udp_enqueue_schedule_skb, struct sock *sk,
struct sk_buff *skb) {
return udp_enqueue_schedule_skb(sk, skb);
}

//发包 udp_send_skb-->ip_send_skb(skb 交给 IP 协议层)
SEC("kprobe/udp_send_skb")
int BPF_KPROBE(udp_send_skb, struct sk_buff *skb) {
if (udp_info)
Expand Down
86 changes: 54 additions & 32 deletions MagicEyes/src/backend/net/net_watcher/bpf/udp.bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
// author: [email protected]

#include "common.bpf.h"

static __always_inline int __udp_rcv(struct sk_buff *skb) {
// receive
static __always_inline int __udp_rcv(struct sk_buff *skb)
{
if (!udp_info || skb == NULL)
return 0;
struct iphdr *ip = skb_to_iphdr(skb);
Expand All @@ -27,14 +28,16 @@ static __always_inline int __udp_rcv(struct sk_buff *skb) {
struct ktime_info *tinfo, zero = {0};
tinfo = (struct ktime_info *)bpf_map_lookup_or_try_init(&timestamps,
&pkt_tuple, &zero);
if (tinfo == NULL) {
if (tinfo == NULL)
{
return 0;
}
tinfo->tran_time = bpf_ktime_get_ns() / 1000;
return 0;
}
static __always_inline int udp_enqueue_schedule_skb(struct sock *sk,
struct sk_buff *skb) {
struct sk_buff *skb)
{
if (!udp_info || skb == NULL)
return 0;
struct iphdr *ip = skb_to_iphdr(skb);
Expand All @@ -44,14 +47,16 @@ static __always_inline int udp_enqueue_schedule_skb(struct sock *sk,
FILTER
struct ktime_info *tinfo, zero = {0};
tinfo = bpf_map_lookup_elem(&timestamps, &pkt_tuple);
if (tinfo == NULL) {
if (tinfo == NULL)
{
return 0;
}
struct udp_message *message;
struct udp_message *udp_message =
bpf_map_lookup_elem(&timestamps, &pkt_tuple);
message = bpf_ringbuf_reserve(&udp_rb, sizeof(*message), 0);
if (!message) {
if (!message)
{
return 0;
}
message->saddr = pkt_tuple.saddr;
Expand All @@ -60,36 +65,37 @@ static __always_inline int udp_enqueue_schedule_skb(struct sock *sk,
message->sport = pkt_tuple.sport;
message->tran_time = bpf_ktime_get_ns() / 1000 - tinfo->tran_time;
message->rx = 1; // 收包
message->len = __bpf_ntohs(BPF_CORE_READ(udp, len));
message->len = __bpf_ntohs(BPF_CORE_READ(udp, len)) - UDP_HEAD;
bpf_ringbuf_submit(message, 0);
return 0;
}

static __always_inline int __udp_send_skb(struct sk_buff *skb) {
// send
static __always_inline int __udp_send_skb(struct sk_buff *skb)
{
if (!udp_info || skb == NULL)
return 0;
struct packet_tuple pkt_tuple = {0};
struct sock *sk = BPF_CORE_READ(skb, sk);
u16 dport = BPF_CORE_READ(sk, __sk_common.skc_dport);
u16 sport = BPF_CORE_READ(sk, __sk_common.skc_num);
pkt_tuple.saddr = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr); // 源ip
pkt_tuple.daddr = BPF_CORE_READ(sk, __sk_common.skc_daddr); // 目的ip
pkt_tuple.sport = sport; // 源端口
pkt_tuple.dport = __bpf_ntohs(dport); // 目的端口并进行字节序转换
pkt_tuple.saddr = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr);
pkt_tuple.daddr = BPF_CORE_READ(sk, __sk_common.skc_daddr);
pkt_tuple.sport = sport;
pkt_tuple.dport = __bpf_ntohs(dport);
pkt_tuple.tran_flag = UDP;
FILTER
struct ktime_info *tinfo, zero = {0};
bpf_printk("udp_send_skb%d %d %d %d", pkt_tuple.saddr, pkt_tuple.daddr,
pkt_tuple.sport, pkt_tuple.dport);
tinfo = (struct ktime_info *)bpf_map_lookup_or_try_init(&timestamps,
&pkt_tuple, &zero);
if (tinfo == NULL) {
if (tinfo == NULL)
{
return 0;
}
tinfo->tran_time = bpf_ktime_get_ns() / 1000;
return 0;
}
static __always_inline int __ip_send_skb(struct sk_buff *skb) {
static __always_inline int __ip_send_skb(struct sk_buff *skb)
{
if (!udp_info || skb == NULL)
return 0;
struct iphdr *ip = skb_to_iphdr(skb);
Expand All @@ -99,28 +105,31 @@ static __always_inline int __ip_send_skb(struct sk_buff *skb) {
FILTER
struct ktime_info *tinfo, zero = {0};
tinfo = bpf_map_lookup_elem(&timestamps, &pkt_tuple);
if (tinfo == NULL) {
if (tinfo == NULL)
{
return 0;
}
struct udp_message *message;
struct udp_message *udp_message =
bpf_map_lookup_elem(&timestamps, &pkt_tuple);
message = bpf_ringbuf_reserve(&udp_rb, sizeof(*message), 0);
if (!message) {
if (!message)
{
return 0;
}
udp = skb_to_udphdr(skb);

message->tran_time = bpf_ktime_get_ns() / 1000 - tinfo->tran_time;
message->saddr = pkt_tuple.saddr;
message->daddr = pkt_tuple.daddr;
message->sport = pkt_tuple.sport;
message->dport = pkt_tuple.dport;
message->rx = 0; // 发包
message->len = __bpf_ntohs(BPF_CORE_READ(udp, len));
message->len = __bpf_ntohs(BPF_CORE_READ(udp, len)) - UDP_HEAD;
bpf_ringbuf_submit(message, 0);
return 0;
}
static __always_inline int process_dns_packet(struct sk_buff *skb, int rx) {
static __always_inline int process_dns_packet(struct sk_buff *skb, int rx)
{
if (skb == NULL)
return 0;
u16 QR_flags;
Expand Down Expand Up @@ -154,31 +163,42 @@ static __always_inline int process_dns_packet(struct sk_buff *skb, int rx) {
1000 0000 0000 0000
&运算提取最高位QR, QR=1 Response QR=0 Request
*/
if (QR_flags & 0x8000) { // 响应
if (QR_flags & 0x8000)
{ // 响应
count_ptr = bpf_map_lookup_elem(&dns_response_count, &key);
if (count_ptr) {
if (count_ptr)
{
response_count = *count_ptr + 1;
} else {
}
else
{
response_count = 1;
}
bpf_map_update_elem(&dns_response_count, &key, &response_count,
BPF_ANY);
// 保留映射中的请求计数值
count_ptr = bpf_map_lookup_elem(&dns_request_count, &key);
if (count_ptr) {
if (count_ptr)
{
request_count = *count_ptr;
}
} else { // 请求
}
else
{ // 请求
count_ptr = bpf_map_lookup_elem(&dns_request_count, &key);
if (count_ptr) {
if (count_ptr)
{
request_count = *count_ptr + 1;
} else {
}
else
{
request_count = 1;
}
bpf_map_update_elem(&dns_request_count, &key, &request_count, BPF_ANY);
// 保留映射中的响应计数值
count_ptr = bpf_map_lookup_elem(&dns_response_count, &key);
if (count_ptr) {
if (count_ptr)
{
response_count = *count_ptr;
}
}
Expand All @@ -197,10 +217,12 @@ static __always_inline int process_dns_packet(struct sk_buff *skb, int rx) {
bpf_ringbuf_submit(message, 0);
return 0;
}
static __always_inline int __dns_rcv(struct sk_buff *skb) {
static __always_inline int __dns_rcv(struct sk_buff *skb)
{
return process_dns_packet(skb, 0); // 0 收
}

static __always_inline int __dns_send(struct sk_buff *skb) {
static __always_inline int __dns_send(struct sk_buff *skb)
{
return process_dns_packet(skb, 1); // 1 发
}
10 changes: 8 additions & 2 deletions MagicEyes/src/backend/net/net_watcher/include/net_watcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,18 @@ typedef unsigned long long u64;
#define MAX_EVENTS 1024
#define CACHEMAXSIZE 5
#define PID 32
#define NS(x) ((x) * 1000000000) // 1 秒等于 10^9 纳秒
#define NS(x) ((x) * 1000000000LL) // 1 秒等于 10^9 纳秒
#define TIME_THRESHOLD_NS NS(10)
#define UDP_HEAD 8

typedef u64 stack_trace_t[MAX_STACK_DEPTH];

typedef struct
{
char key[256];
u32 value;
} kv_pair;

struct conn_t
{
void *sock; // 此tcp连接的 socket 地址
Expand Down Expand Up @@ -317,5 +324,4 @@ struct tcp_args_s {
u64 sample_period;
};


#endif /* __NET_WATCHER_H */
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright 2023 The LMP Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// author: [email protected]

#ifndef NET_WATCHER_HELPER_H
#define NET_WATCHER_HELPER_H
#include "net_watcher/include/net_watcher.h"
#include <arpa/inet.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include <string.h>

// logo
#define LOGO_STRING \
" " \
" __ __ __ " \
" \n" \
" /\\ \\__ /\\ \\__ /\\ \\ " \
" \n" \
" ___ __\\ \\ _\\ __ __ __ __ \\ \\ _\\ ___\\ \\ \\___ " \
" __ _ __ \n" \
"/ _ \\ / __ \\ \\ \\/ /\\ \\/\\ \\/\\ \\ / __ \\ \\ \\ \\/ / ___\\ " \
"\\ _ \\ / __ \\/\\ __\\ \n" \
"/\\ \\/\\ \\/\\ __/\\ \\ \\_\\ \\ \\_/ \\_/ \\/\\ \\_\\ \\_\\ \\ " \
"\\_/\\ \\__/\\ \\ \\ \\ \\/\\ __/\\ \\ \\/ \n" \
"\\ \\_\\ \\_\\ \\____\\ \\__\\ \\_______ / /\\ \\__/\\ \\_\\ \\__\\ " \
"\\____/\\ \\_\\ \\_\\ \\____ \\ \\_\\ \n" \
" \\/_/\\/_/\\/____/ \\/__/ \\/__//__ / \\/_/ \\/_/\\/__/\\/____/ " \
"\\/_/\\/_/\\/____/ \\/_/ \n\n"
//
#define __ATTACH_UPROBE_GENERIC(skel, sym_name, prog_name, is_retprobe) \
do \
{ \
LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts, .func_name = #sym_name, \
.retprobe = is_retprobe); \
skel->links.prog_name = bpf_program__attach_uprobe_opts( \
skel->progs.prog_name, -1, binary_path, 0, &uprobe_opts); \
if (!skel->links.prog_name) \
{ \
perror("no program attached for " #prog_name); \
return -errno; \
} \
} while (false)

// 入口探针
#define ATTACH_UPROBE(skel, sym_name, prog_name) \
__ATTACH_UPROBE_GENERIC(skel, sym_name, prog_name, false)

// 返回探针
#define ATTACH_URETPROBE(skel, sym_name, prog_name) \
__ATTACH_UPROBE_GENERIC(skel, sym_name, prog_name, true)

// 入口探针,检查是否成功附加
#define ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name) \
__ATTACH_UPROBE_GENERIC(skel, sym_name, prog_name, false)

// 返回探针,检查是否成功附加
#define ATTACH_URETPROBE_CHECKED(skel, sym_name, prog_name) \
__ATTACH_UPROBE_GENERIC(skel, sym_name, prog_name, true)

extern struct SymbolEntry symbols[300000];
extern struct SymbolEntry cache[CACHEMAXSIZE];
extern int event_count, num_symbols, cache_size;
extern float ewma_values[NUM_LAYERS];
extern int count[NUM_LAYERS];

int should_filter(const char *src, const char *dst, const char *filter_src_ip, const char *filter_dst_ip);
int process_delay(float layer_delay, int layer_index);
void print_logo();
void bytes_to_str(char *str, unsigned long long num);
void readallsym();
struct SymbolEntry findfunc(unsigned long int addr);
void add_to_cache(struct SymbolEntry entry);
struct SymbolEntry find_in_cache(unsigned long int addr);
int process_delay(float layer_delay, int layer_index);
float calculate_ewma(float new_value, float old_ewma);
int process_redis_first(char flag, char *message);
int create_ring_buffer(struct ring_buffer **rb, int map_fd, void *print_fn, const char *name);
int poll_ring_buffers(struct ring_buffer *buffers[], int num_buffers, int timeout_ms);
void print_domain_name(const unsigned char *data, char *output);
int should_filter_t(const char *src, const char *dst, unsigned short sport, unsigned short dport,const char *filter_src_ip, const char *filter_dst_ip, unsigned short filter_sport, unsigned short filter_dport);

#endif
Loading