Пример #1
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()
Пример #2
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]
                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()
Пример #3
0
    def parse_rx(self, pkt):
        if not pkt:
            return

        if CONFIG.DEBUG_LOG_SERIAL:
            msg = "RX Pay: (%i) %s " % (
                len(pkt), str(map(util.hexify_int, pkt)))
            logging.debug(msg)

        length = len(pkt) - 2
        if length < 0:
            return

        spkt = "".join(map(chr, pkt))

        tid = self.parse_C(spkt[:1])
        (cmd_id, cmd_length) = self.parse_i(spkt[1:])
        pay_start = cmd_length + 1
        payload = spkt[pay_start:]

        try:
            handler = SPINEL_COMMAND_DISPATCH[cmd_id]
            cmd_name = handler.__name__
            handler(self, payload, tid)

        except Exception as _ex:
            print(traceback.format_exc())
            cmd_name = "CB_Unknown"
            logging.info("\n%s (%i): ", cmd_name, cmd_id)

        if CONFIG.DEBUG_CMD_RESPONSE:
            logging.info("\n%s (%i): ", cmd_name, cmd_id)
            logging.info("===> %s", util.hexify_str(payload))
Пример #4
0
 def write(self, packet):
     #global gWpanApi
     #gWpanApi.ip_send(packet)
     # os.write(self.fd, packet)    # Loop back
     if CONFIG.DEBUG_TUN:
         logging.debug("\nTUN: TX (" + str(len(packet)) + ") " +
                       util.hexify_str(packet))
Пример #5
0
 def write(self, packet):
     #global gWpanApi
     #gWpanApi.ip_send(packet)
     # os.write(self.fd, packet)    # Loop back
     if CONFIG.DEBUG_TUN:
         logging.debug("\nTUN: TX (" + str(len(packet)) +
                       ") " + util.hexify_str(packet))
Пример #6
0
    def handle_prop(self, wpan_api, name, payload, tid):
        (prop_id, prop_len) = self.parse_i(payload)

        if prop_id in SPINEL_PROP_DISPATCH:
            handler = SPINEL_PROP_DISPATCH[prop_id]
            prop_name = handler.__name__

            # Skip any VALUE_INSERTED(CHILD_TABLE) or VALUE_REMOVED(CHILD_TABLE)
            if prop_id == SPINEL.PROP_THREAD_CHILD_TABLE:
                if name in ["INSERTED", "REMOVED"]:
                    return

            prop_value = handler(wpan_api, payload[prop_len:])

            if CONFIG.DEBUG_LOG_PROP:

                # Generic output
                if isinstance(prop_value, str):
                    prop_value_str = util.hexify_str(prop_value)
                    CONFIG.LOGGER.debug("PROP_VALUE_%s [tid=%d]: %s = %s",
                                        name, (tid & 0xF), prop_name,
                                        prop_value_str)
                else:
                    prop_value_str = str(prop_value)

                    CONFIG.LOGGER.debug("PROP_VALUE_%s [tid=%d]: %s = %s",
                                        name, (tid & 0xF), prop_name,
                                        prop_value_str)

                # Extend output for certain properties.
                if prop_id == SPINEL.PROP_LAST_STATUS:
                    CONFIG.LOGGER.debug(SPINEL_LAST_STATUS_MAP[prop_value])

            if CONFIG.DEBUG_LOG_PKT:
                if ((prop_id == SPINEL.PROP_STREAM_NET)
                        or (prop_id == SPINEL.PROP_STREAM_NET_INSECURE)):
                    CONFIG.LOGGER.debug("PROP_VALUE_" + name + ": " +
                                        prop_name)

                elif prop_id == SPINEL.PROP_STREAM_DEBUG:
                    CONFIG.LOGGER.debug("DEBUG: " + str(prop_value))

            if wpan_api:
                wpan_api.queue_add(prop_id, prop_value, tid)
            else:
                print("no wpan_api")
        elif CONFIG.DEBUG_LOG_PROP:
            prop_name = "Property Unknown"
            CONFIG.LOGGER.info("\n%s (%i): ", prop_name, prop_id)
Пример #7
0
    def __run_tun_thread(self):
        while self.fd:
            try:
                ready_fd = select([self.fd], [], [])[0][0]
                if ready_fd == self.fd:
                    packet = os.read(self.fd, 4000)
                    if CONFIG.DEBUG_TUN:
                        logging.debug("\nTUN: RX (" + str(len(packet)) + ") " +
                                      util.hexify_str(packet))
                    self.write(packet)
            except:
                print traceback.format_exc()
                break

        logging.info("TUN: exiting")
        if self.fd:
            os.close(self.fd)
            self.fd = None
Пример #8
0
    def __run_tun_thread(self):
        while self.fd:
            try:
                ready_fd = select([self.fd], [], [])[0][0]
                if ready_fd == self.fd:
                    packet = os.read(self.fd, 4000)
                    if CONFIG.DEBUG_TUN:
                        logging.debug("\nTUN: RX (" + str(len(packet)) + ") " +
                                      util.hexify_str(packet))
                    self.write(packet)
            except:
                traceback.print_exc()
                break

        logging.info("TUN: exiting")
        if self.fd:
            os.close(self.fd)
            self.fd = None
