Skip to content
This repository has been archived by the owner on Sep 20, 2022. It is now read-only.

sniffer: rewrite to be completely byte-based #61

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions sniffer/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ BOARD ?= native
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../RIOT

# Define features that are required
FEATURES_REQUIRED += periph_uart

# Define modules that are used
USEMODULE += fmt
USEMODULE += gnrc
USEMODULE += netdev_default
USEMODULE += auto_init_gnrc_netif
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += ps
USEMODULE += ztimer64_usec

# Change this to 0 show compiler invocation lines by default:
Expand Down
193 changes: 133 additions & 60 deletions sniffer/main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015-18 Freie Universität Berlin
* Copyright (C) 2015-19 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
Expand All @@ -22,17 +22,14 @@

#include <stdio.h>

#include "fmt.h"
#include "thread.h"
#include "shell.h"
#include "byteorder.h"
#include "isrpipe.h"
#include "net/gnrc.h"
#include "net/netopt.h"
#include "periph/uart.h"
#include "stdio_uart.h"
#include "ztimer64.h"

/**
* @brief Buffer size used by the shell
*/
#define SHELL_BUFSIZE (64U)

/**
* @brief Priority of the RAW dump thread
*/
Expand All @@ -43,95 +40,171 @@
*/
#define RAWDUMP_MSG_Q_SIZE (32U)

/**
* @brief Stack for the raw dump thread
*/
static char rawdmp_stack[THREAD_STACKSIZE_SMALL];
#define SET_CHAN_MSG_TYPE (0xdd4a)

#define END_BYTE (0xc0U)
#define ESC_BYTE (0xdbU)
#define END_ESC_BYTE (0xdcU)
#define ESC_ESC_BYTE (0xddU)

#ifndef SNIFFER_DEV
#define SNIFFER_DEV (UART_DEV(0))
#endif

#ifndef SNIFFER_BAUDRATE
#define SNIFFER_BAUDRATE (STDIO_UART_BAUDRATE)
#endif

static msg_t msg_q[RAWDUMP_MSG_Q_SIZE];
static kernel_pid_t _main_pid = KERNEL_PID_UNDEF;

static void _rx_uart(void *arg, uint8_t data)
{
/* XXX: read one byte channel. More sync is required for larger channel
* ranges */
msg_t msg = { .type = SET_CHAN_MSG_TYPE, .content = { .value = data } };

(void)arg;
msg_send_int(&msg, _main_pid);
}

static void _tx_byte(uint8_t data)
{
uart_write(SNIFFER_DEV, &data, sizeof(data));
}

static void _tx_bytes(uint8_t *data, size_t len)
{
for (unsigned i = 0; i < len; i++) {
switch (*data) {
case END_BYTE:
_tx_byte(ESC_BYTE);
_tx_byte(END_ESC_BYTE);
break;
case ESC_BYTE:
_tx_byte(ESC_BYTE);
_tx_byte(ESC_ESC_BYTE);
break;
default:
_tx_byte(*data);
break;
}
data++;
}
}

/**
* @brief Make a raw dump of the given packet contents
*/
void dump_pkt(gnrc_pktsnip_t *pkt)
static void _dump_pkt(gnrc_pktsnip_t *pkt)
{
network_uint64_t now_us = byteorder_htonll(ztimer64_now(ZTIMER64_USEC));
gnrc_pktsnip_t *snip = pkt;
network_uint32_t len;
uint8_t lqi = 0;
uint8_t padding[3] = { 0, 0, 0 };

if (pkt->next) {
if (pkt->next->type == GNRC_NETTYPE_NETIF) {
gnrc_netif_hdr_t *netif_hdr = pkt->next->data;
lqi = netif_hdr->lqi;
pkt = gnrc_pktbuf_remove_snip(pkt, pkt->next);
}
}
uint64_t now_us = ztimer64_now(ZTIMER64_USEC);

print_str("rftest-rx --- len ");
print_u32_hex((uint32_t)gnrc_pkt_len(pkt));
print_str(" lqi ");
print_byte_hex(lqi);
print_str(" rx_time ");
print_u64_hex(now_us);
print_str("\n");

len = byteorder_htonl((uint32_t)gnrc_pkt_len(pkt));
/*
* write packet "header" in network byte order:
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | packet length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | LQI | padding |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + Timestamp (in us) +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
_tx_bytes(len.u8, sizeof(len));
_tx_bytes(&lqi, sizeof(lqi));
_tx_bytes(padding, sizeof(padding));
_tx_bytes(now_us.u8, sizeof(now_us));
while (snip) {
for (size_t i = 0; i < snip->size; i++) {
print_byte_hex(((uint8_t *)(snip->data))[i]);
print_str(" ");
}
_tx_bytes(snip->data, snip->size);
snip = snip->next;
}
print_str("\n\n");
_tx_byte(END_BYTE);

gnrc_pktbuf_release(pkt);
}

static void _init_uart(void)
{
int res;

(void)res; /* in case assert is not compiled in */
uart_init(SNIFFER_DEV, SNIFFER_BAUDRATE, _rx_uart, NULL);
assert(res == UART_OK);
}

static void _init_netif(gnrc_netif_t *netif)
{
int res;
netopt_enable_t enable = NETOPT_ENABLE;

(void)res; /* in case assert is not compiled in */
res = gnrc_netapi_set(netif->pid, NETOPT_RAWMODE, 0,
&enable, sizeof(enable));
assert(res >= 0);
res = gnrc_netapi_set(netif->pid, NETOPT_PROMISCUOUSMODE, 0,
&enable, sizeof(enable));
assert(res >= 0);
}

/**
* @brief Event loop of the RAW dump thread
*
* @param[in] arg unused parameter
* @brief Maybe you are a golfer?!
*/
void *rawdump(void *arg)
int main(void)
{
msg_t msg_q[RAWDUMP_MSG_Q_SIZE];
gnrc_netif_t *netif = gnrc_netif_iter(NULL);
gnrc_netreg_entry_t dump;

(void)arg;
assert(netif != NULL);
_main_pid = thread_getpid();
msg_init_queue(msg_q, RAWDUMP_MSG_Q_SIZE);
_init_uart();

/* start and register main thread for dumping */
dump.target.pid = _main_pid;
dump.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL;
gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &dump);

_init_netif(netif);

/* write empty packet to signal start */
_tx_byte(END_BYTE);
while (1) {
msg_t msg;

msg_receive(&msg);
switch (msg.type) {
case GNRC_NETAPI_MSG_TYPE_RCV:
dump_pkt((gnrc_pktsnip_t *)msg.content.ptr);
_dump_pkt((gnrc_pktsnip_t *)msg.content.ptr);
break;
case SET_CHAN_MSG_TYPE: {
uint8_t chan = msg.content.value;
gnrc_netapi_set(netif->pid, NETOPT_CHANNEL, 0, &chan,
sizeof(chan));
break;
}
default:
/* do nothing */
break;
}
}

/* never reached */
return NULL;
}

/**
* @brief Maybe you are a golfer?!
*/
int main(void)
{
gnrc_netreg_entry_t dump;

puts("RIOT sniffer application");

/* start and register rawdump thread */
puts("Run the rawdump thread and register it");
dump.target.pid = thread_create(rawdmp_stack, sizeof(rawdmp_stack), RAWDUMP_PRIO,
THREAD_CREATE_STACKTEST, rawdump, NULL, "rawdump");
dump.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL;
gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &dump);

/* start the shell */
puts("All ok, starting the shell now");
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);

return 0;
}
Loading