Rewriting network packets on the fly using libnetfilter_queue
Asked Answered
O

2

7

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!)

Oby answered 26/11, 2010 at 6:39 Comment(0)
O
13

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.

Oby answered 26/11, 2010 at 7:22 Comment(2)
Sedate, do you experience of using this through Java (JNI)? I'm curious if it decreases the performance.Bs
@TinaJasmin Unfortunately I have no experience with JNI, so I am not sure how much of a performance hit would be involved. Sorry I can't be more helpful.Oby
N
0

Just a wild guess from digging around the source code: try explicitly adding the mangled payload using nfnl_addattr_l(…, NFQA_PAYLOAD, …)?

Nesbitt answered 26/11, 2010 at 6:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.