Exemplo n.º 1
0
def extcap_capture(interface, fifo, control_in, control_out, channel, tap):
    """Start the sniffer to capture packets"""
    # baudrate = detect_baudrate(interface)
    interface_port = str(interface).split(':')[0]
    interface_baudrate = str(interface).split(':')[1]

    with _StreamCloser(StreamOpen('u', interface_port, False, baudrate=int(interface_baudrate))) as stream, \
            WpanApi(stream, nodeid=DEFAULT_NODEID) as wpan_api:
        wpan_api.prop_set_value(SPINEL.PROP_PHY_ENABLED, 1)

    if sys.platform == 'win32':
        python_path = subprocess.Popen(
            'py -3 -c "import sys; print(sys.executable)"',
            stdout=subprocess.PIPE,
            shell=True,
        ).stdout.readline().decode().strip()
        sniffer_py = os.path.join(os.path.dirname(python_path), 'Scripts',
                                  'sniffer.py')
        cmd = ['python', sniffer_py]
    else:
        cmd = ['sniffer.py']
    cmd += [
        '-c', channel, '-u', interface_port, '--crc', '--rssi', '-b',
        interface_baudrate, '-o',
        str(fifo), '--is-fifo', '--use-host-timestamp'
    ]
    if tap:
        cmd.append('--tap')

    subprocess.Popen(cmd).wait()
Exemplo n.º 2
0
    def open(self):
        '''Opens transport for communication.'''
        self._stream = StreamOpen(self._stream_descriptor[0],
                                  self._stream_descriptor[1], False)
        # FIXME: remove node id from constructor after WpanAPI is refactored
        self._wpan = WpanApi(self._stream, 666)
        self._wpan.queue_register(SPINEL.HEADER_DEFAULT)
        self._wpan.queue_register(SPINEL.HEADER_ASYNC)
        self._wpan.callback_register(SPINEL.PROP_STREAM_NET,
                                     self._wpan_receive)

        if (self._config[NCPTransport.CFG_KEY_RESET]
            ) and not self._wpan.cmd_reset():
            raise Exception(
                'Failed to reset NCP. Please flash connectivity firmware.')

        logger.info('Attaching to the network')
        if (not self._attach_to_network()):
            logger.error("Failed to attach to the network")
            raise Exception('Unable to attach')

        self._ml_eid = ipaddress.ip_address(
            self._wpan.prop_get_value(SPINEL.PROP_IPV6_ML_ADDR))
        self._ml_prefix = self._wpan.prop_get_value(SPINEL.PROP_IPV6_ML_PREFIX)

        logger.info("Done")

        self.print_addresses()
Exemplo n.º 3
0
def main():
    """ Top-level main for sniffer host-side tool. """
    (options, remaining_args) = parse_args()

    if options.debug:
        CONFIG.debug_set_level(options.debug)

    # Set default stream to pipe
    stream_type = 'p'
    stream_descriptor = "../../examples/apps/ncp/ot-ncp-ftd "+options.nodeid

    if options.uart:
        stream_type = 'u'
        stream_descriptor = options.uart
    elif options.socket:
        stream_type = 's'
        stream_descriptor = options.socket
    elif options.pipe:
        stream_type = 'p'
        stream_descriptor = options.pipe
        if options.nodeid:
            stream_descriptor += " "+str(options.nodeid)
    else:
        if len(remaining_args) > 0:
            stream_descriptor = " ".join(remaining_args)

    stream = StreamOpen(stream_type, stream_descriptor, False)
    if stream is None: exit()
    wpan_api = WpanApi(stream, options.nodeid)
    sniffer_init(wpan_api, options)

    pcap = PcapCodec()
    hdr = pcap.encode_header()
    if options.hex:
        hdr = util.hexify_str(hdr)+"\n"
    sys.stdout.write(hdr)
    sys.stdout.flush()

    try:
        tid = SPINEL.HEADER_ASYNC
        prop_id = SPINEL.PROP_STREAM_RAW
        while True:
            result = wpan_api.queue_wait_for_prop(prop_id, tid)
            if result and result.prop == prop_id:
                length = wpan_api.parse_S(result.value)
                pkt = result.value[2:2+length]
                if options.ti_crc:
                    pkt = ti_crc(pkt)
                pkt = pcap.encode_frame(pkt)
                if options.hex:
                    pkt = util.hexify_str(pkt)+"\n"
                sys.stdout.write(pkt)
                sys.stdout.flush()

    except KeyboardInterrupt:
        pass

    if wpan_api:
        wpan_api.stream.close()
