Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 52 additions & 24 deletions modules/test/ntp/python/src/ntp_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"""NTP test module"""
from test_module import TestModule
from scapy.all import rdpcap, IP, IPv6, NTP, UDP, Ether
from datetime import datetime
import os
from collections import defaultdict

LOG_NAME = 'test_ntp'
MODULE_REPORT_FILE_NAME = 'ntp_report.html'
Expand Down Expand Up @@ -69,6 +69,33 @@ def generate_module_report(self):
total_responses = sum(1 for row in ntp_table_data
if row['Type'] == 'Server')

# Initialize a dictionary to store timestamps for each unique combination
timestamps = defaultdict(list)

# Collect timestamps for each unique combination
for row in ntp_table_data:
# Add the timestamp to the corresponding combination
key = (row['Source'], row['Destination'], row['Type'], row['Version'])
timestamps[key].append(row['Timestamp'])

# Calculate the average time between requests for each unique combination
average_time_between_requests = {}

for key, times in timestamps.items():
# Sort the timestamps
times.sort()

# Calculate the time differences between consecutive timestamps
time_diffs = [t2 - t1 for t1, t2 in zip(times[:-1], times[1:])]

# Calculate the average of the time differences
if time_diffs:
avg_diff = sum(time_diffs) / len(time_diffs)
else:
avg_diff = 0 # one timestamp, the average difference is 0

average_time_between_requests[key] = avg_diff

# Add summary table
html_content += (f'''
<table class="module-summary">
Expand All @@ -92,7 +119,6 @@ def generate_module_report(self):
''')

if total_requests + total_responses > 0:

table_content = '''
<table class="module-data">
<thead>
Expand All @@ -101,37 +127,39 @@ def generate_module_report(self):
<th>Destination</th>
<th>Type</th>
<th>Version</th>
<th>Timestamp</th>
<th>Count</th>
<th>Sync Request Average</th>
</tr>
</thead>
<tbody>'''

for row in ntp_table_data:

# Timestamp of the NTP packet
dt_object = datetime.utcfromtimestamp(row['Timestamp'])
# Generate the HTML table with the count column
for (src, dst, typ,
version), avg_diff in average_time_between_requests.items():
cnt = len(timestamps[(src, dst, typ, version)])

# Extract milliseconds from the fractional part of the timestamp
milliseconds = int((row['Timestamp'] % 1) * 1000)

# Format the datetime object with milliseconds
formatted_time = dt_object.strftime(
'%b %d, %Y %H:%M:%S.') + f'{milliseconds:03d}'
# Sync Average only applies to client requests
if 'Client' in typ:
# Convert avg_diff to seconds and format it
avg_diff_seconds = avg_diff
avg_formatted_time = f'{avg_diff_seconds:.3f} seconds'
else:
avg_formatted_time = 'N/A'

table_content += (f'''
table_content += f'''
<tr>
<td>{row['Source']}</td>
<td>{row['Destination']}</td>
<td>{row['Type']}</td>
<td>{row['Version']}</td>
<td>{formatted_time}</td>
</tr>''')
<td>{src}</td>
<td>{dst}</td>
<td>{typ}</td>
<td>{version}</td>
<td>{cnt}</td>
<td>{avg_formatted_time}</td>
</tr>'''

table_content += '''
</tbody>
</table>
'''

html_content += table_content

else:
Expand Down Expand Up @@ -159,8 +187,8 @@ def extract_ntp_data(self):

# Read the pcap files
packets = (rdpcap(self.startup_capture_file) +
rdpcap(self.monitor_capture_file) +
rdpcap(self.ntp_server_capture_file))
rdpcap(self.monitor_capture_file) +
rdpcap(self.ntp_server_capture_file))

# Iterate through NTP packets
for packet in packets:
Expand Down Expand Up @@ -283,7 +311,7 @@ def _ntp_network_ntp_dhcp(self):
'server and non-DHCP provided server')
elif ntp_to_remote:
result = ('Feature Not Detected',
'Device sent NTP request to non-DHCP provided server')
'Device sent NTP request to non-DHCP provided server')
elif ntp_to_local:
result = True, 'Device sent NTP request to DHCP provided server'

Expand Down
Loading