Skip to content

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

@fernandoenzo

Description

@fernandoenzo

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions