def _set_cp3_mode(self,year:int): ntp = self.ntp() time = ntplib.system_to_ntp_time(datetime.fromtimestamp(ntplib.ntp_to_system_time(ntp.sent)) .replace(year=year).timestamp()) ntp.sent = time raw = RawNTP(ntp) self.set_transmit_timestamp(raw.transmit_timestamp())
def _process_ntp_result(self, result: RawNTP): orig_digits = extract_64timestamp_fraction(result.origin_timestamp()) trans_digits = extract_64timestamp_fraction( result.transmit_timestamp()) ref_digits = extract_64timestamp_fraction(result.reference_timestamp()) rec_digits = extract_64timestamp_fraction(result.receive_timestamp()) self.log.info('Raw bits: ' + orig_digits + ' ' + trans_digits + ' ' + ref_digits + ' ' + rec_digits) for i in range(9): try: origin_n = int(orig_digits[i]) trans_n = int(trans_digits[i]) ref_n = int(ref_digits[i]) rec_n = int(rec_digits[i]) except: # Sometimes one of the pool servers does not respond with 4 valid timestamp fields. # In that case the response is skipped and another round is re-added. self.log.info( 'Experiment FAILED due to invalid server response. Increasing n by 1' ) self._n += 1 self._error_counter_response += 1 return if self._debug: self.log.info('Iteration bits ' + str(i) + ': ' + str(origin_n) + ' ' + str(trans_n) + ' ' + str(ref_n) + ' ' + str(rec_n)) self._origin_container[i][origin_n] += 1 self._ref_container[i][ref_n] += 1 self._rec_container[i][rec_n] += 1 self._trans_container[i][trans_n] += 1
def test_restore_pck_server_pck_other_timestamps_filled_with_send(self): # Arrange client = CP3Handler('') pck = CP3Package() first_32 = '11111111111111111111000000011111' origin_last_32 = '11111111111110011110111111111111' received_last_32 = '11111111110111011110111111111111' transmit = '1111111111111111111111111111111111111111111111111111111111111111' pck.set_origin_timestamp(first_32 + origin_last_32) pck.set_receive_timestamp(first_32 + received_last_32) pck.set_transmit_timestamp(transmit) pck.set_mode(NTPMode.to_bit_string(NTPMode.SERVER)) # Act result_pck = RawNTP(client.restore_pck(pck)) # Assert self.assertNotEqual(result_pck.transmit_timestamp(), transmit) self.assertEqual(result_pck.origin_timestamp()[32:64], origin_last_32) self.assertEqual(result_pck.receive_timestamp()[32:64], received_last_32) self.assertEqual(result_pck.origin_timestamp()[0:32], result_pck.origin_timestamp()[0:32]) self.assertEqual(result_pck.receive_timestamp()[0:32], result_pck.origin_timestamp()[0:32]) self.assertEqual( datetime.fromtimestamp( ntplib.ntp_to_system_time(result_pck.ntp().sent)).year, datetime.now().year)
def read_transmit_values_raw(file_path): packets = rdpcap(file_path) bin_values = [] for packet in packets: ntp_pck = packet[NTP] ntp_pck_raw = RawNTP(ntp_pck) bin_values.append(ntp_pck_raw.transmit_timestamp()[32:64]) return bin_values
def read_transmit_values(file_path): packets = rdpcap(file_path) values = [] for packet in packets: ntp_pck = packet[NTP] raw_ntp = RawNTP(ntp_pck) trans_digits = extract_64timestamp_fraction( raw_ntp.transmit_timestamp()) values.append(trans_digits) return values
def test_ntp(self): # Arrange ntp_header = NTPHeader() ntp_raw = RawNTP(ntp_header) ntp_raw.set_transmit_timestamp(_TEST_BIN_64BIT) # Act result = RawNTP(ntp_raw.ntp()) # Assert self.assertEqual(result.transmit_timestamp(), _TEST_BIN_64BIT)
def difference_detector(): file_path = '/home/shroud/workbench/MasterThesis/results/operating_system_default/2020_08_19_NTPd_2_Filtered.pcap' packets = rdpcap(file_path) ntp_packets = [] x = 0 counter = 0 for packet in packets: counter += 1 ntp_pck = packet[NTP] ntp_pck_raw = RawNTP(ntp_pck) if (ntp_pck_raw.transmit_timestamp()[0:32] != ntp_pck_raw.receive_timestamp()[0:32]) \ or (ntp_pck_raw.origin_timestamp()[0:32] != ntp_pck_raw.receive_timestamp()[0:32]): x += 1 print("Packet with differences detected, nr.: " + str(counter)) ntp_packets.append(ntp_pck) print("Total amount of differences: " + str(x))
def handle_incoming_pck(self, pck: Packet): ntp_pck = pck[NTP] cp1_pck = CP1Package(ntp_pck) self.log.info('Received pck bits: ' + str(cp1_pck._raw)) if self.send_session is None: self.log.debug("Init new session (1).") self.send_session = CP1Session() next_pck = self.send_session.generate_init_pck(self.client_address) self.add_secret_payload(self.payload, self.static_key) else: next_bits_to_send = self.send_session.secret_to_send.next_bits( self.payload_size) self.log.debug("Next payload bits to send: " + str(next_bits_to_send)) new_cp1_pck = CP1Package(ntp_pck=init_ntp_client_pck()) new_cp1_pck.add_payload(next_bits_to_send) next_pck = new_cp1_pck.ntp() upstream_pck = self.scapy_wrapper.get_upstream_ntp() upstream_pck[NTP].mode = 4 # upstream_pck[NTP].orig = ntp_pck.sent upstream_pck[NTP].sent = next_pck[NTP].sent upstream_pck[NTP].ref = next_pck[NTP].ref upstream_pck[IP].src = pck[IP].dst upstream_pck[IP].dst = pck[IP].src upstream_pck[UDP].sport = pck[UDP].dport upstream_pck[UDP].dport = pck[UDP].sport up_raw = RawNTP(upstream_pck[NTP]) pck_raw = RawNTP(ntp_pck) up_raw.set_origin_timestamp(pck_raw.transmit_timestamp()) upstream_pck[NTP] = up_raw.ntp() self.log.debug("Created new CP1 packet to send...") upstream_pck.show() send(upstream_pck) if not self.has_next_pck(): self.log.debug("Init new session (2).") self.send_session = None
def _process_ntp_result(self, result: RawNTP): orig_digits = extract_64timestamp_fraction(result.origin_timestamp()) trans_digits = extract_64timestamp_fraction( result.transmit_timestamp()) ref_digits = extract_64timestamp_fraction(result.reference_timestamp()) rec_digits = extract_64timestamp_fraction(result.receive_timestamp()) self.log.info('Raw bits: ' + orig_digits + ' ' + trans_digits + ' ' + ref_digits + ' ' + rec_digits) for i in range(9): origin_n = int(orig_digits[i]) trans_n = int(trans_digits[i]) ref_n = int(ref_digits[i]) rec_n = int(rec_digits[i]) self.log.debug('Iteration bits ' + str(i) + ': ' + str(origin_n) + ' ' + str(trans_n) + ' ' + str(ref_n) + ' ' + str(rec_n)) self._origin_container[i][origin_n] += 1 self._ref_container[i][ref_n] += 1 self._rec_container[i][rec_n] += 1 self._trans_container[i][trans_n] += 1
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
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())) log.info("Trasmit:" + str(ntp_raw.transmit_timestamp())) log.info("Received:" + str(ntp_raw.receive_timestamp())) log.info("Experiment done. Total number of deviations=" + str(deviations) + ", number of errors=" + str(error_counter))