TUN / TAP Interfaces
Note
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 (IP
,IPv6
, IPX, etc.)
Requirements
- FreeBSD
Requires the
if_tap
andif_tun
kernel modules.- Linux
Load the
tun
kernel module:# modprobe tun
udev
normally handles the creation of device nodes.See networking/tuntap.txt in the Linux kernel documentation for more information.
- macOS
On macOS 10.14 and earlier, you need to install tuntaposx. macOS 10.14.5 and later will warn about the
tuntaposx
kexts 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 oftuntaposx
which can be extracted.Note
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
Tip
Using TUN/TAP generally requires running Scapy (and these utilities) as
root
.
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
setup an AnsweringMachine
to respond to ICMP
echo-request
:
>>> 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 source
and
destination
fields of any Ether
and IP
headers on
the 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.
TunTapInterface reference
- 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])
- Parameters:
iface (Text) –
The name of the interface to use, eg:
tun0
.On BSD and macOS, this must start with either
tun
ortap
, and have a corresponding/dev/
node (eg:/dev/tun0
).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
iface
parameter.strip_packet_info (bool) –
If True (default), any
TunPacketInfo
will be stripped from the packet (so you getEther
orIP
).Only Linux TUN interfaces have
TunPacketInfo
available.This has no effect for interfaces that do not have
TunPacketInfo
available.default_read_size (int) –
Sets the default size that is read by
SuperSocket.raw_recv()
andSuperSocket.recv()
. This defaults toscapy.data.MTU
.TunTapInterface
always adds overhead forTunPacketInfo
headers, if required.
- class TunPacketInfo(Packet)
Abstract class used to stack layer 3 protocols on a platform-specific header.
See
LinuxTunPacketInfo
for an example.- guess_payload_class(payload)
The default implementation expects the field
proto
to be declared, with a value fromscapy.data.ETHER_TYPES
.
Linux-specific structures
- class LinuxTunPacketInfo(TunPacketInfo)
Packet header used for Linux TUN packets.
This is
struct tun_pi
, declared inlinux/if_tun.h
.- flags
Flags to set on the packet. Only
TUN_VNET_HDR
is supported.
- proto
Layer 3 protocol number, per
scapy.data.ETHER_TYPES
.Used by
TunTapPacketInfo.guess_payload_class()
.
- class LinuxTunIfReq(Packet)
Internal “packet” used for
TUNSETIFF
requests on Linux.This is
struct ifreq
, declared inlinux/if.h
.