diff --git a/dist/tools/ng_sniffer/README.md b/dist/tools/ng_sniffer/README.md new file mode 100644 index 0000000000..1451b722d0 --- /dev/null +++ b/dist/tools/ng_sniffer/README.md @@ -0,0 +1,89 @@ +# RIOT Sniffer Application + + +## About + +This sniffer script can be used to sniff network traffic using RIOT based +nodes. It is primarily designed for sniffing wireless data traffic, but can also +well be used for wired network traffic, as long as the used network devices +support promiscuous mode and output of raw data. + +The sniffer is based on a RIOT node running the [ng_sniffer application](https://github.com/RIOT-OS/applications/tree/master/ng_sniffer) application located in [RIOTs application repository](https://github.com/RIOT-OS/applications). +This node outputs received network traffic via a serial port in the Wireshark +pcap format. This output is then parsed by the `ng_sniffer.py` script included +in this folder run on a host computer. + +The `ng_sniffer.py` script is a modified version of [malvira's script](https://github.com/malvira/libmc1322x/blob/master/tools/rftestrx2pcap.py) for the Redbee Ecotag +(https://github.com/malvira/libmc1322x/wiki/wireshark). + + +## Dependencies + +The `ng_sniffer.py` script needs [pyserial](https://pypi.python.org/pypi/pyserial). + +Installing the dependencies: + +#### Debuntu + apt-get install python-serial + +#### PIP + pip install pyserial + + +## Usage + +General usage: + +1. Flash an applicable RIOT node with the sniffer application from +(https://github.com/RIOT-OS/applications/tree/master/ng_sniffer) + +2. Run the `ng_sniffer.py` script +``` +$ ./ng_sniffer.py [outfile] +``` +The script has the following parameters: + +- **tty:** The serial port the RIOT board is connected to. Under Linux, this is + typically something like /dev/ttyUSB0 or /dev/ttyACM0. Under Windows, + this is typically something like COM0 or COM1 +- **baudrate:** The baudrate the serial port is configured to. The default in + RIOT is 115200, though this is defined per board and some boards + have some other value defined per default. NOTE: when sniffing + networks where the on-air bitrate is > baudrate, it makes sense + to increase the baudrate so no data is skipped when sniffing. +- **channel:** The radio channel to use when sniffing. Possible values vary and + depend on the link-layer that is sniffed. This parameter is + ignored when sniffing wired networks. +- **[outfile]:** When this parameter is specified, the sniffer output is saved + into this file. See the examples below for alternatives to + specifying this parameter. (optional) + + +### Examples + +The following examples are made when using the sniffer application together with +an `iot-lab_M3` node that is connected to /dev/ttyUSB1 (or COM1) and runs per +default with a baudrate of 500000. + +#### Linux + +Dump packets to a file: +``` +$ ./ng_sniffer.py /dev/ttyUSB1 500000 17 > foo.pcap +``` + +This .pcap can then be opened in wireshark. + +Alternatively for live captures, you can pipe directly into wireshark with: +``` +$ ./ng_sniffer.py /dev/ttyUSB1 500000 17 | wireshark -k -i - +``` + +#### Windows + +For windows you can use the optional third argument to output to a +.pcap: + +``` +$ ./ng_sniffer.py COM1 500000 17 foo.pcap +``` diff --git a/dist/tools/ng_sniffer/ng_sniffer.py b/dist/tools/ng_sniffer/ng_sniffer.py new file mode 100755 index 0000000000..e37c221fce --- /dev/null +++ b/dist/tools/ng_sniffer/ng_sniffer.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python2 +''' +(C) 2012, Mariano Alvira +(C) 2014, Oliver Hahm +(C) 2015, Hauke Petersen + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of the Institute nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. +''' + +import sys,os,time +from struct import pack +import re +import serial + +if len(sys.argv) < 4: + sys.stderr.write( "Usage: %s tty baudrate channel [outfile]\n" %(sys.argv[0])) + sys.stderr.write( " channel = 11-26\n") + sys.exit(2) + +# change the channel + +try: + #serport = serial.Serial(sys.argv[1], baudrate=115200, dsrdtr=0, rtscts=0, timeout=1) + serport = serial.Serial(sys.argv[1], sys.argv[2], dsrdtr=0, rtscts=0, timeout=1) + serport.setDTR(0) + serport.setRTS(0) +except IOError: + print "error opening port" + sys.exit(2) + +time.sleep(1) + +sys.stderr.write('ifconfig 4 set chan %s\n' % sys.argv[3]) +sys.stderr.write('ifconfig 4 raw\n') +sys.stderr.write('ifconfig 4 promisc\n') +serport.write('ifconfig 4 set chan %s\n' % sys.argv[3]) +serport.write('ifconfig 4 raw\n') +serport.write('ifconfig 4 promisc\n') + +time.sleep(1) + +# figure out where to write +try: + sys.stderr.write('trying to open file %s\n' % sys.argv[4]) + outfile = open(sys.argv[4], 'w+b') +except IndexError: + outfile = sys.stdout + +# PCAP setup +MAGIC = 0xa1b2c3d4 +MAJOR = 2 +MINOR = 4 +ZONE = 0 +SIG = 0 +SNAPLEN = 0xffff +NETWORK = 230 # 802.15.4 no FCS + +# output overall PCAP header +outfile.write(pack('? *rftest-rx --- len 0x(\w\w).*", line) + if pkt_header: + t = time.time() + sec = int(t) + usec = (t - sec) * 100000 + length = int(pkt_header.group(1), 16) + outfile.write(pack('