iovisor / bcc

BCC - Tools for BPF-based Linux IO analysis, networking, monitoring, and more
Apache License 2.0
20.58k stars 3.88k forks source link

Parsing GRE packets to get inner IPv4 original source and destr addresses #4153

Open AdrianBZG opened 2 years ago

AdrianBZG commented 2 years ago

Hi,

I was trying to find an example of GRE packet inspection but couldn't find one. I'm trying to get the original IPv4 source and destination addresses.

int incoming(struct __sk_buff *skb)
{
    void *data = (void *)(long)skb->data;
    void *data_end = (void *)(long)skb->data_end;

    struct iphdr *inner_ip; <--- Need this

    return TC_ACT_OK;
}

Any ideas?

ljluestc commented 11 hours ago

#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/gre.h>
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>

struct gre_hdr {
    __be16 flags;
    __be16 protocol;
};

SEC("classifier")
int incoming(struct __sk_buff *skb) {
    void *data = (void *)(long)skb->data;
    void *data_end = (void *)(long)skb->data_end;

    struct ethhdr *eth = data;
    if ((void *)(eth + 1) > data_end)
        return TC_ACT_SHOT; // Drop packet

    if (eth->h_proto != htons(ETH_P_IP))
        return TC_ACT_OK; // Not an IP packet

    struct iphdr *outer_ip = (struct iphdr *)(eth + 1);
    if ((void *)(outer_ip + 1) > data_end)
        return TC_ACT_SHOT; // Drop packet

    if (outer_ip->protocol != IPPROTO_GRE)
        return TC_ACT_OK; // Not a GRE packet

    struct gre_hdr *greh = (struct gre_hdr *)(outer_ip + 1);
    if ((void *)(greh + 1) > data_end)
        return TC_ACT_SHOT; // Drop packet

    struct iphdr *inner_ip = (struct iphdr *)(greh + 1);
    if ((void *)(inner_ip + 1) > data_end)
        return TC_ACT_SHOT; // Drop packet

    __be32 src_ip = inner_ip->saddr;
    __be32 dst_ip = inner_ip->daddr;

    // Process the inner IP addresses as needed

    return TC_ACT_OK;
}

char _license[] SEC("license") = "GPL";