This tutorial servies two purposes.

  • We are to understand IPv4 ARP via hands-on packet crafting experiments
  • We need this to realize part of TCP protocol via packet crafting

There are two methods to add (or to spoof) a host.

  • Add a static entry to a host’s ARP table
  • Reply to ARP request

Adding Static ARP Entry

We can add a static ARP entry via the arp command (Linux now considers it deprecated) or via the ip neighbor command . Below is an example of using arp

sudo arp -s 08:00:27:08:0d:a1

Replying to ARP Request

The following program reply to ARP request, as such, it acts as an neighbor.

import signal
import sys

from scapy.sendrecv import sendp
from scapy.sendrecv import sniff
from scapy.layers.l2 import ARP

def gracefully_exit(sig, frame):
    print("Ctrl-C pressed. Exiting ...")

def usage(prog):
    # python 08:00:27:08:0d:a1 enp0s9
    print("Usage: prog PHANTOM_HOST_IP PHANTOM_HW_ADDR NIC")

def main(argv):
    signal.signal(signal.SIGINT, gracefully_exit)
    if len(argv) < 4: 
    # host = ''
    # nic = 'enp0s9'
    # hwaddr = '08:00:27:08:0d:a1'
    host = argv[1]
    hwaddr = argv[2]
    nic = argv[3]
    filter = 'arp dst host ' + host
    while True: 
        packets = sniff(filter=filter, count=1)
        arppkt = packets[0]
        arppkt.dst = arppkt.src
        arppkt.src = hwaddr
        arppkt.op = 2
        arppkt.hwdst = hwaddr
        arppkt.psrc = packets[0].pdst
        arppkt.hwsrc = packets[0].hwdst
        arppkt.hwdst = packets[0].hwsrc
        arppkt.pdst = packets[0].psrc
        sendp(arppkt, iface=nic, verbose=0)

if __name__ == "__main__":