Tun/tap OS X for tunneling


#1

Has anyone gotten tun/tap running on OS X 10.5 so they can tunnel
packets to the USRP?

I have the tun/tap driver installed (from
http://tuntaposx.sourceforge.net/index.xhtml)
and I am already having issues. So I’m wondering if it is even
worth using OS X or if I should just start working this in Linux like
tunnel.py does by default.

The error I’m getting on OS X is:

I type “ifconfig /dev/tun0 create” with permissions to create the
interface and it says “ifconfig: SIOCIFCREATE: Invalid argument.”
tun0 is listed in the my /dev, so that’s rather confusing.

So I’m trying to save some time here. If anyone has any experience
with this, any advice would be appreciated. I’m just tying to connect
the USRP to some upper layer functionality.

Thanks.

Mark


#2

Mark K. removed_email_address@domain.invalid wrote:

Has anyone gotten tun/tap running on OS X 10.5 so they can tunnel
packets to the USRP?

tun/tap has been mentioned before on this list, but I know of noone
who’s actively using it with GNU Radio on OSX; if anyone is, please
speak up! Hence I’m going to try it out & see what it does. Can
you / someone provide me with a quick example script to test the
functionality of a tun/tap device, with or without GNU Radio?

Please note that the pre-compiled PKG version (not the source which
you would then compile) of tuntaposx is meant as a universal binary
for 10.4 or higher, but not specifically compiled for 10.5. Given
that this is a kext, that might make a difference in correct
functionality (or not).

I’ve submitted updates to MacPorts to correct the compile behavior of
“tuntaposx” source code, to allow it to compile correctly on, and
specifically for, 10.4 and 10.5 when using MacPorts. I expect those
change to propagate through the system in the next couple of days. If
anyone wants these files (as an archive which can overwrite that
provided by MacPorts) for testing purposes, I’m happy to provide them.

  • MLD

#3

Using the provided tuntaposx package
(http://tuntaposx.sourceforge.net/index.xhtml
), I finally got the error resolved. I did not have to compile from
the source code. Basically, you just have to open the tap or tun
interface for reading from python first, then you can see the device
using “ifconfig -l” and assign it an address. The kext automatically
creates the device when it is opened for reading.

As for getting it to work with GNU radio, I’m trying to get the
tunnel.py example script to run for testing purposes. Without making
changes to tunnel.py, I am currently receiving the “OError: [Errno 25]
Inappropriate ioctl for device” error on this command:

ifs = ioctl(tun, TUNSETIFF, struct.pack(“16sH”, “gr%d”, mode))

I’m guessing there is a difference in the ioctl implementation between
linux and OS X. I’m working through it and will post any progress.
But if someone can point out what’s wrong that would be helpful.

Mark


#4

On Tue, Jan 6, 2009 at 6:34 AM, Mark K. removed_email_address@domain.invalid wrote:

ifs = ioctl(tun, TUNSETIFF, struct.pack(“16sH”, “gr%d”, mode))

I’m guessing there is a difference in the ioctl implementation between linux
and OS X. I’m working through it and will post any progress. But if
someone can point out what’s wrong that would be helpful.

In tunnel.py, line 77, TUNSETIFF is hardcoded to a value appropriate
for Linux, which really is defined in linux/tun_if.h (see comment on
line 66).

It’s almost a certainty this value is invalid for OS X.

-Johnathan


#5

On Tue, Jan 6, 2009 at 8:59 AM, Ed Criscuolo
removed_email_address@domain.invalid wrote:

There also seems to be a fundamental difference between the
way the TUN/TAP driver works on the two OS’s.

Ah, then it’s not so easy. It would be very useful to GNU Radio to
have a cross-platform implementation of this functionality, written in
C++, that abstracts the differences and presents a simple
write/callback API. I’ve written a TAP/TUN mblock that has the right
C++ guts that could be extracted and reused, but it would still have
the same problem on OS X.

-Johnathan


#6

Johnathan C. wrote:

line 66).

It’s almost a certainty this value is invalid for OS X.

There also seems to be a fundamental difference between the
way the TUN/TAP driver works on the two OS’s.

In the Linux/Unix/Solaris world, the TUN/TAP driver presents
a single character device in the /dev directory (either
/dev/tun or /dev/tap). Opening this creates a NEW device
(/dev/tun0, tun1, etc) using the next available name, and
returns a filehandle to it. An associated pseudo-network
device is created at the time of the open.

