I'm trying to make traceroute implementation in python 3.5. On linux this code works fine. On Windows 10 I have infinity waiting of ICMP packet. Wireshark see ICMP packet in Windows.
import socket
Create a UDP and ICMP sockets
receiver = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname('ICMP'))
sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sender.setsockopt(socket.SOL_IP, socket.IP_TTL, 1)
server_address = (socket.gethostbyname('google.com'), 33434)
try: # Send data receiver.bind(("", 33434)) sent = sender.sendto(b"", server_address) data, server = receiver.recvfrom(512) print('received "%s"\n"%s"' % (data, server[0])) finally: print('closing socket') sender.close() receiver.close()
Answer
The issue you're encountering is likely related to the handling of raw sockets and the way Windows 10 treats ICMP packets. Windows has stricter rules when it comes to raw socket access, especially when it comes to sending and receiving ICMP packets, and this might be causing the infinite wait you're experiencing. Additionally, the use of raw sockets often requires administrative privileges on Windows, which could also be contributing to the issue.
Here's a breakdown of what might be happening and how to resolve it:
Problem Breakdown:
-
Windows and Raw Sockets: In Windows, raw sockets are restricted to users with administrative privileges, and even then, they may behave differently compared to Linux. The issue might be that Windows is silently dropping the ICMP packets or that the TTL value isn't being handled correctly by the system.
-
ICMP and UDP: You're sending a UDP packet with
socket.SOCK_DGRAM
, and you're trying to listen for ICMP (which is typically used for responses to aping
ortraceroute
). However, there might be confusion around how these packets are being handled by the system, especially with respect to the ICMP response.
Recommendations:
-
Administrative Privileges: Ensure you're running your Python script with administrative privileges on Windows. Raw sockets require elevated privileges on Windows, so you may need to run your Python environment (e.g., command prompt, or IDE) as an administrator.
-
ICMP Socket: You're using a raw socket to listen for ICMP packets. Make sure that Windows is allowing raw socket access. You might also want to ensure that the system's firewall is not blocking the ICMP packets.
-
Timeout Handling: It might be helpful to implement a timeout for the
recvfrom
call to prevent it from hanging indefinitely if no ICMP response is received.
Modified Code with Timeout Handling:
import socket
import time
# Create a UDP socket and ICMP raw socket
receiver = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname('ICMP'))
sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Set TTL to 1 to begin traceroute
sender.setsockopt(socket.SOL_IP, socket.IP_TTL, 1)
server_address = (socket.gethostbyname('google.com'), 33434)
try:
# Bind receiver socket
receiver.bind(("", 33434))
sender.sendto(b"", server_address)
# Set timeout for recvfrom to avoid infinite wait
receiver.settimeout(2) # Timeout after 2 seconds
try:
# Wait for the ICMP response
data, server = receiver.recvfrom(512)
print('Received "%s" from %s' % (data, server[0]))
except socket.timeout:
print("No response received within timeout.")
finally:
print('Closing sockets.')
sender.close()
receiver.close()
Key Changes:
-
Timeout for
recvfrom
: I added a timeout of 2 seconds for therecvfrom
call to prevent the script from waiting forever if the ICMP response isn't received. You can adjust the timeout as needed. -
Error Handling: I wrapped the
recvfrom
call in a try-except block to catch timeouts and print a more informative message if no response is received.
Further Troubleshooting:
-
Firewall: Make sure the Windows firewall isn't blocking ICMP requests. You might need to temporarily disable it or add an exception for your Python program.
-
WinPcap / Npcap: On Windows, tools like Wireshark use WinPcap or Npcap to capture raw packets. While this works fine for tools like Wireshark, it may not be enough for your Python program to capture the raw ICMP responses. You can install Npcap (which is more updated) and ensure that it's configured to allow raw socket access.
-
Running as Administrator: Ensure that you're running your Python script as an administrator, as raw socket usage requires elevated privileges on Windows.
If the issue persists after applying these changes, it's likely a combination of Windows' restrictions on raw socket access and the way you're sending and receiving ICMP packets.