Ruby TUN/TAP interface
The universal TUN/TAP drivers have been shipping with the Linux kernel for a while now. vtun builds on this to set up point-to-point tunnels that essentially encapsulate Ethernet frames over a TCP connection. Here’s the Ruby code to setup a tap interface so we can start receiving raw Ethernet frames that are being written to this interface.
class TunTap
# Linux 2.6.17: from /usr/include/linux/if_tun.h
TUNSETIFF = 0x400454ca
IFF_TAP = 0x0002
IFF_NO_PI = 0x1000
def self.open
Kernel.open("/dev/net/tun", "w+") do |tap|
# struct ifreq
ifr = [ "", IFF_TAP|IFF_NO_PI ].pack("a16S")
tap.ioctl(TUNSETIFF, ifr)
ifname = ifr[0, 16].gsub(/x00/, "")
yield(tap, ifname)
end
end
end
So how do you use this? You first open the TunTap interface with a block. The ifname argument will typically be “tap0″ for the first interface opened, “tap1″ for the second and so on.
TunTap.open do |tap, ifname|
end
Inside the block, you can do
pkt = tap.sysread(64*1024)
to receive a raw Ethernet frame written by the networking stack. To inject a frame into the networking stack, use tap.syswrite which are all standard Ruby IO object methods.
When the block returns, the tap interface is automatically destroyed.