- if(!get_config_string(lookup_config(config_tree, "Interface"), &iface))
- iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device);
+ int 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);
+ }
+
+ logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info);
+
+ return true;
+}
+#endif
+
+static bool setup_device(void) {
+ get_config_string(lookup_config(config_tree, "Device"), &device);
+
+ // Find out if it's supposed to be a tun or a tap device
+
+ char *type;