- if(!get_config_string(lookup_config(config_tree, "Device"), &device)) {
- if(routing_mode == RMODE_ROUTER)
- device = xstrdup(DEFAULT_TUN_DEVICE);
- else
- device = xstrdup(DEFAULT_TAP_DEVICE);
+ if(device_fd == -1) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno));
+ return false;
+ }
+
+ struct ctl_info info;
+
+ memset(&info, 0, sizeof(info));
+
+ strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name));
+
+ if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno));
+ return false;
+ }
+
+ long unit = -1;
+ char *p = strstr(device, "utun"), *e = NULL;
+
+ if(p) {
+ unit = strtol(p + 4, &e, 10);
+
+ if(!e) {
+ unit = -1;
+ }
+ }
+
+ struct sockaddr_ctl sc = {
+ .sc_id = info.ctl_id,
+ .sc_len = sizeof(sc),
+ .sc_family = AF_SYSTEM,
+ .ss_sysaddr = AF_SYS_CONTROL,
+ .sc_unit = unit + 1,
+ };
+
+ if(connect(device_fd, (struct sockaddr *)&sc, sizeof(sc)) == -1) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Could not connect utun socket: %s\n", strerror(errno));
+ return false;
+ }
+
+ char name[64] = "";
+ socklen_t len = sizeof(name);
+
+ if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) {
+ iface = xstrdup(device);
+ } else {
+ iface = xstrdup(name);