Files

72 lines
1.5 KiB
C
Raw Permalink Normal View History

#define NEXTHDR_IPV6 41
#ifdef IPV6
static void encap_ipv6(volatile void *data, volatile void *data_end)
{
volatile struct ipv6hdr *ip6h;
volatile struct ethhdr *eth;
size_t len;
struct ipv6hdr encap_hdr = {
.version = 6,
.nexthdr = NEXTHDR_IPV6,
.hop_limit = 16,
.saddr = { .s6_addr = { 0xfc, 0x00, 0xde, 0xad, 0xca, 0xfe,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02 } },
.daddr = { .s6_addr = { 0xfc, 0x00, 0xde, 0xad, 0xca, 0xfe,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01 } },
};
eth = data;
ip6h = (void *)(eth +1);
if (ip6h + 1 > data_end)
return;
eth->h_proto = bpf_htons(ETH_P_IPV6);
*ip6h = encap_hdr;
len = (data_end - data);
ip6h->payload_len = bpf_htons(len - sizeof(struct ethhdr) - sizeof(*ip6h));
}
#else
static __always_inline __u16 csum_fold_helper(__u32 csum)
{
__u32 sum;
sum = (csum >> 16) + (csum & 0xffff);
sum += (sum >> 16);
return ~sum;
}
static void encap_ipv4(volatile void *data, volatile void *data_end)
{
volatile struct ethhdr *eth;
volatile struct iphdr *iph;
size_t len;
struct iphdr encap_hdr = {
.version = 4,
.ihl = 5,
.protocol = NEXTHDR_IPV6,
.ttl = 16,
.saddr = bpf_htonl(0x0a0b0202),
.daddr = bpf_htonl(0x0a0b0201),
};
eth = data;
iph = (void *)(eth +1);
if (iph + 1 > data_end)
return;
eth->h_proto = bpf_htons(ETH_P_IP);
*iph = encap_hdr;
len = (data_end - data);
iph->tot_len = bpf_htons(len - sizeof(struct ethhdr));
iph->check = csum_fold_helper(bpf_csum_diff((__be32 *)iph, 0, (__be32 *)iph, sizeof(*iph), 0));
}
#endif