TUN / TAP Interfaces
This module only works on BSD, Linux and macOS.
TUN/TAP lets you create virtual network interfaces from userspace. There are two types of devices:
- TUN devices
Operates at Layer 3 (
IP), and is generally limited to one protocol.
- TAP devices
Operates at Layer 2 (
Ether), and allows you to use any Layer 3 protocol (
IPv6, IPX, etc.)
# modprobe tun
udevnormally handles the creation of device nodes.
See networking/tuntap.txt in the Linux kernel documentation for more information.
On macOS 10.14 and earlier, you need to install tuntaposx. macOS 10.14.5 and later will warn about the
tuntaposxkexts not being notarised, but this works because it was built before 2019-04-07.
On macOS 10.15 and later, you need to use a notarized build of
tuntaposx. Tunnelblick (OpenVPN client) contains a notarized build of
tuntaposxwhich can be extracted.
On macOS 10.13 and later, you need to explicitly approve loading each third-party kext for the first time.
Using TUN/TAP in Scapy
Using TUN/TAP generally requires running Scapy (and these utilities) as
TunTapInterface lets you easily create a new device:
>>> t = TunTapInterface('tun0')
You’ll then need to bring the interface up, and assign an IP address in another terminal.
Because TUN is a layer 3 connection, it acts as a point-to-point link. We’ll assign these parameters:
local address (for your machine): 192.0.2.1
remote address (for Scapy): 192.0.2.2
On Linux, you would use:
sudo ip link set tun0 up sudo ip addr add 192.0.2.1 peer 192.0.2.2 dev tun0
On BSD and macOS, use:
sudo ifconfig tun0 up sudo ifconfig tun0 192.0.2.1 192.0.2.2
Now, nothing will happen when you ping those addresses – you’ll need to make Scapy respond to that traffic.
TunTapInterface works the same as a
SuperSocket, so lets
AnsweringMachine to respond to
>>> am = t.am(ICMPEcho_am) >>> am()
Now, you can ping Scapy in another terminal:
You should see those packets show up in Scapy:
>>> am() Replying 192.0.2.1 to 192.0.2.2 Replying 192.0.2.1 to 192.0.2.2 Replying 192.0.2.1 to 192.0.2.2
You might have noticed that didn’t configure Scapy with any IP address… and
there’s a trick to this:
ICMPEcho_am swaps the
destination fields of any
IP headers on
ICMP packet that it receives. As a result, it actually responds
to any IP address.
You can stop the
ICMPEcho_am AnsweringMachine with ^C.
When you close Scapy, the
tun0 interface will automatically disappear.
- class TunTapInterface(SimpleSocket)
A socket to act as the remote side of a TUN/TAP interface.
- __init__(iface: Text[, mode_tun][, strip_packet_info = True][, default_read_size = MTU])
iface (Text) –
The name of the interface to use, eg:
On BSD and macOS, this must start with either
tap, and have a corresponding
On Linux, this will be truncated to 16 bytes.
mode_tun (bool) –
If True, create as TUN interface (layer 3). If False, creates a TAP interface (layer 2).
If not supplied, attempts to detect from the
strip_packet_info (bool) –
If True (default), any
TunPacketInfowill be stripped from the packet (so you get
Only Linux TUN interfaces have
This has no effect for interfaces that do not have
default_read_size (int) –
Sets the default size that is read by
SuperSocket.recv(). This defaults to
TunTapInterfacealways adds overhead for
TunPacketInfoheaders, if required.
- class TunPacketInfo(Packet)
Abstract class used to stack layer 3 protocols on a platform-specific header.
LinuxTunPacketInfofor an example.
The default implementation expects the field
prototo be declared, with a value from
- class LinuxTunPacketInfo(TunPacketInfo)
Packet header used for Linux TUN packets.
struct tun_pi, declared in
Flags to set on the packet. Only
Layer 3 protocol number, per
- class LinuxTunIfReq(Packet)
Internal “packet” used for
TUNSETIFFrequests on Linux.
struct ifreq, declared in