Using an IPv6-only internal network in a real-world environment

Problem: Not all client applications are ipv6-aware

Writing a kernel module that overloads the networking calls (like 'connect()'), and translates them to IPv6

This is a first (failed) attempt at this approach. The socket system calls are 'muxed' together in one call, sys_socketcall. sys_socketcall in turn calls sys_sendto et al. When I get an IPv4 sendto() call in sys_socketcall, it's quite possible to create a 'struct sockaddr_in6' to replace the 'struct sockaddr_in' argument of the call with. Unfortunately, sys_socket expects an argument in user space memory. Since sockaddr_in6 is bigger than sockaddr_in, I can't cheat and use the memory used by sockaddr_in. Since sys_socket and the functions it calls aren't exported, it's not practical to re-implement them.

from this point on, this will probably be quite strictly linux-specific.

relevant links:

Inventorisation of system calls that will have to be overloaded:

These probably won't have to change, but some debug-code might be handy :) I will first focus on a relatively simple case, being outgoing UDP traffic. If that's successful I'll attempt to implement incoming UDP traffic, and then in- and outgoing TCP traffic.

Note: IPv6-aware applications will probably run into trouble when they try to bind to both ipv4 and ipv6, since the bind to ipv4 will just bind to ipv6, too, this might yield 'address already in use'.

Step 1: Test setup

In the long term, the goal is to make a kernel module that will overload every single system call above. For testing, however, how these system calls should be implemented, I'm going to write a little library, implementing 'connectv6()' and friends.

I'm going to write a series of small proof-of-concept programs, written for ipv4, but calling 'connectv6()' instead of 'connect()', compiling them with the connectv6()-code and trying to get it to communicate over v6 transparently.
This is work in progress (hardly started yet, actually).

Step 1.1: Sending a single UDP packet

step1-1.c (in progress, 'simple case' functionality is in place.)

Step 1.2: Receiving an UDP packet

step1-2.c (in progress, 'simple case' functionality is in place.)

Step 1.3: Initiating a TCP connection

Step 1.4: Sending a TCP stream

Step 1.5: Receiving a TCP stream

Step 2: The kernel module

A neat article on page 68 of linux magazine, the february 2001 issue, explains how to create a linux kernel module that overloads existing system calls.

Of course, things wouldn't be interesting if we could just use that: it turns out that the socket system calls are 'special', in the way that all of them (socket, bind, connect, listen, accept, getsockname, getpeername, socketpair, send, recv, sendto, recvfrom, shutdown, setsockopt, getsockopt, sendmsg and recvmsg) are all handled by system call 102 ('socketcall'). This appears to be called 'muxing'.