0

Context: I am trying to trace packet of a particular port and redirect it but for a particular process. Right now it traces throughout the interface.

#define KBUILD_MODNAME "filter"
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/udp.h>

int udpfilter(struct xdp_md *ctx) {
  bpf_trace_printk("got a packet\n");
  void *data = (void *)(long)ctx->data;
  void *data_end = (void *)(long)ctx->data_end;
  struct ethhdr *eth = data;
  if ((void*)eth + sizeof(*eth) <= data_end) {
    struct iphdr *ip = data + sizeof(*eth);
    if ((void*)ip + sizeof(*ip) <= data_end) {
      if (ip->protocol == IPPROTO_UDP) {
        struct udphdr *udp = (void*)ip + sizeof(*ip);
        if ((void*)udp + sizeof(*udp) <= data_end) {
          if (udp->dest == ntohs(7999)) {
            bpf_trace_printk("udp port 7999\n");
            udp->dest = ntohs(7998);
          }
        }
      }
    }
  }
  return XDP_PASS;
}

Output I am getting

vagrant@vagrant:~$ sudo python3 main.py
/virtual/main.c:1:9: warning: 'KBUILD_MODNAME' macro redefined [-Wmacro-redefined]
#define KBUILD_MODNAME "filter"
        ^
<command line>:3:9: note: previous definition is here
#define KBUILD_MODNAME "bcc"
        ^
1 warning generated.
b'              nc-1508    [000] ..s1  2564.611068: 0: got packet'
b'              nc-1508    [000] ..s1  2564.611082: 0: udp port 7999'
b'              nc-1508    [000] ..s1  2564.611090: 0: got packet'
b'              nc-1508    [000] ..s1  2564.611093: 0: got packet'
b'              nc-1508    [000] ..s1  2564.611094: 0: udp port 7999'
b'              nc-1508    [000] ..s1  2564.611095: 0: got packet'
b'              nc-1508    [000] ..s1  2565.611593: 0: got packet'
b'              nc-1508    [000] ..s1  2565.611605: 0: udp port 7999'
b'              nc-1508    [000] ..s1  2565.611618: 0: got packet'
b'              nc-1508    [000] ..s1  2566.612184: 0: got packet'
b'              nc-1508    [000] ..s1  2566.612195: 0: udp port 7999'
b'              nc-1508    [000] ..s1  2566.612207: 0: got packet'
b'              nc-1508    [000] ..s1  2567.611801: 0: got packet'
b'              nc-1508    [000] ..s1  2567.611812: 0: udp port 7999'
b'              nc-1508    [000] ..s1  2567.611825: 0: got packet'

Is there any function to grep out the nc and if udp port 7999 is traced I can use XDP_DROP to drop the packet.

Something like this if process == nc && udp->dest == ntohs(7999) XDP_DROP

pchaigno
  • 11,313
  • 2
  • 29
  • 54
zexapod
  • 45
  • 6

1 Answers1

1

The process information is not reliable in XDP programs. It's often just the PID of the process that got interrupted to treat received packets, so it could end up being anything. If you add a bit of load on the receiving server, you'll probably notice that all sorts of userspace processes are reported in place of nc.

pchaigno
  • 11,313
  • 2
  • 29
  • 54
  • So the information is not reliable? How do I fetch PID of the process, I tried ```bpf_get_current_pid_tgid();``` but spits out an error ```unknown bpf..``` I am trying ```xdp_drop``` application specific packet – zexapod Nov 29 '21 at 05:18
  • There is no way to get the destination process for a packet at the XDP hook because that information is simply not computed yet at that point. – pchaigno Nov 29 '21 at 09:54