views:

352

answers:

3

I have a Linux application that talks TCP, and to help with analysis and statistics, I'd like to modify the data in some of the TCP packets that it sends out. I'd prefer to do this without hacking the Linux TCP stack.

The idea I have so far is to make a bridge which acts as a "TCP packet modifier". My idea is to connect to the application via a tun/tap device on one side of the bridge, and to the network card via raw sockets on the other side of the bridge.

My concern is that when you open a raw socket it still sends packets up to Linux's TCP stack, and so I couldn't modify them and send them on even if I wanted to. Is this correct?

A pseudo-C-code sketch of the bridge looks like:

tap_fd = open_tap_device("/dev/net/tun");
raw_fd = open_raw_socket();
for (;;) {
    select(fds = [tap_fd, raw_fd]);
    if (FD_ISSET(tap_fd, &fds)) {
        read_packet(tap_fd);
        modify_packet_if_needed();
        write_packet(raw_fd);
    }
    if (FD_ISSET(raw_fd, &fds)) {
        read_packet(raw_fd);
        modify_packet_if_needed();
        write_packet(tap_fd);
    }
}

Does this look possible, or are there other better ways of achieving the same thing? (TCP packet bridging and modification.)

+1  A: 

There were some apps I used years ago to do some TCP/IP packet manipulation for testing a firewall: fragoute and fragtest. Looks like they haven't been touched in years, but they might give you some ideas of what to do in your code.

dave
+2  A: 

You might want to consider using a LD_PRELOAD library to hook the functions that it uses to send the data out (send(), write() etc).

That wouldn't involve any kernel messing-around at all.

Another option is to NAT the outbound connections to a local proxy which can read the data, make whatever modifications, and send it all out to the real destination (with some options to prevent it being NAT'd again and going round in circles)

MarkR
A: 

You can use the click modular router. It is a software router implemented entirely in C++. Click allows you to capture packets as they pass through elements in the router where you can modify or collect statistics as needed. As a kernel module, you completely override the linux routing mechanism and as a userland binary you simply get a duplicate (as you mention in your post) of each packet from the interface. Packets can be directed through the Click graph by way of pcap filters and a variety of other mechanisms.

If you are headed down the bridge route, I think this provides the most direct support for what you are looking to do as you can use tun/tap, to/from host or to/from device capture methods as you require.

ezpz