Whether the
tap devices are accessed through the special cloning device
/dev/tap or through the specific devices
/dev/tapN, the possible actions to control the matching interface are the same.
When using
/dev/tap though, as the interface is created on-the-fly, its name is not known immediately by the application. Therefore the
TAPGIFNAME ioctl is provided. It should be the first action an application using the special cloning device will do. It takes a pointer to a
struct ifreq as an argument.
Ethernet frames sent out by the kernel on a
tap interface can be obtained by the controlling application with
read(2). It can also inject frames in the kernel with
write(2). There is absolutely no validation of the content of the injected frame, it can be any data, of any length.
One call of
write(2) will inject a single frame in the kernel, as one call of
read(2) will retrieve a single frame from the queue, to the extent of the provided buffer. If the buffer is not large enough, the frame will be truncated.
tap character devices support the
FIONREAD ioctl which returns the size of the next available frame, or 0 if there is no available frame in the queue.
They also support non-blocking I/O through the
FIONBIO ioctl. In that mode,
EWOULDBLOCK is returned by
read(2) when no data is available.
Asynchronous I/O is supported through the
FIOASYNC,
FIOSETOWN, and
FIOGETOWN ioctls. The first will enable
SIGIO generation, while the two other configure the process group that will receive the signal when data is ready.
Synchronisation may also be achieved through the use of
select(2),
poll(2), or
kevent(2).