Skip to content

Instantly share code, notes, and snippets.

@whiler
Last active March 26, 2024 16:19
Show Gist options
  • Save whiler/295113850bd55ed4f4bf898124abe4a8 to your computer and use it in GitHub Desktop.
Save whiler/295113850bd55ed4f4bf898124abe4a8 to your computer and use it in GitHub Desktop.
open utun device in OS X
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# open utun device in OS X
# Refs:
# - https://github.com/python/cpython/blob/master/Modules/socketmodule.c
# - https://opensource.apple.com/source/xnu/xnu-4570.31.3/bsd/sys/kern_control.h.auto.html
# - https://opensource.apple.com/source/xnu/xnu-344.49/bsd/sys/sys_domain.h.auto.html
# - https://opensource.apple.com/source/xnu/xnu-2782.20.48/bsd/net/if_utun.h.auto.html
#
import fcntl
import socket
import struct
MAX_KCTL_NAME = 96
UTUN_CONTROL_NAME = 'com.apple.net.utun_control'.encode()
CTLIOCGINFO = 3227799043
PF_SYSTEM = getattr(socket, 'PF_SYSTEM') if hasattr(socket, 'PF_SYSTEM') else 32
SYSPROTO_CONTROL = getattr(socket, 'SYSPROTO_CONTROL') if hasattr(socket, 'SYSPROTO_CONTROL') else 2
FMT = '<I{}s'.format(MAX_KCTL_NAME)
# raise OSError: [Errno 16] Resource busy
def utun(idx):
sock = socket.socket(PF_SYSTEM, socket.SOCK_DGRAM, SYSPROTO_CONTROL)
arg = struct.pack(FMT, 0, UTUN_CONTROL_NAME)
ctl_info = fcntl.ioctl(sock, CTLIOCGINFO, arg)
ctl_id, ctl_name = struct.unpack(FMT, ctl_info)
sock.connect((ctl_id, idx + 1))
return sock
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment