Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Dec 2006 15:31:24 -0800
From:      Julian Elischer <julian@elischer.org>
To:        Kevin Sanders <newroswell@gmail.com>
Cc:        freebsd-net@freebsd.org, Fabr?cio Barros Cabral <fxcabral@yahoo.com.br>
Subject:   Re: Intercepting a packet,	changing it and re-injecting into the network
Message-ID:  <458C6ACC.2020605@elischer.org>
In-Reply-To: <375baf50612220932m30f84567jdda28b7fc0e62e61@mail.gmail.com>
References:  <1166802209.7642.17.camel@hades.no-ip.org>	<20061222160550.GD47710@lor.one-eyed-alien.net> <375baf50612220932m30f84567jdda28b7fc0e62e61@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Kevin Sanders wrote:
> On 12/22/06, Brooks Davis <brooks@one-eyed-alien.net> wrote:
>>
>> On Fri, Dec 22, 2006 at 12:43:29PM -0300, Fabr?cio Barros Cabral wrote:
>> > Hello everybody!
>> >
>> > I'm developing a network application which needs *to intercept* a 
>> packet
>> > (not just *copy* a packet, like libpcap does), move this packet into my
>> > application (userland), do some checking in the packet and according
>> > with some heuristics, the application may change the payload and
>> > re-inject the modified packet into the network. Note that sometimes,
>> > I'll change the payload, drop the packet or just let it go.
>> >
>> > So, how can a I do that in FreeBSD? I can use 6.1, 7.1, any version.
>>
>> The feature you're looking for is divert(4) sockets.  You use IPFW to
>> decide which packets to divert to userland and can reinject them as
>> needed.
>>
>> -- Brooks
>>
>>
>>
> 
> I'm actually working on something with a similar need.  How would this
> perform compared to a kld module that is using the pfil(9) framework?  I'm
> looking to support very high bandwidth networks, with 400mpbs or more over
> gig ethernet.  In my case I'm looking at HTTP requests and not necessarily
> every packet once I've done what I need to the actual http request/headers.
> Obviousely,  if I grow or shrink the HTTP request, I then have to "massage"
> the seq/ack to keep the two talking, but this is only for a small 
> percentage
> of the sessions, and I didn't want to be hit with a kernel -> user space ->
> kernel transition for every packet.

Divert is designed for diverting from the IP layer, to the user layer 
for processing (and returning the packet to be sent out/in). It is fast 
enough for most WAN applications.

I use patches to allow me to divert from a bridge (Ethernet layer)
but it's still going to userland.

If you want to work in the kernel, then take a look at netgraph.
(check the daemonnews article by Archie Cobbs (google is your friend),
and man 4 netgraph).
It allows you to divert from the Ethernet layer to an arbitrary
in-kernel module for processing in any way you want.
Look at ng_sample.c to get a skeleton netgraph node that you can
use as a starting point for your own processing.

Netgraph does have (due to its generality) some overhead,
but the code you write to make a netgraph node will be the same
code you would write for any other kernel mode processor so
getting it running as a netgraph node will allow you to test it
quickly. You should then test its performance. If this is fast
enough (netgraph CAN be fast so you should test this) then you
are done. If you are not getting enough performance, then you will need 
to write a custom 'pfil' module that puts itself on the pfil
processing list. If you still need more peroformance then I suggest you 
need to start hacking if_ethersubr.c itself and that is not the best
way to go for mainatanability.



> 
> It's also important for me to be able to see the ethernet header, because I
> running in a transparent bridge, and sometimes need to send a redirect back
> to the client making the request, and it needs to appear to come from the
> server the client is talking to.  Yes, this is a content filter.
> 
> I actually have all this working, and I'm currently working on the user
> space "service" which talks to the kernel module and makes decisions to
> allow, block, or modify the request.  Performance is pretty good, but my 10
> years of Win32 development experience didn't prepare me for UNIX kernel
> module development!

I have the same thing.. which is why I divert from ethernet layer.
There are some tricks that can be done to really speat that up however..
for example you only need to look at the first syn packet.. all the rest 
don't need to be looked at or diverted.



> 
> Kevin
> _______________________________________________
> freebsd-net@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-net
> To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?458C6ACC.2020605>