Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 May 2008 15:32:34 -0400
From:      "Bob McConnell" <rvm@CBORD.com>
To:        <freebsd-questions@freebsd.org>
Subject:   Unable to talk to tap(4)
Message-ID:  <FF8482A96323694490C194BABEAC24A002B83B78@Email.cbord.com>

next in thread | raw e-mail | index | archive | help
Good morning,

Does anyone here have experience using tap(4)? I am trying to do some
basic I/O with it, but am not having any success. I have gotten to the
point where I can create and configure the device, and my application
can open it, but read() always returns errors.

The basic setup sequence is:

  ifconfig tap0 create
  ifconfig tap0 inet 10.3.4.254/24
  route -v add 10.3.4.0/24 10.3.4.254

At this point, I can ping that address and my application can open
either /dev/net/tap0 or /dev/tap0. But when I try to read() from those
devices, I have problems.

/dev/net/tap0 always returns with errno =3D 19 (ENODEV - Operation not
supported?).

/dev/tap0 returns errno =3D 14 (EFAULT - bad address). At this point,
'ifconfig' shows that the inet address is no longer attached and
'netstat -rn' shows the route I added above has been dropped.

I have been searching for several days to find more information about
this device, but have not found anything specific to FreeBSD. All of the
examples and instructions are for Linux or tun(4), both of which are
significantly different devices.

My code so far:

----------------- tear along dotted line -----------------
  tapFD =3D open ("/dev/tap0", O_RDWR);
  if (tapFD < 0) {
    fprintf (stderr, "Failed to open /dev/tap0: %d.\n", tapFD);
    exit (2);
  }

  fprintf (stderr, "Successfully opened /dev/tap0.\n");

  unsigned char * buffer =3D (unsigned char*)malloc(1514);
  if (buffer =3D NULL) {
    fprintf (stderr, "No memory available.\n");
    close (tapFD);
    exit(3);
  }
  int lenth =3D 0;

again:
  lenth =3D read(tapFD, buffer, 1514);
  if (lenth < 0) {
    int error =3D errno;
    if (error =3D=3D EINTR)
      goto again;
    fprintf (stderr, "tap read error: %d\n", error);
  }
  else {
    int index;

    fprintf (stdout, "%d bytes received.\n", lenth);
    for (index =3D 0; index < lenth; ++index) {
      fprintf (stdout, " %02x", buffer[index]);
      if (index % 16 =3D=3D 15)
        fprintf (stdout, "\n");
    }
    fprintf (stdout, "\n");
  } =20

  close (tapFD);
----------------- tear along dotted line -----------------

Just in the interest of full disclosure, I am running a stock
installation of FreeBSD 7.0 in a VMWare 5.5.4 session on WinXP. There
are also two virtual Ethernet cards, one connected to a host only
subnet, the other bridged onto a real Ethernet segment. I am using IPFW
with DummyNet to inject some measure of reality into this system.

This is the beginnings of a test bench for several commercial
applications. My goal, once I get this device working, is to write an
application for tap(4) that will emulate a few hundred embedded devices,
each opening a socket directly to a server, which currently resides in
another VM session on the host only network. This setup, coupled with
real devices on the external network should give us a much more
realistic environment for stress testing our systems.

Thank you,

Bob McConnell
Principal Communications Programmer
The CBORD Group, Inc.
61 Brown Road
Ithaca NY, 14850
Phone 607 257-2410
FAX 607 257-1902
Email rvm@cbord.com
Web www.cbord.com



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?FF8482A96323694490C194BABEAC24A002B83B78>