コード例 #1
0
ファイル: streamserver.py プロジェクト: zhihuishuwp/emma
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
コード例 #2
0
    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)
コード例 #3
0
ファイル: emcap.py プロジェクト: zhihuishuwp/emma
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...")