From 67ffe376c2e1e87efc417a759da595cb6bc6b280 Mon Sep 17 00:00:00 2001 From: "MSI\\Jackson Silver" Date: Thu, 17 Oct 2024 13:08:08 -0400 Subject: [PATCH 1/2] init --- examples/dis-logger/app.py | 129 +++++++++++++++++++++++++++++++++++ examples/dis-logger/main.py | 130 ++++++++++++++++++++++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 examples/dis-logger/app.py create mode 100644 examples/dis-logger/main.py diff --git a/examples/dis-logger/app.py b/examples/dis-logger/app.py new file mode 100644 index 0000000..4458b15 --- /dev/null +++ b/examples/dis-logger/app.py @@ -0,0 +1,129 @@ +import tkinter as tk +from tkinter import ttk +from datetime import datetime +import threading +import sqlite3 + +lock = threading.Lock() + +connection = sqlite3.connect('dis_messages_database.db') + +class App(tk.Tk): + def __init__(self): + super().__init__() + self.title('DIS Logger') + + table = ttk.Treeview(self, columns=("num", "time", "type", "src", "dst", "ent_id", "ent_marking"), show = 'headings') + self.table = table + + # Set heading text + table.heading('num', text='No.') + table.heading('time', text='Time') + table.heading('type', text='Message Type') + table.heading('src', text='Source') + table.heading('dst', text='Destination') + table.heading('ent_id', text='Entity ID') + table.heading('ent_marking', text='Entity Marking') + + # Set column widths + table.column('num', width=50) + table.column('ent_id', width=25) + + table.pack() + table.bind("", self.on_table_click) + + # Set message display + message_display = tk.Text(self, height=10, width=60) + self.message_display = message_display + message_display.pack(pady=10) + message_display.insert(tk.END, "Click on a table entry to view more") + + # Setup database + cursor = connection.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") + tables = cursor.fetchall() + + for table_name in tables: + cursor.execute(f"DROP TABLE IF EXISTS {table_name[0]};") + + cursor.execute(''' + CREATE TABLE IF NOT EXISTS messages ( + number INT PRIMARY KEY, + time VARCHAR(255), + type VARCHAR(255), + source_address VARCHAR(255), + source_port VARCHAR(255), + destination_address VARCHAR(255), + destination_port VARCHAR(255), + entity_id INT, + entity_marking VARCHAR(255), + latitude FLOAT, + longitude FLOAT, + altitude FLOAT + ) + ''') + + connection.commit() + cursor.close() + + + def on_table_click(self, event): + item_id = self.table.identify_row(event.y) + if item_id: + item_values = self.table.item(item_id, 'values') + item_number = item_values[0] + self.message_display.insert(tk.END, item_number) + + # Get entry based on number in table + connection = sqlite3.connect('dis_messages_database.db') + cursor = connection.cursor() + cursor.execute("SELECT * FROM messages WHERE number=?", (item_number,)) + entry = cursor.fetchall()[0] + cursor.close() + + # Form message to be displayed + message = ("Received {}".format(entry[2]) + " at {}\n".format(entry[1]) + + " Sending Addr. : {}\n".format(entry[3]) + + " Sending Port : {}\n".format(entry[4]) + + " Destination Addr.: {}\n".format(entry[5]) + + " Destination Port : {}\n".format(entry[6]) + + " Entity Id : {}\n".format(entry[7]) + + " Entity Marking : {}\n".format(entry[8]) + + " Latitude : {:.5f} degrees\n".format(entry[9]) + + " Longitude : {:.5f} degrees\n".format(entry[10]) + + " Altitude : {:.0f} meters\n".format(entry[11]) + ) + + # Show message in message display + self.message_display.delete(1.0, tk.END) + self.message_display.insert(tk.END, message) + + + def add_entry(self, entry): + lock.acquire() + + # Get message info from entry + num = len(self.table.get_children()) + time = datetime.now() + type = entry.type + src_addr = entry.src_addr + dst_addr = entry.dst_addr + ent_id = entry.entityID + ent_marking = entry.marking + latitude = entry.latitude + longitude = entry.longitude + altitude = entry.altitude + + # Add message to table + data = (num, time, type, src_addr, dst_addr, ent_id, ent_marking) + self.table.insert(parent='', index=0, values = data) + + # Add message to database + connection = sqlite3.connect('dis_messages_database.db') + cursor = connection.cursor() + db_entry = (num, time, type, src_addr, dst_addr, ent_id, ent_marking, latitude, longitude, altitude) + cursor.execute('INSERT INTO messages (number, time, type, source_address, destination_address, entity_id, entity_marking, latitude, longitude, altitude) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', db_entry) + connection.commit() + cursor.close() + + lock.release() \ No newline at end of file diff --git a/examples/dis-logger/main.py b/examples/dis-logger/main.py new file mode 100644 index 0000000..7d0bf52 --- /dev/null +++ b/examples/dis-logger/main.py @@ -0,0 +1,130 @@ +from scapy.all import sniff +import threading +from app import * + +from opendis.dis7 import * +from opendis.RangeCoordinates import * +from opendis.PduFactory import createPdu + +app = None +gps = GPS() +quitEvent = threading.Event() + +class DISMessageInfo: + def __init__(self, pdu, src_addr, dst_addr, src_port, dst_port): + self.src_addr = src_addr + self.dst_addr = dst_addr + self.src_port = src_port + self.dst_port = dst_port + + pduTypeName = pdu.__class__.__name__ + self.type = pduTypeName + self.type_number = pdu.pduType + + # PduTypeDecoders.EntityStatePdu is type 1 + if pdu.pduType == 1: + loc = (pdu.entityLocation.x, + pdu.entityLocation.y, + pdu.entityLocation.z, + pdu.entityOrientation.psi, + pdu.entityOrientation.theta, + pdu.entityOrientation.phi + ) + try: + body = gps.ecef2llarpy(*loc) + except: + body = [0,0,0] + + self.latitude = rad2deg(body[0]) + self.longitude = rad2deg(body[1]) + self.altitude = body[2] + + marking_asci = list(pdu.marking.characters) + marking_string = "" + + print(marking_asci) + for i in marking_asci: + try: + if i == 0: + break + + marking_string += chr(i) + except Exception: + break + + self.entityID = pdu.entityID.entityID + self.marking = marking_string + + def __str__(self): + if self.type_number == 1: + return ("Received {}\n".format(self.type) + + " Sending Addr. : {}\n".format(self.src_addr) + + " Sending Port : {}\n".format(self.src_port) + + " Destination Addr.: {}\n".format(self.dst_addr) + + " Destination Port : {}\n".format(self.dst_port) + + " Entity Id : {}\n".format(self.entityID) + + " Entity Marking : {}\n".format(self.marking) + + " Latitude : {:.2f} degrees\n".format(self.latitude) + + " Longitude : {:.2f} degrees\n".format(self.longitude) + + " Altitude : {:.0f} meters\n".format(self.altitude) + ) + else: + return "" + + +def process_packet(packet): + """ + function that takes in packet, processes it into a DIS UDP message, and prints out data if + its of EntityStatePdu type. + """ + + # Check if packet contains UDP layer + if packet.haslayer('UDP'): + udp_layer = packet['UDP'] + src_port = udp_layer.sport + dst_port = udp_layer.dport + + try: + ip_layer = packet['IP'] + src_addr = ip_layer.src + dst_addr = ip_layer.dst + except: + src_addr = "None" + dst_addr = "None" + + # DIS traffic only on port 3000 + if dst_port == 3000: + data = bytes(udp_layer.payload) + + pdu = createPdu(data) + message_info = DISMessageInfo(pdu, src_addr, dst_addr, src_port, dst_port) + if app != None: + app.add_entry(message_info) + print(message_info) + + +def stop_sniffing(x): + return quitEvent.is_set() + + +def sniff_for_traffic(): + print("Listening for DIS traffic...") + sniff(filter="udp and multicast", prn=process_packet, stop_filter=stop_sniffing) + + +def main(): + global app + sniff_thread = threading.Thread(target=sniff_for_traffic) + sniff_thread.start() + + try: + app = App() + app.mainloop() + except: + quitEvent.set() + + quitEvent.set() + sniff_thread.join() + +if __name__=="__main__": + main() \ No newline at end of file From 238d418846020eb0ac7cc910423b2ea108ebb112 Mon Sep 17 00:00:00 2001 From: Leif Gruenwoldt Date: Sat, 29 Nov 2025 17:25:29 -0500 Subject: [PATCH 2/2] Update examples/dis-logger/main.py Co-authored-by: JS Ng --- examples/dis-logger/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/dis-logger/main.py b/examples/dis-logger/main.py index 7d0bf52..8afec9d 100644 --- a/examples/dis-logger/main.py +++ b/examples/dis-logger/main.py @@ -52,7 +52,7 @@ def __init__(self, pdu, src_addr, dst_addr, src_port, dst_port): except Exception: break - self.entityID = pdu.entityID.entityID + self.entityID = pdu.entityID.entityNumber self.marking = marking_string def __str__(self):