Menu

#278 Ethernet support via TUN/TAP, as regular user

v3.x
closed-accepted
gpz
None
enhancement
2021-07-20
2020-12-29
No

This patch adds a file (rawnetarch_tuntap.c) implementing Ethernet support via the Universal TUN/TAP driver.

With this patch, regular users (without root privileges) can run VICE with Ethernet support. Furthermore, VICE will only see the Ethernet frames belonging to the (virtual) Ethernet interface it attaches to: this removes the security issues of the current Ethernet support in VICE, which uses root+libpcap and sees all network traffic.

The patch is developed and tested under Linux, but it should work on any Unix-like OS supporting TUN/TAP (e.g., NetBSD, FreeBSD) with minor tweaks. On the emulated side, I tested it by running various versions of Contiki (1.2-devel1, 3.0, and 2019-05-08) with RR-Net.

How to configure VICE with TUN/TAP Ethernet support

These instructions are tested on Ubuntu 20.10, but they should work on any Linux distribution.

Preliminary setup (as root)

Root privileges are only needed to set up a TUN/TAP virtual Ethernet device accessible by a regular user. For example:

# tunctl -u retro -t tap-c64
# ip link set tap-c64 up
# ip addr add 192.168.64.1/24 dev tap-c64

The commands above have the following effect:

  1. create the persistent tap-c64virtual network interface, giving access to user retro
  2. bring up the interface
  3. assign address 192.168.64.1/24 to the tap-c64 interface

Now, the tap-c64 interface can act as gateway for a private network (192.168.64.X) where VICE-emulated computers can connect.

To give Internet access to the emulated computers, it is necessary to also enable IP forwarding and masquerading:

# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

VICE usage (as regular user)

Let's say that user retro wants to run VICE with Ethernet (RR-Net) emulation. The vicerc file should contain:

ETHERNET_INTERFACE="tap-c64"
ETHERNETCART_ACTIVE=1
ETHERNETCARTMode=1

Now, retro can simply run e.g.:

$ x64sc

and set up networking in the emulated C64, under the tap-c64 private network. For example:

  • IP address: 192.168.64.64
  • Netmask: 255.255.255.0
  • Gateway: 192.168.64.1
  • DNS: 1.1.1.1

Notes and TODOs

At compile-time, the patch checks whether the macro HAVE_TUNTAP is defined --- and if so, it disables rawnetarch_unix.cand enables the new rawnetarch_tuntap.c.

The patch contains a few UI-related changes, to let non-root users have Ethernet support if TUN/TAP is available. It also tweaks some user-visible error messages, to mention TUN/TAP.

At the moment, the name of the TUN/TAP network interface must be specified in vicerc(as in the example above), or using the -cs8900ioif command line option. The GUI would need some additional tweaks: I can look into the GTK3 UI --- if this patch is deemed interesting :-)

1 Attachments

