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?
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. Thesendp()
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.