Exemplo n.º 4
0
def serialopen(interface, log_file):
    """
    Open serial to indentify OpenThread sniffer
    :param interface: string, eg: '/dev/ttyUSB0 - Zolertia Firefly platform', '/dev/ttyACM1 - nRF52840 OpenThread Device'
    """
    sys.stdout = log_file
    sys.stderr = log_file
    interface = str(interface).split()[0]
    baudrate = None

    for speed in COMMON_BAUDRATE:
        with _StreamCloser(StreamOpen('u', interface, False, baudrate=speed)) as stream, \
                WpanApi(stream, nodeid=DEFAULT_NODEID, timeout=0.1) as wpan_api:

            # result should not be None for both NCP and RCP
            result = wpan_api.prop_get_value(
                SPINEL.PROP_CAPS)  # confirm OpenThread Sniffer

            # check whether or not is OpenThread Sniffer
            if result is not None:
                baudrate = speed
                break

    if baudrate is not None:
        if sys.platform == 'win32':
            # Wireshark only shows the value of key `display`('OpenThread Sniffer').
            # Here intentionally appends interface in the end (e.g. 'OpenThread Sniffer: COM0').
            print('interface {value=%s:%s}{display=OpenThread Sniffer %s}' %
                  (interface, baudrate, interface),
                  file=sys.__stdout__,
                  flush=True)
        else:
            # On Linux or MacOS, wireshark will show the concatenation of the content of `display`
            # and `interface` by default (e.g. 'OpenThread Sniffer: /dev/ttyACM0').
            print('interface {value=%s:%s}{display=OpenThread Sniffer}' %
                  (interface, baudrate),
                  file=sys.__stdout__,
                  flush=True)
Exemplo n.º 5
0
def main():
    """ Top-level main for sniffer host-side tool. """
    (options, remaining_args) = parse_args()

    if options.debug:
        CONFIG.debug_set_level(options.debug)

    # Set default stream to pipe
    stream_type = 'p'
    stream_descriptor = "../../examples/apps/ncp/ot-ncp-ftd " + options.nodeid

    if options.uart:
        stream_type = 'u'
        stream_descriptor = options.uart
    elif options.socket:
        stream_type = 's'
        stream_descriptor = options.socket
    elif options.pipe:
        stream_type = 'p'
        stream_descriptor = options.pipe
        if options.nodeid:
            stream_descriptor += " " + str(options.nodeid)
    else:
        if len(remaining_args) > 0:
            stream_descriptor = " ".join(remaining_args)

    stream = StreamOpen(stream_type, stream_descriptor, False,
                        options.baudrate)
    if stream is None: exit()
    wpan_api = WpanApi(stream, options.nodeid)
    result = sniffer_init(wpan_api, options)
    if not result:
        sys.stderr.write("ERROR: failed to initialize sniffer\n")
        exit()
    else:
        sys.stderr.write("SUCCESS: sniffer initialized\nSniffing...\n")

    pcap = PcapCodec()
    hdr = pcap.encode_header()
    if options.hex:
        hdr = util.hexify_str(hdr) + "\n"
    sys.stdout.write(hdr)
    sys.stdout.flush()

    epoch = datetime(1970, 1, 1)
    timebase = datetime.utcnow() - epoch
    timebase_sec = timebase.days * 24 * 60 * 60 + timebase.seconds
    timebase_usec = timebase.microseconds

    try:
        tid = SPINEL.HEADER_ASYNC
        prop_id = SPINEL.PROP_STREAM_RAW
        while True:
            result = wpan_api.queue_wait_for_prop(prop_id, tid)
            if result and result.prop == prop_id:
                length = wpan_api.parse_S(result.value)
                pkt = result.value[2:2 + length]
                if options.crc:
                    pkt = crc(pkt)

                # metadata format (totally 17 bytes):
                # 0. RSSI(int8)
                # 1. Noise Floor(int8)
                # 2. Flags(uint16)
                # 3. PHY-specific data struct contains:
                #     3.0 Channel(uint8)
                #     3.1 LQI(uint8)
                #     3.2 Timestamp Msec(uint32)
                #     3.3 Timestamp Usec(uint16)
                # 4. Vendor data struct contains:
                #     4.0 Receive error(uint8)
                if len(result.value) == 2 + length + 17:
                    metadata = wpan_api.parse_fields(
                        result.value[2 + length:2 + length + 17],
                        "ccSt(CCLS)t(i)")

                    timestamp_usec = timebase_usec + metadata[3][
                        2] * 1000 + metadata[3][3]
                    timestamp_sec = timebase_sec + timestamp_usec / 1000000
                    timestamp_usec = timestamp_usec % 1000000

                    if options.rssi:
                        pkt = pkt[:-2] + chr(metadata[0] & 0xff) + chr(0x80)

                # Some old version NCP doesn't contain timestamp information in metadata
                else:
                    timestamp = datetime.utcnow() - epoch
                    timestamp_sec = timestamp.days * 24 * 60 * 60 + timestamp.seconds
                    timestamp_usec = timestamp.microseconds

                    if options.rssi:
                        pkt = pkt[:-2] + chr(127) + chr(0x80)
                        sys.stderr.write(
                            "WARNING: failed to display RSSI, please update the NCP version\n"
                        )

                pkt = pcap.encode_frame(pkt, timestamp_sec, timestamp_usec)
                if options.hex:
                    pkt = util.hexify_str(pkt) + "\n"
                sys.stdout.write(pkt)
                sys.stdout.flush()

    except KeyboardInterrupt:
        pass

    if wpan_api:
        wpan_api.stream.close()
