-/*
- read, encrypt and send data that is
- available through the ethertap device
-*/
-int read_packet(vpn_packet_t *packet)
-{
- int lenin;
-cp
- if(device_type == DEVICE_TYPE_TUNTAP)
- {
- if((lenin = read(device_fd, packet->data, MTU)) <= 0)
- {
- syslog(LOG_ERR, _("Error while reading from %s %s: %m"), device_info, device_fname);
- return -1;
- }
-
- packet->len = lenin;
- }
- else /* ethertap */
- {
- struct iovec vector[2] = {{packet->len, 2}, {packet->data, MTU}};
-
- if((lenin = readv(device_fd, vector, 2)) <= 0)
- {
- syslog(LOG_ERR, _("Error while reading from %s %s: %m"), device_info, device_fname);
- return -1;
- }
-
- packet->len = lenin - 2;
- }
+#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(!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