In the OSX TUN/TAP driver, a preset number of tun and tap
char devices (/dev/tun0 - /dev/tun15 and /dev/tap0 - /dev/tap15)
are PRECREATED when the driver is installed. You must open
the specific char device you want in order to get a filehandle
to it. An associated pseudo-network device is created at
the time of the open.

@(^.^)@ Ed


#7

On Tue, Jan 06, 2009 at 09:52:14AM -0800, Johnathan C. wrote:

C++ guts that could be extracted and reused, but it would still have
the same problem on OS X.

-Johnathan

IIRC there was a discussion about an OS neutral wrapper for tap/tun
several months back. I don’t remember any solution being found,
proposed or built.

Eric


#8

I’ve got a small update on this.

To read the tap devices on OS X, just issue the os.open command.

self.tap_fd = os.open("/dev/tap0", os.O_RDWR)

Once this open is completed, you can setup the interface with
ifconfig. Spawning this off into a subprocess with popen works well
inside the script.

To write to the tap device, just use os.write(self.tap_fd,DATA)

The ioctl command is challenging since it is implemented differently
as previously discussed. The request constant (second argument) used
by the osxtuntap kernel extensions are different from Linux. Two
request constants are used and defined as follows:

#define TUNSIFHEAD _IOW(‘t’, 96, int)
#define TUNGIFHEAD _IOR(‘t’, 97, int)

Translated they become the following:

TUNSIFHEAD = 2147775584
TUNGIFHEAD = 1074033761

So, in tunnel.py, you can modify the ioctl command to be as follows on
os x and it should not crash.

ifs = ioctl(tun, TUNSIFHEAD, struct.pack(“16sH”, “gr%d”, mode))

I think it is possible to create a cross-platform abstraction of this
functionality that manages the differences between the OSs. Maybe a
tun/tap module that is part of gnuradio, however the reliance on
external pieces such as the os x tun tap kernel extensions could be
problematic. Might want to roll that into the code base as well to
maintain some control of the versioning.


#9

On Sat, Jan 10, 2009 at 2:40 PM, Mark K. removed_email_address@domain.invalid wrote:

I think it is possible to create a cross-platform abstraction of this
functionality that manages the differences between the OSs. Maybe a tun/tap
module that is part of gnuradio, however the reliance on external pieces
such as the os x tun tap kernel extensions could be problematic. Might want
to roll that into the code base as well to maintain some control of the
versioning.

If you’d like to work on this, we’d be happy to include it in the
project, subject to GPL license and copyright assignment to FSF. Not
sure about the external dependency on the OS X kernel extension,
however–perhaps some Mac users could comment on whether that creates
an issue or not.

-Johnathan


#10

On Jan 12, 2009, at 1:13 PM, Johnathan C. wrote:

Not sure about the external dependency on the OS X kernel extension,
however–perhaps some Mac users could comment on whether that creates
an issue or not.

IMHO it would be unwise for any current GR component to be dependent
on “tuntaposx”, since it’s a non-standard addition to the OS (a kernel
extension, not just a library with headers and related files).

If this were made into its own component (e.g., “gr-tuntap”), then I’d
be all for it. On Darwin, it would require tuntaposx to be installed,
which shouldn’t be difficult to check for. On other platforms,
checking might be easier, but all of this would be done during
configure via the config/*.m4 scripts anyway.

My US$.01 (during current economic crisis). - MLD


#11

On Mon, Jan 12, 2009 at 12:48 PM, Michael D. removed_email_address@domain.invalid
wrote:

IMHO it would be unwise for any current GR component to be dependent on
“tuntaposx”, since it’s a non-standard addition to the OS (a kernel
extension, not just a library with headers and related files).

Got it, it’s what I figured.

If this were made into its own component (e.g., “gr-tuntap”), then I’d be
all for it. On Darwin, it would require tuntaposx to be installed, which
shouldn’t be difficult to check for. On other platforms, checking might be
easier, but all of this would be done during configure via the config/*.m4
scripts anyway.

Agree. A short-term version would be a cross-platform object you
could instantiate with an interface name to create and you’d get two
gr.msg_queue’s, one each for rx and tx packet data. It really calls
for either an mblock (which exists), or the message passing extension
to gr-blocks that we’ve been tossing around.

My US$.01 (during current economic crisis). - MLD

The joys of fiat currency :slight_smile:

-Johnathan