static inline void process_packet()

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;
}