Skip to content

Instantly share code, notes, and snippets.

@glacjay
Created September 19, 2010 16:24
Show Gist options
  • Star 40 You must be signed in to star a gist
  • Fork 13 You must be signed in to fork a gist
  • Save glacjay/586892 to your computer and use it in GitHub Desktop.
Save glacjay/586892 to your computer and use it in GitHub Desktop.
Reading/Writing OpenVPN's TUN/TAP Device under Windows using Python.
import _winreg as reg
import win32file
adapter_key = r'SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}'
def get_device_guid():
with reg.OpenKey(reg.HKEY_LOCAL_MACHINE, adapter_key) as adapters:
try:
for i in xrange(10000):
key_name = reg.EnumKey(adapters, i)
with reg.OpenKey(adapters, key_name) as adapter:
try:
component_id = reg.QueryValueEx(adapter, 'ComponentId')[0]
if component_id == 'tap0801':
return reg.QueryValueEx(adapter, 'NetCfgInstanceId')[0]
except WindowsError, err:
pass
except WindowsError, err:
pass
def CTL_CODE(device_type, function, method, access):
return (device_type << 16) | (access << 14) | (function << 2) | method;
def TAP_CONTROL_CODE(request, method):
return CTL_CODE(34, request, method, 0)
TAP_IOCTL_CONFIG_POINT_TO_POINT = TAP_CONTROL_CODE(5, 0)
TAP_IOCTL_SET_MEDIA_STATUS = TAP_CONTROL_CODE(6, 0)
TAP_IOCTL_CONFIG_TUN = TAP_CONTROL_CODE(10, 0)
if __name__ == '__main__':
guid = get_device_guid()
handle = win32file.CreateFile(r'\\.\Global\%s.tap' % guid,
win32file.GENERIC_READ | win32file.GENERIC_WRITE,
win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE,
None, win32file.OPEN_EXISTING,
win32file.FILE_ATTRIBUTE_SYSTEM, # | win32file.FILE_FLAG_OVERLAPPED,
None)
print(handle.handle)
if False:
win32file.DeviceIoControl(handle, TAP_IOCTL_CONFIG_POINT_TO_POINT,
'\xc0\xa8\x11\x01\xc0\xa8\x11\x10', None);
else:
win32file.DeviceIoControl(handle, TAP_IOCTL_SET_MEDIA_STATUS, '\x01\x00\x00\x00', None)
win32file.DeviceIoControl(handle, TAP_IOCTL_CONFIG_TUN,
'\x0a\x03\x00\x01\x0a\x03\x00\x00\xff\xff\xff\x00', None)
while True:
l, p = win32file.ReadFile(handle, 2000)
q = p[:12] + p[16:20] + p[12:16] + p[20:]
win32file.WriteFile(handle, q)
print(p, q)
win32file.CloseHandle(handle)
@alexsunday
Copy link

In my computer, adapter_key hasnot a string key "tap0801" named ComponentId, just has a "tap0901", so, what I can do?

@frogoscar
Copy link

On my Win7, it is also tap0901. So just change the ID with the one you create.

@alex-eri
Copy link

Is there way get devie by name?

@wkgcass
Copy link

wkgcass commented May 2, 2020

Is there way get devie by name?

Yes, the devices in control panel can be found in the Windows Registry.
I have a JNI impl here, you may copy and modify the code, the project is under MIT license.

And you can also refer to the codes in OpenVPN project, tun.c, it not only searches through the adapters with a name in control panel, but also those taps only having a GUID.

(Answer for anyone who might come here through a search engine)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment