Skip to content

Instantly share code, notes, and snippets.

@povilasb
Created August 24, 2017 08:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save povilasb/c886f8fbd0a1968b7fc81968d200a685 to your computer and use it in GitHub Desktop.
Save povilasb/c886f8fbd0a1968b7fc81968d200a685 to your computer and use it in GitHub Desktop.
TUN/TAP in python
import os
from fcntl import ioctl
import struct
import time
import random
from threading import Thread
from pyroute2 import IPRoute
from pypacker.layer3.ip import IP
from pypacker.layer3.ip6 import IP6
from pypacker.layer3.icmp import ICMP
TUNSETIFF = 0x400454ca
IFF_TUN = 0x0001
IFF_TAP = 0x0002
IFF_NO_PI = 0x1000
def main():
fid = os.open("/dev/net/tun", os.O_RDWR)
ioctl(fid, TUNSETIFF, struct.pack("16sH", b"tun0", IFF_TUN | IFF_NO_PI))
set_addr('tun0', '10.0.0.1')
read_thread = Thread(target=read_input, args=(fid,))
read_thread.start()
req_nr = 1
req_id = random.randint(1, 65000)
while True:
icmp_req = IP(src_s="10.0.0.4", dst_s="8.8.8.8", p=1) +\
ICMP(type=8) +\
ICMP.Echo(id=req_id, seq=req_nr, body_bytes=b"test")
os.write(fid, icmp_req.bin())
time.sleep(1)
req_nr += 1
def read_input(fid) -> None:
while True:
data = os.read(fid, 1500)
parse_packet(data)
def parse_packet(data: bytes):
try:
packet = IP(data)
except:
packet = IP6(data)
print(packet)
print()
def set_addr(dev: str, addr: str) -> None:
ip = IPRoute()
idx = ip.link_lookup(ifname=dev)[0]
ip.addr('add', index=idx, address=addr, prefixlen=24)
ip.link('set', index=idx, state='up')
ip.close()
main()
NetLink==0.1
pypacker==4.0
pyroute2==0.4.19
#!/bin/bash
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -P FORWARD ACCEPT
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j MASQUERADE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment