def __restore_ntp_pck(self, ntp: NTP) -> NTP: self.log.debug('Send timestamp for reconstruction: ' + str(ntp.sent)) sent_time_stamp = datetime.fromtimestamp( ntplib.ntp_to_system_time(ntp.sent)) sent_time_stamp = sent_time_stamp.replace(year=datetime.now().year) sent_time_stamp_as_ntp = ntplib.system_to_ntp_time( sent_time_stamp.timestamp()) ntp.sent = sent_time_stamp_as_ntp self.log.debug('Send timestamp after reconstruction: ' + str(ntp.sent)) pck = CP3Package(ntp) if NTPMode.from_bit_string(pck.mode()) is NTPMode.CLIENT: self.log.debug("Restored in Client mode") ntp.ref = 0 ntp.orig = 0 ntp.recv = 0 if NTPMode.from_bit_string(pck.mode()) is NTPMode.SERVER \ or NTPMode.from_bit_string(pck.mode()) is NTPMode.BROADCAST_SERVER: self.log.debug("Restored in Server mode") origin_last_32 = pck.origin_timestamp()[32:64] received_last_32 = pck.receive_timestamp()[32:64] transmit_first_32 = pck.origin_timestamp()[0:32] pck.set_origin_timestamp(transmit_first_32 + origin_last_32) pck.set_receive_timestamp(transmit_first_32 + received_last_32) ntp = pck.ntp() self.log.debug("Reconstruction complete.") #ntp.show() return ntp
def init_ntp_pck(num_of_digits_to_fill_up: int = 12) -> NTP: """ Creates a new NTP package, fills all 4 64 bit timestamps with the current time and fills up the last bits with random values, since they are set to 0 by Scapy :param num_of_digits_to_fill_up: The amount of digits to fill up. :return: The newly created NTP package """ ntp = NTP() ntp.ref = ntp_time_now() ntp.sent = ntp_time_now() ntp.orig = ntp_time_now() ntp.recv = ntp_time_now() raw_ntp = RawNTP(ntp) f_ref = raw_ntp.reference_timestamp() f_trans = raw_ntp.transmit_timestamp() f_orig = raw_ntp.origin_timestamp() f_recv = raw_ntp.receive_timestamp() for i in range(num_of_digits_to_fill_up): pos = 64 - i f_ref = f_ref[:pos - 1] + str(random.randint(0, 1)) + f_ref[pos:] f_trans = f_trans[:pos - 1] + str(random.randint(0, 1)) + f_trans[pos:] f_orig = f_orig[:pos - 1] + str(random.randint(0, 1)) + f_orig[pos:] f_recv = f_recv[:pos - 1] + str(random.randint(0, 1)) + f_recv[pos:] assert len(f_ref) == 64 assert len(f_trans) == 64 assert len(f_orig) == 64 assert len(f_recv) == 64 raw_ntp.set_reference_timestamp(f_ref) raw_ntp.set_transmit_timestamp(f_trans) raw_ntp.set_origin_timestamp(f_orig) raw_ntp.set_receive_timestamp(f_recv) ntp = raw_ntp.ntp() return ntp
def init_ntp_client_pck(num_of_digits_to_fill_up: int = 12): """ Creates a new NTP package, fills only the transmit 64 bit timestamps with the current time and fills up the last bits with random values, since they are set to 0 by Scapy :param num_of_digits_to_fill_up: The amount of digits to fill up. :return: The newly created NTP package """ ntp = NTP() ntp.sent = ntp_time_now() ntp.ref = 0 ntp.orig = 0 ntp.recv = 0 raw_ntp = RawNTP(ntp) f_trans = raw_ntp.transmit_timestamp() for i in range(num_of_digits_to_fill_up): pos = 64 - i f_trans = f_trans[:pos - 1] + str(random.randint(0, 1)) + f_trans[pos:] assert len(f_trans) == 64 raw_ntp.set_transmit_timestamp(f_trans) ntp = raw_ntp.ntp() return ntp
logger_name='CP3-Logger') N = 10000 server_address = '192.168.50.102' deviations = 0 error_counter = 0 log.info("Starting CP3 distribution experiment with N=" + str(N) + " and server address=" + str(server_address)) i = 0 while i < N: i += 1 log.debug("Iteration " + str(i)) ntp = NTP() ntp.orig = None request = IP(dst=server_address) / UDP() / ntp response = sr1(request, timeout=2) if response is None: error_counter += 1 i -= 1 log.info('Error: Server not reached within time.') continue log.debug("Response from: " + response[IP].src) ntp_raw = RawNTP(response[NTP]) if (ntp_raw.origin_timestamp()[0:32] != ntp_raw.transmit_timestamp()[0:32]) \ or (ntp_raw.origin_timestamp()[0:32] != ntp_raw.receive_timestamp()[0:32]): deviations += 1 log.info("Deviation detected") log.info("Origin:" + str(ntp_raw.origin_timestamp()))