Trying to make an ICMP request on windows 10 pro, SOCK_RAW will not read, but writes fine. How can I fix this so it reads and writes?
Ran using admin privileges, and I've tried running without firewall on with no avail
import os
import sys
import struct
import time
import select
import binascii
import socket
ICMP_ECHO_REQUEST = 8
def checksum(string):
csum = 0
countTo = (len(string) // 2) * 2
count = 0
while count < countTo:
thisVal = ord(string[count+1]) * 256 + ord(string[count])
csum = csum + thisVal
csum = csum & 0xffffffff
count = count + 2
if countTo < len(string):
csum = csum + ord(string[len(string) - 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
def receiveOnePing(mySocket, ID, timeout, destAddr):
timeLeft = timeout
while 1:
startedSelect = time.time()
whatReady = select.select([mySocket], [], [], timeLeft)
howLongInSelect = (time.time() - startedSelect)
print(whatReady)
if whatReady[0] == []: # Timeout
return "Request timed out."
timeReceived = time.time()
recPacket, addr = mySocket.recvfrom(1024)
#Fill in start
rtype, code, checksum, recID, sequence = struct.unpack("bbHHh", recPacket[20:28])
if recID != ID or code != 0 or type !=0:
return "there was an error"
origin = struct.unpack('b', recPacket[28:])
rtt = timeReceived - origin
return ('rtt {} ms', rtt)
#Fetch the ICMP header from the IP packet
#Fill in end
timeLeft = timeLeft - howLongInSelect
if timeLeft <= 0:
return "Request timed out."
def sendOnePing(mySocket, destAddr, ID):
# Header is type (8), code (8), checksum (16), id (16), sequence (16)
myChecksum = 0
# Make a dummy header with a 0 checksum
# struct -- Interpret strings as packed binary data
header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, myChecksum, ID, 1)
data = struct.pack("d", time.time())
# Calculate the checksum on the data and the dummy header.
myChecksum = checksum(str(header + data))
# Get the right checksum, and put in the header
if sys.platform == 'darwin':
# Convert 16-bit integers from host to network byte order
myChecksum = socket.htons(myChecksum) & 0xffff
else:
myChecksum = socket.htons(myChecksum)
header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, myChecksum, ID, 1)
packet = header + data
mySocket.sendto(packet, (destAddr, 1)) # AF_INET address must be tuple, not str
# Both LISTS and TUPLES consist of a number of objects
# which can be referenced by their position number within the object.
def doOnePing(destAddr, timeout):
icmp = socket.getprotobyname("icmp")
# SOCK_RAW is a powerful socket type. For more details: http://sockraw.org/papers/sock_raw
try:
mySocket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
except socket.error as e:
if e.errno == 1:
e.msg += "ICMP messages con only be sent from root user processes"
raise socket.error(e.msg)
except Exception as e:
print ("Exception %s" %(e))
myID = os.getpid() & 0xFFFF # Return the current process i
sendOnePing(mySocket, destAddr, myID)
delay = receiveOnePing(mySocket, myID, timeout, destAddr)
mySocket.close()
return delay
def ping(host, timeout=1):
# timeout=1 means: If one second goes by without a reply from the server,
# the client assumes that either the client's ping or the server's pong is lost
dest = socket.gethostbyname(host)
print("Pinging " + dest + " using Python:")
print("")
# Send ping requests to a server separated by approximately one second
while 1 :
delay = doOnePing(dest, timeout)
print(delay)
time.sleep(1)# one second
return delay
ping('127.0.0.1', 32)
My expected results are that I am able to read on the socket, but select.select says that I can't read on the socket.
User contributions licensed under CC BY-SA 3.0