--- gvpe/src/device-linux.C 2003/10/14 03:22:09 1.3 +++ gvpe/src/device-linux.C 2005/04/08 16:48:16 1.15 @@ -1,7 +1,10 @@ /* device-linux.C -- Interaction with Linux tun/tap device + Copyright (C) 2003-2005 Marc Lehmann - This program is free software; you can redistribute it and/or modify + This file is part of GVPE. + + GVPE is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. @@ -12,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software + along with gvpe; if not, write to the Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -43,12 +46,23 @@ #include "conf.h" +#if TEST_ETHEREMU +# define IF_istun +# include "ether_emu.C" +#endif + const char * tap_device::info () { return _("Linux tun/tap device"); } +const char * +tap_device::if_up () +{ + return "/sbin/ifconfig $IFNAME hw ether $MAC mtu $MTU"; +} + tap_device::tap_device () { struct ifreq ifr; @@ -60,11 +74,15 @@ if (fd < 0) { slog (L_ERR, _("could not open device %s: %s"), device, strerror (errno)); - exit (1); + exit (EXIT_FAILURE); } memset (&ifr, 0, sizeof (ifr)); +#if TEST_ETHEREMU + ifr.ifr_flags = IFF_TUN | IFF_NO_PI; +#else ifr.ifr_flags = IFF_TAP | IFF_NO_PI; +#endif if (conf.ifname) strncpy (ifr.ifr_name, conf.ifname, IFNAMSIZ); @@ -78,9 +96,19 @@ } else { - slog (L_CRIT, _("unable to configure tun/tap interface: %s"), strerror (errno)); - exit (1); + slog (L_CRIT, _("unable to configure tun/tap interface, exiting: %s"), strerror (errno)); + exit (EXIT_FAILURE); + } + +#if 0 + does not work + id2mac (THISNODE->id, &ifr.ifr_hwaddr.sa_data); + if (ioctl (fd, SIOCSIFHWADDR, &ifr)) + { + slog (L_ERR, _("cannot set MAC address for device %s, exiting: %s"), ifrname, strerror (errno)); + exit (EXIT_FAILURE); } +#endif if (ioctl (fd, TUNSETPERSIST, conf.ifpersist ? 1 : 0)) slog (L_WARN, _("cannot set persistency mode for device %s: %s"), ifrname, strerror (errno)); @@ -98,7 +126,11 @@ { tap_packet *pkt = new tap_packet; +#if TEST_ETHEREMU + pkt->len = read (fd, &((*pkt)[14]), MAX_MTU - 14); +#else pkt->len = read (fd, &((*pkt)[0]), MAX_MTU); +#endif if (pkt->len <= 0) { @@ -108,13 +140,32 @@ return 0; } +#if TEST_ETHEREMU + pkt->len += 14; + + // assume ipv4 + (*pkt)[12] = 0x08; + (*pkt)[13] = 0x00; + + if (!ether_emu.tun_to_tap (pkt)) + { + delete pkt; + return 0; + } +#endif + return pkt; } void tap_device::send (tap_packet *pkt) { +#if TEST_ETHEREMU + if (ether_emu.tap_to_tun (pkt) && + write (fd, &((*pkt)[14]), pkt->len - 14) < 0) +#else if (write (fd, &((*pkt)[0]), pkt->len) < 0) +#endif slog (L_ERR, _("can't write to %s %s: %s"), info (), DEFAULT_DEVICE, strerror (errno)); }