Пример #9
0
    def test_prop_get(self):
        """ Unit test of SpinelCodec.prop_get_value. """

        mock_stream = MockStream({})

        nodeid = 1
        use_hdlc = False
        tid = SPINEL.HEADER_ASYNC
        prop_id = SPINEL.PROP_STREAM_RAW

        wpan_api = WpanApi(mock_stream, nodeid, use_hdlc)
        wpan_api.queue_register(tid)

        for truth in self.VECTOR:
            mock_stream.write_child_hex(self.HEADER + truth)
            result = wpan_api.queue_wait_for_prop(prop_id, tid)
            packet = util.hexify_str(result.value, "")
            self.failUnless(packet == truth)
Пример #10
0
    def test_prop_get(self):
        """ Unit test of SpinelCodec.prop_get_value. """

        mock_stream = MockStream({})

        nodeid = 1
        use_hdlc = False
        tid = SPINEL.HEADER_ASYNC
        prop_id = SPINEL.PROP_STREAM_RAW

        wpan_api = WpanApi(mock_stream, nodeid, use_hdlc)
        wpan_api.queue_register(tid)

        for truth in self.VECTOR:
            mock_stream.write_child_hex(self.HEADER+truth)
            result = wpan_api.queue_wait_for_prop(prop_id, tid)
            packet = util.hexify_str(result.value,"")
            self.failUnless(packet == truth)
Пример #11
0
    def handle_prop(self, wpan_api, name, payload, tid):
        (prop_id, prop_len) = self.parse_i(payload)

        try:
            handler = SPINEL_PROP_DISPATCH[prop_id]
            prop_name = handler.__name__
            prop_value = handler(wpan_api, payload[prop_len:])

            if CONFIG.DEBUG_LOG_PROP:

                # Generic output
                if isinstance(prop_value, basestring):
                    prop_value_str = util.hexify_str(prop_value)
                    logging.debug("PROP_VALUE_%s [tid=%d]: %s = %s",
                                  name, (tid & 0xF), prop_name, prop_value_str)
                else:
                    prop_value_str = str(prop_value)

                    logging.debug("PROP_VALUE_%s [tid=%d]: %s = %s",
                                  name, (tid & 0xF), prop_name, prop_value_str)

                # Extend output for certain properties.
                if prop_id == SPINEL.PROP_LAST_STATUS:
                    logging.debug(SPINEL_LAST_STATUS_MAP[prop_value])

            if CONFIG.DEBUG_LOG_PKT:
                if ((prop_id == SPINEL.PROP_STREAM_NET) or
                        (prop_id == SPINEL.PROP_STREAM_NET_INSECURE)):
                    logging.debug("PROP_VALUE_" + name + ": " + prop_name)
                    pkt = IPv6(prop_value[2:])
                    pkt.show()

                elif prop_id == SPINEL.PROP_STREAM_DEBUG:
                    logging.debug("DEBUG: " + prop_value)

            if wpan_api:
                wpan_api.queue_add(prop_id, prop_value, tid)
            else:
                print "no wpan_api"

        except Exception as _ex:
            prop_name = "Property Unknown"
            logging.info("\n%s (%i): ", prop_name, prop_id)
            print traceback.format_exc()
Пример #12
0
    def handle_prop(self, wpan_api, name, payload, tid):
        (prop_id, prop_len) = self.parse_i(payload)

        try:
            handler = SPINEL_PROP_DISPATCH[prop_id]
            prop_name = handler.__name__
            prop_value = handler(wpan_api, payload[prop_len:])

            if CONFIG.DEBUG_LOG_PROP:

                # Generic output
                if isinstance(prop_value, basestring):
                    prop_value_str = util.hexify_str(prop_value)
                    logging.debug("PROP_VALUE_%s [tid=%d]: %s = %s", name,
                                  (tid & 0xF), prop_name, prop_value_str)
                else:
                    prop_value_str = str(prop_value)

                    logging.debug("PROP_VALUE_%s [tid=%d]: %s = %s", name,
                                  (tid & 0xF), prop_name, prop_value_str)

                # Extend output for certain properties.
                if prop_id == SPINEL.PROP_LAST_STATUS:
                    logging.debug(SPINEL_LAST_STATUS_MAP[prop_value])

            if CONFIG.DEBUG_LOG_PKT:
                if ((prop_id == SPINEL.PROP_STREAM_NET)
                        or (prop_id == SPINEL.PROP_STREAM_NET_INSECURE)):
                    logging.debug("PROP_VALUE_" + name + ": " + prop_name)
                    pkt = IPv6(prop_value[2:])
                    pkt.show()

                elif prop_id == SPINEL.PROP_STREAM_DEBUG:
                    logging.debug("DEBUG: " + prop_value)

            if wpan_api:
                wpan_api.queue_add(prop_id, prop_value, tid)
            else:
                print "no wpan_api"

        except Exception as _ex:
            prop_name = "Property Unknown"
            logging.info("\n%s (%i): ", prop_name, prop_id)
            print traceback.format_exc()
Пример #13
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()
Пример #14
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()