Python traceroute script doesn't get reply

0

I am trying to write a traceroute script in python 2.7. The script below works fine if it's just use for ping. After I added "send.setsockopt(socket.IPPROTO_IP, socket.IP_TTL, ttl)" in sendOnePing() then it stuck at "reply, address = icmpSocket.recv(1024)" I have no idea what happened. Any help will be great. Thanks!

#!/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")
python
python-2.7
asked on Stack Overflow Feb 21, 2019 by Henry

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0