Exemplo n.º 1
0
def ping(client_socket, dest_host, client_id, seq_no=0):
    """
   Sends echo request, receives response, and returns RTT.
    """
    def icmp_header(host_checksum):
        message = ICMPMessage(type=ECHO_REQUEST.type,
                              code=ECHO_REQUEST.code,
                              checksum=socket.htons(host_checksum),
                              identifier=client_id,
                              sequence_number=seq_no)
        return struct.pack(ICMP_STRUCT_FIELDS, *message)

    #  Create payload for ICMP packet, being the time of its creation
    icmp_payload = struct.pack('d', this_instant())  # double-precision float
    #  Structure packet with checksum value initialised as zero
    icmp_packet_without_checksum = icmp_header(0) + icmp_payload
    #  Calculate checksum value to be used
    checksum = internet_checksum(icmp_packet_without_checksum)
    #  Create final packet to send, with checksum in header, and payload
    icmp_packet = icmp_header(checksum) + icmp_payload

    #  Create variable of the IPv4 destination address, for future use
    dest_host = socket.gethostbyname(dest_host)

    #  Send previously created ICMP packet, to dest host, via client socket
    client_socket.sendto(icmp_packet, (dest_host, ICMP_PORT_PLACEHOLDER))

    #  Blocking code, that waits for reply from the receiver of ICMP packet
    datagram, address = client_socket.recvfrom(BUFFER_SIZE)

    #  Store this_instant() at which datagram was received
    time_recv = this_instant()

    #  Strip IP header off of received datagram (to isolate ICMP packet)
    icmp_packet = datagram[20:]

    #  Use checksum to validate contents of ICMP packet
    checksum = internet_checksum(icmp_packet)
    if (checksum != 0):
        raise ChecksumError

    #  Extract header information of response ICMP packet
    icmp_header_response = ICMPMessage(
        *struct.unpack(ICMP_STRUCT_FIELDS, icmp_packet[:8]))

    #  Extract body of response of ICMP response packet
    icmp_message_response = icmp_packet[8:]

    #  Unpack binary data to recover what time the packet was sent at
    time_sent = struct.unpack('d', icmp_message_response)[0]

    #  Calculate round-trip time by finding the diff between time sent/received
    RTT = (time_recv - time_sent) * MILLISEC_PER_SEC

    #  Return both the RTT, and the header of the response
    return (RTT, icmp_header_response)
Exemplo n.º 2
0
def ping(client_socket, dest_host, client_id, seq_no=0):
    """
    Sends echo request, receives response, and returns RTT.
    """
    def icmp_header(host_checksum):
        message = ICMPMessage(type=ECHO_REQUEST.type,
                              code=ECHO_REQUEST.code,
                              checksum=host_checksum,
                              identifier=client_id,
                              sequence_number=seq_no)
        return struct.pack(ICMP_STRUCT_FIELDS, *message)

    icmp_payload = struct.pack('d', this_instant())  # double-precision float
    icmp_packet_without_checksum = icmp_header(0) + icmp_payload
    checksum = internet_checksum(icmp_packet_without_checksum)
    checksum_string = hex(checksum)
    checksum_string_reversed = checksum_string[4:] + checksum_string[2:4]
    checksum_int_reversed = int(checksum_string_reversed, 16)

    icmp_packet = icmp_header(checksum_int_reversed) + icmp_payload

    # Get the host name (unchanged if already in IPv4 address format)
    dest_host = socket.gethostbyname(dest_host)

    # Send packet to destination host
    client_socket.sendto(icmp_packet, (dest_host, ICMP_PORT_PLACEHOLDER))

    # Try to get response
    datagram, addr = client_socket.recvfrom(BUFFER_SIZE)
    time_recv = this_instant()

    # Extract ICMP packet from datagram (drop IP Header)
    icmp_packet_recv = datagram[IP_HEADER_LENGTH:]

    # Compute checksum on ICMP response packet (header and payload)
    checksum_recv = internet_checksum(icmp_packet_recv)
    if checksum_recv != 0:
        raise ChecksumError()

# Extract ICMP response header from ICMP packet (8 bytes) and unpack
    icmp_recv_header = icmp_packet_recv[0:ICMP_HEADER_LENGTH]
    recv_header = struct.unpack(ICMP_STRUCT_FIELDS, icmp_recv_header)

    # Extract ICMP response payload (remaining bytes) and unpack
    icmp_recv_payolad = icmp_packet_recv[ICMP_HEADER_LENGTH:]
    time_sent = struct.unpack('d', icmp_recv_payolad)[0]

    # Compute round-trip time from "time sent"
    rtt = (time_recv - time_sent) * MILLISEC_PER_SEC

    return (rtt, recv_header)
Exemplo n.º 3
0
def ping(client_socket, dest_host, client_id, seq_no=0):
    """
   Sends echo request, receives response, and returns RTT.
    """

    def icmp_header(host_checksum):
        message = ICMPMessage(
                    type=None,  # TODO: Use appropriate argument here
                    code=None,  # TODO: Use appropriate argument here
                    checksum=host_checksum,
                    identifier=client_id,
                    sequence_number=seq_no)
        return struct.pack(ICMP_STRUCT_FIELDS, *message)

	# TODO: Please study these lines carefully,
	#       noting that "icmp_pack()" (defined above) is called *twice*
    icmp_payload = struct.pack('d', this_instant())  # double-precision float
    icmp_packet_without_checksum = icmp_header(0) + icmp_payload
    checksum = internet_checksum(icmp_packet_without_checksum)
    icmp_packet = icmp_header(checksum) + icmp_payload

    #
    # TODO: Please note that that "icmp_packet" is the
    #       payload that we'll send through for our INET raw socket
    #

    # Note: socket.gethostbyname() returns the host name
    # unchanged if it is already in IPv4 address format.
    dest_host = socket.gethostbyname(dest_host)
Exemplo n.º 4
0
def ping(client_socket, dest_host, client_id, seq_no=0):
    """
   Sends echo request, receives response, and returns RTT.
    """
    def icmp_header(host_checksum):
           
        message = ICMPMessage(
                type=ECHO_REQUEST.type,  # TODO: Use appropriate argument here
                code=ECHO_REQUEST.code,  # TODO: Use appropriate argument here
                checksum=host_checksum,
                identifier=client_id,
                sequence_number=seq_no)      
                    
        return struct.pack(ICMP_STRUCT_FIELDS, *message)

	# TODO: Please study these lines carefully,
	#       noting that "icmp_pack()" (defined above) is called *twice*
    icmp_payload = struct.pack('d', this_instant())  # double-precision float
    icmp_packet_without_checksum = icmp_header(0) + icmp_payload
    checksum = internet_checksum(icmp_packet_without_checksum)   
    icmp_packet = icmp_header(checksum) + icmp_payload

    #
    # TODO: Please note that that "icmp_packet" is the
    #       payload that we'll send through for our INET raw socket
    #
    
    # Note: socket.gethostbyname() returns the host name
    # unchanged if it is already in IPv4 address format.
    dest_host = socket.gethostbyname(dest_host)
    
    
    client_socket.sendto(icmp_packet,(dest_host,ICMP_PORT_PLACEHOLDER))
    client_socket.shutdown(socket.SHUT_WR)
    
    
    reply,addr=client_socket.recvfrom(2048) #hanging
    recieve_time = this_instant()
    
    rpacket = reply[20:]   
    
    
    rheader = rpacket[:8] 
    rimcp_packet = struct.unpack('d',rheader)
   
    
    
    rpayload = rpacket [8:]
    time_sent = struct.unpack('d',rpayload)
    rtt = recieve_time - time_sent[0] #time recieved minus time sent
    
    formatted_output = "ICMPMessage: type= 8, code = 0, checksum= {}, identifier = {}, sequence number = {}".format(
            checksum, client_id, seq_no)
    
    return round(rtt*MILLISEC_PER_SEC), formatted_output
Exemplo n.º 5
0
def ping(client_socket, dest_host, client_id, seq_no=0):
    """
   Sends echo request, receives response, and returns RTT.
    """
    def icmp_header(host_checksum):
        message = ICMPMessage(
            type=ECHO_REQUEST.type,  # TODO: Use appropriate argument here
            code=ECHO_REQUEST.code,  # TODO: Use appropriate argument here
            checksum=host_checksum,
            identifier=client_id,
            sequence_number=seq_no)
        return struct.pack(ICMP_STRUCT_FIELDS, *message)

# Please study these lines carefully,
#       noting that "icmp_pack()" (defined above) is called *twice*

    icmp_payload = struct.pack('d', this_instant())  # double-precision float
    icmp_packet_without_checksum = icmp_header(0) + icmp_payload
    checksum = internet_checksum(icmp_packet_without_checksum)
    icmp_packet = icmp_header(checksum) + icmp_payload

    # Please note that that "icmp_packet" is the
    #       payload that we'll send through for our INET raw socket
    #

    # Note: socket.gethostbyname() returns the host name
    # unchanged if it is already in IPv4 address format.
    dest_host = socket.gethostbyname(dest_host)
    #.
    # 1. Call sendto() on socket to send packet to destination host

    client_socket.sendto(icmp_packet, (dest_host, ICMP_PORT_PLACEHOLDER))
    # 2. Call recvfrom() on socket to receive datagram
    try:
        dgram, address = client_socket.recvfrom(BUFFER_SIZE)
    except socket.timeout as error:
        raise TimeoutError()

    #    (Note: A time-out exception might be raised here).
    # 2. Store this_instant() at which datagram was received
    time_received = this_instant()
    # 3. Extract ICMP packet from datagram i.e. drop IP header (20 bytes)
    #     e.g. "icmp_packet = datagram[20:]"
    icmp_packet = dgram[20:]
    # 4. Compute checksum on ICMP response packet (header and payload);
    #     this will hopefully come to zero

    # get checksum fields
    checksum = int.from_bytes(icmp_packet[2:4], byteorder='big')
    # zero out checksum fields (third and fourth byte) on response
    icmp_packet_copy = icmp_packet[:2] + icmp_packet[4:]
    # verify checksum
    value = internet_checksum(icmp_packet_copy, checksum)
    if value != 0:
        raise ChecksumError()

# 5. Raise exception if checksum is nonzero
# 6. Extract ICMP response header from ICMP packet (8 bytes) and
#     unpack binary response data to obtain ICMPMessage "response"
#     that we'll return with the round-trip time (Step 9, below);
#     notice that this namedstruct is printed in the sample
#     command line output given in the assignment description.
#     e.g. "Reply from 151.101.0.223 in 5ms: ICMPMessage(type=0, code=0, checksum=48791, identifier=33540, sequence_number=0)"
    icmp_header = icmp_packet[:8]
    response = ICMPMessage(*struct.unpack(ICMP_STRUCT_FIELDS, icmp_header))

    # 7. Extract ICMP response payload (remaining bytes) and unpack
    #     binary data to recover "time sent"
    icmp_payload = icmp_packet[8:]
    bytes_in_double = struct.calcsize('d')
    time_sent = struct.unpack('d', icmp_payload[0:bytes_in_double])[0]
    round_trip_time = time_received - time_sent
    return round(round_trip_time * MILLISEC_PER_SEC), response
Exemplo n.º 6
0
from checksum import hextat_complement
from checksum import internet_checksum

if __name__ == '__main__':
    data = bytes.fromhex('0001f203f4f5f6f7')
    checksum = internet_checksum(data)
    assert checksum == 0x0d22
    print('Test 1 passed')

    data = bytes.fromhex('e34f2396442799f3')
    checksum = internet_checksum(data)
    assert checksum == 0xff1a
    print('Test 2 passed')
Exemplo n.º 7
0
def ping(client_socket, dest_host, client_id, seq_no=0):
    """
   Sends echo request, receives response, and returns RTT.
    """
    def icmp_header(host_checksum):
        message = ICMPMessage(
            type=8,  # TODO: Use appropriate argument here
            code=0,  # TODO: Use appropriate argument here
            checksum=host_checksum,
            identifier=client_id,
            sequence_number=seq_no)
        return struct.pack(ICMP_STRUCT_FIELDS, *message)

    # TODO: Please study these lines carefully,
    #       noting that "icmp_pack()" (defined above) is called *twice*
    icmp_payload = struct.pack('d', this_instant())  # double-precision float
    icmp_packet_without_checksum = icmp_header(0) + icmp_payload
    checksum = internet_checksum(icmp_packet_without_checksum)
    icmp_packet = icmp_header(checksum) + icmp_payload

    #
    # TODO: Please note that that "icmp_packet" is the
    #       payload that we'll send through for our INET raw socket
    #

    # Note: socket.gethostbyname() returns the host name
    # unchanged if it is already in IPv4 address format.
    dest_host = socket.gethostbyname(dest_host)
    #
    # TODO:
    # 1. Call sendto() on socket to send packet to destination host
    # 2. Call recvfrom() on socket to receive datagram
    #    (Note: A time-out exception might be raised here).
    # 2. Store this_instant() at which datagram was received
    # 3. Extract ICMP packet from datagram i.e. drop IP header (20 bytes)
    #     e.g. "icmp_packet = datagram[20:]"
    # 4. Compute checksum on ICMP response packet (header and payload);
    #     this will hopefully come to zero
    # 5. Raise exception if checksum is nonzero
    # 6. Extract ICMP response header from ICMP packet (8 bytes) and
    #     unpack binary response data to obtain ICMPMessage "response"
    #     that we'll return with the round-trip time (Step 9, below);
    #     notice that this namedstruct is printed in the sample
    #     command line output given in the assignment description.
    #     e.g. "Reply from 151.101.0.223 in 5ms: ICMPMessage(type=0, code=0, checksum=48791, identifier=33540, sequence_number=0)"
    # 7. Extract ICMP response payload (remaining bytes) and unpack
    #     binary data to recover "time sent"
    # 8. Compute round-trip time from "time sent"
    # 9. Return "(round-trip time in milliseconds, response)"
    #
    # If things go wrong
    # ==================
    # You might like to check ("assert") that:
    # 1. Type field of ICMP response header is ICMP echo reply type
    # 2. Code field of ICMP response header is ICMP echo reply code
    # 3. Identifier field of ICMP response header is client_id
    # 4. len() of ICMP response payload is struct.calcsize('d')
    #

    # Sending packet
    client_socket.sendto(icmp_packet, (dest_host, ICMP_PORT_PLACEHOLDER))

    # Getting packet back and the time it was received
    try:
        datagram, addr = client_socket.recvfrom(ICMP_MAX_SIZE)
        log_time = this_instant()
    except TimeoutError:
        raise

    # Extracting datagram header
    icmp_packet_rec = datagram[20:]

    # Checking validity of received packet
    if internet_checksum(icmp_packet_rec) != 0:
        raise ChecksumError

    icmp_header_rec = icmp_packet_rec[:8]

    # Getting ICMP header
    response_header = ICMPMessage(
        *struct.unpack(ICMP_STRUCT_FIELDS, icmp_header_rec))

    # Getting the time sent from the payload
    time_sent = struct.unpack("d", datagram[28:28 + struct.calcsize("d")])[0]

    rtt = log_time - time_sent

    return rtt * MILLISEC_PER_SEC, response_header