1
0
Fork 0
This repository has been archived on 2023-05-11. You can view files and clone it, but cannot push or open issues or pull requests.
lesson-python_ip_tunnel/main.py

81 lines
2.1 KiB
Python
Executable File

#!/usr/bin/env python3
import sys
import pytun
import struct
import ipaddress
import json
import socket
class IpHeader:
def __init__(self, raw):
self.ver_ihl, \
self.tos, \
self.total_length, \
self.ident, \
self.flags_fragoffset, \
self.ttl, \
self.proto, \
self.chksum, \
src, \
dst, \
self.opt1, \
self.opt2, \
self.pad = struct.unpack('>BBHHHBBHIIHBB', raw)
self.src = ipaddress.IPv4Address(src)
self.dst = ipaddress.IPv4Address(dst)
def main():
config_filename = sys.argv[1]
with open(config_filename) as config_file:
config = json.load(config_file)
tun_iface = pytun.TunTapDevice()
print(tun_iface.name)
tun_iface.addr = config['iface_addr']
tun_iface.dstaddr = config['iface_dstaddr']
tun_iface.netmask = config['iface_netmask']
tun_iface.mtu = config['iface_mtu']
tun_iface.up()
addr_and_port = (config['address'], config['port'])
if config['mode'] == 'client':
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('connecting to %s, port %s' % addr_and_port)
conn.connect(addr_and_port)
print('connected!')
elif config['mode'] == 'server':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('binding to %s, port %s' % addr_and_port)
sock.bind(addr_and_port)
sock.listen(1)
print('waiting for incoming connection')
conn, client_addr = sock.accept()
print('accepted incoming connection from %s' % client_addr[0])
else:
raise RuntimeError('invalid mode "%s"' % config['mode'])
while True:
buf = tun_iface.read(tun_iface.mtu)
flags = buf[:2]
proto = buf[2:4]
if proto != b'\x08\x00':
continue
ip_header = IpHeader(buf[4:28])
body = buf[28:]
print(ip_header.src, '', ip_header.dst, 'len: %d' % ip_header.total_length)
if __name__ == '__main__':
main()