class StreamServer(): def __init__(self, conf): self.conf = conf self.queue = Queue() if self.conf.online: settings = configparser.RawConfigParser() settings.read('settings.conf') interface = settings.get("Datasets", "stream_interface") ip_address = get_ip_address(interface) addr_tuple = (ip_address, 3885) self.server = SocketWrapper( socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM), addr_tuple, self._cb_server) self.server.start() print("Listening for sample streams at %s" % str(addr_tuple)) def _cb_server(self, client_socket, client_address, data): if len(data) < 5: # Not enough for TLV return 0 else: pkt_type, payload_len = struct.unpack(">BI", data[0:5]) payload = data[5:] if len(payload) < payload_len: return 0 # Not enough for payload else: # Depickle and add to queue # TODO: Check for correctness. EMcap is Python2 (because it needs to) # use GNU Radio. Therefore the pickling format is different, which # we need to make sure doesn't cause any differences. trace_set = pickle.loads(payload, encoding='latin1', fix_imports=True) logger.debug("Stream: got %d traces" % len(trace_set.traces)) self.queue.put(trace_set) return payload_len + 5
app = QApplication(sys.argv) main_window = QWidget() main_window.setWindowTitle('lab 1 task 4') main_window.setLayout(QVBoxLayout()) server_ip = IPWidget("Server IP:", main_window) receiver_ip = IPWidget("Receiver IP:", main_window) instance_panel = QWidget() instance_panel.setLayout(QHBoxLayout()) port_field = QLineEdit() server_socket = SocketWrapper(server_ip, receiver_ip, port_field) server_socket.start() conn_panel = QWidget() conn_panel.setLayout(QHBoxLayout()) conn_btn = QPushButton("Connect") conn_btn.clicked.connect(server_socket.sock_init) disconnect_btn = QPushButton("Disconnect") disconnect_btn.clicked.connect(server_socket.close) user_list_btn = QPushButton("User list") user_list_btn.clicked.connect(lambda x: server_socket.msg_send("", True)) status_label = QLabel("not connected") server_socket.conn_status.connect(status_label.setText)
class EMCap(): def __init__(self, cap_kwargs={}, kwargs={}, ctrl_socket_type=None): # Set up data socket self.data_socket = SocketWrapper(socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM), ('127.0.0.1', 3884), self.cb_data) self.online = kwargs['online'] # Set up sockets self.ctrl_socket_type = ctrl_socket_type if ctrl_socket_type == CtrlType.DOMAIN: unix_domain_socket = '/tmp/emma.socket' self.clear_domain_socket(unix_domain_socket) self.ctrl_socket = SocketWrapper(socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM), unix_domain_socket, self.cb_ctrl) elif ctrl_socket_type == CtrlType.UDP: self.ctrl_socket = SocketWrapper(socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM), ('172.18.15.21', 3884), self.cb_ctrl) elif ctrl_socket_type == CtrlType.SERIAL: self.ctrl_socket = TTYWrapper("/dev/ttyUSB0", self.cb_ctrl) else: logger.error("Unknown ctrl_socket_type") exit(1) if not self.online is None: try: self.emma_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.emma_client.connect((self.online, 3885)) except Exception as e: print(e) exit(1) self.sdr = SDR(**cap_kwargs) self.cap_kwargs = cap_kwargs self.kwargs = kwargs self.store = False self.stored_plaintext = [] self.stored_key = [] self.stored_data = [] self.trace_set = [] self.plaintexts = [] self.keys = [] self.online_counter = 0 self.limit_counter = 0 self.limit = kwargs['limit'] #self.manifest = kwargs['manifest'] self.compress = kwargs['compress'] if self.sdr.hw == 'usrp': self.wait_num_chunks = 0 else: self.wait_num_chunks = 50 # Bug in rtl-sdr? self.global_meta = { "core:datatype": "cf32_le", "core:version": "0.0.1", "core:license": "CC0", "core:hw": self.sdr.hw, "core:sample_rate": self.sdr.samp_rate, "core:author": "Pieter Robyns" } self.capture_meta = { "core:sample_start": 0, "core:frequency": self.sdr.freq, "core:datetime": str(datetime.utcnow()), } def clear_domain_socket(self, address): try: os.unlink(address) except OSError: if os.path.exists(address): raise def cb_timeout(self): logger.warning("Timeout on capture, skipping...") self.sdr.stop() def cb_data(self, client_socket, client_address, data): self.stored_data.append(data) return len(data) def cb_ctrl(self, client_socket, client_address, data): logger.log(logging.NOTSET, "Control packet: %s" % binary_to_hex(data)) if len(data) < 5: # Not enough for TLV return 0 else: pkt_type, payload_len = struct.unpack(">BI", data[0:5]) payload = data[5:] if len(payload) < payload_len: return 0 # Not enough for payload else: self.process_ctrl_packet(pkt_type, payload) # Send ack if self.ctrl_socket_type == CtrlType.SERIAL: client_socket.write(b"k") else: client_socket.sendall("k") return payload_len + 5 def parse_ies(self, payload): while len(payload) >= 5: # Extract IE header ie_type, ie_len = struct.unpack(">BI", payload[0:5]) payload = payload[5:] # Extract IE data ie = payload[0:ie_len] payload = payload[ie_len:] logger.debug("IE type %d of len %d: %s" % (ie_type, ie_len, binary_to_hex(ie))) # Determine what to do with IE if ie_type == InformationElementType.PLAINTEXT: self.stored_plaintext = [ord(c) for c in ie] elif ie_type == InformationElementType.KEY: self.stored_key = [ord(c) for c in ie] else: logger.warning("Unknown IE type: %d" % ie_type) def process_ctrl_packet(self, pkt_type, payload): if pkt_type == CtrlPacketType.SIGNAL_START: logger.debug("Starting for payload: %s" % binary_to_hex(payload)) self.parse_ies(payload) self.sdr.start() # Spinlock until data timeout = 3 current_time = 0.0 while len(self.stored_data) <= self.wait_num_chunks: sleep(0.0001) current_time += 0.0001 if current_time >= timeout: logger.warning("Timeout while waiting for data. Did the SDR crash? Reinstantiating...") del self.sdr self.data_socket.socket.close() self.data_socket = SocketWrapper(socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM), ('127.0.0.1', 3884), self.cb_data) self.data_socket.start() self.sdr = SDR(**self.cap_kwargs) self.process_ctrl_packet(pkt_type, payload) elif pkt_type == CtrlPacketType.SIGNAL_END: # self.sdr.sdr_source.stop() self.sdr.stop() self.sdr.wait() logger.debug("Stopped after receiving %d chunks" % len(self.stored_data)) #sleep(0.5) #logger.debug("After sleep we have %d chunks" % len(self.stored_data)) # Successful capture (no errors or timeouts) if len(self.stored_data) > 0: # We have more than 1 chunk # Data to file np_data = np.fromstring(b"".join(self.stored_data), dtype=np.complex64) self.trace_set.append(np_data) self.plaintexts.append(self.stored_plaintext) self.keys.append(self.stored_key) if len(self.trace_set) >= self.kwargs['traces_per_set']: assert(len(self.trace_set) == len(self.plaintexts)) assert(len(self.trace_set) == len(self.keys)) np_trace_set = np.array(self.trace_set) np_plaintexts = np.array(self.plaintexts, dtype=np.uint8) np_keys = np.array(self.keys, dtype=np.uint8) if not self.online is None: # Stream online ts = TraceSet(name="online %d" % self.online_counter, traces=np_trace_set, plaintexts=np_plaintexts, ciphertexts=None, keys=np_keys) logger.info("Pickling") ts_p = pickle.dumps(ts) logger.info("Size is %d" % len(ts_p)) stream_payload = ts_p stream_payload_len = len(stream_payload) logger.info("Streaming trace set of %d bytes to server" % stream_payload_len) stream_hdr = struct.pack(">BI", 0, stream_payload_len) self.emma_client.send(stream_hdr + stream_payload) self.online_counter += 1 else: # Save to disk if not self.kwargs['dry']: # Write metadata to sigmf file # if sigmf #with open(test_meta_path, 'w') as f: # test_sigmf = SigMFFile(data_file=test_data_path, global_info=copy.deepcopy(self.global_meta)) # test_sigmf.add_capture(0, metadata=capture_meta) # test_sigmf.dump(f, pretty=True) # elif chipwhisperer: logger.info("Dumping %d traces to file" % len(self.trace_set)) filename = str(datetime.utcnow()).replace(" ","_").replace(".","_") output_dir = self.kwargs['output_dir'] np.save(os.path.join(output_dir, "%s_traces.npy" % filename), np_trace_set) # TODO abstract this in trace_set class np.save(os.path.join(output_dir, "%s_textin.npy" % filename), np_plaintexts) np.save(os.path.join(output_dir, "%s_knownkey.npy" % filename), np_keys) if self.compress: logger.info("Calling emcap-compress...") subprocess.call(['/usr/bin/python', 'emcap-compress.py', os.path.join(output_dir, "%s_traces.npy" % filename)]) self.limit_counter += len(self.trace_set) if self.limit_counter >= self.limit: print("Done") exit(0) # Clear results self.trace_set = [] self.plaintexts = [] self.keys = [] # Clear self.stored_data = [] self.stored_plaintext = [] def capture(self, to_skip=0, timeout=1.0): # Start listening for signals self.data_socket.start() self.ctrl_socket.start() # Wait until supplicant signals end of acquisition while self.ctrl_socket.is_alive(): self.ctrl_socket.join(timeout=1.0) logging.info("Supplicant disconnected on control channel. Stopping...")