Skip to content

Instantly share code, notes, and snippets.

@francisrstokes
Created October 10, 2024 21:22
Show Gist options
  • Save francisrstokes/6dacd3cfa90ec75a321c173071d4fd60 to your computer and use it in GitHub Desktop.
Save francisrstokes/6dacd3cfa90ec75a321c173071d4fd60 to your computer and use it in GitHub Desktop.
Sending raw ethernet packets with python
from socket import socket, AF_PACKET, SOCK_RAW
ETH_P_ALL = 0x0003
print("Starting")
interface = "enx7cc2c65485c0"
# interface_mac = 7c:c2:c6:54:85:c0
# Note: When sending ethernet frames, only the following data is actually supplied at this level:
# - Destination MAC
# - Source MAC
# - EtherType
# - Payload data
arp_packet = bytearray([
# Ethernet frame data exposed at this level (missing Preamble / Start of frame delimiter from hardware level)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # Destination MAC (broadcast)
0x7c, 0xc2, 0xc6, 0x54, 0x85, 0xc0, # Source MAC
0x08, 0x06, # EtherType (0x0806 for ARP)
# ARP packet data starts here
0x00, 0x01, # Hardware type (Ethernet)
0x08, 0x00, # Protocol type (IPv4)
0x06, # Hardware size
0x04, # Protocol size
0x00, 0x01, # Opcode (request)
0x7c, 0xc2, 0xc6, 0x54, 0x85, 0xc0, # Sender MAC address
0xC0, 0xA8, 0x01, 0x02, # Sender IP address
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # Target MAC address (unknown)
0xC0, 0xA8, 0x01, 0x01, # Target IP address
# No padding or frame check sequence CRC is added here either
])
ethernet_frame = bytearray([
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # Destination MAC (broadcast)
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, # Source MAC
0x12, 0x34, # Custom EtherType (0x1234)
# Payload (just some test data)
0xde, 0xad, 0xbe, 0xef # Example payload
])
# AF_PACKET is a low-level interface to network devices
# SOCK_RAW, when combined with AF_PACKET, refers to raw ethernet packets
with socket(AF_PACKET, SOCK_RAW) as raw_socket:
print(raw_socket)
print(f"Binding to interface: {interface}")
raw_socket.bind((interface, ETH_P_ALL))
print("Sending raw ARP packet")
bytes_sent = raw_socket.send(arp_packet)
# bytes_sent = raw_socket.send(ethernet_frame)
print(f"Sent {bytes_sent} bytes to the interface")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment