Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug in send method. Interface is not being taken into account #4506

Closed
fernandoenzo opened this issue Aug 22, 2024 · 1 comment
Closed

Bug in send method. Interface is not being taken into account #4506

fernandoenzo opened this issue Aug 22, 2024 · 1 comment

Comments

@fernandoenzo
Copy link

fernandoenzo commented Aug 22, 2024

Brief description

Specified interface is not being taken into account when using send method.

Scapy version

2.5.0

Python version

3.11

Operating system

Debian 12

Additional environment information

No response

How to reproduce

When trying to send a packet over a specific interface, the interface specified is being ignored in the send method in scapy/arch/linux.py. For example:

import random
from scapy.all import *

random_data = random.randbytes(1024)
packet = IP(dst='192.168.4.3') / UDP(sport=4321, dport=1234) / Raw(load=random_data)
send(packet, iface="eth1")

Upon opening Wireshark, I noticed that packets were being sent over my eth0 interface rather than the specified eth1. After further inspecting the code and debugging, I found this function in scapy:

class L3PacketSocket(L2Socket):
    def send(self, x):
        # type: (Packet) -> int
        iff = x.route()[0]
        if iff is None:
            iff = network_name(conf.iface)
        sdto = (iff, self.type)
        self.outs.bind(sdto)
        sn = self.outs.getsockname()
        ll = lambda x: x  # type: Callable[[Packet], Packet]
        type_x = type(x)
        if type_x in conf.l3types:
            sdto = (iff, conf.l3types.layer2num[type_x])
        if sn[3] in conf.l2types:
            ll = lambda x: conf.l2types.num2layer[sn[3]]() / x
        if self.lvl == 3 and type_x != self.LL:
            warning("Incompatible L3 types detected using %s instead of %s !",
                    type_x, self.LL)
            self.LL = type_x
        sx = raw(ll(x))
        x.sent_time = time.time()
        try:
            return self.outs.sendto(sx, sdto)
        except socket.error as msg:
            if msg.errno == 22 and len(sx) < conf.min_pkt_size:
                return self.outs.send(
                    sx + b"\x00" * (conf.min_pkt_size - len(sx))
                )
            elif conf.auto_fragment and msg.errno == 90:
                i = 0
                for p in x.fragment():
                    i += self.outs.sendto(raw(ll(p)), sdto)
                return i
            else:
                raise

As you can see in iff = x.route()[0], the interface is being determined by the route method, and the one I specified is completely ignored throughout the function.

Actual result

No response

Expected result

No response

Related resources

No response

@fernandoenzo fernandoenzo changed the title Bug in send method. Interface is not being taked into account Bug in send method. Interface is not being taken into account Aug 22, 2024
@gpotter2
Copy link
Member

This is by design. L3 functions (send...) use the routing table. If you want to select the interface, use L2 functions (sendp...).

Since #4461 there should be a syntax warning when iface is used on L3 functions. It never did much, but is now officially invalid.

@gpotter2 gpotter2 closed this as completed Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants