docs: def receive_one_ping(sock: socket, icmp_id: int, seq: int, timeout: int) -> float or None:
      """Receives the ping from the socket.
  
      IP Header (bits): version (8), type of service (8), length (16), id (16), flags (16), time to live (8), protocol (8), checksum (16), source ip (32), destination ip (32).
      ICMP Packet (bytes): IP Header (20), ICMP Header (8), ICMP Payload (*).
      Ping Wikipedia: https://en.wikipedia.org/wiki/Ping_(networking_utility)
      ToS (Type of Service) in IP header for ICMP is 0. Protocol in IP header for ICMP is 1.
  
      Args:
          sock: The same socket used for send the ping.
          icmp_id: ICMP packet id. Sent packet id should be identical with received packet id.
          seq: ICMP packet sequence. Sent packet sequence should be identical with received packet sequence.
          timeout: Timeout in seconds.
  
      Returns:
          The delay in seconds or None on timeout.
  
      Raises:
          TimeToLiveExpired: If the Time-To-Live in IP Header is not large enough for destination.
          TimeExceeded: If time exceeded but Time-To-Live does not expired.
      """
      ip_header_slice = slice(0, struct.calcsize(IP_HEADER_FORMAT))  # [0:20]
      icmp_header_slice = slice(ip_header_slice.stop, ip_header_slice.stop + struct.calcsize(ICMP_HEADER_FORMAT))  # [20:28]
      ip_header_keys = ('version', 'tos', 'len', 'id', 'flags', 'ttl', 'protocol', 'checksum', 'src_addr', 'dest_addr')
      icmp_header_keys = ('type', 'code', 'checksum', 'id', 'seq')
      while True:
          selected = select.select([sock], [], [], timeout)
          if selected[0] == []:  # Timeout
              raise errors.Timeout(timeout)
          time_recv = default_timer()
          recv_data, addr = sock.recvfrom(1024)
          ip_header_raw, icmp_header_raw, icmp_payload_raw = recv_data[ip_header_slice], recv_data[icmp_header_slice], recv_data[icmp_header_slice.stop:]
          ip_header = dict(zip(ip_header_keys, struct.unpack(IP_HEADER_FORMAT, ip_header_raw)))
          _debug("IP HEADER:", ip_header)
          icmp_header = dict(zip(icmp_header_keys, struct.unpack(ICMP_HEADER_FORMAT, icmp_header_raw)))
          _debug("ICMP HEADER:", icmp_header)
          if icmp_header['type'] == IcmpType.TIME_EXCEEDED:  # TIME_EXCEEDED has no icmp_id and icmp_seq. Usually they are 0.
              if icmp_header['code'] == IcmpTimeExceededCode.TTL_EXPIRED:
                  raise errors.TimeToLiveExpired()  # Some router does not report TTL expired and then timeout shows.
              raise errors.TimeExceeded()
          if icmp_header['id'] == icmp_id and icmp_header['seq'] == seq:  # ECHO_REPLY should match the
              if icmp_header['type'] == IcmpType.ECHO_REQUEST:  # filters out the ECHO_REQUEST itself.
                  _debug("ECHO_REQUEST filtered out.")
                  continue
              if icmp_header['type'] == IcmpType.ECHO_REPLY:
                  time_sent = struct.unpack(ICMP_TIME_FORMAT, icmp_payload_raw[0:struct.calcsize(ICMP_TIME_FORMAT)])[0]
                  return time_recv - time_sent