+
+#ifdef HAVE_LINUX_IF_TUN_H
+ /* Ok now check if this is an old ethertap or a new tun/tap thingie */
+
+ memset(&ifr, 0, sizeof(ifr));
+
+ get_config_string(lookup_config(config_tree, "DeviceType"), &type);
+
+ if(type && strcasecmp(type, "tun") && strcasecmp(type, "tap")) {
+ logger(LOG_ERR, "Unknown device type %s!", type);
+ return false;
+ }
+
+ if((type && !strcasecmp(type, "tun")) || (!type && routing_mode == RMODE_ROUTER)) {
+ ifr.ifr_flags = IFF_TUN;
+ device_type = DEVICE_TYPE_TUN;
+ device_info = "Linux tun/tap device (tun mode)";
+ } else {
+ if(routing_mode == RMODE_ROUTER) {
+ overwrite_mac = true;
+ }
+
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ device_type = DEVICE_TYPE_TAP;
+ device_info = "Linux tun/tap device (tap mode)";
+ }
+
+#ifdef IFF_ONE_QUEUE
+
+ /* Set IFF_ONE_QUEUE flag... */
+ if(get_config_bool(lookup_config(config_tree, "IffOneQueue"), &t1q) && t1q) {
+ ifr.ifr_flags |= IFF_ONE_QUEUE;
+ }
+
+#endif
+
+ if(iface) {
+ strncpy(ifr.ifr_name, iface, IFNAMSIZ);
+ ifr.ifr_name[IFNAMSIZ - 1] = 0;
+ }
+
+ if(!ioctl(device_fd, TUNSETIFF, &ifr)) {
+ strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
+ ifrname[IFNAMSIZ - 1] = 0;
+ free(iface);
+ iface = xstrdup(ifrname);
+ } else if(errno == EPERM || errno == EBUSY) {
+ logger(LOG_ERR, "Error while trying to configure %s: %s", device, strerror(errno));
+ return false;
+ } else if(!ioctl(device_fd, (('T' << 8) | 202), &ifr)) {
+ logger(LOG_WARNING, "Old ioctl() request was needed for %s", device);
+ strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
+ ifrname[IFNAMSIZ - 1] = 0;
+ free(iface);
+ iface = xstrdup(ifrname);
+ } else
+#endif
+ {
+ if(routing_mode == RMODE_ROUTER) {
+ overwrite_mac = true;
+ }
+
+ device_info = "Linux ethertap device";
+ device_type = DEVICE_TYPE_ETHERTAP;
+ free(iface);
+ iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device);
+ }
+
+ if(overwrite_mac && !ioctl(device_fd, SIOCGIFHWADDR, &ifr)) {
+ memcpy(mymac.x, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
+ }
+
+ logger(LOG_INFO, "%s is a %s", device, device_info);
+
+ return true;