someuser
someuser

Reputation: 189

Interception of udp-packets on router

I have a client on PC. I have a server on PC. The client and server are connected via a router with firmware based on Linux OS.
The client sends a packet to the server and receive a response. The router must intercept the packets and modify it. Something like sniffing but it's not a sniffing because i need to modify the packets.
I must to write a program for this.
I tried to open a raw socket on the router, but reсvfrom on raw socket does not intercept the packet and just copy it. The packet is going on.
Could you suggest me any way to solve this problem?
P.S. Sorry for my bad English. :)

Upvotes: 2

Views: 2390

Answers (3)

someuser
someuser

Reputation: 189

I wrote the module for the kernel and some applications. Module uses netfilter and discards packets that I need to netfilter_queue. The application processes a queue and I decide what to do with each package.

uint hook_main(uint hooknum,
                  struct sk_buff *skb,
                  const struct net_device *in,
                  const struct net_device *out,
                  int (*okfn)(struct sk_buff *)  )
{
     struct iphdr *ip;
     struct udphdr *udp;
     if (skb->protocol == htons(ETH_P_IP)){
        ip = (struct iphdr *)(skb->data);
        if (ip->version == 4 && ip->protocol == IPPROTO_UDP){
            udp = (struct udphdr *)(skb->data + sizeof(struct iphdr));
            if(ntohs(udp->dest) == SOME_PORT){
                return NF_QUEUE;
            }
        }
     }
     return NF_ACCEPT;
}

int init_module ()
{
    printk("[udp-catch] start udp-catch\n");

    catch_hook.hook = hook_main;
    catch_hook.owner = THIS_MODULE;
    catch_hook.pf = PF_INET;
    catch_hook.hooknum = NF_INET_FORWARD;
    catch_hook.priority = NF_IP_PRI_FIRST;
    nf_register_hook(&catch_hook);

    return 0;
}

And a redesigned sample from netfilter.org is the application.

Upvotes: 1

Davide Berra
Davide Berra

Reputation: 6568

I'd use a mix of iptables and libnetfilter_queue (assuming your kernel is relatively recent)

  1. Add to the iptables a rules that forward all the udp packets to the NFQUEUE 0 in order to get packets from kernel to user space.

    iptables -A INPUT -p udp -m udp --dport xxxxx -j NFQUEUE --queue-num 0

  2. Build a process who listen to the NFQUEUE number 0, modify payload and give the full packet back to the kernel space using libnetfilter_queue capabilities. Follow this link to know how to do it.

In a nutshell you have to open the queue 0 (nfq_create_queue), set the mode in order to get the content of the packet (nfq_set_mode), then loop in an infinite recv to get ever udp packet filtered by iptables

fd = nfq_fd(h);

while ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) {
    printf("pkt received\n");
    nfq_handle_packet(h, buf, rv);
}

Everytime you call nfq_handle_packet is called, the callback defined during the nfq_create_queue phase is called. In that callback you have to modify the payload, update the size and recalculate the checksum, then set as "valid" with nfq_set_verdict

Upvotes: 4

Neil
Neil

Reputation: 11889

Routers will automatically send out whatever they receive on their other ports.

e.g. For a 4 port router, what comes in on port 1 will be sent out on ports 2,3 & 4.

To do what you require, you need another PC with 2 network cards. Connect your client PC to one network card, and the server PC to the other.

Then your program will need to recvfrom on one network card, modify the packet and sendto on the other network card.

Upvotes: 0

Related Questions