-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpytuncreate.py
More file actions
83 lines (63 loc) · 2.53 KB
/
Copy pathpytuncreate.py
File metadata and controls
83 lines (63 loc) · 2.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import os
import struct
import subprocess
import time
from fcntl import ioctl
from ipaddress import IPv4Address
_UNIX_TUNSETIFF = 0x400454ca
_UNIX_TUNSETPERSIST = 0x400454cb
_UNIX_IFF_TUN = 0x0001
_UNIX_IFF_TAP = 0x0002
_UNIX_IFF_NO_PI = 0x1000
### References:
### https://stackoverflow.com/a/55276723
### https://gist.github.com/abdelrahman-t/a23f57986a40f54108a71d4b91f145b2
class TUNTAPInterface:
def __init__(self, name: str, address: IPv4Address = None, persist: bool = False, tap: bool = False):
self._name = name
self._address = address
mode = _UNIX_IFF_TAP if tap else _UNIX_IFF_TUN
# Create TUN interface.
self._descriptor = os.open('/dev/net/tun', os.O_RDWR)
ioctl(self._descriptor,
_UNIX_TUNSETIFF,
struct.pack('16sH', name.encode('ASCII'), mode | _UNIX_IFF_NO_PI)
)
if persist:
ioctl(self._descriptor,
_UNIX_TUNSETPERSIST,
struct.pack('I', 1),
)
if address != None:
# Assign address to interface.
subprocess.call(['/sbin/ip', 'addr', 'add', str(address), 'dev', name])
@property
def name(self) -> str:
return self._name
@property
def address(self) -> IPv4Address:
return self._address
def up(self) -> None:
# Put interface into "up" state.
subprocess.call(['/sbin/ip', 'link', 'set', 'dev', self._name, 'up'])
def read(self, number_bytes: int) -> bytes:
packet = os.read(self._descriptor, number_bytes)
return packet
def write(self, packet: bytes) -> None:
os.write(self._descriptor, packet)
def test() -> None:
interface = TUNTAPInterface('persist-tunnel', address=IPv4Address('10.1.0.1'), persist=1)
interface.up()
print ("The interface persist-tunnel is created. It will stay after the program dies")
interface = TUNTAPInterface('persist-tap', address=IPv4Address('10.2.0.1'), persist=1, tap=True)
interface.up()
print ("The tap interface persist-tap is created. It will stay after the program dies")
interface = TUNTAPInterface('custom-tunnel', address=IPv4Address('10.3.0.1'))
interface.up()
print ("The interface custom-tunnel is created. It will go away if this program dies")
interface = TUNTAPInterface('custom-tap', address=IPv4Address('10.4.0.1'), tap=True)
interface.up()
print ("The interface custom-tap is created. It will go away if this program dies")
time.sleep(100)
if __name__ == '__main__':
test()