Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP][DO NOT MERGE] Incorrect L4 offset for IP packets with Options field #88

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions connection-limit/connection_limit_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,15 +275,20 @@ int _xdp_limit_conn(struct xdp_md *ctx)

/* Check if its valid ip packet */
struct iphdr *iph = (struct iphdr *)(data + sizeof(struct ethhdr));
if (iph + 1 > data_end)
__u8 ip_hdr_len = iph->ihl * 4;

/* Validating IP Header */
if ((iph->ihl < 5 || iph->ihl > 15) ||
((__u8 *)iph + ip_hdr_len) > data_end) {
return XDP_PASS;
}

/* Ignore other than TCP packets */
if (iph->protocol != IPPROTO_TCP)
return XDP_PASS;

/* Check if its valid tcp packet */
struct tcphdr *tcph = (struct tcphdr *)(iph + 1);
struct tcphdr *tcph = (struct tcphdr *)((__u8 *)iph + ip_hdr_len);
if (tcph + 1 > data_end)
return XDP_PASS;

Expand Down
10 changes: 7 additions & 3 deletions ipfix-flow-exporter/bpf_ipfix_egress_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ void parse_ipv4(struct __sk_buff *skb, u64 l3_offset)
u16 pckt_size = data_end - data;

struct iphdr *iph = data + l3_offset;
u8 ip_hdr_len = (iph->ihl * 4);

if (iph > data_end)
return;
Expand All @@ -238,13 +239,16 @@ void parse_ipv4(struct __sk_buff *skb, u64 l3_offset)
u16 control_bit = 0;
u16 icmp_type = 0;

if (iph + 1 > data_end)
/* Validating IP Header */
if ((iph->ihl < 5 || iph->ihl > 15) ||
((u8 *)iph + ip_hdr_len) > data_end) {
return;
}

if(iph->protocol == ICMP)
parse_icmp_type(iph+1, data_end, &icmp_type);
parse_icmp_type(((u8 *)iph + ip_hdr_len), data_end, &icmp_type);

parse_port(iph+1, data_end, iph->protocol, &dport, &sport, &control_bit);
parse_port(((u8 *)iph + ip_hdr_len), data_end, iph->protocol, &dport, &sport, &control_bit);

memset(&flow_key, 0, sizeof(flow_key));
flow_key.sa = iph->saddr;
Expand Down
10 changes: 7 additions & 3 deletions ipfix-flow-exporter/bpf_ipfix_ingress_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ void parse_ipv4(struct __sk_buff *skb, u64 l3_offset)
u16 pckt_size = data_end - data;

struct iphdr *iph = data + l3_offset;
u8 ip_hdr_len = (iph->ihl * 4);

if (iph > data_end)
return;
Expand All @@ -238,13 +239,16 @@ void parse_ipv4(struct __sk_buff *skb, u64 l3_offset)
u16 control_bit = 0;
u16 icmp_type = 0;

if (iph + 1 > data_end)
/* Validating IP Header */
if ((iph->ihl < 5 || iph->ihl > 15) ||
((u8 *)iph + ip_hdr_len) > data_end) {
return;
}

if(iph->protocol == ICMP)
parse_icmp_type(iph+1, data_end, &icmp_type);
parse_icmp_type(((u8 *)iph + ip_hdr_len), data_end, &icmp_type);

parse_port(iph+1, data_end, iph->protocol, &dport, &sport, &control_bit);
parse_port(((u8 *)iph + ip_hdr_len), data_end, iph->protocol, &dport, &sport, &control_bit);

memset(&flow_key, 0, sizeof(flow_key));
flow_key.sa = iph->saddr;
Expand Down
9 changes: 7 additions & 2 deletions ratelimiting/ratelimiting_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,20 @@ static __always_inline int _xdp_ratelimit(struct xdp_md *ctx)

/* Ignore other than IP packets */
struct iphdr *iph = data + sizeof(struct ethhdr);
if (iph + 1 > data_end)
uint8_t ip_hdr_len = iph->ihl * 4;

/* Validating IP Header */
if ((iph->ihl < 5 || iph->ihl > 15) ||
((uint8_t *)iph + ip_hdr_len) > data_end) {
return XDP_PASS;
}

/* Ignore other than TCP packets */
if (iph->protocol != IPPROTO_TCP)
return XDP_PASS;

/* Check if its valid tcp packet */
struct tcphdr *tcph = (struct tcphdr *)(iph + 1);
struct tcphdr *tcph = (struct tcphdr *)((uint8_t *)iph + ip_hdr_len);
if (tcph + 1 > data_end)
return XDP_PASS;

Expand Down
8 changes: 5 additions & 3 deletions traffic-mirroring/mirroring_egress_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ static __always_inline int egress_redirect(struct __sk_buff *skb)
void *data_end = (void *)(long)skb->data_end;

const int l3_off = ETH_HLEN; // IP header offset
const int l4_off = l3_off + sizeof(struct iphdr); // TCP header offset
struct iphdr *iph = (struct iphdr *)(data + l3_off);
const int l4_off = l3_off + (iph->ihl * 4); // TCP header offset

struct ethhdr *eth = data;
int l7_off;
Expand All @@ -142,10 +143,11 @@ static __always_inline int egress_redirect(struct __sk_buff *skb)
return TC_ACT_OK;
}

if (data + l4_off > data_end) {
/* Validating IP Header */
if ((iph->ihl < 5 || iph->ihl > 15) ||
(data + l4_off > data_end)) {
return TC_ACT_OK; // Not our packet, handover to kernel
}
struct iphdr *iph = (struct iphdr *)(data + l3_off);

if (iph->protocol == IPPROTO_TCP) {
l7_off = l4_off + sizeof(struct tcphdr); // L7 (e.g. HTTP) header offset
Expand Down
8 changes: 5 additions & 3 deletions traffic-mirroring/mirroring_ingress_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ static __always_inline int ingress_redirect(struct __sk_buff *skb)
void *data_end = (void *)(long)skb->data_end;

const int l3_off = ETH_HLEN; // IP header offset
const int l4_off = l3_off + sizeof(struct iphdr); // TCP header offset
struct iphdr *iph = (struct iphdr *)(data + l3_off);
const int l4_off = l3_off + (iph->ihl * 4); // TCP header offset // TCP header offset

struct ethhdr *eth = data;
int l7_off;
Expand All @@ -141,10 +142,11 @@ static __always_inline int ingress_redirect(struct __sk_buff *skb)
return TC_ACT_OK;
}

if (data + l4_off > data_end) {
/* Validating IP Header */
if ((iph->ihl < 5 || iph->ihl > 15) ||
(data + l4_off > data_end)) {
return TC_ACT_OK; // Not our packet, handover to kernel
}
struct iphdr *iph = (struct iphdr *)(data + l3_off);

if (iph->protocol == IPPROTO_TCP) {
l7_off = l4_off + sizeof(struct tcphdr); // L7 (e.g. HTTP) header offset
Expand Down
Loading