Exemplo n.º 6
0
def main():
    """ Top-level main for sniffer host-side tool. """
    (options, remaining_args) = parse_args()

    if options.debug:
        CONFIG.debug_set_level(options.debug)

    if options.use_host_timestamp:
        print('WARNING: Using host timestamp, may be inaccurate',
              file=sys.stderr)

    # Set default stream to pipe
    stream_type = 'p'
    stream_descriptor = "../../examples/apps/ncp/ot-ncp-ftd " + options.nodeid

    if options.uart:
        stream_type = 'u'
        stream_descriptor = options.uart
    elif options.socket:
        stream_type = 's'
        stream_descriptor = options.socket
    elif options.pipe:
        stream_type = 'p'
        stream_descriptor = options.pipe
        if options.nodeid:
            stream_descriptor += " " + str(options.nodeid)
    else:
        if len(remaining_args) > 0:
            stream_descriptor = " ".join(remaining_args)

    stream = StreamOpen(stream_type, stream_descriptor, False,
                        options.baudrate, options.rtscts)
    if stream is None:
        exit()
    wpan_api = WpanApi(stream, options.nodeid)
    result = sniffer_init(wpan_api, options)
    if not result:
        sys.stderr.write("ERROR: failed to initialize sniffer\n")
        exit()
    else:
        sys.stderr.write("SUCCESS: sniffer initialized\nSniffing...\n")

    pcap = PcapCodec()
    hdr = pcap.encode_header(
        DLT_IEEE802_15_4_TAP if options.tap else DLT_IEEE802_15_4_WITHFCS)

    if options.hex:
        hdr = util.hexify_str(hdr) + "\n"

    if options.output:
        output = open(options.output, 'wb')
    elif hasattr(sys.stdout, 'buffer'):
        output = sys.stdout.buffer
    else:
        output = sys.stdout

    output.write(hdr)
    output.flush()

    if options.is_fifo:
        threading.Thread(target=check_fifo, args=(output, )).start()

    epoch = datetime(1970, 1, 1)
    timebase = datetime.utcnow() - epoch
    timebase_sec = timebase.days * 24 * 60 * 60 + timebase.seconds
    timebase_usec = timebase.microseconds

    try:
        tid = SPINEL.HEADER_ASYNC
        prop_id = SPINEL.PROP_STREAM_RAW
        while True:
            result = wpan_api.queue_wait_for_prop(prop_id, tid)
            if result and result.prop == prop_id:
                length = wpan_api.parse_S(result.value)
                pkt = result.value[2:2 + length]

                # metadata format (totally 19 bytes):
                # 0. RSSI(int8)
                # 1. Noise Floor(int8)
                # 2. Flags(uint16)
                # 3. PHY-specific data struct contains:
                #     3.0 Channel(uint8)
                #     3.1 LQI(uint8)
                #     3.2 Timestamp in microseconds(uint64)
                # 4. Vendor data struct contains:
                #     4.0 Receive error(uint8)
                if len(result.value) == 2 + length + 19:
                    metadata = wpan_api.parse_fields(
                        result.value[2 + length:2 + length + 19],
                        "ccSt(CCX)t(i)")

                    timestamp = metadata[3][2]
                    timestamp_sec = timestamp / 1000000
                    timestamp_usec = timestamp % 1000000

                # (deprecated) metadata format (totally 17 bytes):
                # 0. RSSI(int8)
                # 1. Noise Floor(int8)
                # 2. Flags(uint16)
                # 3. PHY-specific data struct contains:
                #     3.0 Channel(uint8)
                #     3.1 LQI(uint8)
                #     3.2 Timestamp Msec(uint32)
                #     3.3 Timestamp Usec(uint16)
                # 4. Vendor data struct contains:
                #     4.0 Receive error(uint8)
                elif len(result.value) == 2 + length + 17:
                    metadata = wpan_api.parse_fields(
                        result.value[2 + length:2 + length + 17],
                        "ccSt(CCLS)t(i)")

                    timestamp_usec = timebase_usec + metadata[3][
                        2] * 1000 + metadata[3][3]
                    timestamp_sec = timebase_sec + timestamp_usec / 1000000
                    timestamp_usec = timestamp_usec % 1000000

                # Some old version NCP doesn't contain timestamp information in metadata
                else:
                    timestamp = datetime.utcnow() - epoch
                    timestamp_sec = timestamp.days * 24 * 60 * 60 + timestamp.seconds
                    timestamp_usec = timestamp.microseconds

                    if options.rssi:
                        sys.stderr.write(
                            "WARNING: failed to display RSSI, please update the NCP version\n"
                        )

                if options.use_host_timestamp:
                    timestamp = round(time.time() * 1000000)
                    timestamp_sec = timestamp // 1000000
                    timestamp_usec = timestamp % 1000000

                pkt = pcap.encode_frame(pkt, int(timestamp_sec),
                                        timestamp_usec, options.rssi,
                                        options.crc, metadata)

                if options.hex:
                    pkt = util.hexify_str(pkt) + "\n"
                output.write(pkt)
                output.flush()

    except KeyboardInterrupt:
        pass

    if wpan_api:
        wpan_api.stream.close()

    output.close()
