Skip to content

Commit a7eefa8

Browse files
authored
fix(bpf): Correctly parse IP headers with options (#337)
* feat(bpf): Improve PID attribution and IP parsing This commit introduces several improvements to the eBPF probe to enhance robustness and feature completeness. - feat: Add fallback for PID attribution Uses `bpf_get_current_task()` as a fallback mechanism to resolve the process ID for a packet. This significantly improves PID attribution for scenarios where the primary flow-based mapping might fail, such as with short-lived connections. Includes a check for kernel support to ensure backward compatibility. - fix: Correctly parse IP headers with options The IP header length is now dynamically calculated based on the IHL (Internet Header Length) field. This fixes a bug where packets with IP options would be parsed incorrectly, leading to errors in L4 (TCP/UDP) header analysis. - chore: Clean up debug logs Commented out several `debug_log` statements to reduce noise and performance overhead. * refactor(bpf): Remove unsafe PID fallback Removes the PID fallback mechanism that uses bpf_get_current_task(). This is unsafe without a reliable way to detect interrupt context (e.g., bpf_in_interrupt()), as it can lead to incorrect PID association. The explanatory comment is updated to reflect this.
1 parent 2b157b7 commit a7eefa8

11 files changed

+46
-6
lines changed

bpf/bpf_arm64_bpfel.o

4.49 KB
Binary file not shown.

bpf/bpf_arm_bpfel.o

3.84 KB
Binary file not shown.

bpf/bpf_legacy_arm64_bpfel.o

1.91 KB
Binary file not shown.

bpf/bpf_legacy_arm_bpfel.o

2.63 KB
Binary file not shown.

bpf/bpf_legacy_x86_bpfel.o

1.92 KB
Binary file not shown.

bpf/bpf_no_tracing_arm64_bpfel.o

2.48 KB
Binary file not shown.

bpf/bpf_no_tracing_arm_bpfel.o

3.52 KB
Binary file not shown.

bpf/bpf_no_tracing_x86_bpfel.o

2.47 KB
Binary file not shown.

bpf/bpf_x86_bpfel.o

4.43 KB
Binary file not shown.

bpf/net.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,22 @@ static __always_inline int parse_skb_l3(struct __sk_buff *skb, u16 protocol, str
7676
l3->protocol = ip_hdr.protocol;
7777
l3->saddr[0] = ip_hdr.saddr;
7878
l3->daddr[0] = ip_hdr.daddr;
79-
*offset += sizeof(struct iphdr);
79+
80+
u8 ip_ihl = 0;
81+
u32 ip_hdr_len = 0;
82+
// support ip options
83+
if (bpf_skb_load_bytes(skb, *offset, &ip_ihl, sizeof(ip_ihl)) == 0) {
84+
ip_hdr_len = (ip_ihl & 0x0f) * 4;
85+
}
86+
if (ip_hdr_len < sizeof(struct iphdr)) {
87+
// debug_log("[ptcpdump] invalid ip header length: %d, use default %d\n", ip_hdr_len,
88+
// sizeof(struct iphdr));
89+
ip_hdr_len = sizeof(struct iphdr);
90+
}
91+
92+
// debug_log("source_ip: %pI4, dest_ip: %pI4\n", &l3->saddr[0], &l3->daddr[0]);
93+
94+
*offset += ip_hdr_len;
8095
return 0;
8196
}
8297
case ETH_P_IPV6: {
@@ -122,14 +137,17 @@ static __always_inline int parse_skb_l4(struct __sk_buff *skb, u8 protocol, stru
122137
case IPPROTO_TCP: {
123138
struct tcphdr tcp_hdr;
124139
if (bpf_skb_load_bytes(skb, *offset, &tcp_hdr, sizeof(struct tcphdr)) < 0) {
125-
// debug_log("parse_skb_l4 1 failed:\n");
140+
// debug_log("parse_skb_l4 1 failed:\n");
126141
return -1;
127142
}
128143
l4->sport = bpf_ntohs(tcp_hdr.source);
129144
l4->dport = bpf_ntohs(tcp_hdr.dest);
145+
146+
// debug_log("parse_skb_l4 1 success: %d -> %d\n", l4->sport, l4->dport);
147+
130148
*offset += sizeof(struct tcphdr);
131-
}
132149
return 0;
150+
}
133151
case IPPROTO_UDP: {
134152
struct udphdr udp_hdr;
135153
if (bpf_skb_load_bytes(skb, *offset, &udp_hdr, sizeof(struct udphdr)) < 0) {

0 commit comments

Comments
 (0)