Discussion

  • gpz

    gpz - 2020-12-29

    we had tun/tap support in VICE before... it was removed because it broke rawnet support. it should be possible to have either, exclusively or both. we cant replace rawnet support with tuntap, because not all kernals have it. so, this patch should be reworked in a way that when HAVE_TUNTAP is enabled, it should enable this as an option, not replace rawnet alltogether (which also makes it kinda annoying to test both on the same machine).

     

    Last edit: gpz 2020-12-29
    • Alceste Scalas

      Alceste Scalas - 2020-12-29

      Yes, the current version of the patch is quite rough --- this is what worked for me, and I wanted to see whether somebody else could find it useful :-)

      So, I understand there is interest in re-integrating TUN/TAP support in VICE (as long as it doesn't come at the expense of libpcap support): I'll revise the patch.

       
  • gpz

    gpz - 2020-12-29

    yes, there is definetly interest in merging it again. IF it works without breaking anything that is already working :)

    please also make sure you are respecting the codestyle outlined in doc/coding-guidelines.txt ... i have quickly skimmed over it and it seems to be mostly ok. one thing i noticed are missing spaces before and after operators in one or two lines, eg

    for (i=0; (i<8) && len1>0; len1--, i++) {
    

    should be

    for (i = 0; (i < 8) && (len1 > 0); len1--, i++) {
    

    Then for bonus points, provide the documentation as a (seperate) diff to vice.texi :)

     
  • Olaf Seibert

    Olaf Seibert - 2020-12-30

    I will keep an eye on this for usability on NetBSD. There is much the same between Linux and NetBSD in how to use a tun or tap device, but there is much different in how to set it up for use (both in VICE as for the user). Don't worry too much about it though, it can be smoothed over :)

     
  • Alceste Scalas

    Alceste Scalas - 2021-01-02

    New year, new TUN/TAP patch!

    How to configure VICE with TUN/TAP Ethernet support

    Please see the instructions for the first patch --- with one key difference: this new patch has a new setting for vicerc, i.e.,

    ETHERNET_DRIVER="tuntap"
    

    or, from the command line:

    $ x64sc -cs8900iodriver tuntap
    

    By writing pcap instead of tuntap above, VICE will use the libpcap-based rawnet driver (if availble).

    If neither ETHERNET_DRIVER nor -cs8900iodriver is specified, then:

    • if the current user is root, and libpcap is available, then VICE will use the libpcap-based rawnet driver

    • otherwise (i.e., if the user is not root, or libpcap is unavailable), VICE will use the new TUN/TAP-based rawnet driver

    This means that:

    • users of VICE+libpcap+root will see no difference in how VICE behaves --- unless they explicitly add the setting ETHERNET_DRIVER="tuntap" or -cs8900iodriver tuntap

    • non-root users will have the new TUN/TAP Ethernet support enabled by default

    Another difference with the previous patch is that it is now possible to select the TUN/TAP interface from the VICE GUI.

    How does it work?

    Under Windows, this patch should have no effect: rawnetarch_win32.c is unchanged, and still included as-is in src/arch/shared/rawnetarch.c (NOTE: I could not test the patch under Windows).

    Under Unix, the patch turns src/arch/shared/rawnetarch.c into an abstraction layer over two lower-level drivers:

    • ./src/arch/shared/rawnetarch_unix.c (the libpcap-based driver --- maybe the file should be renamed...)

    • src/arch/shared/rawnetarch_tuntap.c (the new TUN/TAP-based driver)

    The two drivers can be switched at run-time.

    The patch also includes some refactoring: it moves some code and comments from rawnetarch_unix.c to rawnetarch.c, to avoid duplication in rawnetarch_tuntap.c.

    I hope this makes sense. Questions and comments are welcome :-)

     

    Last edit: Alceste Scalas 2021-01-02
    • Alceste Scalas

      Alceste Scalas - 2021-01-03

      Uh, I realised that something is missing in the patch, for Windows. The following new functions (declared in rawnetarch.h) need to be defined in rawnetarch_win32.c:

      extern int rawnet_arch_resources_init(void);
      extern int rawnet_arch_cmdline_options_init(void);
      extern void rawnet_arch_resources_shutdown(void);
      

      They should simply do nothing and return success.

       
  • gpz

    gpz - 2021-04-02

    applied the patch in r39893 (sorry for the delay) i verified ethernet still works for me with pcap, so at least that didnt break. i didnt test any of the new things.

    one thing i didnt quite understand: why at the bottom of rawnetarch.c there is

    #ifdef HAVE_TUNTAP
    #include "rawnetarch_tuntap.c"
    #else
    #include "rawnetarch_unix.c"
    #endif
    

    ?

    also, some things are still missing to make this perfect:

    • when pcap is used on *nix (and perhaps also on windows) the code should check if the user has the permissions needed to use it, instead of the "is root" check
    • the info from this ticket should be merged into the documentation (new cmdline option, how to setup and use)
    • BSD/macOS/Windows must be tested and/or fixed
     
    • compyx

      compyx - 2021-04-03

      when pcap is used on *nix (and perhaps also on windows) the code should check if the user has the permissions needed to use it, instead of the "is root" check

      Perhaps just remove the root check and also don't check for permissions, but just present/log a proper error message?

       
    • Alceste Scalas

      Alceste Scalas - 2021-04-03

      Great news! Unfortunately I will be very busy in the upcoming weeks, but I will try to update the documentation. Meanwhile, here are a few answers:

      one thing i didnt quite understand: why at the bottom of rawnetarch.c there is (bunch of #ifdefs)?

      Good question! Those #ifdefs are a leftover from the original patch, and they should be removed. Now both rawnetarch_tuntap.c and rawnetarch_unix.c are always compiled under Unix (see Makefile.am), and they have their own #ifdefs to check whether their dependencies are available.

      Suggestion: maybe it is worth adding the option --warn-common when generating libarchdep.a and the vice executables? If I am not mistaken, it should detect duplicated symbol definitions during static linking, and it would have helped in spotting the redundant #ifdefs above.

      Regarding the "is root" checks for libpcap, and the chained assignments pointed out by @compyx : I agree they should be improved, but I must confess that I copy'n'pasted both of them from the original code (in particular, rawnetarch_unix.c) :-)

       

      Last edit: Alceste Scalas 2021-04-03
  • compyx

    compyx - 2021-04-03

    Next time, please don't do this:

        /* We don't decide if this frame fits the needs;
    
         * by setting all zero, we let tfe.c do the work for us
         */
        *phashed =
        *phash_index =
        *pbroadcast = 
        *pcorrect_mac =
        *pcrc_error = 0;
    

    Took me almost 30 seconds to figure out what was going on there. VICE isn't competing in the IOCCC, though some parts could I suppose ;)

    But massive kudos for actually documenting the code, using Doyxgen even, that makes me very happy =)

     
  • gpz

    gpz - 2021-04-04

    Ok i cleaned up (removed) that ifdef, and removed the root check (which is really a bit questionable).

    So the only major thing missing is the documentation now...

     
  • gpz

    gpz - 2021-04-04

    ok so, i renamed -cs8900ioif to -ethernetioif and -cs8900iodriver to -ethernetiodriver.
    and i also updated/added docs for the ethernet related cmdline options and resources....

    Missing now is:

    • GUI support for tuntap. I am not sure how to implement this exactly, is there a good way to query existing tuntap devices similar to what it does for pcap?
    • perhaps an extra chapter in the docs that describes how to set up the tuntap device etc
     
  • Alceste Scalas

    Alceste Scalas - 2021-04-04

    Regarding the GUI support: I also wanted to only show TUN/TAP devices, but

    • I could not find a portable way to list TUN/TAP devices. There is some code in iproute2, but it is Linux-specific
    • Besides listing the TUN/TAP interfaces, it may also be advisable to only list the devices that have type TAP (not TUN!) and are accessible by the current user. However, I suspect that this would require even more non-portable code...
    • In any case, users needs to set up the TAP device they want use with vice, so they should know the name of the device they have created.

    For these reasons, rawnet_arch_tuntap_enumadapter() (in rawnetarch_tuntap.c) lists all network devices in a way that should be portable across Unix variants. For the GUI, I would probably just add a helpful error message with a list of things to check in case of error:

    • did the user select a TAP device?
    • does the user have the correct permissions?
    • is some other application already using the device?
     
  • gpz

    gpz - 2021-04-05

    For a start, it would be fine with me to have a way to select the device at all.... one that isnt a textbox that is :)

     
    • Alceste Scalas

      Alceste Scalas - 2021-04-05

      Just for clarity, I am attaching the Ethernet settings window I can see on my system, running r39902.

      This drop-down box allows users to select the TUN/TAP device, without having to write its name in a textbox: would this be enough, besides some polish and more helpful error messages?

      Besides: I have noticed that vice is now sometimes trying to load the libpcap Ethernet driver first, and causing errors without falling back to the TUN/TAP driver (even if I select the latter in vicerc, via ETHERNET_DRIVER="tuntap").

      I suspect this is related to the removal of root checks for libpcap in r39900, that subtly break my patch (which used root checks as found in the rest of the vice codebase to select which Ethernet driver to use).

      If root checks are removed, then there should be some way to tell whether the libpcap driver is actually usable by the current user. Recovering from an error later might be much trickier...

       

      Last edit: Alceste Scalas 2021-04-05
  • gpz

    gpz - 2021-04-05

    This drop-down box allows users to select the TUN/TAP device, without having to write its name in a textbox: would this be enough, besides some polish and more helpful error messages?

    Thats just fine IMHO. Of course proper error messages are always a plus :)

    If root checks are removed, then there should be some way to tell whether the libpcap driver is actually usable by the current user. Recovering from an error later might be much trickier...

    r39904 hopefully fixes this... it now checks for root or CAP_NET_RAW. please test :)

     
  • gpz

    gpz - 2021-04-10

    r39915 also adds an enumerate function for the driver ... there are some more challenges left to make this stuff more sane:

    • somehow setup a proper default interface in the init code. this appears to be kinda tricky (hopefully fixed in r39920)
    • remove the functions in rawnet.c and call the functions in rawnetarch.c directly instead. that extra wrapper makes no sense
    • perhaps make the adapter enumarate function only return the adapters that match the currently selected driver (that will require the UI to renumerate when the driver was changed)

    please test! :)

     

    Last edit: gpz 2021-04-10
    • Alceste Scalas

      Alceste Scalas - 2021-04-11

      I tested r39922, and it looks good to me. Thanks!

      I am attaching a small patch that improves the error message when the Ethernet cartridge emulation cannot be initialized. The main use case the patch addresses is: a user enables Ethernet cartridge emulation without first setting up ETHERNET_INTERFACE (either on .vicerc or via the GUI). When this happens, VICE selects a default interface (eth0 on Unix) that may not even exist, and this may be quite puzzling.

       
  • gpz

    gpz - 2021-04-18

    applied, thanks

     
  • gpz

    gpz - 2021-04-18
    • assigned_to: gpz
     
  • gpz

    gpz - 2021-07-16

    can we close this?

     
  • Alceste Scalas

    Alceste Scalas - 2021-07-20

    Yes, I think so. Thanks!

     
  • gpz

    gpz - 2021-07-20
    • status: open --> closed-accepted
     

Log in to post a comment.

MongoDB Logo MongoDB