Repository: secdev/scapy

Issue:
Unable to send L2 packet if TCP/IP is disabled in the adapter
<!--
Things to consider

1.  Please check that you are using the latest scapy version, e.g. installed via:

    `pip install --upgrade git+git://github.com/secdev/scapy`

2.  If you are here to ask a question - please check previous issues and online resources, and consider using gitter instead: <https://gitter.im/secdev/scapy>

3.  Please understand that **this is not a forum** but an issue tracker. The following article explains why you should limit questions asked on Github issues: <https://medium.com/@methane/why-you-must-not-ask-questions-on-github-issues-51d741d83fde>
-->

#### Brief description

Scapy does not recognize networks with disabled TCP/IP protocols and unable to send custom L2 packet.

<!-- describe the main issue in one sentence -->
<!-- if possible, describe what components / protocols could be affected by the issue (e.g. wrpcap() + IPv6, it is likely this also affects XXX) -->

#### Environment

-   Scapy version: 2.4.4
-   Python version: 3.7.8
-   Operating System: Windows 10 (also Windows 7 SP1)

<!-- if needed - further information to get a picture of your setup (e.g. a sketch of your network setup) -->

#### Problem and workaround

I have to test a device in a isolated and fully controlled LAN. The Windows PC with LAN adapter itself sends packets into the network, which interferes with tests. Switching to Linux is not possible.

To stop Windows from sending packets, all services, the TCP/IPv4 and TCP/IPv6 protocols were disabled. Npcap Packet Driver, Link-Layer Topology Discovery Mapper I/O Driver, Link-Layer Topology Discovery Responder were enabled.

With that configuration Scapy does not see those networks in `get_windows_if_list()` and results in `ValueError: Unknown pypcap network interface 'local4'` when `sendp(iface='local4', x=Ether())` is executed. 

To fix that problem, I've modified the https://github.com/secdev/scapy/blob/master/scapy/arch/windows/structures.py changing the flags of `GetAdapterAddresses` function to include all interfaces `GAA_FLAG_INCLUDE_ALL_INTERFACES`.

```diff
...
- 244. GAA_FLAG_INCLUDE_PREFIX = ULONG(0x0010)
+ 244.GAA_FLAG = ULONG(0x0010 | 0x0100)
...
- 438. flags = GAA_FLAG_INCLUDE_PREFIX
+ 438. flags = GAA_FLAG
...
```

With that fix it is possible to send a L2 packet into the network.

Is there a better way to do it?



Discussion:
Hi & thanks for reporting this.
I don't know why we didn't use those flags already, your fix looks great. I have some very minor suggestions, for instance:
```diff
diff --git a/scapy/arch/windows/structures.py b/scapy/arch/windows/structures.py
index af8cfb11..1cac35e0 100644
--- a/scapy/arch/windows/structures.py
+++ b/scapy/arch/windows/structures.py
@@ -241,7 +241,8 @@ def GetIcmpStatistics():
 MAX_ADAPTER_ADDRESS_LENGTH = 8
 MAX_DHCPV6_DUID_LENGTH = 130

-GAA_FLAG_INCLUDE_PREFIX = ULONG(0x0010)
+GAA_FLAG_INCLUDE_PREFIX = 0x0010
+GAA_FLAG_INCLUDE_ALL_INTERFACES = 0x0100
 # for now, just use void * for pointers to unused structures
 PIP_ADAPTER_WINS_SERVER_ADDRESS_LH = VOID
 PIP_ADAPTER_GATEWAY_ADDRESS_LH = VOID
@@ -435,7 +436,7 @@ def GetAdaptersAddresses(AF=AF_UNSPEC):
     """Return all Windows Adapters addresses from iphlpapi"""
     # We get the size first
     size = ULONG()
-    flags = GAA_FLAG_INCLUDE_PREFIX
+    flags = ULONG(GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_ALL_INTERFACES)
     res = _GetAdaptersAddresses(AF, flags,
                                 None, None,
                                 byref(size))
```

Would you mind submitting a PR or do you want us to do it ? Thanks !

Resolving patch:
diff --git a/scapy/arch/windows/structures.py b/scapy/arch/windows/structures.py
--- a/scapy/arch/windows/structures.py
+++ b/scapy/arch/windows/structures.py
@@ -241,7 +241,8 @@ def GetIcmpStatistics():
 MAX_ADAPTER_ADDRESS_LENGTH = 8
 MAX_DHCPV6_DUID_LENGTH = 130
 
-GAA_FLAG_INCLUDE_PREFIX = ULONG(0x0010)
+GAA_FLAG_INCLUDE_PREFIX = 0x0010
+GAA_FLAG_INCLUDE_ALL_INTERFACES = 0x0100
 # for now, just use void * for pointers to unused structures
 PIP_ADAPTER_WINS_SERVER_ADDRESS_LH = VOID
 PIP_ADAPTER_GATEWAY_ADDRESS_LH = VOID
@@ -435,7 +436,7 @@ def GetAdaptersAddresses(AF=AF_UNSPEC):
     """Return all Windows Adapters addresses from iphlpapi"""
     # We get the size first
     size = ULONG()
-    flags = GAA_FLAG_INCLUDE_PREFIX
+    flags = ULONG(GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_ALL_INTERFACES)
     res = _GetAdaptersAddresses(AF, flags,
                                 None, None,
                                 byref(size))


Test patch: