Beispiel #1
0
def measure_distance(destination):
    lat1, long1 = get_geo_coord(localinfo.get_local_ip())
    lat2, long2 = get_geo_coord(socket.gethostbyname(destination))
    delta_lat = fabs(lat2-lat1)
    delta_long = fabs(long2-long1)
    # The Haversine formula
    # http://www.movable-type.co.uk/scripts/latlong.html
    # "a is the square of half of the chord length between the points"
    # "c is the angular distance in radians"
    a = sin(delta_lat/2)**2 + (cos(lat1) * cos(lat2) * sin(delta_long/2)**2)
    c = 2 * atan2(sqrt(a), sqrt(1-a))
    # Mean Earth Radius in kilometers
    earth_radius = 6371
    # Distance in kilometers
    distance = earth_radius * c
    print "Distance for %s: %d km" % (destination, distance)
Beispiel #2
0
def measure_info(destination):
    # The official traceroute port should return port unreachable ICMP packets/messages
    # Other ports would work as well ie 49152 through 65535 and really any normally unused port
    # https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Dynamic.2C_private_or_ephemeral_ports
    port = 33434    
    # Get the expected protocols for the sockets
    icmp = socket.getprotobyname('icmp')
    udp = socket.getprotobyname('udp')
    # A known ttl 
    ttl = 32
    # A known message
    message = "abcdefgh"
    # Get the destination IP - non-deterministic gets first DNS response
    destination_ip = socket.gethostbyname(destination)
    
    # Create sockets 
    
    # One to send a packet with a known ttl 
    sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, udp)
    
    # Set the TTL explicitly so that we know what it was originally
    sender.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl)
    
    # One to receive an ICMP packet ideally with code 3
    receiver = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
    
    # Set the blocking receiver to time out if no response
    receiver.settimeout(3)
    
    # Start a timer to get RTT
    start_time = time.time()
    
    # Send the packet to the destination
    sender.sendto(message, (destination_ip, port))
    
    # Attempt to get the data from the receiver by polling
    try:
        # Get data from the receiver = the argument is the buffer size
        data, addr = receiver.recvfrom(2048)
        # Stop the timer
        end_time = time.time()
    except socket.error:
        print "%s did not respond or the packet was lost." % (destination)        
        return
    finally:
        # Close the sockets
        sender.close()
        receiver.close()
        
    # Process the data and determine how many hops the packet travelled
    
    # The first 20 bytes of the response 0 - 19 is the containing IPv4 header
    # The next 8 are the ICMP response 20-27
    # Specifically byte 20 is the type should be 3 for destination unreachable
    # Specifically byte 21 is the code should be 3 for port unreachable
    # The next 20 28 - 47 bytes are the IPv4 headers sent earlier
    # Specifically byte 36 is the ttl field indicating how many steps it took to get to the destination
    # The last 8 48 - 55 are the data in the packet sent
    
    icmp_type = ord(data[20])
    icmp_code = ord(data[21])
    new_ttl = ord(data[36])
    
    response_source_ip = make_string_ip(data[40:44])
    response_destination_ip = make_string_ip(data[44:48])  
    
    icmp_source_ip = make_string_ip(data[12:16])
    icmp_destination_ip = make_string_ip(data[16:20])
 
    if  (   
            # The message is not ICMP destination / port unreachable
            icmp_type != 3 or icmp_code != 3 or
            # The source IP on the IPv4 packet within the ICMP does not match our IP
            response_source_ip  != localinfo.get_local_ip() or
            # The destination IP on the IPv4 packet within the ICMP does not match the destination
            response_destination_ip != destination_ip or
            # The source IP on the ICMP packet is not the destination
            icmp_source_ip != destination_ip or
            # The destination IP on the ICMP packet is not this address
            icmp_destination_ip != localinfo.get_local_ip() or
            # The ICMP packet returned my message and it doesn't match
            (len(data) == 64 and not do_bytes_match_string(data[len(data)-8:], message))
        ):
        print "Did not receive expected response for host %s." % (destination)
        return
        
    hop_count = ttl - new_ttl
    print "Data for host: %s (%s)" % (destination, destination_ip)
    print "Hops: %d" % (hop_count)
    time_in_sec = end_time - start_time
    time_in_milli_sec = time_in_sec * 1000
    print "RTT (milliseconds): %f"  % (time_in_milli_sec)
    
    return hop_count, time_in_milli_sec