diff --git a/MagicEyes/src/backend/net/net_watcher/bpf/common.bpf.h b/MagicEyes/src/backend/net/net_watcher/bpf/common.bpf.h index 93e5080cf..87a70d5fd 100644 --- a/MagicEyes/src/backend/net/net_watcher/bpf/common.bpf.h +++ b/MagicEyes/src/backend/net/net_watcher/bpf/common.bpf.h @@ -28,7 +28,8 @@ #include #include -struct ktime_info { // us time stamp info发送数据包 +struct ktime_info +{ // us time stamp info发送数据包 u64 qdisc_time; // tx包离开mac层时间戳 u64 mac_time; // tx、rx包到达mac层时间戳 u64 ip_time; // tx、rx包到达ip层时间戳 @@ -39,7 +40,8 @@ struct ktime_info { // us time stamp info发送数据包 u8 data[MAX_HTTP_HEADER]; // 用户层数据 }; -struct packet_tuple { +struct packet_tuple +{ unsigned __int128 saddr_v6; // ipv6 源地址 unsigned __int128 daddr_v6; // ipv6 目的地址 u32 saddr; // 源地址 @@ -52,7 +54,8 @@ struct packet_tuple { u32 len; }; -struct tcpstate { +struct tcpstate +{ u32 saddr; u32 daddr; u16 sport; @@ -63,7 +66,8 @@ struct tcpstate { u64 time; }; -enum { +enum +{ e_ip_rcv = 0, e_ip_local_deliver, e_ip_local_deliver_finish, @@ -75,7 +79,8 @@ enum { nf_max } nf_hook; -enum { +enum +{ PROTO_TCP = 0, PROTO_UDP, PROTO_ICMP, @@ -83,18 +88,21 @@ enum { PROTO_MAX, }; -struct filtertime { +struct filtertime +{ struct packet_tuple init; struct packet_tuple done; u64 time[nf_max]; }; -struct ip_packet { +struct ip_packet +{ unsigned int saddr; // 源地址 unsigned int daddr; // 目的地址 }; -struct dns_header { +struct dns_header +{ u16 id; // 事务ID u16 flags; // 标志字段 u16 qdcount; // 问题部分计数 @@ -103,29 +111,34 @@ struct dns_header { u16 arcount; // 附加记录计数 }; -struct dns_query { +struct dns_query +{ struct dns_header header; // DNS头部 char data[64]; // 可变长度数据(域名+类型+类) }; -struct dns { +struct dns +{ u32 saddr; u32 daddr; }; -struct query_info { +struct query_info +{ char msql[256]; u32 size; u64 start_time; }; -struct hist { +struct hist +{ u64 slots[MAX_SLOTS]; u64 latency; u64 cnt; }; -struct trace_event_raw_tcp_send_reset { +struct trace_event_raw_tcp_send_reset +{ unsigned short common_type; unsigned char common_flags; unsigned char common_preempt_count; @@ -142,7 +155,8 @@ struct trace_event_raw_tcp_send_reset { __u8 daddr_v6[16]; }; -struct trace_event_raw_tcp_receive_reset { +struct trace_event_raw_tcp_receive_reset +{ unsigned short common_type; unsigned char common_flags; unsigned char common_preempt_count; @@ -159,16 +173,17 @@ struct trace_event_raw_tcp_receive_reset { }; #define MAX_CONN 1000 #define MAX_SLOTS 27 -// 操作BPF映射的一个辅助函数 -static __always_inline void * //__always_inline强制内联 -bpf_map_lookup_or_try_init(void *map, const void *key, const void *init) { + +static __always_inline void * +bpf_map_lookup_or_try_init(void *map, const void *key, const void *init) +{ void *val; long err; - val = bpf_map_lookup_elem(map, key); // 在BPF映射中查找具有给定键的条目 + val = bpf_map_lookup_elem(map, key); if (val) return val; - // 此时没有对应key的value + err = bpf_map_update_elem(map, key, init, BPF_NOEXIST); // 向BPF映射中插入或更新一个条目 if (err && err != -EEXIST) // 插入失败 @@ -180,7 +195,8 @@ bpf_map_lookup_or_try_init(void *map, const void *key, const void *init) { char LICENSE[] SEC("license") = "Dual BSD/GPL"; // 存储每个packet_tuple包所对应的ktime_info时间戳 -struct { +struct +{ __uint(type, BPF_MAP_TYPE_LRU_HASH); __uint(max_entries, MAX_CONN *MAX_PACKET); __type(key, struct packet_tuple); @@ -188,78 +204,93 @@ struct { } timestamps SEC(".maps"); // 包相关信息通过此buffer提供给userspace -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } rb SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } rtt_rb SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } udp_rb SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } netfilter_rb SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } mysql_rb SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } redis_rb SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } kfree_rb SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } icmp_rb SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } tcp_rb SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } dns_rb SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } trace_rb SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } redis_stat_rb SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } events SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } port_rb SEC(".maps"); // 存储每个tcp连接所对应的conn_t -struct { +struct +{ __uint(type, BPF_MAP_TYPE_LRU_HASH); __uint(max_entries, MAX_CONN); __type(key, struct sock *); @@ -267,7 +298,8 @@ struct { } conns_info SEC(".maps"); // 根据ptid存储sock指针,从而在上下文无sock的内核探测点获得sock -struct { +struct +{ __uint(type, BPF_MAP_TYPE_LRU_HASH); __uint(max_entries, MAX_CONN); __type(key, u64); @@ -275,35 +307,40 @@ struct { } sock_stores SEC(".maps"); // 存储每个pid所对应的udp包 -struct { +struct +{ __uint(type, BPF_MAP_TYPE_LRU_HASH); __uint(max_entries, MAX_CONN *MAX_PACKET); __type(key, int); __type(value, struct packet_tuple); } pid_UDP SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_LRU_HASH); __uint(max_entries, MAX_CONN *MAX_PACKET); __type(key, struct sk_buff *); __type(value, struct filtertime); } netfilter_time SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_LRU_HASH); __uint(max_entries, MAX_CONN *MAX_PACKET); __type(key, int); __type(value, struct packet_tuple); } kfree SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_LRU_HASH); __uint(max_entries, MAX_CONN *MAX_PACKET); __type(key, struct ip_packet); __type(value, unsigned long long); } icmp_time SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 256 * 1024); __type(key, struct sock *); @@ -311,7 +348,8 @@ struct { } tcp_state SEC(".maps"); // sql 耗时 -struct { +struct +{ __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 256 * 1024); __type(key, __u32); @@ -319,7 +357,8 @@ struct { } mysql_time SEC(".maps"); // redis 耗时 -struct { +struct +{ __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 256 * 1024); __type(key, __u32); @@ -327,7 +366,8 @@ struct { } redis_time SEC(".maps"); // sql请求数 -struct { +struct +{ __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 1024); __type(key, __u32); @@ -335,21 +375,24 @@ struct { } sql_count SEC(".maps"); // dns计数根据每个saddr、daddr -struct { +struct +{ __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 1024); __type(key, struct dns); __type(value, __u64); } dns_request_count SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 1024); __type(key, struct dns); __type(value, __u64); } dns_response_count SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 1024); __type(key, __u32); @@ -357,31 +400,35 @@ struct { } queries SEC(".maps"); // 定义一个哈希映射,用于存储直方图数据 -struct { +struct +{ __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 256 * 1024); __type(key, struct ip_packet); __type(value, struct hist); } hists SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_HASH); __type(key, u32); __type(value, u64); __uint(max_entries, 1024); } counters SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_ARRAY); __uint(max_entries, MAX_COMM *MAX_PACKET); __type(key, u32); __type(value, struct packet_count); } proto_stats SEC(".maps"); -struct { +struct +{ __uint(type, BPF_MAP_TYPE_HASH); - __type(key, char*); // 键的最大长度,假设为 256 字节 - __type(value, u32); // 计数值 - __uint(max_entries, 1024); // 最大条目数 + __type(key, char *); // 键的最大长度,假设为 256 字节 + __type(value, u32); // 计数值 + __uint(max_entries, 1024); // 最大条目数 } key_count SEC(".maps"); const volatile int filter_dport = 0; @@ -391,117 +438,126 @@ const volatile int all_conn = 0, err_packet = 0, extra_conn_info = 0, udp_info = 0, net_filter = 0, drop_reason = 0, icmp_info = 0, tcp_info = 0, dns_info = 0, stack_info = 0, mysql_info = 0, redis_info = 0, rtt_info = 0, rst_info = 0, - protocol_count = 0,redis_stat = 0;; + protocol_count = 0, redis_stat = 0; +; /* help macro */ -#define FILTER \ - if (filter_dport && filter_dport != pkt_tuple.dport) \ - return 0; \ - if (filter_sport && filter_sport != pkt_tuple.sport) \ +#define FILTER \ + if (filter_dport && filter_dport != pkt_tuple.dport) \ + return 0; \ + if (filter_sport && filter_sport != pkt_tuple.sport) \ return 0; // 连接的目标端口是否匹配于filter_dport的值 -#define FILTER_DPORT \ - if (filter_dport) { \ - if (conn.dport != filter_dport) { \ - return 0; \ - } \ +#define FILTER_DPORT \ + if (filter_dport) \ + { \ + if (conn.dport != filter_dport) \ + { \ + return 0; \ + } \ } // 连接的源端口是否匹配于filter_sport的值 -#define FILTER_SPORT \ - if (filter_sport) { \ - if (conn.sport != filter_sport) { \ - return 0; \ - } \ +#define FILTER_SPORT \ + if (filter_sport) \ + { \ + if (conn.sport != filter_sport) \ + { \ + return 0; \ + } \ } // 初始化conn_t结构 -#define CONN_INIT \ - struct conn_t conn = {0}; \ - conn.pid = ptid >> 32; \ - conn.ptid = ptid; \ - u16 protocol = BPF_CORE_READ(sk, sk_protocol); \ - if (protocol != IPPROTO_TCP) \ - return 0; \ - bpf_get_current_comm(&conn.comm, sizeof(conn.comm)); \ - conn.sock = sk; \ - u16 family = BPF_CORE_READ(sk, __sk_common.skc_family); \ - __be16 dport = BPF_CORE_READ(sk, __sk_common.skc_dport); \ - u16 sport = BPF_CORE_READ(sk, __sk_common.skc_num); \ - conn.family = family; \ - conn.sport = sport; \ - conn.dport = __bpf_ntohs(dport); \ +#define CONN_INIT \ + struct conn_t conn = {0}; \ + conn.pid = ptid >> 32; \ + conn.ptid = ptid; \ + u16 protocol = BPF_CORE_READ(sk, sk_protocol); \ + if (protocol != IPPROTO_TCP) \ + return 0; \ + bpf_get_current_comm(&conn.comm, sizeof(conn.comm)); \ + conn.sock = sk; \ + u16 family = BPF_CORE_READ(sk, __sk_common.skc_family); \ + __be16 dport = BPF_CORE_READ(sk, __sk_common.skc_dport); \ + u16 sport = BPF_CORE_READ(sk, __sk_common.skc_num); \ + conn.family = family; \ + conn.sport = sport; \ + conn.dport = __bpf_ntohs(dport); \ conn.init_timestamp = bpf_ktime_get_ns() / 1000; -//初始化conn_t地址相关信息 -#define CONN_ADD_ADDRESS \ - if (family == AF_INET) { \ - conn.saddr = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr); \ - conn.daddr = BPF_CORE_READ(sk, __sk_common.skc_daddr); \ - } else if (family == AF_INET6) { \ - bpf_probe_read_kernel( \ - &conn.saddr_v6, \ - sizeof(sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32), \ - &sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32); \ - bpf_probe_read_kernel( \ - &conn.daddr_v6, \ - sizeof(sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32), \ - &sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32); \ +// 初始化conn_t地址相关信息 +#define CONN_ADD_ADDRESS \ + if (family == AF_INET) \ + { \ + conn.saddr = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr); \ + conn.daddr = BPF_CORE_READ(sk, __sk_common.skc_daddr); \ + } \ + else if (family == AF_INET6) \ + { \ + bpf_probe_read_kernel( \ + &conn.saddr_v6, \ + sizeof(sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32), \ + &sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32); \ + bpf_probe_read_kernel( \ + &conn.daddr_v6, \ + sizeof(sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32), \ + &sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32); \ } -//初始化conn其余额外信息 -#define CONN_ADD_EXTRA_INFO \ - if (extra_conn_info) { \ - struct tcp_sock *tp = (struct tcp_sock *)sk; \ - conn->srtt = BPF_CORE_READ(tp, srtt_us); \ - conn->duration = bpf_ktime_get_ns() / 1000 - conn->init_timestamp; \ - conn->bytes_acked = BPF_CORE_READ(tp, bytes_acked); \ - conn->bytes_received = BPF_CORE_READ(tp, bytes_received); \ - conn->snd_cwnd = BPF_CORE_READ(tp, snd_cwnd); \ - conn->rcv_wnd = BPF_CORE_READ(tp, rcv_wnd); \ - conn->snd_ssthresh = BPF_CORE_READ(tp, snd_ssthresh); \ - conn->total_retrans = BPF_CORE_READ(tp, total_retrans); \ - conn->sndbuf = BPF_CORE_READ(sk, sk_sndbuf); \ - conn->sk_wmem_queued = BPF_CORE_READ(sk, sk_wmem_queued); \ - conn->tcp_backlog = BPF_CORE_READ(sk, sk_ack_backlog); \ - conn->max_tcp_backlog = BPF_CORE_READ(sk, sk_max_ack_backlog); \ +// 初始化conn其余额外信息 +#define CONN_ADD_EXTRA_INFO \ + if (extra_conn_info) \ + { \ + struct tcp_sock *tp = (struct tcp_sock *)sk; \ + conn->srtt = BPF_CORE_READ(tp, srtt_us); \ + conn->duration = bpf_ktime_get_ns() / 1000 - conn->init_timestamp; \ + conn->bytes_acked = BPF_CORE_READ(tp, bytes_acked); \ + conn->bytes_received = BPF_CORE_READ(tp, bytes_received); \ + conn->snd_cwnd = BPF_CORE_READ(tp, snd_cwnd); \ + conn->rcv_wnd = BPF_CORE_READ(tp, rcv_wnd); \ + conn->snd_ssthresh = BPF_CORE_READ(tp, snd_ssthresh); \ + conn->total_retrans = BPF_CORE_READ(tp, total_retrans); \ + conn->sndbuf = BPF_CORE_READ(sk, sk_sndbuf); \ + conn->sk_wmem_queued = BPF_CORE_READ(sk, sk_wmem_queued); \ + conn->tcp_backlog = BPF_CORE_READ(sk, sk_ack_backlog); \ + conn->max_tcp_backlog = BPF_CORE_READ(sk, sk_max_ack_backlog); \ } #define CONN_INFO_TRANSFER tinfo->sk = conn->sock; // 将conn->sock赋给tinfo->sk -#define PACKET_INIT_WITH_COMMON_INFO \ - struct pack_t *packet; \ - packet = bpf_ringbuf_reserve(&rb, sizeof(*packet), 0); \ - if (!packet) { \ - return 0; \ - } \ - packet->err = 0; \ - packet->sock = sk; \ - packet->ack = pkt_tuple.ack; \ +#define PACKET_INIT_WITH_COMMON_INFO \ + struct pack_t *packet; \ + packet = bpf_ringbuf_reserve(&rb, sizeof(*packet), 0); \ + if (!packet) \ + { \ + return 0; \ + } \ + packet->err = 0; \ + packet->sock = sk; \ + packet->ack = pkt_tuple.ack; \ packet->seq = pkt_tuple.seq; #define READ_ONCE(x) (*(volatile typeof(x) *)&(x)) #define WRITE_ONCE(x, val) ((*(volatile typeof(x) *)&(x)) = val) -#define INIT_PACKET_TCP_TUPLE(sk, pkt) \ - struct packet_tuple pkt = { \ - .saddr = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr), \ - .daddr = BPF_CORE_READ(sk, __sk_common.skc_daddr), \ - .sport = BPF_CORE_READ(sk, __sk_common.skc_num), \ - .dport = __bpf_ntohs(BPF_CORE_READ(sk, __sk_common.skc_dport)), \ +#define INIT_PACKET_TCP_TUPLE(sk, pkt) \ + struct packet_tuple pkt = { \ + .saddr = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr), \ + .daddr = BPF_CORE_READ(sk, __sk_common.skc_daddr), \ + .sport = BPF_CORE_READ(sk, __sk_common.skc_num), \ + .dport = __bpf_ntohs(BPF_CORE_READ(sk, __sk_common.skc_dport)), \ .tran_flag = TCP} -#define INIT_PACKET_UDP_TUPLE(sk, pkt) \ - struct packet_tuple pkt = { \ - .saddr = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr), \ - .daddr = BPF_CORE_READ(sk, __sk_common.skc_daddr), \ - .sport = BPF_CORE_READ(sk, __sk_common.skc_num), \ - .dport = __bpf_ntohs(BPF_CORE_READ(sk, __sk_common.skc_dport)), \ +#define INIT_PACKET_UDP_TUPLE(sk, pkt) \ + struct packet_tuple pkt = { \ + .saddr = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr), \ + .daddr = BPF_CORE_READ(sk, __sk_common.skc_daddr), \ + .sport = BPF_CORE_READ(sk, __sk_common.skc_num), \ + .dport = __bpf_ntohs(BPF_CORE_READ(sk, __sk_common.skc_dport)), \ .tran_flag = UDP} - -//http data +// http data #if defined(USE_NEW_GET_USER_DATA) #define GET_USER_DATA(msg) BPF_CORE_READ(msg, msg_iter.iov, iov_base) #else @@ -512,34 +568,40 @@ const volatile int all_conn = 0, err_packet = 0, extra_conn_info = 0, /* help functions */ // 将struct sock类型的指针转化为struct tcp_sock类型的指针 -static __always_inline struct tcp_sock *tcp_sk(const struct sock *sk) { +static __always_inline struct tcp_sock *tcp_sk(const struct sock *sk) +{ return (struct tcp_sock *)sk; } // 将struct sk_buff类型的指针转化为struct udphdr类型的指针 -static __always_inline struct udphdr *skb_to_udphdr(const struct sk_buff *skb) { +static __always_inline struct udphdr *skb_to_udphdr(const struct sk_buff *skb) +{ return (struct udphdr *)(( - BPF_CORE_READ(skb, head) + // 报文头部偏移 - BPF_CORE_READ(skb, transport_header))); // 传输层部分偏移 + BPF_CORE_READ(skb, head) + + BPF_CORE_READ(skb, transport_header))); } // 将struct sk_buff类型的指针转化为struct tcphdr类型的指针 -static __always_inline struct tcphdr *skb_to_tcphdr(const struct sk_buff *skb) { +static __always_inline struct tcphdr *skb_to_tcphdr(const struct sk_buff *skb) +{ return (struct tcphdr *)(( - BPF_CORE_READ(skb, head) + // 报文头部偏移 - BPF_CORE_READ(skb, transport_header))); // 传输层部分偏移 + BPF_CORE_READ(skb, head) + + BPF_CORE_READ(skb, transport_header))); } // 将struct sk_buff类型的指针转化为struct iphdr类型的指针 -static __always_inline struct iphdr *skb_to_iphdr(const struct sk_buff *skb) { +static __always_inline struct iphdr *skb_to_iphdr(const struct sk_buff *skb) +{ return (struct iphdr *)(BPF_CORE_READ(skb, head) + BPF_CORE_READ(skb, network_header)); } // 将struct sk_buff类型的指针转化为struct ipv6hdr类型的指针 static __always_inline struct ipv6hdr * -skb_to_ipv6hdr(const struct sk_buff *skb) { +skb_to_ipv6hdr(const struct sk_buff *skb) +{ return (struct ipv6hdr *)(BPF_CORE_READ(skb, head) + BPF_CORE_READ(skb, network_header)); } // 初始化ip_packet -static void get_ip_pkt_tuple(struct ip_packet *ipk, struct iphdr *ip) { +static void get_ip_pkt_tuple(struct ip_packet *ipk, struct iphdr *ip) +{ ipk->saddr = BPF_CORE_READ(ip, saddr); ipk->daddr = BPF_CORE_READ(ip, daddr); } @@ -547,7 +609,8 @@ static void get_ip_pkt_tuple(struct ip_packet *ipk, struct iphdr *ip) { // 初始化packet_tuple结构指针pkt_tuple static __always_inline void get_pkt_tuple(struct packet_tuple *pkt_tuple, struct iphdr *ip, - struct tcphdr *tcp) { + struct tcphdr *tcp) +{ pkt_tuple->saddr = BPF_CORE_READ(ip, saddr); pkt_tuple->daddr = BPF_CORE_READ(ip, daddr); u16 sport = BPF_CORE_READ(tcp, source); @@ -570,7 +633,8 @@ static __always_inline void get_pkt_tuple(struct packet_tuple *pkt_tuple, // 初始化packet_tuple结构指针pkt_tuple static __always_inline void get_udp_pkt_tuple(struct packet_tuple *pkt_tuple, struct iphdr *ip, - struct udphdr *udp) { + struct udphdr *udp) +{ pkt_tuple->saddr = BPF_CORE_READ(ip, saddr); pkt_tuple->daddr = BPF_CORE_READ(ip, daddr); u16 sport = BPF_CORE_READ(udp, source); @@ -585,7 +649,8 @@ static __always_inline void get_udp_pkt_tuple(struct packet_tuple *pkt_tuple, static __always_inline void get_pkt_tuple_v6(struct packet_tuple *pkt_tuple, struct ipv6hdr *ip6h, - struct tcphdr *tcp) { + struct tcphdr *tcp) +{ bpf_probe_read_kernel(&pkt_tuple->saddr_v6, sizeof(pkt_tuple->saddr_v6), &ip6h->saddr.in6_u.u6_addr32); bpf_probe_read_kernel(&pkt_tuple->daddr_v6, sizeof(pkt_tuple->daddr_v6), @@ -601,7 +666,8 @@ static __always_inline void get_pkt_tuple_v6(struct packet_tuple *pkt_tuple, pkt_tuple->tran_flag = 1; // tcp包 } -int getstack(void *ctx) { +int getstack(void *ctx) +{ int pid = bpf_get_current_pid_tgid() >> 32; int cpu_id = bpf_get_smp_processor_id(); struct stacktrace_event *event; @@ -635,11 +701,12 @@ int getstack(void *ctx) { 5、v=4,右移1位10,r|=2>>1=1 r=14|1=14 */ -static __always_inline u64 log2(u32 v) { +static __always_inline u64 log2(u32 v) +{ u32 shift, r; - //检测v是否大于0xFFFF(65535),如果是,则将r设置为16 + // 检测v是否大于0xFFFF(65535),如果是,则将r设置为16 r = (v > 0xFFFF) << 4; - v >>= r; //右移 + v >>= r; // 右移 shift = (v > 0xFF) << 3; v >>= shift; r |= shift; @@ -649,7 +716,7 @@ static __always_inline u64 log2(u32 v) { shift = (v > 0x3) << 1; v >>= shift; r |= shift; - //右移v一位并将结果累加到r中 + // 右移v一位并将结果累加到r中 r |= (v >> 1); return r; } @@ -659,8 +726,9 @@ static __always_inline u64 log2(u32 v) { 1、v右移32位 1 2、log2(1)=0 计算得0+32=32 */ -static __always_inline u64 log2l(u64 v) { - u32 hi = v >> 32; //取v的高32位 +static __always_inline u64 log2l(u64 v) +{ + u32 hi = v >> 32; // 取v的高32位 // 如果高32位非0,计算高32位的对数并加32 if (hi) return log2(hi) + 32; diff --git a/MagicEyes/src/backend/net/net_watcher/bpf/drop.bpf.h b/MagicEyes/src/backend/net/net_watcher/bpf/drop.bpf.h index 56848f52f..d4fbe23c9 100644 --- a/MagicEyes/src/backend/net/net_watcher/bpf/drop.bpf.h +++ b/MagicEyes/src/backend/net/net_watcher/bpf/drop.bpf.h @@ -16,22 +16,22 @@ // net_watcher libbpf 丢包 #include "common.bpf.h" -static __always_inline -int __tp_kfree(struct trace_event_raw_kfree_skb *ctx) +static __always_inline int __tp_kfree(struct trace_event_raw_kfree_skb *ctx) { - if(!drop_reason) + if (!drop_reason) return 0; - struct sk_buff *skb=ctx->skbaddr; - if (skb == NULL) // 判断是否为空 + struct sk_buff *skb = ctx->skbaddr; + if (skb == NULL) return 0; struct iphdr *ip = skb_to_iphdr(skb); struct tcphdr *tcp = skb_to_tcphdr(skb); struct packet_tuple pkt_tuple = {0}; get_pkt_tuple(&pkt_tuple, ip, tcp); - struct reasonissue *message; + struct reasonissue *message; message = bpf_ringbuf_reserve(&kfree_rb, sizeof(*message), 0); - if(!message){ + if (!message) + { return 0; } message->saddr = pkt_tuple.saddr; @@ -41,8 +41,8 @@ int __tp_kfree(struct trace_event_raw_kfree_skb *ctx) message->protocol = ctx->protocol; message->location = (long)ctx->location; message->drop_reason = ctx->reason; - bpf_ringbuf_submit(message,0); - if(stack_info) + bpf_ringbuf_submit(message, 0); + if (stack_info) getstack(ctx); return 0; -} \ No newline at end of file +} \ No newline at end of file diff --git a/MagicEyes/src/backend/net/net_watcher/bpf/mysql.bpf.h b/MagicEyes/src/backend/net/net_watcher/bpf/mysql.bpf.h index 13e802887..e046338ce 100644 --- a/MagicEyes/src/backend/net/net_watcher/bpf/mysql.bpf.h +++ b/MagicEyes/src/backend/net/net_watcher/bpf/mysql.bpf.h @@ -28,14 +28,10 @@ static __always_inline int __handle_mysql_start(struct pt_regs *ctx) { u32 size = 0; char *sql; - if (command != COM_QUERY) { - return 0; - } - bpf_probe_read(&info.size, sizeof(info.size), &com_data->com_query.length); - bpf_probe_read_str(&sql, sizeof(sql), &com_data->com_query.query); - bpf_probe_read_str(&info.msql, sizeof(info.msql), sql); - // bpf_printk("sql1==%s size1==%lu", info.msql,info.size); + bpf_probe_read(&sql, sizeof(sql), &com_data->com_query.query); + bpf_probe_read(&info.msql, sizeof(info.msql), sql); + //bpf_printk("sql==%s size1==%lu", info.msql,info.size); info.start_time = bpf_ktime_get_ns() / 1000; bpf_map_update_elem(&queries, &tid, &info, BPF_ANY); @@ -70,8 +66,6 @@ static __always_inline int __handle_mysql_end(struct pt_regs *ctx) { bpf_get_current_comm(&message->comm, sizeof(comm)); message->size = info->size; bpf_probe_read_str(&message->msql, sizeof(message->msql), info->msql); - // bpf_printk("C==%d D==%lu S==%lu SQL==%s",count, - // message->duratime,message->size,message->msql); bpf_ringbuf_submit(message, 0); return 0; diff --git a/MagicEyes/src/backend/net/net_watcher/bpf/net_watcher.bpf.c b/MagicEyes/src/backend/net/net_watcher/bpf/net_watcher.bpf.c index 5db4a8064..d1a095425 100644 --- a/MagicEyes/src/backend/net/net_watcher/bpf/net_watcher.bpf.c +++ b/MagicEyes/src/backend/net/net_watcher/bpf/net_watcher.bpf.c @@ -317,14 +317,15 @@ int BPF_KPROBE(icmp_reply, struct icmp_bxm *icmp_param, struct sk_buff *skb) { // mysql SEC("uprobe/_Z16dispatch_commandP3THDPK8COM_DATA19enum_server_command") -int BPF_KPROBE(query__start) { return __handle_mysql_start(ctx); } +int BPF_UPROBE(query__start) { return __handle_mysql_start(ctx); } SEC("uretprobe/_Z16dispatch_commandP3THDPK8COM_DATA19enum_server_command") -int BPF_KPROBE(query__end) { return __handle_mysql_end(ctx); } +int BPF_UPROBE(query__end) { return __handle_mysql_end(ctx); } //redis SEC("uprobe/processCommand") -int BPF_KPROBE(redis_processCommand) { return __handle_redis_start(ctx); } +int BPF_KPROBE(redis_processCommand) { + return __handle_redis_start(ctx); } SEC("uretprobe/call") int BPF_KPROBE(redis_call) { return __handle_redis_end(ctx); } diff --git a/MagicEyes/src/backend/net/net_watcher/bpf/netfilter.bpf.h b/MagicEyes/src/backend/net/net_watcher/bpf/netfilter.bpf.h index f6eea5202..8fc9772ef 100644 --- a/MagicEyes/src/backend/net/net_watcher/bpf/netfilter.bpf.h +++ b/MagicEyes/src/backend/net/net_watcher/bpf/netfilter.bpf.h @@ -97,7 +97,7 @@ int store_nf_time(struct sk_buff *skb, int hook) { if(!net_filter) return 0; - if (skb == NULL) // 判断是否为空 + if (skb == NULL) return 0; struct iphdr *ip = skb_to_iphdr(skb); struct tcphdr *tcp = skb_to_tcphdr(skb); diff --git a/MagicEyes/src/backend/net/net_watcher/bpf/packet.bpf.h b/MagicEyes/src/backend/net/net_watcher/bpf/packet.bpf.h index c75dbea20..c74ed2482 100644 --- a/MagicEyes/src/backend/net/net_watcher/bpf/packet.bpf.h +++ b/MagicEyes/src/backend/net/net_watcher/bpf/packet.bpf.h @@ -31,20 +31,24 @@ kprobe/skb_copy_datagram_iter */ static __always_inline struct packet_count *count_packet(u32 proto, - bool is_tx) { + bool is_tx) +{ struct packet_count *count; struct packet_count initial_count = {0}; count = bpf_map_lookup_elem(&proto_stats, &proto); - if (!count) { + if (!count) + { initial_count.tx_count = 0; initial_count.rx_count = 0; if (bpf_map_update_elem(&proto_stats, &proto, &initial_count, - BPF_ANY)) { + BPF_ANY)) + { return NULL; } count = bpf_map_lookup_elem(&proto_stats, &proto); - if (!count) { + if (!count) + { return NULL; } } @@ -56,22 +60,26 @@ static __always_inline struct packet_count *count_packet(u32 proto, return count; } -static __always_inline int sum_protocol(struct sk_buff *skb, bool is_tx) { +static __always_inline int sum_protocol(struct sk_buff *skb, bool is_tx) +{ const struct ethhdr *eth = (struct ethhdr *)BPF_CORE_READ(skb, data); u16 proto = BPF_CORE_READ(eth, h_proto); struct packet_info *pkt = bpf_ringbuf_reserve(&port_rb, sizeof(*pkt), 0); - if (!pkt) { + if (!pkt) + { return 0; } - if (BPF_CORE_READ(eth, h_proto) != __bpf_htons(ETH_P_IP)) { + if (BPF_CORE_READ(eth, h_proto) != __bpf_htons(ETH_P_IP)) + { bpf_ringbuf_discard(pkt, 0); return 0; } struct iphdr *ip = (struct iphdr *)(BPF_CORE_READ(skb, data) + 14); - if (!ip) { + if (!ip) + { bpf_ringbuf_discard(pkt, 0); return 0; } @@ -80,48 +88,55 @@ static __always_inline int sum_protocol(struct sk_buff *skb, bool is_tx) { pkt->daddr = BPF_CORE_READ(ip, daddr); pkt->proto = BPF_CORE_READ(ip, protocol); - if (pkt->proto == IPPROTO_TCP) { + if (pkt->proto == IPPROTO_TCP) + { struct tcphdr *tcp = (struct tcphdr *)(BPF_CORE_READ(skb, data) + sizeof(struct ethhdr) + sizeof(struct iphdr)); pkt->sport = BPF_CORE_READ(tcp, source); pkt->dport = BPF_CORE_READ(tcp, dest); pkt->proto = PROTO_TCP; - } else if (pkt->proto == IPPROTO_UDP) { + } + else if (pkt->proto == IPPROTO_UDP) + { struct udphdr *udp = (struct udphdr *)(BPF_CORE_READ(skb, data) + sizeof(struct ethhdr) + sizeof(struct iphdr)); pkt->sport = BPF_CORE_READ(udp, source); pkt->dport = BPF_CORE_READ(udp, dest); pkt->proto = PROTO_UDP; - } else if (pkt->proto == IPPROTO_ICMP) { + } + else if (pkt->proto == IPPROTO_ICMP) + { pkt->proto = PROTO_ICMP; - } else { + } + else + { pkt->proto = PROTO_UNKNOWN; } struct packet_count *count = count_packet(pkt->proto, is_tx); - if (count) { + if (count) + { pkt->count.tx_count = count->tx_count; pkt->count.rx_count = count->rx_count; - } else { + } + else + { pkt->count.tx_count = 0; pkt->count.rx_count = 0; } - - // bpf_printk("pkt: saddr=%u, daddr=%u, proto=%u\n", pkt->saddr, pkt->daddr, - // pkt->proto); bpf_printk("sport=%d, dport=%d\n", pkt->sport, pkt->dport); - // bpf_printk("count_tx=%llu, count_rx=%llu\n", pkt->count.tx_count, - // pkt->count.rx_count); bpf_ringbuf_submit(pkt, 0); return 0; } -static __always_inline int __eth_type_trans(struct sk_buff *skb) { +static __always_inline int __eth_type_trans(struct sk_buff *skb) +{ const struct ethhdr *eth = - (struct ethhdr *)BPF_CORE_READ(skb, data); // 读取里面的报文数据 - u16 protocol = BPF_CORE_READ(eth, h_proto); // 读取包ID + (struct ethhdr *)BPF_CORE_READ(skb, data); + u16 protocol = BPF_CORE_READ(eth, h_proto); // bpf_printk("protocol: %d\n", __bpf_ntohs(protocol)); - if (protocol == __bpf_htons(ETH_P_IP)) { // Protocol is IP 0x0800 + if (protocol == __bpf_htons(ETH_P_IP)) + { // Protocol is IP 0x0800 // 14 --> sizeof(struct ethhdr) / define struct iphdr *ip = (struct iphdr *)(BPF_CORE_READ(skb, data) + @@ -129,21 +144,24 @@ static __always_inline int __eth_type_trans(struct sk_buff *skb) { // 目的端口6字节 类型2字节 struct tcphdr *tcp = (struct tcphdr *)(BPF_CORE_READ(skb, data) + sizeof(struct iphdr) + 14); - struct packet_tuple pkt_tuple = {0}; // 声明packet_tuple结构pkt_tuple - get_pkt_tuple(&pkt_tuple, ip, tcp); // 初始化pkt_tuple + struct packet_tuple pkt_tuple = {0}; + get_pkt_tuple(&pkt_tuple, ip, tcp); - struct ktime_info *tinfo, zero = {0}; // 定义ktime_info结构zero以及tinfo + struct ktime_info *tinfo, zero = {0}; tinfo = (struct ktime_info *)bpf_map_lookup_or_try_init( ×tamps, &pkt_tuple, &zero); - if (tinfo == NULL) { // 初始化失败 + if (tinfo == NULL) + { // bpf_printk("v4 rx tinfo init fail.\n"); return 0; } - // 成功则获取当前内核时间并转换成毫秒 + tinfo->mac_time = bpf_ktime_get_ns() / 1000; // bpf_printk("v4 rx init.\n"); - } else if (protocol == __bpf_htons(ETH_P_IPV6)) { // Protocol is IPV6 + } + else if (protocol == __bpf_htons(ETH_P_IPV6)) + { // Protocol is IPV6 struct ipv6hdr *ip6h = (struct ipv6hdr *)(BPF_CORE_READ(skb, data) + 14); struct tcphdr *tcp = (struct tcphdr *)(BPF_CORE_READ(skb, data) + @@ -155,7 +173,8 @@ static __always_inline int __eth_type_trans(struct sk_buff *skb) { tinfo = (struct ktime_info *)bpf_map_lookup_or_try_init( ×tamps, &pkt_tuple, &zero); - if (tinfo == NULL) { + if (tinfo == NULL) + { // bpf_printk("v6 rx tinfo init fail.\n"); return 0; } @@ -165,21 +184,24 @@ static __always_inline int __eth_type_trans(struct sk_buff *skb) { return 0; } -static __always_inline int __ip_rcv_core(struct sk_buff *skb) { - if (!layer_time) { +static __always_inline int __ip_rcv_core(struct sk_buff *skb) +{ + if (!layer_time) + { return 0; } if (skb == NULL) return 0; - struct iphdr *ip = skb_to_iphdr(skb); // 通过skb获取ipv4包头信息 - struct tcphdr *tcp = skb_to_tcphdr(skb); // 获取tcp包头信息 + struct iphdr *ip = skb_to_iphdr(skb); + struct tcphdr *tcp = skb_to_tcphdr(skb); struct packet_tuple pkt_tuple = { - 0}; // 定义一个packet_tuple结构体变量pkt_tuple并初始化 + 0}; get_pkt_tuple(&pkt_tuple, ip, tcp); struct ktime_info *tinfo; tinfo = bpf_map_lookup_elem( - ×tamps, &pkt_tuple); // 在timestamps映射中查找元素pkt_tuple - if (tinfo == NULL) { + ×tamps, &pkt_tuple); + if (tinfo == NULL) + { return 0; } tinfo->ip_time = bpf_ktime_get_ns() / 1000; @@ -187,8 +209,10 @@ static __always_inline int __ip_rcv_core(struct sk_buff *skb) { return 0; } -static __always_inline int __ip6_rcv_core(struct sk_buff *skb) { - if (!layer_time) { +static __always_inline int __ip6_rcv_core(struct sk_buff *skb) +{ + if (!layer_time) + { return 0; } if (skb == NULL) @@ -200,7 +224,8 @@ static __always_inline int __ip6_rcv_core(struct sk_buff *skb) { struct ktime_info *tinfo; tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple); - if (tinfo == NULL) { + if (tinfo == NULL) + { return 0; } @@ -208,8 +233,10 @@ static __always_inline int __ip6_rcv_core(struct sk_buff *skb) { // bpf_printk("rx enter ipv6 layer.\n"); return 0; } -static __always_inline int __tcp_v4_rcv(struct sk_buff *skb) { - if (!layer_time) { +static __always_inline int __tcp_v4_rcv(struct sk_buff *skb) +{ + if (!layer_time) + { return 0; } if (skb == NULL) @@ -220,15 +247,18 @@ static __always_inline int __tcp_v4_rcv(struct sk_buff *skb) { get_pkt_tuple(&pkt_tuple, ip, tcp); struct ktime_info *tinfo; tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple); - if (tinfo == NULL) { + if (tinfo == NULL) + { return 0; } tinfo->tran_time = bpf_ktime_get_ns() / 1000; // bpf_printk("rx enter tcp4 layer.\n"); return 0; } -static __always_inline int __tcp_v6_rcv(struct sk_buff *skb) { - if (!layer_time) { +static __always_inline int __tcp_v6_rcv(struct sk_buff *skb) +{ + if (!layer_time) + { return 0; } if (skb == NULL) @@ -240,7 +270,8 @@ static __always_inline int __tcp_v6_rcv(struct sk_buff *skb) { struct ktime_info *tinfo; tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple); - if (tinfo == NULL) { + if (tinfo == NULL) + { return 0; } tinfo->tran_time = bpf_ktime_get_ns() / 1000; @@ -248,11 +279,13 @@ static __always_inline int __tcp_v6_rcv(struct sk_buff *skb) { return 0; } static __always_inline int __tcp_v4_do_rcv(struct sock *sk, - struct sk_buff *skb) { + struct sk_buff *skb) +{ if (sk == NULL || skb == NULL) return 0; struct conn_t *conn = bpf_map_lookup_elem(&conns_info, &sk); - if (conn == NULL) { + if (conn == NULL) + { // bpf_printk("get a v4 rx pack but conn not record, its sock is: // %p",sk); return 0; @@ -264,7 +297,8 @@ static __always_inline int __tcp_v4_do_rcv(struct sock *sk, struct ktime_info *tinfo; tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple); - if (tinfo == NULL) { + if (tinfo == NULL) + { return 0; } @@ -277,12 +311,14 @@ static __always_inline int __tcp_v4_do_rcv(struct sock *sk, return 0; } static __always_inline int __tcp_v6_do_rcv(struct sock *sk, - struct sk_buff *skb) { + struct sk_buff *skb) +{ if (sk == NULL || skb == NULL) return 0; // bpf_printk("rx enter tcp6_do_rcv. \n"); struct conn_t *conn = bpf_map_lookup_elem(&conns_info, &sk); - if (conn == NULL) { + if (conn == NULL) + { // bpf_printk("get a v6 rx pack but conn not record, its sock is: %p", // sk); return 0; @@ -291,11 +327,12 @@ static __always_inline int __tcp_v6_do_rcv(struct sock *sk, struct ipv6hdr *ip6h = skb_to_ipv6hdr(skb); struct tcphdr *tcp = skb_to_tcphdr(skb); struct packet_tuple pkt_tuple = {0}; - get_pkt_tuple_v6(&pkt_tuple, ip6h, tcp); // 使用ip和tcp信息填充pkt_tuple + get_pkt_tuple_v6(&pkt_tuple, ip6h, tcp); struct ktime_info *tinfo; tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple); - if (tinfo == NULL) { + if (tinfo == NULL) + { return 0; } @@ -307,42 +344,52 @@ static __always_inline int __tcp_v6_do_rcv(struct sock *sk, return 0; } -static __always_inline int __skb_copy_datagram_iter(struct sk_buff *skb) { +static __always_inline int __skb_copy_datagram_iter(struct sk_buff *skb) +{ if (skb == NULL) return 0; - __be16 protocol = BPF_CORE_READ(skb, protocol); // 读取skb协议字段 + __be16 protocol = BPF_CORE_READ(skb, protocol); struct tcphdr *tcp = skb_to_tcphdr(skb); struct packet_tuple pkt_tuple = {0}; struct ktime_info *tinfo; - if (protocol == __bpf_htons(ETH_P_IP)) { /** ipv4 */ + if (protocol == __bpf_htons(ETH_P_IP)) + { /** ipv4 */ struct iphdr *ip = skb_to_iphdr(skb); get_pkt_tuple(&pkt_tuple, ip, tcp); tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple); - if (tinfo == NULL) { + if (tinfo == NULL) + { return 0; } tinfo->app_time = bpf_ktime_get_ns() / 1000; - } else if (protocol == __bpf_ntohs(ETH_P_IPV6)) { + } + else if (protocol == __bpf_ntohs(ETH_P_IPV6)) + { /** ipv6 */ struct ipv6hdr *ip6h = skb_to_ipv6hdr(skb); get_pkt_tuple_v6(&pkt_tuple, ip6h, tcp); - if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) { + if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) + { return 0; } tinfo->app_time = bpf_ktime_get_ns() / 1000; - } else { + } + else + { return 0; } /*----- record packet time info ------*/ - if (tinfo == NULL) { + if (tinfo == NULL) + { return 0; } struct sock *sk = tinfo->sk; - if (sk == NULL) { + if (sk == NULL) + { return 0; } // bpf_printk("rx enter app layer.\n"); @@ -353,7 +400,8 @@ static __always_inline int __skb_copy_datagram_iter(struct sk_buff *skb) { packet->sport = pkt_tuple.sport; packet->dport = pkt_tuple.dport; - if (layer_time) { + if (layer_time) + { packet->mac_time = tinfo->ip_time - tinfo->mac_time; // 计算MAC层和ip层之间的时间差 packet->ip_time = tinfo->tran_time - tinfo->ip_time; @@ -364,7 +412,8 @@ static __always_inline int __skb_copy_datagram_iter(struct sk_buff *skb) { packet->rx = 1; // 数据包已经被接收 // RX HTTP INFO - if (http_info) { + if (http_info) + { int doff = BPF_CORE_READ_BITFIELD_PROBED(tcp, doff); // 得用bitfield_probed // 读取tcp头部中的数据偏移字段 @@ -376,7 +425,7 @@ static __always_inline int __skb_copy_datagram_iter(struct sk_buff *skb) { bpf_probe_read_str(packet->data, sizeof(packet->data), user_data); // 将tcp负载数据读取到packet->data } - bpf_ringbuf_submit(packet, 0); // 将packet提交到缓冲区 + bpf_ringbuf_submit(packet, 0); return 0; } /* @@ -393,22 +442,25 @@ static __always_inline int __skb_copy_datagram_iter(struct sk_buff *skb) { kprobe/dev_hard_start_xmit */ static __always_inline int __tcp_sendmsg(struct sock *sk, struct msghdr *msg, - size_t size) { + size_t size) +{ struct conn_t *conn = bpf_map_lookup_elem(&conns_info, &sk); - if (conn == NULL) { + if (conn == NULL) + { return 0; } u16 family = BPF_CORE_READ(sk, __sk_common.skc_family); - struct ktime_info *tinfo, zero = {0}; // 存储时间 - struct packet_tuple pkt_tuple = {0}; // 存储数据包信息 + struct ktime_info *tinfo, zero = {0}; + struct packet_tuple pkt_tuple = {0}; /** ipv4 */ - if (family == AF_INET) { + if (family == AF_INET) + { u16 dport = BPF_CORE_READ(sk, __sk_common.skc_dport); - 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 = BPF_CORE_READ(sk, __sk_common.skc_num); // 源端口 - 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 = BPF_CORE_READ(sk, __sk_common.skc_num); + pkt_tuple.dport = __bpf_ntohs(dport); u32 snd_nxt = BPF_CORE_READ(tcp_sk(sk), snd_nxt); // tcp要发送的下一个字节序列号 @@ -419,12 +471,15 @@ static __always_inline int __tcp_sendmsg(struct sock *sk, struct msghdr *msg, pkt_tuple.tran_flag = TCP; tinfo = (struct ktime_info *)bpf_map_lookup_or_try_init( ×tamps, &pkt_tuple, - &zero); // timestamps的BPF map保存数据包与时间戳的映射 - if (tinfo == NULL) { + &zero); + if (tinfo == NULL) + { return 0; } tinfo->tran_time = bpf_ktime_get_ns() / 1000; - } else if (family == AF_INET6) { + } + else if (family == AF_INET6) + { // 读取ipv6源地址 bpf_probe_read_kernel( &pkt_tuple.saddr_v6, @@ -451,7 +506,8 @@ static __always_inline int __tcp_sendmsg(struct sock *sk, struct msghdr *msg, tinfo = (struct ktime_info *)bpf_map_lookup_or_try_init( ×tamps, &pkt_tuple, &zero); - if (tinfo == NULL) { + if (tinfo == NULL) + { return 0; } tinfo->tran_time = bpf_ktime_get_ns() / 1000; @@ -462,11 +518,13 @@ static __always_inline int __tcp_sendmsg(struct sock *sk, struct msghdr *msg, CONN_ADD_EXTRA_INFO // TX HTTP info - if (http_info) { + if (http_info) + { u8 *user_data = GET_USER_DATA(msg); tinfo = (struct ktime_info *)bpf_map_lookup_or_try_init( ×tamps, &pkt_tuple, &zero); - if (tinfo == NULL) { + if (tinfo == NULL) + { return 0; } bpf_probe_read_str(tinfo->data, sizeof(tinfo->data), user_data); @@ -474,15 +532,18 @@ static __always_inline int __tcp_sendmsg(struct sock *sk, struct msghdr *msg, return 0; } static __always_inline int __ip_queue_xmit(struct sock *sk, - struct sk_buff *skb) { - if (!layer_time) { + struct sk_buff *skb) +{ + if (!layer_time) + { return 0; } u16 family = BPF_CORE_READ(sk, __sk_common.skc_family); struct packet_tuple pkt_tuple = {0}; struct ktime_info *tinfo; struct tcphdr *tcp = skb_to_tcphdr(skb); - if (family == AF_INET) { + if (family == AF_INET) + { u16 dport; u32 seq, ack; pkt_tuple.saddr = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr); @@ -495,7 +556,8 @@ static __always_inline int __ip_queue_xmit(struct sock *sk, pkt_tuple.seq = __bpf_ntohl(seq); pkt_tuple.ack = __bpf_ntohl(ack); pkt_tuple.tran_flag = TCP; - if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) { + if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) + { return 0; } tinfo->ip_time = bpf_ktime_get_ns() / 1000; @@ -504,15 +566,18 @@ static __always_inline int __ip_queue_xmit(struct sock *sk, return 0; } static __always_inline int __inet6_csk_xmit(struct sock *sk, - struct sk_buff *skb) { - if (!layer_time) { + struct sk_buff *skb) +{ + if (!layer_time) + { return 0; } u16 family = BPF_CORE_READ(sk, __sk_common.skc_family); struct tcphdr *tcp = skb_to_tcphdr(skb); struct packet_tuple pkt_tuple = {0}; struct ktime_info *tinfo; - if (family == AF_INET6) { + if (family == AF_INET6) + { u16 dport; u32 seq, ack; @@ -534,81 +599,99 @@ static __always_inline int __inet6_csk_xmit(struct sock *sk, pkt_tuple.seq = __bpf_ntohl(seq); pkt_tuple.ack = __bpf_ntohl(ack); pkt_tuple.tran_flag = TCP; - if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) { + if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) + { return 0; } tinfo->ip_time = bpf_ktime_get_ns() / 1000; } return 0; } -static __always_inline int dev_queue_xmit(struct sk_buff *skb) { - if (!layer_time) { +static __always_inline int dev_queue_xmit(struct sk_buff *skb) +{ + if (!layer_time) + { return 0; } // 从skb中读取以太网头部 const struct ethhdr *eth = (struct ethhdr *)BPF_CORE_READ(skb, data); u16 protocol = BPF_CORE_READ( eth, - h_proto); // 以太网头部协议字段该字段存储的是以太网帧所封装的上层协议类型 + h_proto); struct tcphdr *tcp = skb_to_tcphdr(skb); struct packet_tuple pkt_tuple = {0}; struct ktime_info *tinfo; - if (protocol == __bpf_ntohs(ETH_P_IP)) { + if (protocol == __bpf_ntohs(ETH_P_IP)) + { /** ipv4 */ struct iphdr *ip = skb_to_iphdr(skb); get_pkt_tuple(&pkt_tuple, ip, tcp); - if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) { + if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) + { return 0; } tinfo->mac_time = bpf_ktime_get_ns() / 1000; - } else if (protocol == __bpf_ntohs(ETH_P_IPV6)) { + } + else if (protocol == __bpf_ntohs(ETH_P_IPV6)) + { /** ipv6 */ struct ipv6hdr *ip6h = skb_to_ipv6hdr(skb); get_pkt_tuple_v6(&pkt_tuple, ip6h, tcp); - if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) { + if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) + { return 0; } tinfo->mac_time = bpf_ktime_get_ns() / 1000; } return 0; } -static __always_inline int __dev_hard_start_xmit(struct sk_buff *skb) { +static __always_inline int __dev_hard_start_xmit(struct sk_buff *skb) +{ const struct ethhdr *eth = (struct ethhdr *)BPF_CORE_READ(skb, data); u16 protocol = BPF_CORE_READ(eth, h_proto); struct tcphdr *tcp = skb_to_tcphdr(skb); struct packet_tuple pkt_tuple = {0}; struct ktime_info *tinfo; - if (protocol == __bpf_ntohs(ETH_P_IP)) { + if (protocol == __bpf_ntohs(ETH_P_IP)) + { /** ipv4 */ struct iphdr *ip = skb_to_iphdr(skb); get_pkt_tuple(&pkt_tuple, ip, tcp); - if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) { + if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) + { return 0; } - // 数据包在队列中等待的时间 + tinfo->qdisc_time = bpf_ktime_get_ns() / 1000; - } else if (protocol == __bpf_ntohs(ETH_P_IPV6)) { + } + else if (protocol == __bpf_ntohs(ETH_P_IPV6)) + { /** ipv6 */ struct ipv6hdr *ip6h = skb_to_ipv6hdr(skb); get_pkt_tuple_v6(&pkt_tuple, ip6h, tcp); - if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) { + if ((tinfo = bpf_map_lookup_elem(×tamps, &pkt_tuple)) == NULL) + { return 0; } tinfo->qdisc_time = bpf_ktime_get_ns() / 1000; - } else { + } + else + { return 0; } /*----- record packet time info ------*/ - if (tinfo == NULL) { + if (tinfo == NULL) + { return 0; } struct sock *sk = tinfo->sk; - if (!sk) { + if (!sk) + { return 0; } PACKET_INIT_WITH_COMMON_INFO @@ -616,19 +699,21 @@ static __always_inline int __dev_hard_start_xmit(struct sk_buff *skb) { packet->daddr = pkt_tuple.daddr; packet->sport = pkt_tuple.sport; packet->dport = pkt_tuple.dport; - // 记录各层的时间差值 - if (layer_time) { + + if (layer_time) + { packet->tran_time = tinfo->ip_time - tinfo->tran_time; packet->ip_time = tinfo->mac_time - tinfo->ip_time; packet->mac_time = tinfo->qdisc_time - tinfo - ->mac_time; // 队列纪律层,处于网络协议栈最底层,负责实际数据传输与接收 + ->mac_time; } packet->rx = 0; // 发送一个数据包 // TX HTTP Info - if (http_info) { + if (http_info) + { bpf_probe_read_str(packet->data, sizeof(packet->data), tinfo->data); // bpf_printk("%s", packet->data); } diff --git a/MagicEyes/src/backend/net/net_watcher/bpf/tcp.bpf.h b/MagicEyes/src/backend/net/net_watcher/bpf/tcp.bpf.h index abcc05698..e81932871 100644 --- a/MagicEyes/src/backend/net/net_watcher/bpf/tcp.bpf.h +++ b/MagicEyes/src/backend/net/net_watcher/bpf/tcp.bpf.h @@ -17,12 +17,14 @@ #include "common.bpf.h" -static __always_inline int __inet_csk_accept(struct sock *sk) { - if (sk == NULL) { // newsk is null +static __always_inline int __inet_csk_accept(struct sock *sk) +{ + if (sk == NULL) + { // newsk is null // bpf_printk("inet_accept_ret err: newsk is null\n"); return 0; } - u64 ptid = bpf_get_current_pid_tgid(); // 获取当前进程pid + u64 ptid = bpf_get_current_pid_tgid(); CONN_INIT // 初始化conn_t结构中基本信息 conn.is_server = 1; @@ -35,7 +37,8 @@ static __always_inline int __inet_csk_accept(struct sock *sk) { // 更新/插入conns_info中的键值对 int err = bpf_map_update_elem(&conns_info, &sk, &conn, BPF_ANY); - if (err) { // 更新错误 + if (err) + { // 更新错误 // bpf_printk("inet_accept update err.\n"); return 0; } @@ -43,33 +46,38 @@ static __always_inline int __inet_csk_accept(struct sock *sk) { return 0; } -static __always_inline int __tcp_v4_connect(const struct sock *sk) { - u64 ptid = bpf_get_current_pid_tgid(); // 获取当前pid +static __always_inline int __tcp_v4_connect(const struct sock *sk) +{ + u64 ptid = bpf_get_current_pid_tgid(); int err = bpf_map_update_elem(&sock_stores, &ptid, &sk, BPF_ANY); // 更新/插入sock_stores中的键值对 - if (err) { + if (err) + { // bpf_printk("tcp_v4_connect update sock_stores err.\n"); return 0; } return 0; } -static __always_inline int __tcp_v4_connect_exit(int ret) { - u64 ptid = bpf_get_current_pid_tgid(); // 获取当前pid +static __always_inline int __tcp_v4_connect_exit(int ret) +{ + u64 ptid = bpf_get_current_pid_tgid(); struct sock **skp = bpf_map_lookup_elem(&sock_stores, &ptid); - // 获得sock_stores中ptid对应的*sk 用skp指向 - if (skp == NULL) { + + if (skp == NULL) + { return 0; } // bpf_printk("tcp_v4_connect_exit\n"); - if (ret != 0) { // 连接失败 + if (ret != 0) + { // 连接失败 // bpf_printk("tcp_v4_connect_exit but ret %d\n", ret); bpf_map_delete_elem(&sock_stores, &ptid); // 删除对应键值对 return 0; } struct sock *sk = *skp; - CONN_INIT // 初始化conn_t结构中基本信息 - conn.is_server = 0; // 主动连接 + CONN_INIT + conn.is_server = 0; // 主动连接 FILTER_DPORT // 过滤目标端口 @@ -79,31 +87,37 @@ static __always_inline int __tcp_v4_connect_exit(int ret) { long err = bpf_map_update_elem(&conns_info, &sk, &conn, BPF_ANY); // 更新conns_info中sk对应的conn - if (err) { + if (err) + { return 0; } return 0; } -static __always_inline int __tcp_v6_connect(const struct sock *sk) { +static __always_inline int __tcp_v6_connect(const struct sock *sk) +{ u64 pid = bpf_get_current_pid_tgid(); // 获取pid int err = bpf_map_update_elem(&sock_stores, &pid, &sk, BPF_ANY); // 更新sock_stores中对应pid对应的sk - if (err) { + if (err) + { return 0; } return 0; } -static __always_inline int __tcp_v6_connect_exit(int ret) { +static __always_inline int __tcp_v6_connect_exit(int ret) +{ u64 ptid = bpf_get_current_pid_tgid(); // 获取pid struct sock **skp = bpf_map_lookup_elem(&sock_stores, &ptid); // 获得sock_stores中ptid对应的*sk 用skp指向 - if (skp == NULL) { + if (skp == NULL) + { return 0; } - if (ret != 0) { // 错误 - bpf_map_delete_elem(&sock_stores, &ptid); // 删除对应键值对 + if (ret != 0) + { + bpf_map_delete_elem(&sock_stores, &ptid); return 0; } struct sock *sk = *skp; @@ -119,19 +133,23 @@ static __always_inline int __tcp_v6_connect_exit(int ret) { long err = bpf_map_update_elem(&conns_info, &sk, &conn, BPF_ANY); // 更新conns_info中sk对应的conn - if (err) { + if (err) + { return 0; } // bpf_printk("tcp_v4_connect_exit update sk: %p.\n", sk); return 0; } -static __always_inline int __tcp_set_state(struct sock *sk, int state) { - if (all_conn) { +static __always_inline int __tcp_set_state(struct sock *sk, int state) +{ + if (all_conn) + { return 0; } struct conn_t *value = bpf_map_lookup_elem(&conns_info, &sk); // 查找sk对应的conn_t - if (state == TCP_CLOSE && value != NULL) { // TCP_CLOSE置1 说明关闭连接 + if (state == TCP_CLOSE && value != NULL) + { // TCP_CLOSE置1 说明关闭连接 // delete bpf_map_delete_elem(&sock_stores, &value->ptid); // 删除sock_stores bpf_map_delete_elem(&conns_info, &sk); // 删除conns_info @@ -141,15 +159,18 @@ static __always_inline int __tcp_set_state(struct sock *sk, int state) { // receive error packet static __always_inline int __tcp_validate_incoming(struct sock *sk, - struct sk_buff *skb) { - if (!err_packet) { + struct sk_buff *skb) +{ + if (!err_packet) + { return 0; } if (sk == NULL || skb == NULL) return 0; struct conn_t *conn = bpf_map_lookup_elem(&conns_info, &sk); // BPFmap查找与套接字sk关联的信息 - if (conn == NULL) { + if (conn == NULL) + { return 0; } struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); // 数据包信息 @@ -159,12 +180,13 @@ static __always_inline int __tcp_validate_incoming(struct sock *sk, u32 rcv_wup = BPF_CORE_READ( tp, rcv_wup); // 接收方已经确认并准备接收的数据最后一个字节的序列号 u32 rcv_nxt = - BPF_CORE_READ(tp, rcv_nxt); // 期望发送发下次发送的数据字节序列号 + BPF_CORE_READ(tp, rcv_nxt); // 期望发送发下次发送的数据字节序列号 u32 rcv_wnd = BPF_CORE_READ(tp, rcv_wnd); // tcp接收窗口大小 u32 receive_window = rcv_wup + rcv_nxt - rcv_wnd; // 当前可用的接收窗口 receive_window = 0; - if (end_seq >= rcv_wup && rcv_nxt + receive_window >= start_seq) { + if (end_seq >= rcv_wup && rcv_nxt + receive_window >= start_seq) + { // bpf_printk("error_identify: tcp seq validated. \n"); return 0; // 检查数据包序列号是否在接收窗口内 @@ -174,20 +196,26 @@ static __always_inline int __tcp_validate_incoming(struct sock *sk, u16 family = BPF_CORE_READ( sk, __sk_common.skc_family); // 获取套接字的地址族就是获得当前ip协议 struct packet_tuple pkt_tuple = {0}; - if (family == AF_INET) { + if (family == AF_INET) + { struct iphdr *ip = skb_to_iphdr(skb); struct tcphdr *tcp = skb_to_tcphdr(skb); get_pkt_tuple(&pkt_tuple, ip, tcp); - } else if (family == AF_INET6) { + } + else if (family == AF_INET6) + { struct ipv6hdr *ip6h = skb_to_ipv6hdr(skb); struct tcphdr *tcp = skb_to_tcphdr(skb); get_pkt_tuple_v6(&pkt_tuple, ip6h, tcp); - } else { + } + else + { return 0; } struct pack_t *packet; packet = bpf_ringbuf_reserve(&rb, sizeof(*packet), 0); - if (!packet) { + if (!packet) + { return 0; } packet->err = 1; // 错误标记此数据包有问题 @@ -197,28 +225,34 @@ static __always_inline int __tcp_validate_incoming(struct sock *sk, bpf_ringbuf_submit(packet, 0); return 0; } -static __always_inline int skb_checksum_complete(int ret) { - if (!err_packet) { +static __always_inline int skb_checksum_complete(int ret) +{ + if (!err_packet) + { return 0; } u64 pid = bpf_get_current_pid_tgid(); struct sock **skp = bpf_map_lookup_elem(&sock_stores, &pid); - if (skp == NULL) { + if (skp == NULL) + { return 0; } - if (ret == 0) { + if (ret == 0) + { // bpf_printk("error_identify: tcp checksum validated. \n"); return 0; } // bpf_printk("error_identify: tcp checksum error. \n"); struct sock *sk = *skp; struct conn_t *conn = bpf_map_lookup_elem(&conns_info, &sk); - if (conn == NULL) { + if (conn == NULL) + { return 0; } struct pack_t *packet; packet = bpf_ringbuf_reserve(&rb, sizeof(*packet), 0); - if (!packet) { + if (!packet) + { return 0; } packet->err = 2; // 校验和错误 @@ -227,13 +261,16 @@ static __always_inline int skb_checksum_complete(int ret) { return 0; } -////retrans packet -static __always_inline int __tcp_enter_recovery(struct sock *sk) { - if (!retrans_info) { +// retrans packet +static __always_inline int __tcp_enter_recovery(struct sock *sk) +{ + if (!retrans_info) + { return 0; } struct conn_t *conn = bpf_map_lookup_elem(&conns_info, &sk); - if (conn == NULL) { + if (conn == NULL) + { // bpf_printk("get a v4 rx pack but conn not record, its sock is: %p", // sk); return 0; @@ -242,19 +279,23 @@ static __always_inline int __tcp_enter_recovery(struct sock *sk) { return 0; } -static __always_inline int __tcp_enter_loss(struct sock *sk) { - if (!retrans_info) { +static __always_inline int __tcp_enter_loss(struct sock *sk) +{ + if (!retrans_info) + { return 0; } struct conn_t *conn = bpf_map_lookup_elem(&conns_info, &sk); - if (conn == NULL) { + if (conn == NULL) + { return 0; } conn->timeout += 1; return 0; } static __always_inline int -__handle_set_state(struct trace_event_raw_inet_sock_set_state *ctx) { +__handle_set_state(struct trace_event_raw_inet_sock_set_state *ctx) +{ if (ctx->protocol != IPPROTO_TCP) return 0; @@ -278,6 +319,7 @@ __handle_set_state(struct trace_event_raw_inet_sock_set_state *ctx) { bpf_probe_read_kernel(&tcpstate.daddr, sizeof(tcpstate.daddr), &sk->__sk_common.skc_daddr); tcpstate.time = time; + if (ctx->newstate == TCP_CLOSE) bpf_map_delete_elem(&tcp_state, &sk); else @@ -285,9 +327,11 @@ __handle_set_state(struct trace_event_raw_inet_sock_set_state *ctx) { struct tcp_state *message; message = bpf_ringbuf_reserve(&tcp_rb, sizeof(*message), 0); - if (!message) { + if (!message) + { return 0; } + message->saddr = tcpstate.saddr; message->daddr = tcpstate.daddr; message->sport = tcpstate.sport; @@ -295,13 +339,14 @@ __handle_set_state(struct trace_event_raw_inet_sock_set_state *ctx) { message->oldstate = tcpstate.oldstate; message->newstate = tcpstate.newstate; message->time = tcpstate.time; - bpf_printk("Dport:%d time:%d", tcpstate.dport, tcpstate.time); + bpf_ringbuf_submit(message, 0); return 0; } static __always_inline int __tcp_rcv_established(struct sock *sk, - struct sk_buff *skb) { + struct sk_buff *skb) +{ const struct inet_sock *inet = (struct inet_sock *)(sk); struct tcp_sock *ts; struct hist *histp; @@ -315,13 +360,14 @@ static __always_inline int __tcp_rcv_established(struct sock *sk, struct ip_packet key = {.saddr = pkt_tuple.saddr, .daddr = pkt_tuple.daddr}; histp = bpf_map_lookup_elem(&hists, &key); - if (!histp) { - // 初始化值 + if (!histp) + { + struct hist zero = {}; bpf_map_update_elem(&hists, &key, &zero, BPF_ANY); histp = bpf_map_lookup_elem(&hists, &key); if (!histp) - return 0; // 如果仍然查找失败,则返回 + return 0; } ts = (struct tcp_sock *)(sk); @@ -339,7 +385,8 @@ static __always_inline int __tcp_rcv_established(struct sock *sk, struct RTT *message; message = bpf_ringbuf_reserve(&rtt_rb, sizeof(*message), 0); - if (!message) { + if (!message) + { return 0; } message->saddr = pkt_tuple.saddr; @@ -355,7 +402,8 @@ static __always_inline int __tcp_rcv_established(struct sock *sk, } static __always_inline int ret(void *ctx, u8 direction, u16 sport, - u16 dport) { + u16 dport) +{ struct reset_event_t *message = bpf_ringbuf_reserve(&events, sizeof(*message), 0); if (!message) @@ -366,27 +414,36 @@ static __always_inline int ret(void *ctx, u8 direction, u16 sport, struct sock *sk = (struct sock *)ctx; message->family = BPF_CORE_READ(sk, __sk_common.skc_family); - message->timestamp = bpf_ktime_get_ns(); + message->timestamp = bpf_ktime_get_ns() / 1000; - if (message->family == AF_INET) { - if (direction == 0) { // Send + if (message->family == AF_INET) + { + if (direction == 0) + { // Send message->saddr = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr); message->daddr = BPF_CORE_READ(sk, __sk_common.skc_daddr); - } else { // Receive + } + else + { // Receive message->saddr = BPF_CORE_READ(sk, __sk_common.skc_daddr); message->daddr = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr); } message->saddr_v6 = 0; message->daddr_v6 = 0; - } else if (message->family == AF_INET6) { - if (direction == 0) { // Send + } + else if (message->family == AF_INET6) + { + if (direction == 0) + { // Send bpf_probe_read_kernel( &message->saddr_v6, sizeof(message->saddr_v6), &sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32); bpf_probe_read_kernel( &message->daddr_v6, sizeof(message->daddr_v6), &sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32); - } else { // Receive + } + else + { // Receive bpf_probe_read_kernel( &message->saddr_v6, sizeof(message->saddr_v6), &sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32); @@ -399,10 +456,13 @@ static __always_inline int ret(void *ctx, u8 direction, u16 sport, message->daddr = 0; } - if (direction == 0) { // Send + if (direction == 0) + { // Send message->sport = bpf_ntohs(sport); message->dport = bpf_ntohs(dport); - } else { // Receive + } + else + { // Receive message->sport = bpf_ntohs(dport); message->dport = bpf_ntohs(sport); } @@ -411,9 +471,12 @@ static __always_inline int ret(void *ctx, u8 direction, u16 sport, // 增加 RST 计数 u32 pid = message->pid; u64 *count = bpf_map_lookup_elem(&counters, &pid); - if (count) { + if (count) + { *count += 1; - } else { + } + else + { u64 initial_count = 1; bpf_map_update_elem(&counters, &pid, &initial_count, BPF_ANY); count = &initial_count; @@ -425,7 +488,8 @@ static __always_inline int ret(void *ctx, u8 direction, u16 sport, return 0; } static __always_inline int -__handle_send_reset(struct trace_event_raw_tcp_send_reset *ctx) { +__handle_send_reset(struct trace_event_raw_tcp_send_reset *ctx) +{ struct sock *sk = (struct sock *)ctx->skaddr; if (!sk) return 0; @@ -434,7 +498,8 @@ __handle_send_reset(struct trace_event_raw_tcp_send_reset *ctx) { } static __always_inline int -__handle_receive_reset(struct trace_event_raw_tcp_receive_reset *ctx) { +__handle_receive_reset(struct trace_event_raw_tcp_receive_reset *ctx) +{ struct sock *sk = (struct sock *)ctx->skaddr; if (!sk) return 0; diff --git a/MagicEyes/src/backend/net/net_watcher/include/net_watcher.h b/MagicEyes/src/backend/net/net_watcher/include/net_watcher.h index e331c59f7..c3253b607 100644 --- a/MagicEyes/src/backend/net/net_watcher/include/net_watcher.h +++ b/MagicEyes/src/backend/net/net_watcher/include/net_watcher.h @@ -57,7 +57,8 @@ typedef unsigned long long u64; #define CACHEMAXSIZE 5 typedef u64 stack_trace_t[MAX_STACK_DEPTH]; -struct conn_t { +struct conn_t +{ void *sock; // 此tcp连接的 socket 地址 int pid; // pid u64 ptid; // 此tcp连接的 ptid(ebpf def) @@ -90,7 +91,8 @@ struct conn_t { u64 duration; // 连接已建立时长 }; -struct pack_t { +struct pack_t +{ int err; // no err(0) invalid seq(1) invalid checksum(2) u64 mac_time; // mac layer 处理时间(us) u64 ip_time; // ip layer 处理时间(us) @@ -109,7 +111,8 @@ struct pack_t { u16 dport; }; -struct udp_message { +struct udp_message +{ u32 saddr; u32 daddr; u16 sport; @@ -118,7 +121,8 @@ struct udp_message { int rx; int len; }; -struct netfilter { +struct netfilter +{ u32 saddr; u32 daddr; u16 sport; @@ -130,7 +134,8 @@ struct netfilter { u64 post_routing_time; u32 rx; }; -struct reasonissue { +struct reasonissue +{ u32 saddr; u32 daddr; u16 sport; @@ -139,14 +144,16 @@ struct reasonissue { u16 protocol; int drop_reason; }; -struct icmptime { +struct icmptime +{ unsigned int saddr; unsigned int daddr; unsigned long long icmp_tran_time; unsigned int flag; // 0 send 1 rcv }; -struct tcp_state { +struct tcp_state +{ u32 saddr; u32 daddr; u16 sport; @@ -155,7 +162,8 @@ struct tcp_state { int newstate; u64 time; }; -struct dns_information { +struct dns_information +{ u32 saddr; u32 daddr; u16 id; @@ -169,7 +177,8 @@ struct dns_information { int response_count; int request_count; }; -struct stacktrace_event { +struct stacktrace_event +{ u32 pid; u32 cpu_id; char comm[16]; @@ -178,7 +187,9 @@ struct stacktrace_event { stack_trace_t kstack; stack_trace_t ustack; }; -typedef struct mysql_query { + +typedef struct mysql_query +{ int pid; int tid; char comm[20]; @@ -187,7 +198,8 @@ typedef struct mysql_query { u64 duratime; int count; } mysql_query; -struct redis_query { +struct redis_query +{ int pid; int tid; char comm[20]; @@ -198,7 +210,8 @@ struct redis_query { u64 begin_time; int argc; }; -struct redis_stat_query { +struct redis_stat_query +{ int pid; char comm[20]; char key[20]; @@ -207,14 +220,16 @@ struct redis_stat_query { int value_type; }; -struct RTT { +struct RTT +{ u32 saddr; u32 daddr; u64 slots[64]; u64 latency; u64 cnt; }; -struct reset_event_t { +struct reset_event_t +{ int pid; char comm[16]; u16 family; @@ -229,11 +244,13 @@ struct reset_event_t { u64 timestamp; u8 state; }; -struct packet_count { +struct packet_count +{ u64 rx_count; u64 tx_count; }; -struct packet_info { +struct packet_info +{ u32 saddr; u32 daddr; u16 sport; @@ -241,7 +258,8 @@ struct packet_info { u16 proto; struct packet_count count; }; -struct SymbolEntry { +struct SymbolEntry +{ unsigned long addr; char name[30]; }; @@ -253,13 +271,22 @@ static const char *protocol[] = { [3] = "UNKNOWN", }; static const char *tcp_states[] = { - [1] = "ESTABLISHED", [2] = "SYN_SENT", [3] = "SYN_RECV", - [4] = "FIN_WAIT1", [5] = "FIN_WAIT2", [6] = "TIME_WAIT", - [7] = "CLOSE", [8] = "CLOSE_WAIT", [9] = "LAST_ACK", - [10] = "LISTEN", [11] = "CLOSING", [12] = "NEW_SYN_RECV", + [1] = "ESTABLISHED", + [2] = "SYN_SENT", + [3] = "SYN_RECV", + [4] = "FIN_WAIT1", + [5] = "FIN_WAIT2", + [6] = "TIME_WAIT", + [7] = "CLOSE", + [8] = "CLOSE_WAIT", + [9] = "LAST_ACK", + [10] = "LISTEN", + [11] = "CLOSING", + [12] = "NEW_SYN_RECV", [13] = "UNKNOWN", }; -struct LayerDelayInfo { +struct LayerDelayInfo +{ float delay; // 时延数据 int layer_index; // 层索引 }; diff --git a/MagicEyes/src/backend/net/net_watcher/src/net_watcher.c b/MagicEyes/src/backend/net/net_watcher/src/net_watcher.c index 96e719dbc..701c82a96 100644 --- a/MagicEyes/src/backend/net/net_watcher/src/net_watcher.c +++ b/MagicEyes/src/backend/net/net_watcher/src/net_watcher.c @@ -37,17 +37,11 @@ static volatile bool exiting = false; struct packet_count proto_stats[256] = {0}; static u64 rst_count = 0; static struct reset_event_t event_store[MAX_EVENTS]; -static int event_count = 0; -static char connects_file_path[1024]; -static char err_file_path[1024]; -static char packets_file_path[1024]; -static char udp_file_path[1024]; +static int event_count = 0, num_symbols = 0, cache_size = 0; static char binary_path[64] = ""; -int num_symbols = 0; -int cache_size = 0; -// 用于存储从 eBPF map 读取的数据 -typedef struct { +typedef struct +{ char key[256]; u32 value; } kv_pair; @@ -60,7 +54,7 @@ static int all_conn = 0, err_packet = 0, extra_conn_info = 0, layer_time = 0, drop_reason = 0, addr_to_func = 0, icmp_info = 0, tcp_info = 0, time_load = 0, dns_info = 0, stack_info = 0, mysql_info = 0, redis_info = 0, count_info = 0, rtt_info = 0, rst_info = 0, - protocol_count = 0,redis_stat = 0; // flag + protocol_count = 0, redis_stat = 0; // flag static const char argp_program_doc[] = "Watch tcp/ip in network subsystem \n"; static const struct argp_option opts[] = { @@ -96,9 +90,11 @@ static const struct argp_option opts[] = { {"protocol_count", 'p', 0, 0, "set to trace protocol count"}, {}}; -static error_t parse_arg(int key, char *arg, struct argp_state *state) { +static error_t parse_arg(int key, char *arg, struct argp_state *state) +{ char *end; - switch (key) { + switch (key) + { case 'a': all_conn = 1; break; @@ -181,7 +177,8 @@ static const struct argp argp = { .parser = parse_arg, .doc = argp_program_doc, }; -enum MonitorMode { +enum MonitorMode +{ MODE_UDP, MODE_NET_FILTER, MODE_DROP_REASON, @@ -194,34 +191,80 @@ enum MonitorMode { MODE_RST, MODE_PROTOCOL_COUNT, MODE_REDIS_STAT, + MODE_EXTRA_CONN, + MODE_RETRANS, + MODE_CONN, + MODE_ERROR, MODE_DEFAULT }; -enum MonitorMode get_monitor_mode() { - if (udp_info) { +enum MonitorMode get_monitor_mode() +{ + if (udp_info) + { return MODE_UDP; - } else if (net_filter) { + } + else if (net_filter) + { return MODE_NET_FILTER; - } else if (drop_reason) { + } + else if (drop_reason) + { return MODE_DROP_REASON; - } else if (icmp_info) { + } + else if (icmp_info) + { return MODE_ICMP; - } else if (tcp_info) { + } + else if (tcp_info) + { return MODE_TCP; - } else if (dns_info) { + } + else if (dns_info) + { return MODE_DNS; - } else if (mysql_info) { + } + else if (mysql_info) + { return MODE_MYSQL; - } else if (redis_info) { + } + else if (redis_info) + { return MODE_REDIS; - } else if (redis_stat) { + } + else if (redis_stat) + { return MODE_REDIS_STAT; - } else if (rtt_info) { + } + else if (rtt_info) + { return MODE_RTT; - } else if (rst_info) { + } + else if (rst_info) + { return MODE_RST; - } else if (protocol_count) { + } + else if (protocol_count) + { return MODE_PROTOCOL_COUNT; - } else { + } + else if (extra_conn_info) + { + return MODE_EXTRA_CONN; + } + else if (retrans_info) + { + return MODE_RETRANS; + } + else if (all_conn) + { + return MODE_CONN; + } + else if (err_packet) + { + return MODE_ERROR; + } + else + { return MODE_DEFAULT; } } @@ -242,16 +285,19 @@ enum MonitorMode get_monitor_mode() { " \\/_/\\/_/\\/____/ \\/__/ \\/__//__ / \\/_/ \\/_/\\/__/\\/____/ " \ "\\/_/\\/_/\\/____/ \\/_/ \n\n" -void print_logo() { +void print_logo() +{ char *logo = LOGO_STRING; int i = 0; FILE *lolcat_pipe = popen("/usr/games/lolcat", "w"); - if (lolcat_pipe == NULL) { + if (lolcat_pipe == NULL) + { printf("Error: Unable to execute lolcat command.\n"); return; } // 像lolcat管道逐个字符写入字符串 - while (logo[i] != '\0') { + while (logo[i] != '\0') + { fputc(logo[i], lolcat_pipe); fflush(lolcat_pipe); // 刷新管道,确保字符被立即发送给lolcat usleep(150); @@ -260,49 +306,57 @@ void print_logo() { pclose(lolcat_pipe); } -#define __ATTACH_UPROBE(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); \ +#define __ATTACH_UPROBE(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); \ } while (false) -#define __CHECK_PROGRAM(skel, prog_name) \ - do { \ - if (!skel->links.prog_name) { \ - perror("no program attached for " #prog_name); \ - return -errno; \ - } \ +#define __CHECK_PROGRAM(skel, prog_name) \ + do \ + { \ + if (!skel->links.prog_name) \ + { \ + perror("no program attached for " #prog_name); \ + return -errno; \ + } \ } while (false) -#define __ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, is_retprobe) \ - do { \ - __ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe); \ - __CHECK_PROGRAM(skel, prog_name); \ +#define __ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, is_retprobe) \ + do \ + { \ + __ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe); \ + __CHECK_PROGRAM(skel, prog_name); \ } while (false) -#define ATTACH_UPROBE(skel, sym_name, prog_name) \ +#define ATTACH_UPROBE(skel, sym_name, prog_name) \ __ATTACH_UPROBE(skel, sym_name, prog_name, false) -#define ATTACH_URETPROBE(skel, sym_name, prog_name) \ +#define ATTACH_URETPROBE(skel, sym_name, prog_name) \ __ATTACH_UPROBE(skel, sym_name, prog_name, true) -#define ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name) \ +#define ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name) \ __ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, false) -#define ATTACH_URETPROBE_CHECKED(skel, sym_name, prog_name) \ +#define ATTACH_URETPROBE_CHECKED(skel, sym_name, prog_name) \ __ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, true) struct SymbolEntry symbols[300000]; struct SymbolEntry cache[CACHEMAXSIZE]; // LRU算法查找函数 -struct SymbolEntry find_in_cache(unsigned long int addr) { +struct SymbolEntry find_in_cache(unsigned long int addr) +{ // 查找地址是否在快表中 - for (int i = 0; i < cache_size; i++) { - if (cache[i].addr == addr) { + for (int i = 0; i < cache_size; i++) + { + if (cache[i].addr == addr) + { // 更新访问时间 struct SymbolEntry temp = cache[i]; // 将访问的元素移动到快表的最前面,即最近使用的位置 - for (int j = i; j > 0; j--) { + for (int j = i; j > 0; j--) + { cache[j] = cache[j - 1]; } cache[0] = temp; @@ -315,55 +369,72 @@ struct SymbolEntry find_in_cache(unsigned long int addr) { return empty_entry; } // 将新的符号条目加入快表 -void add_to_cache(struct SymbolEntry entry) { +void add_to_cache(struct SymbolEntry entry) +{ // 如果快表已满,则移除最久未使用的条目 - if (cache_size == CACHEMAXSIZE) { - for (int i = cache_size - 1; i > 0; i--) { + if (cache_size == CACHEMAXSIZE) + { + for (int i = cache_size - 1; i > 0; i--) + { cache[i] = cache[i - 1]; } cache[0] = entry; - } else { + } + else + { // 否则,直接加入快表 - for (int i = cache_size; i > 0; i--) { + for (int i = cache_size; i > 0; i--) + { cache[i] = cache[i - 1]; } cache[0] = entry; cache_size++; } } -struct SymbolEntry findfunc(unsigned long int addr) { +struct SymbolEntry findfunc(unsigned long int addr) +{ // 先在快表中查找 struct SymbolEntry entry = find_in_cache(addr); - if (entry.addr != 0) { + if (entry.addr != 0) + { return entry; } unsigned long long low = 0, high = num_symbols - 1; unsigned long long result = -1; - while (low <= high) { + while (low <= high) + { int mid = low + (high - low) / 2; - if (symbols[mid].addr < addr) { + if (symbols[mid].addr < addr) + { result = mid; low = mid + 1; - } else { + } + else + { high = mid - 1; } } add_to_cache(symbols[result]); return symbols[result]; }; -void readallsym() { + +void readallsym() +{ FILE *file = fopen("/proc/kallsyms", "r"); - if (!file) { + if (!file) + { perror("Error opening file"); exit(EXIT_FAILURE); } char line[256]; - while (fgets(line, sizeof(line), file)) { + while (fgets(line, sizeof(line), file)) + { unsigned long addr; char type, name[30]; int ret = sscanf(line, "%lx %c %s", &addr, &type, name); - if (ret == 3) { + if (ret == 3) + { symbols[num_symbols].addr = addr; strncpy(symbols[num_symbols].name, name, 30); num_symbols++; @@ -387,17 +458,20 @@ float ewma_values[NUM_LAYERS] = {0}; int count[NUM_LAYERS] = {0}; // 指数加权移动平均算法 -float calculate_ewma(float new_value, float old_ewma) { +float calculate_ewma(float new_value, float old_ewma) +{ return ALPHA * new_value + (1 - ALPHA) * old_ewma; } // 收集时延数据并检测异常 -int process_delay(float layer_delay, int layer_index) { +int process_delay(float layer_delay, int layer_index) +{ if (layer_delay == 0) return 0; count[layer_index]++; - if (ewma_values[layer_index] == 0) { + if (ewma_values[layer_index] == 0) + { ewma_values[layer_index] = layer_delay; return 0; } @@ -405,19 +479,24 @@ int process_delay(float layer_delay, int layer_index) { ewma_values[layer_index] = calculate_ewma(layer_delay, ewma_values[layer_index]); float threshold = ewma_values[layer_index] * GRANULARITY; - if (count[layer_index] > 30) { + if (count[layer_index] > 30) + { // 判断当前时延是否超过阈值 // printf("%d %d:%f %f // ",layer_index,count[layer_index]++,threshold,layer_delay); - if (layer_delay > threshold) { // 异常 + if (layer_delay > threshold) + { // 异常 return 1; - } else { + } + else + { return 0; } } return 0; } -static void set_rodata_flags(struct net_watcher_bpf *skel) { +static void set_rodata_flags(struct net_watcher_bpf *skel) +{ skel->rodata->filter_dport = dport; skel->rodata->filter_sport = sport; skel->rodata->all_conn = all_conn; @@ -440,7 +519,8 @@ static void set_rodata_flags(struct net_watcher_bpf *skel) { skel->rodata->rst_info = rst_info; skel->rodata->protocol_count = protocol_count; } -static void set_disable_load(struct net_watcher_bpf *skel) { +static void set_disable_load(struct net_watcher_bpf *skel) +{ bpf_program__set_autoload(skel->progs.inet_csk_accept_exit, (all_conn || err_packet || extra_conn_info || @@ -614,8 +694,10 @@ static void set_disable_load(struct net_watcher_bpf *skel) { bpf_program__set_autoload(skel->progs.handle_receive_reset, rst_info ? true : false); } -static void print_header(enum MonitorMode mode) { - switch (mode) { +static void print_header(enum MonitorMode mode) +{ + switch (mode) + { case MODE_UDP: printf("===============================================================" "UDP " @@ -681,12 +763,12 @@ static void print_header(enum MonitorMode mode) { printf("%-20s %-20s %-20s %-20s %-20s \n", "Pid", "Comm", "Size", "Redis", "duration/μs"); break; - case MODE_REDIS_STAT: + case MODE_REDIS_STAT: printf("===============================================================" "====================REDIS " "INFORMATION====================================================" "============================\n"); - printf("%-20s %-20s %-20s %-20s %-20s %-20s\n", "Pid", "Comm", "key", "Key_count","Value_Type","Value"); + printf("%-20s %-20s %-20s %-20s %-20s %-20s\n", "Pid", "Comm", "key", "Key_count", "Value_Type", "Value"); break; case MODE_RTT: printf("===============================================================" @@ -699,16 +781,44 @@ static void print_header(enum MonitorMode mode) { "====================RST " "INFORMATION====================================================" "============================\n"); - printf("%-20s %-20s %-20s %-20s %-20s %-20s %-20s \n", "Pid", "Comm", + printf("%-10s %-20s %-10s %-10s %-10s %-10s %-20s \n", "Pid", "Comm", "Saddr", "Daddr", "Sport", "Dport", "Time"); break; + case MODE_EXTRA_CONN: + printf("===============================================================" + "====================EXTRA CONN " + "INFORMATION====================================================" + "============================\n"); + printf("%-15s %-15s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-13s %-10s %-10s %-10s %-10s\n", "Saddr", "Daddr", "Sport", "Dport", "backlog", "maxbacklog", "rwnd", "cwnd", "ssthresh", "sndbuf", "wmem_queued", "rx_bytes", "tx_bytes", "srtt", "duration"); + break; + case MODE_RETRANS: + printf("===============================================================" + "====================RETRANS " + "INFORMATION====================================================" + "============================\n"); + printf("%-15s %-15s %-10s %-10s %-10s %-10s %-10s\n", "Saddr", "Daddr", "Sport", "Dport", "fastRe", "total_retrans", "timeout"); + break; + case MODE_CONN: + printf("===============================================================" + "====================CONN " + "INFORMATION====================================================" + "============================\n"); + printf("%-15s %-20s %-15s %-15s %-10s %-10s %-10s\n", "Pid", "Sock", "Saddr", "Daddr", "Sport", "Dport", "Is_Server"); + break; case MODE_DEFAULT: printf("===============================================================" "=INFORMATION===================================================" "======================\n"); - printf("%-22s %-20s %-8s %-20s %-8s %-15s %-15s %-15s %-15s %-15s \n", + printf("%-22s %-20s %-8s %-20s %-8s %-15s %-15s %-15s %-14s %-14s %-14s %-16s \n", "SOCK", "Saddr", "Sport", "Daddr", "Dport", "MAC_TIME/μs", - "IP_TIME/μs", "TRAN_TIME/μs", "RX/direction", "HTTP"); + "IP_TIME/μs", "TRAN_TIME/μs", "Seq", "Ack", "RX/direction", "HTTP"); + break; + case MODE_ERROR: + printf("===============================================================" + "=ERROR INFORMATION===================================================" + "======================\n"); + printf("%-22s %-20s %-8s %-20s %-8s %-14s %-14s %-15s \n", + "SOCK", "Saddr", "Sport", "Daddr", "Dport", "Seq", "Ack", "Reason"); break; case MODE_PROTOCOL_COUNT: printf("===============================================================" @@ -718,64 +828,40 @@ static void print_header(enum MonitorMode mode) { break; } } -static void open_log_files() { - FILE *connect_file = fopen(connects_file_path, "w+"); - if (connect_file == NULL) { - fprintf(stderr, "Failed to open connect.log: (%s)\n", strerror(errno)); - exit(EXIT_FAILURE); - } - fclose(connect_file); - - FILE *err_file = fopen(err_file_path, "w+"); - if (err_file == NULL) { - fprintf(stderr, "Failed to open err.log: (%s)\n", strerror(errno)); - exit(EXIT_FAILURE); - } - fclose(err_file); - - FILE *packet_file = fopen(packets_file_path, "w+"); - if (packet_file == NULL) { - fprintf(stderr, "Failed to open packets.log: (%s)\n", strerror(errno)); - exit(EXIT_FAILURE); - } - fclose(packet_file); - - FILE *udp_file = fopen(udp_file_path, "w+"); - if (udp_file == NULL) { - fprintf(stderr, "Failed to open udp.log: (%s)\n", strerror(errno)); - exit(EXIT_FAILURE); - } - fclose(udp_file); -} static void sig_handler(int signo) { exiting = true; } -static void bytes_to_str(char *str, unsigned long long num) { - if (num > 1e9) { +static void bytes_to_str(char *str, unsigned long long num) +{ + if (num > 1e9) + { sprintf(str, "%.8lfG", (double)num / 1e9); - } else if (num > 1e6) { + } + else if (num > 1e6) + { sprintf(str, "%.6lfM", (double)num / 1e6); - } else if (num > 1e3) { + } + else if (num > 1e3) + { sprintf(str, "%.3lfK", (double)num / 1e3); - } else { + } + else + { sprintf(str, "%llu", num); } } -static int print_conns(struct net_watcher_bpf *skel) { - - FILE *file = fopen(connects_file_path, "w"); - if (file == NULL) { - fprintf(stderr, "Failed to open connects.log: (%s)\n", strerror(errno)); - return 0; - } +static int print_conns(struct net_watcher_bpf *skel) +{ int map_fd = bpf_map__fd(skel->maps.conns_info); struct sock *sk = NULL; - while (bpf_map_get_next_key(map_fd, &sk, &sk) == 0) { + while (bpf_map_get_next_key(map_fd, &sk, &sk) == 0) + { // fprintf(stdout, "next_sk: (%p)\n", sk); struct conn_t d = {}; int err = bpf_map_lookup_elem(map_fd, &sk, &d); - if (err) { + if (err) + { fprintf(stderr, "Failed to read value from the conns map: (%s)\n", strerror(errno)); return 0; @@ -791,72 +877,59 @@ static int print_conns(struct net_watcher_bpf *skel) { if ((d.saddr & 0x0000FFFF) == 0x0000007F || (d.daddr & 0x0000FFFF) == 0x0000007F) return 0; - if (d.family == AF_INET) { - sprintf(s_ip_port_str, "%s:%d", - inet_ntop(AF_INET, &d.saddr, s_str, sizeof(s_str)), - d.sport); - sprintf(d_ip_port_str, "%s:%d", - inet_ntop(AF_INET, &d.daddr, d_str, sizeof(d_str)), - d.dport); - } else { // AF_INET6 - sprintf( - s_ip_port_str, "%s:%d", - inet_ntop(AF_INET6, &d.saddr_v6, s_str_v6, sizeof(s_str_v6)), - d.sport); - sprintf( - d_ip_port_str, "%s:%d", - inet_ntop(AF_INET6, &d.daddr_v6, d_str_v6, sizeof(d_str_v6)), - d.dport); + if (d.family == AF_INET) + { + inet_ntop(AF_INET, &d.saddr, s_str, sizeof(s_str)); + inet_ntop(AF_INET, &d.daddr, d_str, sizeof(d_str)); + sprintf(s_ip_port_str, "%s:%d", s_str, d.sport); + sprintf(d_ip_port_str, "%s:%d", d_str, d.dport); + } + else + { + inet_ntop(AF_INET6, &d.saddr_v6, s_str_v6, sizeof(s_str_v6)); + inet_ntop(AF_INET6, &d.daddr_v6, d_str_v6, sizeof(d_str_v6)); + sprintf(s_ip_port_str, "%s:%d", s_str_v6, d.sport); + sprintf(d_ip_port_str, "%s:%d", d_str_v6, d.dport); } + + char s_ip_only[INET_ADDRSTRLEN]; + char d_ip_only[INET_ADDRSTRLEN]; + strncpy(s_ip_only, s_str, sizeof(s_ip_only)); + strncpy(d_ip_only, d_str, sizeof(d_ip_only)); + char received_bytes[11], acked_bytes[11]; bytes_to_str(received_bytes, d.bytes_received); bytes_to_str(acked_bytes, d.bytes_acked); - fprintf(file, - "connection{pid=\"%d\",sock=\"%p\",src=\"%s\",dst=\"%s\"," - "is_server=\"%d\"", - d.pid, d.sock, s_ip_port_str, d_ip_port_str, d.is_server); - if (extra_conn_info) { - fprintf(file, - ",backlog=\"%u\"" - ",maxbacklog=\"%u\"" - ",rwnd=\"%u\"" - ",cwnd=\"%u\"" - ",ssthresh=\"%u\"" - ",sndbuf=\"%u\"" - ",wmem_queued=\"%u\"" - ",rx_bytes=\"%s\"" - ",tx_bytes=\"%s\"" - ",srtt=\"%u\"" - ",duration=\"%llu\"" - ",total_retrans=\"%u\"", - d.tcp_backlog, d.max_tcp_backlog, d.rcv_wnd, d.snd_cwnd, - d.snd_ssthresh, d.sndbuf, d.sk_wmem_queued, received_bytes, - acked_bytes, d.srtt, d.duration, d.total_retrans); - } else { - fprintf(file, - ",backlog=\"-\",maxbacklog=\"-\",cwnd=\"-\",ssthresh=\"-\"," - "sndbuf=\"-\",wmem_queued=\"-\",rx_bytes=\"-\",tx_bytes=\"-" - "\",srtt=\"-\",duration=\"-\",total_retrans=\"-\""); + + if (extra_conn_info) + { + printf("%-15s %-15s %-10d %-10d %-10u %-10u %-10u %-10u %-10u %-10u %-13u %-10s %-10s %-10u %-10llu\n", + s_ip_only, d_ip_only, d.sport, d.dport, d.tcp_backlog, + d.max_tcp_backlog, d.rcv_wnd, d.snd_cwnd, d.snd_ssthresh, + d.sndbuf, d.sk_wmem_queued, received_bytes, acked_bytes, d.srtt, + d.duration); + } + if (retrans_info) + { + printf("%-15s %-15s %-10d %-10d %-10u %-14u %-10u\n", s_ip_only, d_ip_only, d.sport, d.dport, d.fastRe, d.total_retrans, d.timeout); } - if (retrans_info) { - fprintf(file, ",fast_retrans=\"%u\",timeout_retrans=\"%u\"", - d.fastRe, d.timeout); - } else { - fprintf(file, ",fast_retrans=\"-\",timeout_retrans=\"-\""); + if (all_conn) + { + printf("%-15d %-20p %-15s %-15s %-10d %-10d %-10u\n", d.pid, d.sock, s_ip_only, d_ip_only, d.sport, d.dport, d.is_server); } - fprintf(file, "}\n"); } - fflush(file); - fclose(file); return 0; } -static int print_packet(void *ctx, void *packet_info, size_t size) { - if (udp_info || net_filter || drop_reason || icmp_info || tcp_info || - dns_info || mysql_info || redis_info || rtt_info || protocol_count||redis_stat) +static int print_packet(void *ctx, void *packet_info, size_t size) +{ + if (udp_info || net_filter || drop_reason || icmp_info || tcp_info || all_conn || + dns_info || mysql_info || redis_info || rtt_info || protocol_count || redis_stat || extra_conn_info || retrans_info) return 0; + char http_data[256]; const struct pack_t *pack_info = packet_info; if (pack_info->mac_time > MAXTIME || pack_info->ip_time > MAXTIME || - pack_info->tran_time > MAXTIME) { + pack_info->tran_time > MAXTIME) + { return 0; } char d_str[INET_ADDRSTRLEN]; @@ -872,109 +945,95 @@ static int print_packet(void *ctx, void *packet_info, size_t size) { if (sport) if (pack_info->sport != sport) return 0; - if (pack_info->err) { - FILE *file = fopen(err_file_path, "a"); - char reason[20]; - if (pack_info->err == 1) { - printf("[X] invalid SEQ: sock = %p,seq= %u,ack = %u\n", - pack_info->sock, pack_info->seq, pack_info->ack); - sprintf(reason, "Invalid SEQ"); - } else if (pack_info->err == 2) { - printf("[X] invalid checksum: sock = %p\n", pack_info->sock); - sprintf(reason, "Invalid checksum"); - } else { - printf("UNEXPECTED packet error %d.\n", pack_info->err); - sprintf(reason, "Unkonwn"); - } - fprintf(file, - "error{sock=\"%p\",seq=\"%u\",ack=\"%u\"," - "reason=\"%s\"} \n", - pack_info->sock, pack_info->seq, pack_info->ack, reason); - fclose(file); - } else { - FILE *file = fopen(packets_file_path, "a"); - char http_data[256]; - - if (strstr((char *)pack_info->data, "HTTP/1")) { - - for (int i = 0; i < sizeof(pack_info->data); ++i) { - if (pack_info->data[i] == '\r') { - http_data[i] = '\0'; - break; - } - http_data[i] = pack_info->data[i]; - } - } else { + if (strstr((char *)pack_info->data, "HTTP/1")) + { - sprintf(http_data, "-"); + for (int i = 0; i < sizeof(pack_info->data); ++i) + { + if (pack_info->data[i] == '\r') + { + http_data[i] = '\0'; + break; + } + http_data[i] = pack_info->data[i]; } - if (layer_time) { - printf("%-22p %-20s %-8d %-20s %-8d %-14llu %-14llu %-14llu %-15d " - "%-16s", - pack_info->sock, - inet_ntop(AF_INET, &saddr, s_str, sizeof(s_str)), - pack_info->sport, - inet_ntop(AF_INET, &daddr, d_str, sizeof(d_str)), - pack_info->dport, pack_info->mac_time, pack_info->ip_time, - pack_info->tran_time, pack_info->rx, http_data); - fprintf( - file, - "packet{sock=\"%p\",saddr=\"%s\",sport=\"%d\",daddr=\"%s\"," - "dport=\"%d\",seq=\"%u\",ack=\"%u\"," - "mac_time=\"%llu\",ip_time=\"%llu\",tran_time=\"%llu\",http_" - "info=\"%s\",rx=\"%d\"} \n", - pack_info->sock, - inet_ntop(AF_INET, &saddr, s_str, sizeof(s_str)), - pack_info->sport, - inet_ntop(AF_INET, &daddr, d_str, sizeof(d_str)), - pack_info->dport, pack_info->seq, pack_info->ack, - pack_info->mac_time, pack_info->ip_time, pack_info->tran_time, - http_data, pack_info->rx); - } else { - printf("%-22p %-20s %-8d %-20s %-8d %-10d %-10d %-10d %-5d %-10s", + } + else + { + sprintf(http_data, "-"); + } + if (layer_time) + { + printf("%-22p %-20s %-8d %-20s %-8d %-14llu %-14llu %-14llu %-14u %-14u %-14d " + "%-16s", + pack_info->sock, + inet_ntop(AF_INET, &saddr, s_str, sizeof(s_str)), + pack_info->sport, + inet_ntop(AF_INET, &daddr, d_str, sizeof(d_str)), + pack_info->dport, pack_info->mac_time, pack_info->ip_time, + pack_info->tran_time, pack_info->seq, pack_info->ack, pack_info->rx, http_data); + } + else if (err_packet) + { + if (pack_info->err) + { + char reason[20]; + if (pack_info->err == 1) + { + printf("[X] invalid SEQ: sock = %p,seq= %u,ack = %u\n", + pack_info->sock, pack_info->seq, pack_info->ack); + sprintf(reason, "Invalid SEQ"); + } + else if (pack_info->err == 2) + { + printf("[X] invalid checksum: sock = %p\n", pack_info->sock); + sprintf(reason, "Invalid checksum"); + } + else + { + printf("UNEXPECTED packet error %d.\n", pack_info->err); + sprintf(reason, "Unkonwn"); + } + printf("%-22p %-20s %-8d %-20s %-8d %-14u %-14u %-14s ", pack_info->sock, inet_ntop(AF_INET, &saddr, s_str, sizeof(s_str)), pack_info->sport, inet_ntop(AF_INET, &daddr, d_str, sizeof(d_str)), - pack_info->dport, 0, 0, 0, pack_info->rx, http_data); - fprintf(file, - "packet{sock=\"%p\",saddr=\"%s\",sport=\"%d\",daddr=\"%s\"," - "dport=\"%d\",seq=\"%u\",ack=\"%u\"," - "mac_time=\"%d\",ip_time=\"%d\",tran_time=\"%d\",http_" - "info=\"%s\",rx=\"%d\"} \n", - pack_info->sock, - inet_ntop(AF_INET, &saddr, s_str, sizeof(s_str)), - pack_info->sport, - inet_ntop(AF_INET, &daddr, d_str, sizeof(d_str)), - pack_info->dport, pack_info->seq, pack_info->ack, 0, 0, 0, - http_data, pack_info->rx); + pack_info->dport, pack_info->seq, pack_info->ack, reason); } - fclose(file); } - if (time_load) { + else + { + printf("%-22p %-20s %-8d %-20s %-8d %-14u %-14u %-14u %-14u %-14u %-14d %-16s\n", + pack_info->sock, + inet_ntop(AF_INET, &saddr, s_str, sizeof(s_str)), + pack_info->sport, + inet_ntop(AF_INET, &daddr, d_str, sizeof(d_str)), + pack_info->dport, 0, 0, 0, pack_info->seq, pack_info->ack, pack_info->rx, http_data); + } + if (time_load) + { int mac = process_delay(pack_info->mac_time, 0); int ip = process_delay(pack_info->ip_time, 1); int tran = process_delay(pack_info->tran_time, 2); - if (mac || ip || tran) { + if (mac || ip || tran) + { printf("%-15s", "abnormal data"); } } printf("\n"); return 0; } -static int print_udp(void *ctx, void *packet_info, size_t size) { +static int print_udp(void *ctx, void *packet_info, size_t size) +{ if (!udp_info) return 0; - FILE *file = fopen(udp_file_path, "a+"); // 追加 - if (file == NULL) { - fprintf(stderr, "Failed to open udp.log: (%s)\n", strerror(errno)); - return 0; - } char d_str[INET_ADDRSTRLEN]; char s_str[INET_ADDRSTRLEN]; const struct udp_message *pack_info = packet_info; unsigned int saddr = pack_info->saddr; unsigned int daddr = pack_info->daddr; + if (pack_info->tran_time > MAXTIME || (daddr & 0x0000FFFF) == 0x0000007F || (saddr & 0x0000FFFF) == 0x0000007F) return 0; @@ -983,15 +1042,9 @@ static int print_udp(void *ctx, void *packet_info, size_t size) { inet_ntop(AF_INET, &daddr, d_str, sizeof(d_str)), pack_info->sport, pack_info->dport, pack_info->tran_time, pack_info->rx, pack_info->len); - fprintf(file, - "packet{saddr=\"%s\",daddr=\"%s\",sport=\"%u\"," - "dport=\"%u\",udp_time=\"%llu\",rx=\"%d\",len=\"%d\"} \n", - inet_ntop(AF_INET, &saddr, s_str, sizeof(s_str)), - inet_ntop(AF_INET, &daddr, d_str, sizeof(d_str)), pack_info->sport, - pack_info->dport, pack_info->tran_time, pack_info->rx, - pack_info->len); - fclose(file); - if (time_load) { + + if (time_load) + { int flag = process_delay(pack_info->tran_time, 3); if (flag) printf("%-15s", "abnormal data"); @@ -999,7 +1052,8 @@ static int print_udp(void *ctx, void *packet_info, size_t size) { printf("\n"); return 0; } -static int print_netfilter(void *ctx, void *packet_info, size_t size) { +static int print_netfilter(void *ctx, void *packet_info, size_t size) +{ if (!net_filter) return 0; char d_str[INET_ADDRSTRLEN]; @@ -1030,9 +1084,11 @@ static int print_netfilter(void *ctx, void *packet_info, size_t size) { {pack_info->forward_time, 6}, {pack_info->post_routing_time, 7}, {pack_info->local_out_time, 8}}; - if (time_load) { + if (time_load) + { // 循环遍历数组 - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 5; i++) + { // 数组的总字节数除以第一个元素的字节数得到元素的个数 float delay = layer_delay_infos[i].delay; int layer_net = layer_delay_infos[i].layer_index; @@ -1045,7 +1101,8 @@ static int print_netfilter(void *ctx, void *packet_info, size_t size) { return 0; } -static int print_tcpstate(void *ctx, void *packet_info, size_t size) { +static int print_tcpstate(void *ctx, void *packet_info, size_t size) +{ if (!tcp_info) return 0; char d_str[INET_ADDRSTRLEN]; @@ -1062,60 +1119,80 @@ static int print_tcpstate(void *ctx, void *packet_info, size_t size) { return 0; } static void calculate_protocol_usage(struct packet_count proto_stats[], - int num_protocols, int interval) { + int num_protocols, int interval) +{ static uint64_t last_rx[256] = {0}, last_tx[256] = {0}; uint64_t current_rx = 0, current_tx = 0; uint64_t delta_rx[256] = {0}, delta_tx[256] = {0}; - //遍历所有的协议 - for (int i = 0; i < num_protocols; i++) { - //计算数据包增量 - if (proto_stats[i].rx_count >= last_rx[i]) { + // 遍历所有的协议 + for (int i = 0; i < num_protocols; i++) + { + // 计算数据包增量 + if (proto_stats[i].rx_count >= last_rx[i]) + { delta_rx[i] = proto_stats[i].rx_count - last_rx[i]; - } else { + } + else + { delta_rx[i] = proto_stats[i].rx_count; } - if (proto_stats[i].tx_count >= last_tx[i]) { + if (proto_stats[i].tx_count >= last_tx[i]) + { delta_tx[i] = proto_stats[i].tx_count - last_tx[i]; - } else { + } + else + { delta_tx[i] = proto_stats[i].tx_count; } - //时间段内总的接收和发送包数 + // 时间段内总的接收和发送包数 current_rx += delta_rx[i]; current_tx += delta_tx[i]; - //更新上次统计的包数 + // 更新上次统计的包数 last_rx[i] = proto_stats[i].rx_count; last_tx[i] = proto_stats[i].tx_count; } printf("Protocol Usage in Last %d Seconds:\n", interval); printf("Total_rx_count:%ld Total_tx_count:%ld\n", current_rx, current_tx); - if (current_rx > 0) { + if (current_rx > 0) + { printf("Receive Protocol Usage:\n"); - for (int i = 0; i < num_protocols; i++) { - if (delta_rx[i] > 0) { + for (int i = 0; i < num_protocols; i++) + { + if (delta_rx[i] > 0) + { double rx_percentage = (double)delta_rx[i] / current_rx * 100; - if (rx_percentage >= 80.0) { + if (rx_percentage >= 80.0) + { printf(RED_TEXT "Protocol %s: %.2f%% Rx_count:%ld\n" RESET_TEXT, protocol[i], rx_percentage, delta_rx[i]); - } else { + } + else + { printf("Protocol %s: %.2f%% Rx_count:%ld\n", protocol[i], rx_percentage, delta_rx[i]); } } } } - if (current_tx > 0) { + if (current_tx > 0) + { printf("Transmit Protocol Usage:\n"); - for (int i = 0; i < num_protocols; i++) { - if (delta_tx[i] > 0) { + for (int i = 0; i < num_protocols; i++) + { + if (delta_tx[i] > 0) + { double tx_percentage = (double)delta_tx[i] / current_tx * 100; - if (tx_percentage >= 80.0) { + if (tx_percentage >= 80.0) + { printf(RED_TEXT "Protocol %s: %.2f%% Tx_count:%ld\n" RESET_TEXT, protocol[i], tx_percentage, delta_tx[i]); - } else { + } + else + { printf("Protocol %s: %.2f%% Tx_count:%ld\n", protocol[i], tx_percentage, delta_tx[i]); } @@ -1124,10 +1201,12 @@ static void calculate_protocol_usage(struct packet_count proto_stats[], } memset(proto_stats, 0, num_protocols * sizeof(struct packet_count)); } -static int print_protocol_count(void *ctx, void *packet_info, size_t size) { +static int print_protocol_count(void *ctx, void *packet_info, size_t size) +{ const struct packet_info *pack_protocol_info = (const struct packet_info *)packet_info; - if (!protocol_count) { + if (!protocol_count) + { return 0; } proto_stats[pack_protocol_info->proto].rx_count = @@ -1136,7 +1215,8 @@ static int print_protocol_count(void *ctx, void *packet_info, size_t size) { pack_protocol_info->count.tx_count; return 0; } -static int print_kfree(void *ctx, void *packet_info, size_t size) { +static int print_kfree(void *ctx, void *packet_info, size_t size) +{ if (!drop_reason) return 0; char d_str[INET_ADDRSTRLEN]; @@ -1144,15 +1224,21 @@ static int print_kfree(void *ctx, void *packet_info, size_t size) { const struct reasonissue *pack_info = packet_info; unsigned int saddr = pack_info->saddr; unsigned int daddr = pack_info->daddr; - if (saddr == 0 && daddr == 0) { + if (saddr == 0 && daddr == 0) + { return 0; } char prot[6]; - if (pack_info->protocol == 2048) { + if (pack_info->protocol == 2048) + { strcpy(prot, "ipv4"); - } else if (pack_info->protocol == 34525) { + } + else if (pack_info->protocol == 34525) + { strcpy(prot, "ipv6"); - } else { + } + else + { // 其他协议 strcpy(prot, "other"); } @@ -1165,7 +1251,8 @@ static int print_kfree(void *ctx, void *packet_info, size_t size) { pack_info->dport, prot); if (!addr_to_func) printf("%-34lx", pack_info->location); - else { + else + { struct SymbolEntry data = findfunc(pack_info->location); char result[40]; sprintf(result, "%s+0x%lx", data.name, pack_info->location - data.addr); @@ -1174,13 +1261,15 @@ static int print_kfree(void *ctx, void *packet_info, size_t size) { printf("%s\n", SKB_Drop_Reason_Strings[pack_info->drop_reason]); return 0; } -static int print_icmptime(void *ctx, void *packet_info, size_t size) { +static int print_icmptime(void *ctx, void *packet_info, size_t size) +{ if (!icmp_info) return 0; char d_str[INET_ADDRSTRLEN]; char s_str[INET_ADDRSTRLEN]; const struct icmptime *pack_info = packet_info; - if (pack_info->icmp_tran_time > MAXTIME) { + if (pack_info->icmp_tran_time > MAXTIME) + { return 0; } unsigned int saddr = pack_info->saddr; @@ -1189,23 +1278,28 @@ static int print_icmptime(void *ctx, void *packet_info, size_t size) { inet_ntop(AF_INET, &saddr, s_str, sizeof(s_str)), inet_ntop(AF_INET, &daddr, d_str, sizeof(d_str)), pack_info->icmp_tran_time, pack_info->flag); - if (time_load) { + if (time_load) + { int icmp_data = process_delay(pack_info->icmp_tran_time, 9); - if (icmp_data) { + if (icmp_data) + { printf("%-15s\n", "abnormal data"); } } printf("\n"); return 0; } -static int print_rst(void *ctx, void *packet_info, size_t size) { - if (!rst_info) { +static int print_rst(void *ctx, void *packet_info, size_t size) +{ + if (!rst_info) + { return 0; } struct reset_event_t *event = packet_info; // 将事件存储到全局存储中 - if (event_count < MAX_EVENTS) { + if (event_count < MAX_EVENTS) + { memcpy(&event_store[event_count], event, sizeof(struct reset_event_t)); event_count++; } @@ -1213,53 +1307,67 @@ static int print_rst(void *ctx, void *packet_info, size_t size) { rst_count++; return 0; } -static void print_stored_events() { +static void print_stored_events() +{ char s_str[INET_ADDRSTRLEN]; char d_str[INET_ADDRSTRLEN]; - - for (int i = 0; i < event_count; i++) { + char saddr_v6[INET6_ADDRSTRLEN]; + char daddr_v6[INET6_ADDRSTRLEN]; + + for (int i = 0; i < event_count; i++) + { struct reset_event_t *event = &event_store[i]; unsigned int saddr = event->saddr; unsigned int daddr = event->daddr; - if (event->family == AF_INET) { + if (event->family == AF_INET) + { inet_ntop(AF_INET, &saddr, s_str, sizeof(s_str)); inet_ntop(AF_INET, &daddr, d_str, sizeof(d_str)); - printf("%-20llu %-20s %-20s %-20s %-20u %-20u %-20llu\n", - (unsigned long long)event->pid, event->comm, s_str, d_str, + printf("%-10d %-10s %-10s %-10s %-10u %-10u %-20llu", + event->pid, event->comm, s_str, d_str, event->sport, event->dport, - (unsigned long long)event->timestamp); - } else if (event->family == AF_INET6) { - char saddr_v6[INET6_ADDRSTRLEN]; - char daddr_v6[INET6_ADDRSTRLEN]; + event->timestamp); + } + else if (event->family == AF_INET6) + { + inet_ntop(AF_INET6, &event->saddr_v6, saddr_v6, sizeof(saddr_v6)); inet_ntop(AF_INET6, &event->daddr_v6, daddr_v6, sizeof(daddr_v6)); - printf("%-10llu %-16s %-16s %-16s %-8u %-8u %-20llu\n", - (unsigned long long)event->pid, event->comm, saddr_v6, + printf("%-10d %10s %-10s %-10s %-10u %-10u %-20llu\n", + event->pid, event->comm, saddr_v6, daddr_v6, event->sport, event->dport, - (unsigned long long)event->timestamp); + event->timestamp); } + printf("\n"); } } -static void print_domain_name(const unsigned char *data, char *output) { +static void print_domain_name(const unsigned char *data, char *output) +{ const unsigned char *next = data; int pos = 0, first = 1; // 循环到尾部,标志0 - while (*next != 0) { - if (!first) { + while (*next != 0) + { + if (!first) + { output[pos++] = '.'; // 在每个段之前添加点号 - } else { + } + else + { first = 0; // 第一个段后清除标志 } int len = *next++; // 下一个段长度 - for (int i = 0; i < len; ++i) { + for (int i = 0; i < len; ++i) + { output[pos++] = *next++; } } - output[pos] = '\0'; // 确保字符串正确结束 + output[pos] = '\0'; } -static int print_dns(void *ctx, void *packet_info, size_t size) { +static int print_dns(void *ctx, void *packet_info, size_t size) +{ if (!packet_info) return 0; char d_str[INET_ADDRSTRLEN]; @@ -1274,7 +1382,8 @@ static int print_dns(void *ctx, void *packet_info, size_t size) { inet_ntop(AF_INET, &daddr, d_str, sizeof(d_str)); print_domain_name((const unsigned char *)pack_info->data, domain_name); - if (pack_info->daddr == 0) { + if (pack_info->daddr == 0) + { return 0; } printf("%-20s %-20s %-#12x %-#12x %-5x %-5x %-5x %-5x %-47s %-10d %-10d " @@ -1285,27 +1394,34 @@ static int print_dns(void *ctx, void *packet_info, size_t size) { pack_info->rx); return 0; } -static int print_mysql(void *ctx, void *packet_info, size_t size) { - if (!mysql_info) { +static int print_mysql(void *ctx, void *packet_info, size_t size) +{ + if (!mysql_info) + { return 0; } const mysql_query *pack_info = packet_info; printf("%-20d %-20d %-20s %-20u %-41s", pack_info->pid, pack_info->tid, pack_info->comm, pack_info->size, pack_info->msql); - if (pack_info->duratime > count_info) { + if (pack_info->duratime > count_info) + { printf("%-21llu", pack_info->duratime); - } else { + } + else + { printf("%-21s", ""); } printf("%-20d\n", pack_info->count); return 0; } -static int print_redis(void *ctx, void *packet_info, size_t size) { +static int print_redis(void *ctx, void *packet_info, size_t size) +{ const struct redis_query *pack_info = packet_info; int i = 0; char redis[64]; - for (i = 0; i < pack_info->argc; i++) { + for (i = 0; i < pack_info->argc; i++) + { strcat(redis, pack_info->redis[i]); strcat(redis, " "); } @@ -1314,74 +1430,85 @@ static int print_redis(void *ctx, void *packet_info, size_t size) { strcpy(redis, ""); return 0; } -static int process_redis_first(char flag,char *message) { - if(flag=='+') +static int process_redis_first(char flag, char *message) +{ + if (flag == '+') { strcpy(message, "Status Reply"); } - else if (flag=='-') + else if (flag == '-') { strcpy(message, "Error Reply"); } - else if (flag==':') + else if (flag == ':') { strcpy(message, "Integer Reply"); } - else if (flag=='$') + else if (flag == '$') { strcpy(message, "Bulk String Reply"); } - else if (flag=='*') + else if (flag == '*') { strcpy(message, "Array Reply"); } - else{ + else + { strcpy(message, "Unknown Type"); } return 0; } -static int print_redis_stat(void *ctx, void *packet_info, size_t size) { - if (!redis_stat) { +static int print_redis_stat(void *ctx, void *packet_info, size_t size) +{ + if (!redis_stat) + { return 0; } - char message[20]={}; + char message[20] = {}; const struct redis_stat_query *pack_info = packet_info; - if(pack_info->key_count) + if (pack_info->key_count) { printf("%-20d %-20s %-20s %-20d %-20s %-20s\n", pack_info->pid, pack_info->comm, - pack_info->key,pack_info->key_count,"-","-"); + pack_info->key, pack_info->key_count, "-", "-"); } else { - process_redis_first(pack_info->value[0],message); + process_redis_first(pack_info->value[0], message); printf("%-20d %-20s %-20s %-20s %-20s %-20s\n", pack_info->pid, pack_info->comm, - "-","-",message,pack_info->value); + "-", "-", message, pack_info->value); } - + return 0; } static int libbpf_print_fn(enum libbpf_print_level level, const char *format, - va_list args) { + va_list args) +{ return vfprintf(stderr, format, args); } -static void show_stack_trace(__u64 *stack, int stack_sz, pid_t pid) { +static void show_stack_trace(__u64 *stack, int stack_sz, pid_t pid) +{ int i; printf("-----------------------------------\n"); - for (i = 1; i < stack_sz; i++) { - if (addr_to_func) { + for (i = 1; i < stack_sz; i++) + { + if (addr_to_func) + { struct SymbolEntry data = findfunc(stack[i]); char result[40]; sprintf(result, "%s+0x%llx", data.name, stack[i] - data.addr); printf("%-10d [<%016llx>]=%s\n", i, stack[i], result); - } else { + } + else + { printf("%-10d [<%016llx>]\n", i, stack[i]); } } printf("-----------------------------------\n"); } -static int print_trace(void *_ctx, void *data, size_t size) { +static int print_trace(void *_ctx, void *data, size_t size) +{ struct stacktrace_event *event = data; if (event->kstack_sz <= 0 && event->ustack_sz <= 0) @@ -1390,16 +1517,20 @@ static int print_trace(void *_ctx, void *data, size_t size) { printf("COMM: %s (pid=%d) @ CPU %d\n", event->comm, event->pid, event->cpu_id); - if (event->kstack_sz > 0) { + if (event->kstack_sz > 0) + { printf("Kernel:\n"); show_stack_trace(event->kstack, event->kstack_sz / sizeof(__u64), 0); - } else { + } + else + { printf("No Kernel Stack\n"); } printf("\n"); return 0; } -static int print_rtt(void *ctx, void *data, size_t size) { +static int print_rtt(void *ctx, void *data, size_t size) +{ if (!rtt_info) return 0; struct RTT *rtt_tuple = data; @@ -1412,7 +1543,8 @@ static int print_rtt(void *ctx, void *data, size_t size) { if ((rtt_tuple->saddr & 0x0000FFFF) == 0x0000007F || (rtt_tuple->daddr & 0x0000FFFF) == 0x0000007F || rtt_tuple->saddr == htonl(0xC0A83C01) || - rtt_tuple->daddr == htonl(0xC0A83C01)) { + rtt_tuple->daddr == htonl(0xC0A83C01)) + { return 0; // 如果匹配任一过滤条件,放弃处理这些数据包 } // 打印源地址和目的地址 @@ -1431,25 +1563,28 @@ static int print_rtt(void *ctx, void *data, size_t size) { // 计算和打印RTT分布图 printf(" usecs : count distribution\n"); int bucket_size = 1; - for (int i = 0; i < MAX_SLOTS; i++) { + for (int i = 0; i < MAX_SLOTS; i++) + { int start_range = bucket_size == 1 ? 0 : bucket_size; int end_range = bucket_size * 2 - 1; printf("%8d -> %-8d : %-8llu |", start_range, end_range, rtt_tuple->slots[i]); int bar_length = rtt_tuple->slots[i] / - 10; //计算该延迟范围内的计数对应的直方图条形长度,每个'*' - //表示 10 个计数 - for (int j = 0; j < bar_length; j++) { + 10; // 计算该延迟范围内的计数对应的直方图条形长度,每个'*' + // 表示 10 个计数 + for (int j = 0; j < bar_length; j++) + { printf("*"); } printf("\n"); - bucket_size *= 2; //以对数方式扩展 + bucket_size *= 2; // 以对数方式扩展 } printf("===============================================================\n"); return 0; } -int attach_uprobe_mysql(struct net_watcher_bpf *skel) { +int attach_uprobe_mysql(struct net_watcher_bpf *skel) +{ ATTACH_UPROBE_CHECKED( skel, _Z16dispatch_commandP3THDPK8COM_DATA19enum_server_command, @@ -1459,48 +1594,58 @@ int attach_uprobe_mysql(struct net_watcher_bpf *skel) { query__end); return 0; } -int attach_uprobe_redis(struct net_watcher_bpf *skel) { - if(redis_info){ +int attach_uprobe_redis(struct net_watcher_bpf *skel) +{ + if (redis_info) + { ATTACH_UPROBE_CHECKED(skel, call, redis_call); ATTACH_UPROBE_CHECKED(skel, processCommand, redis_processCommand); } - if(redis_stat){ + if (redis_stat) + { ATTACH_UPROBE_CHECKED(skel, lookupKey, redis_lookupKey); ATTACH_UPROBE_CHECKED(skel, addReply, redis_addReply); } return 0; } -void print_top_5_keys() { +void print_top_5_keys() +{ kv_pair *pairs; pairs = malloc(sizeof(kv_pair) * 1024); - if (!pairs) { + if (!pairs) + { perror("Failed to allocate memory"); exit(EXIT_FAILURE); } int index = 0; char *key = NULL; - while (bpf_map_get_next_key(map_fd, &key, &key) == 0) { + while (bpf_map_get_next_key(map_fd, &key, &key) == 0) + { // fprintf(stdout, "next_sk: (%p)\n", sk); int count; int err = bpf_map_lookup_elem(map_fd, &key, &count); - if (err) { + if (err) + { fprintf(stderr, "Failed to read value from the conns map: (%s)\n", strerror(errno)); - return ; + return; } memcpy(pairs[index].key, &key, 256); pairs[index].value = count; - //printf("Key: %s, Count: %u\n", pairs[index].key, pairs[index].value); + // printf("Key: %s, Count: %u\n", pairs[index].key, pairs[index].value); index++; - } + } // 获取所有键值对 // 排序前 5 个元素 // 简单选择排序(可替换为其他高效排序算法) - for (int i = 0; i < index - 1; i++) { - for (int j = i + 1; j < index; j++) { - if (pairs[j].value > pairs[i].value) { + for (int i = 0; i < index - 1; i++) + { + for (int j = i + 1; j < index; j++) + { + if (pairs[j].value > pairs[i].value) + { kv_pair temp = pairs[i]; pairs[i] = pairs[j]; pairs[j] = temp; @@ -1508,30 +1653,18 @@ void print_top_5_keys() { } } printf("----------------------------\n"); - // 打印前 5 个元素 + printf("Top 5 Keys:\n"); - for (int i = 0; i < 5 && i < index; i++) { + for (int i = 0; i < 5 && i < index; i++) + { printf("Key: %s, Count: %u\n", pairs[i].key, pairs[i].value); } free(pairs); } -int main(int argc, char **argv) { - char *last_slash = strrchr(argv[0], '/'); - if (last_slash) { - *(last_slash + 1) = '\0'; - } - strcpy(connects_file_path, argv[0]); - strcpy(err_file_path, argv[0]); - strcpy(packets_file_path, argv[0]); - strcpy(udp_file_path, argv[0]); - if (connects_file_path[strlen(connects_file_path) - 1] != '/') - strcat(connects_file_path, "/connects.log"); - else - strcat(connects_file_path, "connects.log"); - // strcat(connects_file_path, "./connects.log"); - strcat(err_file_path, "./err.log"); - strcat(packets_file_path, "./packets.log"); - strcat(udp_file_path, "./udp.log"); + +int main(int argc, char **argv) +{ + struct ring_buffer *rb = NULL; struct ring_buffer *udp_rb = NULL; struct ring_buffer *netfilter_rb = NULL; @@ -1549,18 +1682,22 @@ int main(int argc, char **argv) { struct net_watcher_bpf *skel; int err; /* Parse command line arguments */ - if (argc > 1) { + if (argc > 1) + { err = argp_parse(&argp, argc, argv, 0, NULL, NULL); if (err) return err; } - libbpf_set_print(libbpf_print_fn); + + // libbpf_set_print(libbpf_print_fn); + /* Cleaner handling of Ctrl-C */ signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); /* Open load and verify BPF application */ skel = net_watcher_bpf__open(); - if (!skel) { + if (!skel) + { fprintf(stderr, "Failed to open BPF skeleton\n"); return 1; } @@ -1571,120 +1708,141 @@ int main(int argc, char **argv) { if (addr_to_func) readallsym(); err = net_watcher_bpf__load(skel); - if (err) { + if (err) + { fprintf(stderr, "Failed to load and verify BPF skeleton\n"); goto cleanup; } /* Attach tracepoint handler */ - if (mysql_info) { + if (mysql_info) + { strcpy(binary_path, "/usr/sbin/mysqld"); err = attach_uprobe_mysql(skel); - if (err) { + if (err) + { fprintf(stderr, "failed to attach uprobes\n"); goto cleanup; } - } else if (redis_info||redis_stat) { + } + else if (redis_info || redis_stat) + { strcpy(binary_path, "/usr/bin/redis-server"); err = attach_uprobe_redis(skel); - if (err) { + if (err) + { fprintf(stderr, "failed to attach uprobes\n"); goto cleanup; } - } else { + } + else + { err = net_watcher_bpf__attach(skel); - if (err) { + if (err) + { fprintf(stderr, "Failed to attach BPF skeleton\n"); goto cleanup; } } enum MonitorMode mode = get_monitor_mode(); - // print_logo(); + print_logo(); print_header(mode); udp_rb = ring_buffer__new(bpf_map__fd(skel->maps.udp_rb), print_udp, NULL, NULL); - if (!udp_rb) { + if (!udp_rb) + { err = -1; fprintf(stderr, "Failed to create ring buffer(udp)\n"); goto cleanup; } netfilter_rb = ring_buffer__new(bpf_map__fd(skel->maps.netfilter_rb), print_netfilter, NULL, NULL); - if (!netfilter_rb) { + if (!netfilter_rb) + { err = -1; fprintf(stderr, "Failed to create ring buffer(netfilter)\n"); goto cleanup; } kfree_rb = ring_buffer__new(bpf_map__fd(skel->maps.kfree_rb), print_kfree, NULL, NULL); - if (!kfree_rb) { + if (!kfree_rb) + { err = -1; fprintf(stderr, "Failed to create ring buffer(kfree)\n"); goto cleanup; } icmp_rb = ring_buffer__new(bpf_map__fd(skel->maps.icmp_rb), print_icmptime, NULL, NULL); - if (!icmp_rb) { + if (!icmp_rb) + { err = -1; fprintf(stderr, "Failed to create ring buffer(icmp)\n"); goto cleanup; } tcp_rb = ring_buffer__new(bpf_map__fd(skel->maps.tcp_rb), print_tcpstate, NULL, NULL); - if (!tcp_rb) { + if (!tcp_rb) + { err = -1; fprintf(stderr, "Failed to create ring buffer(tcp)\n"); goto cleanup; } dns_rb = ring_buffer__new(bpf_map__fd(skel->maps.dns_rb), print_dns, NULL, NULL); - if (!dns_rb) { + if (!dns_rb) + { err = -1; fprintf(stderr, "Failed to create ring buffer(dns)\n"); goto cleanup; } trace_rb = ring_buffer__new(bpf_map__fd(skel->maps.trace_rb), print_trace, NULL, NULL); - if (!trace_rb) { + if (!trace_rb) + { err = -1; fprintf(stderr, "Failed to create ring buffer(trace)\n"); goto cleanup; } mysql_rb = ring_buffer__new(bpf_map__fd(skel->maps.mysql_rb), print_mysql, NULL, NULL); - if (!mysql_rb) { + if (!mysql_rb) + { err = -1; fprintf(stderr, "Failed to create ring buffer(trace)\n"); goto cleanup; } redis_rb = ring_buffer__new(bpf_map__fd(skel->maps.redis_rb), print_redis, NULL, NULL); - if (!redis_rb) { + if (!redis_rb) + { err = -1; fprintf(stderr, "Failed to create ring buffer(trace)\n"); goto cleanup; } redis_stat_rb = ring_buffer__new(bpf_map__fd(skel->maps.redis_stat_rb), print_redis_stat, - NULL, NULL); - if (!redis_stat_rb) { + NULL, NULL); + if (!redis_stat_rb) + { err = -1; fprintf(stderr, "Failed to create ring buffer(trace)\n"); goto cleanup; } rtt_rb = ring_buffer__new(bpf_map__fd(skel->maps.rtt_rb), print_rtt, NULL, NULL); - if (!rtt_rb) { + if (!rtt_rb) + { err = -1; fprintf(stderr, "Failed to create ring buffer(connect_rb)\n"); goto cleanup; } events = ring_buffer__new(bpf_map__fd(skel->maps.events), print_rst, NULL, NULL); - if (!events) { + if (!events) + { err = -1; fprintf(stderr, "Failed to create ring buffer(rst_rb)\n"); goto cleanup; @@ -1692,24 +1850,27 @@ int main(int argc, char **argv) { port_rb = ring_buffer__new(bpf_map__fd(skel->maps.port_rb), print_protocol_count, NULL, NULL); - if (!port_rb) { + if (!port_rb) + { err = -1; fprintf(stderr, "Failed to create ring buffer(trace)\n"); goto cleanup; } /* Set up ring buffer polling */ rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), print_packet, NULL, NULL); - if (!rb) { + if (!rb) + { err = -1; fprintf(stderr, "Failed to create ring buffer(packet)\n"); goto cleanup; } - //open_log_files(); + // open_log_files(); struct timeval start, end; gettimeofday(&start, NULL); /* Process events */ - while (!exiting) { + while (!exiting) + { err = ring_buffer__poll(rb, 100 /* timeout, ms */); err = ring_buffer__poll(udp_rb, 100 /* timeout, ms */); err = ring_buffer__poll(netfilter_rb, 100 /* timeout, ms */); @@ -1727,37 +1888,59 @@ int main(int argc, char **argv) { print_conns(skel); sleep(1); /* Ctrl-C will cause -EINTR */ - if (err == -EINTR) { + if (err == -EINTR) + { err = 0; break; } - if (err < 0) { + if (err < 0) + { printf("Error polling perf buffer: %d\n", err); break; } gettimeofday(&end, NULL); - if ((end.tv_sec - start.tv_sec) >= 5) { - if (rst_info) { + if ((end.tv_sec - start.tv_sec) >= 5) + { + if (rst_info) + { print_stored_events(); - printf("Total RSTs in the last 5 seconds: %llu\n\n",rst_count); - rst_count = 0; - event_count = 0; - }else if (protocol_count) { - calculate_protocol_usage(proto_stats, 256, 5); - }else if(redis_stat) + printf("Total RSTs in the last 5 seconds: %llu\n\n", rst_count); + rst_count = 0; + event_count = 0; + } + else if (protocol_count) + { + calculate_protocol_usage(proto_stats, 256, 5); + } + else if (redis_stat) + { + map_fd = bpf_map__fd(skel->maps.key_count); + if (map_fd < 0) { - map_fd = bpf_map__fd(skel->maps.key_count); - if (map_fd < 0) { - perror("Failed to get map FD"); - return 1; - } - print_top_5_keys(); + perror("Failed to get map FD"); + return 1; } - gettimeofday(&start, NULL); + print_top_5_keys(); } + gettimeofday(&start, NULL); + } } cleanup: + ring_buffer__free(rb); + ring_buffer__free(udp_rb); + ring_buffer__free(netfilter_rb); + ring_buffer__free(kfree_rb); + ring_buffer__free(icmp_rb); + ring_buffer__free(tcp_rb); + ring_buffer__free(dns_rb); + ring_buffer__free(trace_rb); + ring_buffer__free(mysql_rb); + ring_buffer__free(redis_rb); + ring_buffer__free(rtt_rb); + ring_buffer__free(events); + ring_buffer__free(port_rb); + ring_buffer__free(redis_stat_rb); net_watcher_bpf__destroy(skel); return err < 0 ? -err : 0; } diff --git a/eBPF_Supermarket/Network_Subsystem/net_watcher/mysql.bpf.h b/eBPF_Supermarket/Network_Subsystem/net_watcher/mysql.bpf.h index 13e802887..1ba2474db 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_watcher/mysql.bpf.h +++ b/eBPF_Supermarket/Network_Subsystem/net_watcher/mysql.bpf.h @@ -28,14 +28,10 @@ static __always_inline int __handle_mysql_start(struct pt_regs *ctx) { u32 size = 0; char *sql; - if (command != COM_QUERY) { - return 0; - } - bpf_probe_read(&info.size, sizeof(info.size), &com_data->com_query.length); - bpf_probe_read_str(&sql, sizeof(sql), &com_data->com_query.query); - bpf_probe_read_str(&info.msql, sizeof(info.msql), sql); - // bpf_printk("sql1==%s size1==%lu", info.msql,info.size); + bpf_probe_read(&sql, sizeof(sql), &com_data->com_query.query); + bpf_probe_read(&info.msql, sizeof(info.msql), sql); + // bpf_printk("sql1==%s size1==%lu", sql,info.size); info.start_time = bpf_ktime_get_ns() / 1000; bpf_map_update_elem(&queries, &tid, &info, BPF_ANY); @@ -70,8 +66,6 @@ static __always_inline int __handle_mysql_end(struct pt_regs *ctx) { bpf_get_current_comm(&message->comm, sizeof(comm)); message->size = info->size; bpf_probe_read_str(&message->msql, sizeof(message->msql), info->msql); - // bpf_printk("C==%d D==%lu S==%lu SQL==%s",count, - // message->duratime,message->size,message->msql); bpf_ringbuf_submit(message, 0); return 0;