scapy icon indicating copy to clipboard operation
scapy copied to clipboard

Fallback to IPv6 default routes for network interface detection

Open guedou opened this issue 1 year ago • 8 comments

This PR improves the selection of the default interface in an IPv6-only environment. See https://github.com/secdev/scapy/issues/4304 for context

~~To maintainers: shoud I add unit tests?~~

guedou avatar Mar 16 '24 10:03 guedou

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 78.53%. Comparing base (ac3d5bb) to head (6a4d90a). Report is 49 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4321      +/-   ##
==========================================
- Coverage   82.20%   78.53%   -3.67%     
==========================================
  Files         353      354       +1     
  Lines       83529    92937    +9408     
==========================================
+ Hits        68662    72985    +4323     
- Misses      14867    19952    +5085     
Files Coverage Δ
scapy/interfaces.py 96.80% <100.00%> (+0.20%) :arrow_up:
scapy/route6.py 86.26% <100.00%> (-2.14%) :arrow_down:

... and 66 files with indirect coverage changes

codecov[bot] avatar Mar 16 '24 11:03 codecov[bot]

I would argue this needs tests considering it's already a regression.

Also you need to rebase ;p

gpotter2 avatar Mar 17 '24 15:03 gpotter2

This makes me kinda wonder why we deprecated conf.iface6.

gpotter2 avatar Mar 23 '24 12:03 gpotter2

I always found conf.iface6 confusing.

It makes sense to use it to control how IPv6 packets are built, but fe80::/64 and multiple interfaces break its usefulness.

However, for sending with high-level functions or SuperSocket, it adds complexity and non-standard behavior.

When iface= is not specified by the user, shall Scapy use conf.iface6, conf.iface or both ? It gets even more complicated if we consider that sr*() can receive a list of IP and IPv6 packets that must be sent to different interfaces.

guedou avatar Mar 23 '24 18:03 guedou

Hey, I only noticed this after I opened my own PR #4380. According to my tests, it is not going to work because conf.route6 is not populated by the time get_working_if() is called. This can be fixed by calling conf.ifaces.reload() at the end of route6.py. Also I think it would be better to consider only default or generic enough routes. When someone has for instance an IPv6-only machine with a VPN that pushes route say 10.0.0.0/8, then the interface with IPv6 default route should be preferred over the VPN interface with /8 IPv4 route.

oskar456 avatar May 07 '24 09:05 oskar456

@oskar456 sorry for the delay. I slightly modified this PR and it should now work as expected. Do you have time to test it?

guedou avatar Jul 12 '24 19:07 guedou

Hey, thanks a lot! I can confirm that this PR fixes #4304.

oskar456 avatar Jul 14 '24 09:07 oskar456

So we have to discuss a bit regarding this. It's a good idea to have a better default selection when no IPv4 is available, however I disagree with the added documentation regarding iface and conf.iface.

Regarding link-local / multicast destinations, https://github.com/secdev/scapy/pull/4461 should properly add a route on interfaces that support multicast, so that should supposedly also fix the OP's question (as they only have a single interface with multicast). It also allows for a much more flexible behavior, which aims at avoiding to have to change conf.iface or iface.

gpotter2 avatar Jul 14 '24 09:07 gpotter2