test_pkt_access.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /* Copyright (c) 2017 Facebook
  2. *
  3. * This program is free software; you can redistribute it and/or
  4. * modify it under the terms of version 2 of the GNU General Public
  5. * License as published by the Free Software Foundation.
  6. */
  7. #include <stddef.h>
  8. #include <string.h>
  9. #include <linux/bpf.h>
  10. #include <linux/if_ether.h>
  11. #include <linux/if_packet.h>
  12. #include <linux/ip.h>
  13. #include <linux/ipv6.h>
  14. #include <linux/in.h>
  15. #include <linux/tcp.h>
  16. #include <linux/pkt_cls.h>
  17. #include "bpf_helpers.h"
  18. #include "bpf_endian.h"
  19. #define barrier() __asm__ __volatile__("": : :"memory")
  20. int _version SEC("version") = 1;
  21. SEC("test1")
  22. int process(struct __sk_buff *skb)
  23. {
  24. void *data_end = (void *)(long)skb->data_end;
  25. void *data = (void *)(long)skb->data;
  26. struct ethhdr *eth = (struct ethhdr *)(data);
  27. struct tcphdr *tcp = NULL;
  28. __u8 proto = 255;
  29. __u64 ihl_len;
  30. if (eth + 1 > data_end)
  31. return TC_ACT_SHOT;
  32. if (eth->h_proto == bpf_htons(ETH_P_IP)) {
  33. struct iphdr *iph = (struct iphdr *)(eth + 1);
  34. if (iph + 1 > data_end)
  35. return TC_ACT_SHOT;
  36. ihl_len = iph->ihl * 4;
  37. proto = iph->protocol;
  38. tcp = (struct tcphdr *)((void *)(iph) + ihl_len);
  39. } else if (eth->h_proto == bpf_htons(ETH_P_IPV6)) {
  40. struct ipv6hdr *ip6h = (struct ipv6hdr *)(eth + 1);
  41. if (ip6h + 1 > data_end)
  42. return TC_ACT_SHOT;
  43. ihl_len = sizeof(*ip6h);
  44. proto = ip6h->nexthdr;
  45. tcp = (struct tcphdr *)((void *)(ip6h) + ihl_len);
  46. }
  47. if (tcp) {
  48. if (((void *)(tcp) + 20) > data_end || proto != 6)
  49. return TC_ACT_SHOT;
  50. barrier(); /* to force ordering of checks */
  51. if (((void *)(tcp) + 18) > data_end)
  52. return TC_ACT_SHOT;
  53. if (tcp->urg_ptr == 123)
  54. return TC_ACT_OK;
  55. }
  56. return TC_ACT_UNSPEC;
  57. }