How to send traffic through IP Tunnel?

 

[Network Topology]

 

There are two computers, i.e. A and B. We want to set up a tunnel between two hosts. We can modify the tunnel setup program (tunproxy.py) so that we can covert the content of traffic to lower case without modifying source programs.

 

[tunproxy.py]

#! /usr/bin/env python

 

#############################################################################

##                                                                         ##

## tunproxy.py --- small demo program for tunneling over UDP with tun/tap  ##

##                                                                         ##

## Copyright (C) 2003  Philippe Biondi <phil@secdev.org>                   ##

##                                                                         ##

## This program is free software; you can redistribute it and/or modify it ##

## under the terms of the GNU General Public License as published by the   ##

## Free Software Foundation; either version 2, or (at your option) any     ##

## later version.                                                          ##

##                                                                         ##

## This program is distributed in the hope that it will be useful, but     ##

## WITHOUT ANY WARRANTY; without even the implied warranty of              ##

## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       ##

## General Public License for more details.                                ##

##                                                                         ##

#############################################################################

 

import os, sys

from socket import *

from fcntl import ioctl

from select import select

import getopt,struct

from struct import *

 

MAGIC_WORD = "Wazaaaaaaaaaaahhhh !"

 

TUNSETIFF = 0x400454ca

IFF_TUN   = 0x0001

IFF_TAP   = 0x0002

 

TUNMODE = IFF_TUN

MODE = 0

DEBUG = 1

 

def usage(status=0):

    print "Usage: tunproxy [-s port|-c targetip:port] [-e]"

    sys.exit(status)

 

opts = getopt.getopt(sys.argv[1:],"s:c:ehd")

 

for opt,optarg in opts[0]:

    if opt == "-h":

        usage()

    elif opt == "-d":

        DEBUG += 1

    elif opt == "-s":

        MODE = 1

        PORT = int(optarg)

    elif opt == "-c":

        MODE = 2

        IP,PORT = optarg.split(":")

        PORT = int(PORT)

        peer = (IP,PORT)

    elif opt == "-e":

        TUNMODE = IFF_TAP

       

if MODE == 0:

    usage(1)

 

 

f = os.open("/dev/net/tun", os.O_RDWR)

ifs = ioctl(f, TUNSETIFF, struct.pack("16sH", "toto%d", TUNMODE))

ifname = ifs[:16].strip("\x00")

 

print "Allocated interface %s. Configure it and use it" % ifname

 

s = socket(AF_INET, SOCK_DGRAM)

 

try:

    if MODE == 1:

        s.bind(("", PORT))

        while 1:

            word,peer = s.recvfrom(1500)

            if word == MAGIC_WORD:

                break

            print "Bad magic word for %s:%i" % peer

        s.sendto(MAGIC_WORD, peer)

    else:

        s.sendto(MAGIC_WORD, peer)

        word,peer = s.recvfrom(1500)

        if word != MAGIC_WORD:

            print "Bad magic word for %s:%i" % peer

            sys.exit(2)

    print "Connection with %s:%i established" % peer

   

    while 1:

        r = select([f,s],[],[])[0][0]

        if r == f:

            if DEBUG: os.write(1,">")

            sent_data=os.read(f,1500)

            #take first 20 characters for the ip header

            ip_header = sent_data[4:24]

    

            #now unpack them :)

            iph = unpack('!BBHHHBBH4s4s' , ip_header)

 

            version_ihl = iph[0]

            version = version_ihl >> 4

            ihl = version_ihl & 0xF

    

            iph_length = ihl * 4

    

            ttl = iph[5]

            protocol = iph[6]

            import socket

            s_addr = socket.inet_ntoa(iph[8]);

            d_addr = socket.inet_ntoa(iph[9]);

    

            print 'Version : ' + str(version) + ' IP Header Length : ' + str(ihl) + ' TTL : ' + str(ttl) + ' Protocol : ' + str(protocol) + ' Source Address : ' + str(s_addr) + ' Destination Address : ' + str(d_addr)

            udp_header = sent_data[24:32]

            app_data = sent_data[32:]

            a=sent_data[0:30]

            b='\x00\x00'    #udp checksum

            c=a+b+(sent_data[32:]).lower()  

            s.sendto(c,peer)

        else:

            buf,p = s.recvfrom(1500)

            if p != peer:

                print "Got packet from %s:%i instead of %s:%i" % (p+peer)

                continue

            if DEBUG: os.write(1,"<")

            os.write(f, buf)

except KeyboardInterrupt:

    print "Stopped by user."

 

[udp_send.py]

import socket

 

UDP_IP = "10.0.0.2"

UDP_PORT = 5005

MESSAGE = "Hello, World!"

 

print "UDP target IP:", UDP_IP

print "UDP target port:", UDP_PORT

print "message:", MESSAGE

 

sock = socket.socket(socket.AF_INET, # Internet

                     socket.SOCK_DGRAM) # UDP

sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))

 

[udp_receive.py]

import socket

 

UDP_IP = "10.0.0.2"

UDP_PORT = 5005

 

sock = socket.socket(socket.AF_INET, # Internet

                     socket.SOCK_DGRAM) # UDP

sock.bind((UDP_IP, UDP_PORT))

 

while True:

    data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes

    print "received message:", data

 

[Execution]

In computer B

 

In computer A

 

When computer A is connected to computer B, you can see the following message in computer B.

 

In computer B, start udp_receive.py program

 

In computer A, start udp_send.py program

 

In computer B, you can see the following message in computer B

 

Open wireshark in computer B

 

Dr. Chih-Heng Ke (smallko@gmail.com)

Department of Computer Science and Information Engineering,

National Quemoy University, Kinmen, Taiwan.