Skip to content

Commit

Permalink
Merge pull request #4725 from kaspar030/ethos_br_hack
Browse files Browse the repository at this point in the history
simplified border router setup
  • Loading branch information
haukepetersen committed Apr 12, 2016
2 parents 690b505 + edb5f08 commit 5fe57b4
Show file tree
Hide file tree
Showing 20 changed files with 763 additions and 60 deletions.
6 changes: 6 additions & 0 deletions Makefile.dep
Expand Up @@ -25,6 +25,12 @@ ifneq (,$(filter netdev2_ieee802154,$(USEMODULE)))
USEMODULE += ieee802154
endif

ifneq (,$(filter gnrc_uhcpc,$(USEMODULE)))
USEMODULE += uhcpc
USEMODULE += gnrc_conn_udp
USEMODULE += fmt
endif

ifneq (,$(filter gnrc_%,$(filter-out gnrc_netapi gnrc_netreg gnrc_netif% gnrc_pktbuf,$(USEMODULE))))
USEMODULE += gnrc
endif
Expand Down
4 changes: 2 additions & 2 deletions cpu/native/netdev2_tap/netdev2_tap.c
Expand Up @@ -107,7 +107,7 @@ static inline void _isr(netdev2_t *netdev)
#endif
}

int _get(netdev2_t *dev, netopt_t opt, void *value, size_t max_len)
static int _get(netdev2_t *dev, netopt_t opt, void *value, size_t max_len)
{
if (dev != (netdev2_t *)&netdev2_tap) {
return -ENODEV;
Expand Down Expand Up @@ -137,7 +137,7 @@ int _get(netdev2_t *dev, netopt_t opt, void *value, size_t max_len)
return res;
}

int _set(netdev2_t *dev, netopt_t opt, void *value, size_t value_len)
static int _set(netdev2_t *dev, netopt_t opt, void *value, size_t value_len)
{
(void)value_len;

Expand Down
3 changes: 3 additions & 0 deletions dist/tools/ethos/Makefile
Expand Up @@ -2,3 +2,6 @@ all: ethos

ethos: ethos.c
$(CC) -O3 -Wall ethos.c -o ethos

clean:
rm -f ethos
42 changes: 42 additions & 0 deletions dist/tools/ethos/start_network.sh
@@ -0,0 +1,42 @@
#!/bin/sh

create_tap() {
ip tuntap add ${TAP} mode tap user ${USER}
sysctl -w net.ipv6.conf.${TAP}.forwarding=1
sysctl -w net.ipv6.conf.${TAP}.accept_ra=0
ip link set ${TAP} up
ip a a fe80::1/64 dev ${TAP}
ip a a fd00:dead:beef::1/128 dev lo
ip route add ${PREFIX} via fe80::2 dev ${TAP}
}

remove_tap() {
ip tuntap del ${TAP} mode tap
}

cleanup() {
echo "Cleaning up..."
remove_tap
ip a d fd00:dead:beef::1/128 dev lo
kill $UHCPD_PID
trap "" INT QUIT TERM EXIT
}

start_uhcpd() {
${UHCPD} ${TAP} ${PREFIX} > /dev/null &
UHCPD_PID=$!
}

PORT=$1
TAP=$2
PREFIX=$3
UHCPD=../uhcpd/bin/uhcpd

[ -z "$PORT" -o -z "$TAP" -o -z "$PREFIX" ] && {
echo "usage: $0 <serial-port> <tap-device> <prefix>"
exit 1
}

trap "cleanup" INT QUIT TERM EXIT

create_tap && start_uhcpd && ./ethos $TAP $PORT
1 change: 1 addition & 0 deletions dist/tools/uhcpd/.gitignore
@@ -0,0 +1 @@
bin
17 changes: 17 additions & 0 deletions dist/tools/uhcpd/Makefile
@@ -0,0 +1,17 @@
CFLAGS?=-g -O3 -Wall
CFLAGS_EXTRA=-DUHCP_SERVER
all: bin bin/uhcpd

bin:
mkdir bin

RIOTBASE:=../../..
UHCP_DIR:=$(RIOTBASE)/sys/net/application_layer/uhcp
RIOT_INCLUDE=$(RIOTBASE)/sys/include
SRCS:=$(UHCP_DIR)/uhcp.c uhcpd.c
HDRS:=$(RIOT_INCLUDE)/net/uhcp.h
bin/uhcpd: $(SRCS) $(HDRS)
$(CC) $(CFLAGS) $(CFLAGS_EXTRA) -I$(RIOT_INCLUDE) $(SRCS) -o $@

clean:
rm -f bin/uhcpd
5 changes: 5 additions & 0 deletions dist/tools/uhcpd/project.py
@@ -0,0 +1,5 @@
# pyjam build file. See https://github.com/kaspar030/pyjam for info.

default.CFLAGS = "-O3 -DUHCP_SYSTEM_LINUX -DUHCP_SERVER"

Main("uhcpd")
146 changes: 146 additions & 0 deletions dist/tools/uhcpd/uhcpd.c
@@ -0,0 +1,146 @@
/*
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
*
* This file is subject to the terms and conditions of the GNU General Public
* License v2. See the file LICENSE for more details.
*/

#define UHCP_MCAST_ADDR "ff15::ABCD"

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <net/if.h>
#include <arpa/inet.h>

#include "net/uhcp.h"

char _prefix[16];
unsigned _prefix_len;

int ipv6_addr_split(char *addr_str, char seperator, int _default)
{
char *sep = addr_str;
while(*++sep) {
if (*sep == seperator) {
*sep++ = '\0';
if (*sep) {
_default = atoi(sep);
}
break;
}
}

return _default;
}

int main(int argc, char *argv[])
{
static unsigned ifindex;

if (argc < 3) {
fprintf(stderr, "usage: uhcpd <interface> <prefix/prefix_length>\n");
exit(1);
}

ifindex = if_nametoindex(argv[1]);
if (!ifindex) {
fprintf(stderr, "error: invalid interface \"%s\"\n", argv[1]);
exit(1);
}

_prefix_len = ipv6_addr_split(argv[2], '/', 64);
if ((!inet_pton(AF_INET6, argv[2], _prefix)) || (_prefix_len > 128)) {
fprintf(stderr, "error: cannot parse prefix\n");
exit(1);
}

char *addr_str = UHCP_MCAST_ADDR;

struct addrinfo hint;
memset(&hint, 0, sizeof(hint));
hint.ai_family = AF_INET6;
hint.ai_socktype = SOCK_DGRAM;
hint.ai_protocol = IPPROTO_UDP;
hint.ai_flags |= AI_NUMERICHOST;

struct addrinfo *mcast_addr;
int res = getaddrinfo(addr_str, UHCP_PORT_STR,
&hint, &mcast_addr);
if (res != 0) {
perror("getaddrinfo()");
exit(1);
}

int sock = socket(mcast_addr->ai_family, mcast_addr->ai_socktype,
mcast_addr->ai_protocol);
if (sock < 0) {
perror("socket() failed");
exit(1);
}

if (bind(sock, mcast_addr->ai_addr, mcast_addr->ai_addrlen) < 0) {
perror("bind() failed");
exit(1);
}

/* join multicast group */
struct ipv6_mreq mreq;
memcpy(&mreq.ipv6mr_multiaddr,
&((struct sockaddr_in6 *)mcast_addr->ai_addr)->sin6_addr,
sizeof(struct in6_addr));

mreq.ipv6mr_interface = ifindex;

puts("Joining IPv6 multicast group...");
if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
&mreq, sizeof(mreq)) < 0) {
perror("setsockopt(IPV6_JOIN_GROUP) failed");
exit(1);
}
freeaddrinfo(mcast_addr);

char buf[2048];
struct sockaddr_in6 src_addr;
unsigned n = sizeof(src_addr);;

puts("entering loop...");
while(1) {
int nbytes = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr*)&src_addr, &n);
if (nbytes < 0) {
perror("recvfrom() failed");
continue;
}
uhcp_handle_udp((uint8_t *)buf, nbytes, (uint8_t *)&src_addr.sin6_addr, ntohs(src_addr.sin6_port), ifindex);
}

close(sock);
exit(0);
}

int udp_sendto(uint8_t *buf, size_t len, uint8_t *dst, uint16_t dst_port, uhcp_iface_t iface)
{
struct sockaddr_in6 dst_addr;
memset(&dst_addr, '\0', sizeof(dst_addr));
dst_addr.sin6_family = AF_INET6;
memcpy(&dst_addr.sin6_addr, dst, 16);
dst_addr.sin6_port = htons(dst_port);
dst_addr.sin6_scope_id = iface;

int fd = socket(AF_INET6, SOCK_DGRAM, 0);
if (fd == -1) {
perror("creating send socket");
return -1;
}

ssize_t res;
if ((res = sendto(fd, buf, len, 0, (struct sockaddr *)&dst_addr, sizeof(dst_addr))) == -1) {
perror("udp_sendto(): sendto()");
}

close(fd);

return res;
}
1 change: 1 addition & 0 deletions drivers/Makefile.dep
Expand Up @@ -50,6 +50,7 @@ endif
ifneq (,$(filter ethos,$(USEMODULE)))
USEMODULE += netdev2_eth
USEMODULE += random
USEMODULE += tsrb
endif

ifneq (,$(filter hih6130,$(USEMODULE)))
Expand Down
11 changes: 6 additions & 5 deletions drivers/ethos/ethos.c
Expand Up @@ -26,6 +26,7 @@
#include "ethos.h"
#include "periph/uart.h"
#include "tsrb.h"
#include "irq.h"

