1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

tools/zep_dispatch: send frames to virtual 802.15.4 interface

This commit is contained in:
Benjamin Valentin 2022-06-19 23:07:14 +02:00
parent 34ae8db68b
commit 965e3857fb
2 changed files with 96 additions and 13 deletions

View File

@ -45,6 +45,27 @@ There can only be as many nodes connected to the dispatcher as have been named i
the topology file.
Any additional nodes that try to connect will be ignored.
Packet capture
--------------
To view traffic in Wireshark you need to create a virtual 802.15.4 device to which
the network traffic is sent. This can then be selected as a capture source in Wireshark.
To create the virtual device, load the `mac802154_hwsim` module
sudo modprobe mac802154_hwsim
This will create two wpan devices, `wpan0` and `wpan1`.
If you then run the dispatcher with
sudo zep_dispatch -w wpan0 ::1 17754
all traffic on the simulated network will be also sent to the virtual `wpan0` interface
where it can be captures with Wireshark.
Network visualization
---------------------

View File

@ -19,10 +19,16 @@
#include <time.h>
#include <unistd.h>
#include <linux/if.h>
#include <linux/if_packet.h>
#include <sys/ioctl.h>
#include "kernel_defines.h"
#include "topology.h"
#include "zep_parser.h"
#define ETH_P_IEEE802154 0x00F6
typedef struct {
list_node_t node;
struct sockaddr_in6 addr;
@ -89,7 +95,7 @@ static void _send_topology(void *ctx, void *buffer, size_t len,
topology_send(ctx, sock, src_addr, buffer, len);
}
static void dispatch_loop(int sock, dispatch_cb_t dispatch, void *ctx)
static void dispatch_loop(int sock, int tap, dispatch_cb_t dispatch, void *ctx)
{
puts("entering loop…");
while (1) {
@ -105,6 +111,20 @@ static void dispatch_loop(int sock, dispatch_cb_t dispatch, void *ctx)
continue;
}
/* send packet to virtual 802.15.4 interface */
if (tap) {
size_t len = bytes_in;
const void *payload = zep_get_payload(buffer, &len);
if (payload) {
if (write(tap, payload, len) < 0) {
puts("Can't write to virtual 802.15.4 device");
close(tap);
tap = 0;
}
}
}
/* send packet to the topology */
dispatch(ctx, buffer, bytes_in, sock, &src_addr);
}
}
@ -125,9 +145,43 @@ static void _info_handler(int signal)
}
}
/* open mac802154_hwsim device to send frames to it */
static int _open_mac802154_hwsim(const char *iface)
{
int res;
int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IEEE802154));
/* get interface index for interface name */
struct ifreq ifr;
strncpy(ifr.ifr_name, iface, IFNAMSIZ);
if ((res = ioctl(fd, SIOCGIFINDEX, &ifr)) < 0) {
goto error;
}
/* bind socket to the device */
struct sockaddr_ll sll = {
.sll_family = AF_PACKET,
.sll_ifindex = ifr.ifr_ifindex,
.sll_protocol = htons(ETH_P_IEEE802154),
};
if ((res = bind(fd, (struct sockaddr *)&sll, sizeof(sll))) < 0) {
goto error;
}
return fd;
error:
close(fd);
fprintf(stderr, "open mac802154_hwsim: %s\n", strerror(res));
return res;
}
static void _print_help(const char *progname)
{
fprintf(stderr, "usage: %s [-t topology] [-s seed] [-g graphviz_out] <address> <port>\n",
fprintf(stderr, "usage: %s [-t topology] [-s seed] "
"[-g graphviz_out] [-w interface] <address> <port>\n",
progname);
fprintf(stderr, "\npositional arguments:\n");
@ -138,16 +192,25 @@ static void _print_help(const char *progname)
fprintf(stderr, "\t-t <file>\tLoad toplogy from file\n");
fprintf(stderr, "\t-s <seed>\tRandom seed used to simulate packet loss\n");
fprintf(stderr, "\t-g <file>\tFile to dump topology as Graphviz visualisation on SIGUSR1\n");
fprintf(stderr, "\t-w <interface>\tSend frames to virtual 802.15.4 "
"interface (mac802154_hwsim)\n");
}
int main(int argc, char **argv)
{
int c;
int c, tap_fd = 0;
unsigned int seed = time(NULL);
const char *topo_file = NULL;
const char *progname = argv[0];
while ((c = getopt(argc, argv, "t:s:g:")) != -1) {
const struct addrinfo hint = {
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_DGRAM,
.ai_protocol = IPPROTO_UDP,
.ai_flags = AI_NUMERICHOST,
};
while ((c = getopt(argc, argv, "t:s:g:w:")) != -1) {
switch (c) {
case 't':
topo_file = optarg;
@ -158,6 +221,12 @@ int main(int argc, char **argv)
case 'g':
graphviz_file = optarg;
break;
case 'w':
tap_fd = _open_mac802154_hwsim(optarg);
if (tap_fd < 0) {
return tap_fd;
}
break;
default:
_print_help(progname);
exit(1);
@ -189,13 +258,6 @@ int main(int argc, char **argv)
signal(SIGUSR1, _info_handler);
}
struct addrinfo hint = {
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_DGRAM,
.ai_protocol = IPPROTO_UDP,
.ai_flags = AI_NUMERICHOST,
};
struct addrinfo *server_addr;
int res = getaddrinfo(argv[0], argv[1],
&hint, &server_addr);
@ -221,10 +283,10 @@ int main(int argc, char **argv)
freeaddrinfo(server_addr);
if (topology.flat) {
dispatch_loop(sock, _send_flat, &topology.nodes);
dispatch_loop(sock, tap_fd, _send_flat, &topology.nodes);
}
else {
dispatch_loop(sock, _send_topology, &topology);
dispatch_loop(sock, tap_fd, _send_topology, &topology);
}
close(sock);