Exemplo n.º 7
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('rcp', type=str, help='path to rcp executable')

    args = parser.parse_args()

    stream = StreamOpen('p', f'{args.rcp} 1', False, 115200, False)
    wpan_api = WpanApi(stream, 1)

    assert wpan_api.prop_set_value(SPINEL.PROP_PHY_ENABLED, 1) == 1

    ext_addr = b'\x00\x11\x22\x33\x44\x55\x66\x77'

    assert wpan_api.prop_set_value(SPINEL.PROP_PHY_CHAN, 17) == 17
    assert wpan_api.prop_set_value(SPINEL.PROP_MAC_15_4_SADDR, 0x1234,
                                   'H') == 0x1234
    assert wpan_api.prop_set_value(SPINEL.PROP_MAC_15_4_LADDR, ext_addr,
                                   '8s') == ext_addr
    assert wpan_api.prop_set_value(SPINEL.PROP_MAC_SRC_MATCH_ENABLED, 1) == 1

    while wpan_api.prop_insert_value(
            SPINEL.PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, ext_addr,
            '8s') == ext_addr:
        ext_addr = (int.from_bytes(ext_addr, 'little') + 1).to_bytes(
            8, 'little')

    short_addr = 0x2345
    while wpan_api.prop_insert_value(SPINEL.PROP_MAC_SRC_MATCH_SHORT_ADDRESSES,
                                     short_addr, 'H') == short_addr:
        short_addr += 1

    assert wpan_api.prop_set_value(SPINEL.PROP_MAC_FILTER_MODE,
                                   SPINEL.MAC_FILTER_MODE_PROMISCUOUS) in {
                                       SPINEL.MAC_FILTER_MODE_PROMISCUOUS,
                                       SPINEL.MAC_FILTER_MODE_MONITOR,
                                   }
    assert wpan_api.prop_set_value(SPINEL.PROP_MAC_RAW_STREAM_ENABLED, 1) == 1

    assert wpan_api.prop_set_value(SPINEL.PROP_MAC_SCAN_MASK, 11) == [11]
    assert wpan_api.prop_set_value(
        SPINEL.PROP_MAC_SCAN_STATE,
        SPINEL.SCAN_STATE_ENERGY) == SPINEL.SCAN_STATE_ENERGY

    wpan_api.cmd_send(SPINEL.CMD_RESET)

    assert wpan_api.prop_get_value(SPINEL.PROP_PHY_ENABLED) == 0
    assert wpan_api.prop_set_value(SPINEL.PROP_PHY_ENABLED, 1) == 1

    assert wpan_api.prop_get_value(SPINEL.PROP_PHY_CHAN) == 11
    assert wpan_api.prop_get_value(SPINEL.PROP_MAC_15_4_SADDR) == 0xfffe
    assert wpan_api.prop_get_value(SPINEL.PROP_MAC_15_4_LADDR) == b'\x00' * 8

    assert wpan_api.prop_get_value(SPINEL.PROP_MAC_SRC_MATCH_ENABLED) == 0
    assert wpan_api.prop_set_value(SPINEL.PROP_MAC_SRC_MATCH_ENABLED, 1) == 1
    assert wpan_api.prop_insert_value(
        SPINEL.PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, ext_addr,
        '8s') == ext_addr
    assert wpan_api.prop_insert_value(
        SPINEL.PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, short_addr,
        'H') == short_addr

    assert wpan_api.prop_get_value(
        SPINEL.PROP_MAC_FILTER_MODE) == SPINEL.MAC_FILTER_MDOE_NORMAL
    assert wpan_api.prop_get_value(SPINEL.PROP_MAC_RAW_STREAM_ENABLED) == 0
    assert wpan_api.prop_get_value(
        SPINEL.PROP_MAC_SCAN_STATE) == SPINEL.SCAN_STATE_IDLE