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()
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()
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))
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))
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)
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
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
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)
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)
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()
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()
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()