IPv6 to IPv4 bouncers in Python

From Catholicpenguin

Two simple python scripts to relay connections between IPv4 and IPv6 sockets. Such functionality already exists in socat, so if you're on a Unix machine, I'd advise using that instead. However, I haven't found a compiled socat for Windows XP that supports IPv6, and none of the free utilities I could find worked properly.

Note, these were designed for Python 2.5 in mind, and are not Python 3 safe.

relay4

  • accepts connections on 0.0.0.0 (IPv4 from anywhere), sends them out to IPv6
  • for example, to allow Windows XP Remote Desktop to connect to a remote machine 2001:db8::1,
    • python relay4.py 3390 2001:db8::1 3389
    • then connect Remote Desktop to 127.0.0.1:3390
from socket import *
import thread
import sys

# TODO: If the remote connection dies, we should kill the local connection as well.
# Currently, nothing notifies our local client that the connection is gone other then
# an application level timeout, which is bad.

#HOST = '127.0.0.1'
#PORT = 22
#LISTEN = 24
LISTEN = int(sys.argv[1])
HOST = sys.argv[2]
PORT = int(sys.argv[3])


def io_runner(ins,outs):
    while True:
        outs.send(ins.recv(8192))

def handle_connection(conn,addr):
    outs=socket(AF_INET6,SOCK_STREAM)
    outs.connect((HOST,PORT))
    print 'Connected to',
    print HOST,
    print PORT
    # Now two threads for the input/output pipes
    thread.start_new_thread(io_runner,(conn,outs))    
    thread.start_new_thread(io_runner,(outs,conn))    

ins=socket(AF_INET,SOCK_STREAM)
ins.bind(('0.0.0.0',LISTEN))
ins.listen(1)
while True:
    conn,addr = ins.accept()
    print conn,addr
    thread.start_new_thread(handle_connection,(conn,addr))
ins.close()

relay6

  • accepts connections on :: (IPv6 from anywhere), sends them out to IPv4
  • for example, to allow other machines to connect to your Windows XP Remote Desktop server, run this on the same machine:
    • python relay6.py 3390 127.0.0.1 3389
    • then other users can connect to your-machine:3390 over IPv6
from socket import *
import thread
import sys

#HOST = '127.0.0.1'
#PORT = 22
#LISTEN = 24
LISTEN = int(sys.argv[1])
HOST = sys.argv[2]
PORT = int(sys.argv[3])


def io_runner(ins,outs):
    while True:
        outs.send(ins.recv(8192))

def handle_connection(conn,addr):
    outs=socket(AF_INET,SOCK_STREAM)
    outs.connect((HOST,PORT))
    print 'Connected to',
    print HOST,
    print PORT
    # Now two threads for the input/output pipes
    thread.start_new_thread(io_runner,(conn,outs))    
    thread.start_new_thread(io_runner,(outs,conn))    

ins=socket(AF_INET6,SOCK_STREAM)
ins.bind(('::',LISTEN))
ins.listen(1)
while True:
    conn,addr = ins.accept()
    print conn,addr
    thread.start_new_thread(handle_connection,(conn,addr))
ins.close()