Ping command using raw socket
Implementation of an Internet Control Message Protocol (ICMP) "ping" in Python without using any external packages:
import socket
import struct
import time
# Create a raw socket to receive ICMP packets
icmp = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname("icmp"))
# Set a timeout for the socket
icmp.settimeout(3)
# Create the checksum of the data that will be sent
def checksum(data):
csum = 0
countTo = (len(data) // 2) * 2
count = 0
while count < countTo:
thisVal = data[count+1] * 256 + data[count]
csum = csum + thisVal
csum = csum & 0xffffffff
count = count + 2
if countTo < len(data):
csum = csum + data[len(data) - 1]
csum = csum & 0xffffffff
csum = (csum >> 16) + (csum & 0xffff)
csum = csum + (csum >> 16)
answer = ~csum
answer = answer & 0xffff
answer = answer >> 8 | (answer << 8 & 0xff00)
return answer
# Send an ICMP "ping" request to a target host
def ping(host):
# Set the destination IP address
destination_ip = socket.gethostbyname(host)
# Build the ICMP header
header = struct.pack("!BBHHH", 8, 0, 0, 1, 1)
data = struct.pack("!d", time.time())
packet = header + data
packet = packet[0:8] + struct.pack("H", checksum(packet)) + packet[10:]
# Send the ICMP packet to the target host
icmp.sendto(packet, (destination_ip, 1))
# Wait for a response from the target host
try:
_, address = icmp.recvfrom(1024)
address = address[0]
except socket.timeout:
return None
# Return the address of the host that responded to the ping request
return address
# Example usage
host = "www.google.com"
response = ping(host)
if response:
print("Ping to", host, "was successful. Host IP:", response)
else:
print("Ping to", host, "timed out.")
Keep in mind that raw sockets may require elevated permissions on some systems, and that this code may not work on all platforms.