#include "net/netdev2.h"
#include "net/netdev2/eth.h"
Expand All @@ -41,7 +42,7 @@

static void _get_mac_addr(netdev2_t *dev, uint8_t* buf);
static void ethos_isr(void *arg, uint8_t c);
const static netdev2_driver_t netdev2_driver_ethos;
static const netdev2_driver_t netdev2_driver_ethos;

static const uint8_t _esc_esc[] = {ETHOS_ESC_CHAR, (ETHOS_ESC_CHAR ^ 0x20)};
static const uint8_t _esc_delim[] = {ETHOS_ESC_CHAR, (ETHOS_FRAME_DELIMITER ^ 0x20)};
Expand Down Expand Up @@ -297,12 +298,12 @@ static int _recv(netdev2_t *netdev, char* buf, int len, void* info)
ethos_t * dev = (ethos_t *) netdev;

if (buf) {
if (len < dev->last_framesize) {
if (len < (int)dev->last_framesize) {
DEBUG("ethos _recv(): receive buffer too small.");
return -1;
}

len = dev->last_framesize;
len = (int)dev->last_framesize;
dev->last_framesize = 0;

if ((tsrb_get(&dev->inbuf, buf, len) != len)) {
Expand All @@ -317,7 +318,7 @@ static int _recv(netdev2_t *netdev, char* buf, int len, void* info)
}
}

int _get(netdev2_t *dev, netopt_t opt, void *value, size_t max_len)
static int _get(netdev2_t *dev, netopt_t opt, void *value, size_t max_len)
{
int res = 0;

Expand All @@ -340,7 +341,7 @@ int _get(netdev2_t *dev, netopt_t opt, void *value, size_t max_len)
}

/* netdev2 interface */
const static netdev2_driver_t netdev2_driver_ethos = {
static const netdev2_driver_t netdev2_driver_ethos = {
.send = _send,
.recv = _recv,
.init = _init,
Expand Down
24 changes: 10 additions & 14 deletions examples/gnrc_border_router/Makefile
Expand Up @@ -12,26 +12,19 @@ BOARD_INSUFFICIENT_MEMORY := airfy-beacon msb-430 msb-430h pca10000 pca10005 \
spark-core stm32f0discovery telosb \
weio wsn430-v1_3b wsn430-v1_4 yunjia-nrf51822 z1 nucleo-f072

ifeq (,$(SLIP_UART))
# set default (last available UART)
SLIP_UART="UART_DEV(UART_NUMOF-1)"
endif
ifeq (,$(SLIP_BAUDRATE))
# set default
SLIP_BAUDRATE=115200
endif

# use ethos (ethernet over serial) for network communication and stdio over
# UART, but not on native, as native has a tap interface towards the host.
ifeq (,$(filter native,$(BOARD)))
GNRC_NETIF_NUMOF := 2
INCLUDES += -I$(CURDIR)
CFLAGS += -DSLIP_UART=$(SLIP_UART)
CFLAGS += -DSLIP_BAUDRATE=$(SLIP_BAUDRATE)
USEMODULE += ethos gnrc_netdev2
CFLAGS += '-DETHOS_UART=UART_DEV(0)' -DETHOS_BAUDRATE=115200 -DUSE_ETHOS_FOR_STDIO
FEATURES_REQUIRED += periph_uart
endif

# Include packages that pull up and auto-init the link layer.
# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present
USEMODULE += gnrc_netdev_default
USEMODULE += auto_init_gnrc_netif
# Include SLIP package for IP over Serial communication
USEMODULE += gnrc_slip
# Specify the mandatory networking modules for 6LoWPAN border router
USEMODULE += gnrc_sixlowpan_border_router_default
# Add forwarding table
Expand All @@ -43,6 +36,9 @@ USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += ps

# include UHCP client
USEMODULE += gnrc_uhcpc

# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
Expand Down
39 changes: 0 additions & 39 deletions examples/gnrc_border_router/slip_params.h

This file was deleted.

0 comments on commit 5fe57b4

Please sign in to comment.