Skip to content

Commit c2745fc

Browse files
committed
Use IPv6 default route when no IPv4 is available
1 parent c301a6c commit c2745fc

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

doc/scapy/usage.rst

+3
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ make\_table() displays a table according to a lambda function
225225
Sending packets
226226
---------------
227227

228+
.. note::
229+
Scapy automatically detects the network interface to be used by default, and stores this result in ``conf.iface``. Packets built by Scapy uses this variable to set relevant fields such as Ethernet source addresses. When sending packets, with functions such as ``send()``, Scapy will use the network interface stored in ``conf.iface``. This behavior can be changed using the ``iface=`` argument. With IPv6 and link-local addresses, it is mandatory to setup both ``conf.iface`` and ``iface=`` the same value to get the desired result, as Scapy cannot find which interface to use for link-local communications.
230+
228231
.. index::
229232
single: Sending packets, send
230233

scapy/interfaces.py

+16
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,8 @@ def get_if_list():
372372
def get_working_if():
373373
# type: () -> NetworkInterface
374374
"""Return an interface that works"""
375+
376+
# IPv4
375377
# return the interface associated with the route with smallest
376378
# mask (route by default if it exists)
377379
routes = conf.route.routes[:]
@@ -383,6 +385,20 @@ def get_working_if():
383385
iface = resolve_iface(ifname) # type: ignore
384386
if iface.is_valid():
385387
return iface
388+
389+
# IPv6
390+
routes_ipv6 = conf.route6.routes
391+
default_routes_ipv6 = [r for r in routes_ipv6 if r[0] == "::"]
392+
if default_routes_ipv6:
393+
# Sort the default routes using the priority (at index -1)
394+
tmp_routes = sorted(default_routes_ipv6, key=lambda r: r[-1])
395+
396+
# Return the interface (at index 2) of the highest priority default
397+
ifname = tmp_routes[-1][2]
398+
iface = resolve_iface(ifname) # type: ignore
399+
if iface.is_valid():
400+
return iface
401+
386402
# There is no hope left
387403
return resolve_iface(conf.loopback_name)
388404

0 commit comments

Comments
 (0)