我正在尝试在python 2.7中编写traceroute脚本。 如果仅用于ping,则以下脚本可以正常工作。 在sendOnePing()中添加“ send.setsockopt(socket.IPPROTO_IP,socket.IP_TTL,ttl)”之后,它卡在“回复,地址= icmpSocket.recv(1024)”上 我不知道发生了什么事。任何帮助都会很棒。谢谢!
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import socket
import os
import sys
import struct
import time
import select
import binascii
ICMP_ECHO_REQUEST = 8 #ICMP type code for echo request messages
ICMP_ECHO_REPLY = 0 #ICMP type code for echo reply messages
ICMP_TIME_EXCEEDED = 11 #ICMP type code for time exceeded
icmpStructure = "bbHHh"
icmpCode = socket.getprotobyname("icmp")
port = 80
myID = 9
ttl = 1
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)
if sys.platform == 'darwin':
answer = socket.htons(answer) & 0xffff
else:
answer = socket.htons(answer)
return answer
def receiveOnePing(icmpSocket, destinationAddress, ID, timeout):
waitForReply = select.select([icmpSocket], [], [], timeout)
if waitForReply[0] == []: # wait for reply if not timeout
print "Packet received!"
endTime = 0
endTime = time.time()
startTime = sendOnePing.startTime
receiveOnePing.totalDelay = (endTime - startTime) * 1000
reply, address = icmpSocket.recv(1024) #This is where my script get stuck because it's not getting response
icmpHeader = reply[20:28]
type, code, checksum, packetID, sequence =
struct.unpack(icmpStructure, icmpHeader)
if type == ICMP_TIME_EXCEEDED:
doOnePing.ttl = doOnePing.ttl + 1
print "Hop!"
doOnePing(destinationAddress, timeout)
elif type == ICMP_ECHO_REPLY and packetID == ID:
print "Destination reached!"
def sendOnePing(icmpSocket, destinationAddress, ID):
header = struct.pack(icmpStructure, ICMP_ECHO_REQUEST, 0, 0, ID, 1)
data = "message"
myChecksum = checksum(header + data)
myHeader = struct.pack(icmpStructure, ICMP_ECHO_REQUEST, 0,
myChecksum, ID, 1)
myPacket = myHeader + data
icmpSocket.connect((destinationAddress, port))
icmpSocket.sendto(myPacket, (destinationAddress, ID))
sendOnePing.startTime = time.time()
def doOnePing(destinationAddress, timeout):
send = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmpCode)
send.setsockopt(socket.IPPROTO_IP, socket.IP_TTL, ttl)
sendOnePing(send, destinationAddress, myID)
receiveOnePing(send, destinationAddress, myID, timeout)
send.close()
doOnePing.totalDelay = receiveOnePing.totalDelay
def ping(host, timeout=2):
host = socket.gethostbyname(host)
while True:
time.sleep(1)
doOnePing(host, timeout)
totalDelay = doOnePing.totalDelay
print "Total network delay: " + str(totalDelay)
ping("www.google.com")