Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rewriting network packets on the fly using libnetfilter_queue

I am attempting to write a userspace application that can hook into an OS's network stack, sniff packets flying past and edit ones that its interested in.

After much Googling, it appears to me that the simplest (yet reasonably robust) method of doing so (on any platform) is Linux's libnetfilter_queue project. However, I'm having trouble finding any reasonable documentation for the project, outside of the limited official documentation. Its main features (as stated by the first link are)

  • receiving queued packets from the kernel nfnetlink_queue subsystem
  • issuing verdicts and/or reinjecting altered packets to the kernel nfnetlink_queue subsystem

Emphasis is my own. How exactly am I meant go about this? I've tried modifying the sample code provided, but perhaps I am misunderstanding something. The code is operating in NFQNL_COPY_PACKET mode, so I am receiving the whole packet -- but my modifications to it seem to be restricted to my own application -- as one would expect, given the "copy" semantics.

My feeling is that I am meant to make use of NF_QUEUE somehow, but I haven't quite grokked it. Any pointers?

(If there is a simpler mechanism for doing this, which is also cross-platform, I'd love to hear about it!)

like image 949
Sedate Alien Avatar asked Nov 26 '10 06:11

Sedate Alien


1 Answers

I can't believe I missed this previously. As reticent as I am to post questions on SO, I thought I would never work this one out myself. :)

I didn't look at the function prototype properly. It turns out in the "verdict" function (outlined below),

int nfq_set_verdict(struct nfq_q_handle *qh,
    u_int32_t id,
    u_int32_t verdict,
    u_int32_t data_len,
    const unsigned char *buf     
)

The last two parameters are for the data to be returned to the network stack. Obvious in hindsight, but I missed it completely as the print_pkt function doesn't take the packet data as a parameter, but extracts it from the struct nfq_data.

The key is to NF_ACCEPT the packet and pass the suitably modified packet back to the kernel.

like image 192
Sedate Alien Avatar answered Sep 30 '22 14:09

Sedate Alien