pythonscapy

Create Malformed Ether Frame?


I would expect this to be trivial but I can't get it to work.

I want to send a forged ARP using scapy in Python but I need to spoof the source MAC address as well in this scenario (vmac, vip, rip are all valid values)

op = 1
who_has_router = Ether(src=vmac)/ARP(op=op,psrc=vip,pdst=rip,hwsrc=vmac)
send(who_has_router)

The above appears as a malformed packet in Wireshark and is ignored by everyone on the network.

If I remove the Ether() layer it works fine (but then it doesn't spoof the source mac so isn't good enough in this case):

# This works exactly as expected
op = 1
who_has_router = ARP(op=op,psrc=vip,pdst=rip,hwsrc=vmac)
send(who_has_router)

How can I add the Ether() layer in Python/scapy without causing a malformed packet?

enter image description here


Solution

  • The send function is used to send packets in layer 3, while your packet is a layer 2 one. You should use the sendp function.

    See scapy's docs for further information:

    The send() function will send packets at layer 3. That is to say it will handle routing and layer 2 for you. The sendp() function will work at layer 2. It’s up to you to choose the right interface and the right link layer protocol.

    The official API documentation states this as well:

    send(pkts, inter=0, loop=0, verbose=None)

    Send packets at layer 3, using the conf.L3socket supersocket.

    sendp(pkts, inter=0, loop=0, iface=None, iface hint=None, verbose=None)

    Send packets at layer 2 using the conf.L2socket supersocket.