@@ -101,21 +101,36 @@ def label_packets():
101101 400: Error if required fields are missing or packet decoding fails.
102102 500: Error if database insertion fails.
103103 """
104+ raw_packets = []
105+ capture_times = []
106+ capture_lengths = []
107+
104108 data = request .get_json ()
105109 app .logger .info ("Received POST data:" , json .dumps (data , indent = 4 ))
106110 required_keys = ["packets" , "prolific_id" , "mac_address" , "device_name" , "activity_label" , "start_time" , "end_time" ]
107111 if not data or not all (key in data for key in required_keys ):
108112 app .logger .warning ("Missing required fields in POST data" )
109113 return jsonify ({"error" : "Missing required fields" }), 400
114+
115+ if not is_prolific_id_valid (data ["prolific_id" ]):
116+ app .logger .warning ("Invalid Prolific ID received" )
117+ return jsonify ({"error" : "Prolific ID is invalid" }), 500
118+
110119 try :
111- raw_packets = [base64 .b64decode (pkt ) for pkt in data ["packets" ]]
120+ for pkt_metadata in data ["packets" ]:
121+ # Validate essential keys are present
122+ if not isinstance (pkt_metadata , dict ) or 'time' not in pkt_metadata or 'raw_data' not in pkt_metadata :
123+ app .logger .error ("Packet object missing 'time' or 'raw_data' key." )
124+ return jsonify ({"error" : "Packet metadata structure is invalid" }), 400
125+
126+ raw_data_bytes = base64 .b64decode (pkt_metadata ["raw_data" ])
127+ raw_packets .append (raw_data_bytes )
128+ capture_times .append (float (pkt_metadata ["time" ]))
129+ capture_lengths .append (len (raw_data_bytes ))
112130 except Exception as e :
113131 app .logger .warning (f"Packet decoding occurred for collection '{ data ['prolific_id' ]} ': { e } " )
114132 return jsonify ({"error" : "Packet decoding failed" }), 400
115133
116- if not is_prolific_id_valid (data ["prolific_id" ]):
117- app .logger .warning ("Invalid Prolific ID received" )
118- return jsonify ({"error" : "Prolific ID is invalid" }), 500
119134 folder_path : str = os .path .join (str (data ["prolific_id" ]), str (data ["device_name" ]), str (data ["activity_label" ]))
120135 fullpath = os .path .normpath (os .path .join (packet_root_dir , folder_path ))
121136 if not fullpath .startswith (packet_root_dir ):
@@ -130,7 +145,9 @@ def label_packets():
130145 "activity_label" : data ["activity_label" ],
131146 "start_time" : int (data ["start_time" ]),
132147 "end_time" : int (data ["end_time" ]),
133- "raw_packets" : raw_packets
148+ "raw_packets" : raw_packets ,
149+ "capture_times" : capture_times ,
150+ "capture_lengths" : capture_lengths
134151 }
135152 try :
136153 prolific_user_packets_collected .insert_one (doc )
@@ -142,7 +159,7 @@ def label_packets():
142159 os .makedirs (fullpath , exist_ok = True )
143160 pcap_file_name : str = make_pcap_filename (int (data ["start_time" ]), int (data ["end_time" ]))
144161 pcap_name : str = os .path .join (fullpath , pcap_file_name )
145- save_packets_to_pcap (raw_packets , pcap_name )
162+ save_packets_to_pcap (raw_packets , capture_times , pcap_name )
146163 except Exception as e :
147164 # If file saving fails, return a 500 but note that the DB save succeeded
148165 app .logger .warning (f"PCAP File Save FAILED for ID: { e } " )
@@ -173,22 +190,27 @@ def make_pcap_filename(start_time: int, end_time: int) -> str:
173190 return filename
174191
175192
176- def save_packets_to_pcap (raw_packets : list , filename = "output.pcap" ):
193+ def save_packets_to_pcap (raw_packets : list , capture_times : list , filename = "output.pcap" ):
177194 """
178195 Saves a list of raw packet bytes to a pcap file.
179196
180197 Args:
181198 raw_packets (list): List of bytes objects representing raw packets.
199+ capture_times (list): The epoch time of each packet when it was captured by IoT Inspector.
182200 filename (str): Output pcap file name.
183201 """
184202 scapy_packets = []
185- for pkt_bytes in raw_packets :
203+ for i , pkt_bytes in enumerate ( raw_packets ) :
186204 try :
187205 pkt = Ether (pkt_bytes )
188206 if pkt .__class__ .__name__ == "Raw" :
189207 pkt = IP (pkt_bytes )
190208 except Exception :
191209 pkt = IP (pkt_bytes )
210+
211+ # CRITICAL STEP: Assign the supplied original capture time
212+ # This is guaranteed to be correct for ALL packets.
213+ pkt .time = capture_times [i ]
192214 scapy_packets .append (pkt )
193215 wrpcap (filename , scapy_packets )
194216
0 commit comments