in tools/xdpdump/XdpDumpKern.h [132:247]
static inline void process_packet(void *data, __u64 off, void *data_end,
bool is_ipv6, struct xdp_md *xdp) {
struct iphdr *iph;
struct ipv6hdr *ip6h;
struct packet_description pckt = {};
__u64 iph_len;
__u8 protocol;
struct XdpDumpOutput output = {};
#ifdef CPU_NUMBER
if (bpf_get_smp_processor_id() != CPU_NUMBER) {
return;
}
#endif
if (is_ipv6) {
ip6h = data + off;
if ((void *)(ip6h + 1) > data_end) {
return;
}
iph_len = sizeof(struct ipv6hdr);
protocol = ip6h->nexthdr;
pckt.proto = protocol;
off += iph_len;
memcpy(pckt.srcv6, ip6h->saddr.s6_addr32, 16);
memcpy(pckt.dstv6, ip6h->daddr.s6_addr32, 16);
} else {
iph = data + off;
if ((void *)(iph + 1) > data_end) {
return;
}
protocol = iph->protocol;
pckt.proto = protocol;
off += IPV4_HDR_LEN_NO_OPT;
pckt.src = iph->saddr;
pckt.dst = iph->daddr;
}
protocol = pckt.proto;
if (protocol == IPPROTO_TCP) {
parse_tcp(data, data_end, is_ipv6, &pckt);
} else if (protocol == IPPROTO_UDP) {
parse_udp(data, data_end, is_ipv6, &pckt);
}
#ifdef SRCV6_0
if ((pckt.srcv6[0] != SRCV6_0) ||
(pckt.srcv6[1] != SRCV6_1) ||
(pckt.srcv6[2] != SRCV6_2) ||
(pckt.srcv6[3] != SRCV6_3)) {
return;
}
#endif
#ifdef DSTV6_0
if ((pckt.dstv6[0] != DSTV6_0) ||
(pckt.dstv6[1] != DSTV6_1) ||
(pckt.dstv6[2] != DSTV6_2) ||
(pckt.dstv6[3] != DSTV6_3)) {
return;
}
#endif
#ifdef SRCV4
if(pckt.src != SRCV4) {
return;
}
#endif
#ifdef DSTV4
if(pckt.dst != DSTV4) {
return;
}
#endif
#ifdef SPORT
if(pckt.port16[0] != SPORT) {
return;
}
#endif
#ifdef DPORT
if(pckt.port16[1] != DPORT) {
return;
}
#endif
#ifdef PROTO
if(pckt.proto != PROTO) {
return;
}
#endif
#ifdef OFFSET
if((data + sizeof(struct ethhdr) + OFFSET + sizeof(__u32)) > data_end) {
return;
}
__u32 pkt_chunk = *(__u32 *)(data + sizeof(struct ethhdr) + OFFSET);
pkt_chunk &=(0xFFFFFFFF >> ((4 - O_LEN) * 8));
if ((pkt_chunk & O_PATTERN) != O_PATTERN) {
return;
}
#endif
output.ipv6 = is_ipv6;
if (is_ipv6) {
memcpy(output.srcv6, pckt.srcv6, 16);
memcpy(output.dstv6, pckt.dstv6, 16);
} else {
output.src = pckt.src;
output.dst = pckt.dst;
}
output.sport = pckt.port16[0];
output.dport = pckt.port16[1];
output.proto = pckt.proto;
output.pkt_size = data_end - data;
__u16 data_len = output.pkt_size < MAX_LEN ? output.pkt_size : MAX_LEN;
output.data_len = data_len;
perf_event_map.perf_submit_skb(xdp, data_len, &output, sizeof(output));
return;
}