Skip to content

Instantly share code, notes, and snippets.

@bringhurst
Created January 28, 2012 06:42
Show Gist options
  • Save bringhurst/1693075 to your computer and use it in GitHub Desktop.
Save bringhurst/1693075 to your computer and use it in GitHub Desktop.
How to create a tun in osx without installing 3rd party crap
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/kern_control.h>
#include <sys/ioctl.h>
#include <sys/sys_domain.h>
#include <sys/kern_event.h>
#include <sys/errno.h>
#define UTUN_CONTROL_NAME "com.apple.net.utun_control"
int get_utun_socket() {
int sock = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
struct sockaddr_ctl addr;
/* get/set the id */
struct ctl_info info;
memset(&info, 0, sizeof(info)) ;
strncpy(info.ctl_name, UTUN_CONTROL_NAME, strlen(UTUN_CONTROL_NAME));
ioctl(sock, CTLIOCGINFO, &info) ;
addr.sc_id = info.ctl_id;
addr.sc_len = sizeof(addr) ;
addr.sc_family = AF_SYSTEM ;
addr.ss_sysaddr = AF_SYS_CONTROL ;
addr.sc_unit = 0 ; /* allocate dynamically */
connect(sock, (struct sockaddr*)&addr, sizeof(addr)) ;
sleep(500);
return sock;
}
int main(void) {
get_utun_socket();
}
/* EOf */
@werner291
Copy link

Why did I have to dig this deeply on the Internet to find such a simple piece of code?

@wxdao
Copy link

wxdao commented Mar 12, 2017

You should include "net/if_utun.h", where UTUN_CONTROL_NAME is defined.

@sfionov
Copy link

sfionov commented Jan 20, 2024

You may also need this to determine tun number:

    socklen_t addr_len = sizeof(addr);
    if (getpeername(fd, (sockaddr *) &addr, &addr_len) != 0) {
        close(fd);
        return -1;
    }
    int tun_num = ((int)addr.sc_unit) - 1;

@bringhurst
Copy link
Author

It may also be useful to review this:

https://github.com/cjdelisle/cjdns/blob/master/interface/tuntap/TUNInterface_darwin.c

This gist is an early experiment that eventually went into that code.

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