Specify IP header of packet in Python

453 Views Asked by At

I'm trying to send a raw IP packet with a custom IP header and ICMP payload. When running the code I wrote below, Wireshark shows that both an Ethernet and IP header was prepended to the data. Instead, I want only an Ethernet header to be prepended so that I can provide a custom IP header.

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)

# IP header
ip_header = b'\x45\x00\x00\x1c'     # Version, IHL, Type of Service, Total Length
ip_header += b'\xab\xcd\x00\x00'    # Identification, Flags, Fragment Offset
ip_header += b'\x40\x01\x6b\xd8'    # TTL, Protocol, Header Checksum
ip_header += b'\xc0\xa8\x92\x83'    # Source Address
ip_header += b'\x08\x08\x08\x08'    # Destination Address

# IP payload/ICMP header
icmp_header = b'\x08\x00\xe5\xca'   # Type of message, Code, Checksum
icmp_header += b'\x12\x34\x00\x01'  # Identifier, Sequence Number

packet = ip_header + icmp_header

s.sendto(packet, ('8.8.8.8', 1))
s.close()

Here is how the packets showed up in Wireshark:

screenshot of wireshark

I thought that setting socket.IP_HDRINCL would let me specify my own IP header, so I added this line below the call to socket.socket():

s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

But when I did that, the packets stopped showing up in Wireshark altogether. I also tried changing the protocol to socket.IPPROTO_IP, but an IP header was still prepended.

I don't think that it matters, but I'm using a Mac and this is the command that I am using to run the code: sudo python3 code.py

So, how can I tell Python/the OS to not prepend an IP header to my packet?

0

There are 0 best solutions below