

6 changed files with 1111 additions and 0 deletions
@ -0,0 +1,21 @@
|
||||
APPLICATION = gnrc_sock_udp
|
||||
|
||||
BOARD ?= native
|
||||
|
||||
RIOTBASE ?= $(CURDIR)/../..
|
||||
|
||||
USEMODULE += gnrc_sock_check_reuse
|
||||
USEMODULE += gnrc_sock_udp
|
||||
USEMODULE += gnrc_ipv6
|
||||
USEMODULE += ps
|
||||
|
||||
CFLAGS += -DDEVELHELP
|
||||
CFLAGS += -DGNRC_PKTBUF_SIZE=200
|
||||
CFLAGS += -DTEST_SUITES
|
||||
|
||||
QUIET ?= 1
|
||||
|
||||
include $(RIOTBASE)/Makefile.include |
||||
|
||||
test: |
||||
./tests/01-run.py
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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 |
||||
* directory for more details. |
||||
*/ |
||||
|
||||
/**
|
||||
* @defgroup |
||||
* @ingroup |
||||
* @brief |
||||
* @{ |
||||
* |
||||
* @file |
||||
* @brief |
||||
* |
||||
* @author Martine Lenders <m.lenders@fu-berlin.de> |
||||
*/ |
||||
#ifndef CONSTANTS_H_ |
||||
#define CONSTANTS_H_ |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
#define _TEST_PORT_LOCAL (0x2c94) |
||||
#define _TEST_PORT_REMOTE (0xa615) |
||||
#define _TEST_NETIF (31) |
||||
#define _TEST_TIMEOUT (1000000U) |
||||
#define _TEST_ADDR_LOCAL { 0x7f, 0xc4, 0x11, 0x5a, 0xe6, 0x91, 0x8d, 0x5d, \ |
||||
0x8c, 0xd1, 0x47, 0x07, 0xb7, 0x6f, 0x9b, 0x48 } |
||||
#define _TEST_ADDR_REMOTE { 0xe8, 0xb3, 0xb2, 0xe6, 0x70, 0xd4, 0x55, 0xba, \ |
||||
0x93, 0xcf, 0x11, 0xe1, 0x72, 0x44, 0xc5, 0x9d } |
||||
#define _TEST_ADDR_WRONG { 0x2a, 0xce, 0x5d, 0x4e, 0xc8, 0xbf, 0x86, 0xf7, \ |
||||
0x85, 0x49, 0xb4, 0x19, 0xf2, 0x28, 0xde, 0x9b } |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* CONSTANTS_H_ */ |
||||
/** @} */ |
@ -0,0 +1,705 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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 |
||||
* directory for more details. |
||||
*/ |
||||
|
||||
/**
|
||||
* @ingroup tests |
||||
* @{ |
||||
* |
||||
* @file |
||||
* @brief Test for UDP socks |
||||
* |
||||
* @author Martine Lenders <m.lenders@fu-berlin.de> |
||||
* @} |
||||
*/ |
||||
|
||||
#include <errno.h> |
||||
#include <stdbool.h> |
||||
#include <stdint.h> |
||||
#include <stdio.h> |
||||
|
||||
#include "net/af.h" |
||||
#include "net/sock/udp.h" |
||||
#include "xtimer.h" |
||||
|
||||
#include "constants.h" |
||||
#include "stack.h" |
||||
|
||||
#define _TEST_BUFFER_SIZE (128) |
||||
|
||||
static uint8_t _test_buffer[_TEST_BUFFER_SIZE]; |
||||
static sock_udp_t _sock, _sock2; |
||||
|
||||
#define CALL(fn) puts("Calling " # fn); fn; tear_down() |
||||
|
||||
static void tear_down(void) |
||||
{ |
||||
sock_udp_close(&_sock); |
||||
memset(&_sock, 0, sizeof(_sock)); |
||||
} |
||||
|
||||
#ifdef MODULE_GNRC_SOCK_CHECK_REUSE |
||||
static void test_sock_udp_create__EADDRINUSE(void) |
||||
{ |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, 0)); |
||||
assert(-EADDRINUSE == sock_udp_create(&_sock2, &local, NULL, 0)); |
||||
} |
||||
#endif |
||||
|
||||
static void test_sock_udp_create__EAFNOSUPPORT(void) |
||||
{ |
||||
/* port may not be NULL according to doc */ |
||||
static const sock_udp_ep_t local = { .family = AF_UNSPEC, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
/* port may not be NULL according to doc */ |
||||
static const sock_udp_ep_t remote = { .family = AF_UNSPEC, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(-EAFNOSUPPORT == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(-EAFNOSUPPORT == sock_udp_create(&_sock, NULL, &remote, SOCK_FLAGS_REUSE_EP)); |
||||
} |
||||
|
||||
static void test_sock_udp_create__EINVAL_addr(void) |
||||
{ |
||||
/* port may not be NULL according to doc */ |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, .netif = _TEST_NETIF, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
/* port may not be NULL according to doc */ |
||||
static const sock_udp_ep_t remote = { .family = AF_INET6, |
||||
.netif = _TEST_NETIF, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(-EINVAL == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP)); |
||||
} |
||||
|
||||
static void test_sock_udp_create__EINVAL_netif(void) |
||||
{ |
||||
/* port may not be NULL according to doc */ |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, .netif = _TEST_NETIF, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
/* port may not be NULL according to doc */ |
||||
static const sock_udp_ep_t remote = { .family = AF_INET6, |
||||
.netif = (_TEST_NETIF + 1), |
||||
.port = _TEST_PORT_REMOTE, |
||||
.addr = { .ipv6 = _TEST_ADDR_REMOTE } }; |
||||
|
||||
assert(-EINVAL == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP)); |
||||
} |
||||
|
||||
static void test_sock_udp_create__no_endpoints(void) |
||||
{ |
||||
sock_udp_ep_t ep; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, NULL, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(-EADDRNOTAVAIL == sock_udp_get_local(&_sock, &ep)); |
||||
assert(-ENOTCONN == sock_udp_get_remote(&_sock, &ep)); |
||||
} |
||||
|
||||
static void test_sock_udp_create__only_local(void) |
||||
{ |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
sock_udp_ep_t ep; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(0 == sock_udp_get_local(&_sock, &ep)); |
||||
assert(AF_INET6 == ep.family); |
||||
assert(memcmp(&ipv6_addr_unspecified, &ep.addr.ipv6, |
||||
sizeof(ipv6_addr_t)) == 0); |
||||
assert(SOCK_ADDR_ANY_NETIF == ep.netif); |
||||
assert(_TEST_PORT_LOCAL == ep.port); |
||||
assert(-ENOTCONN == sock_udp_get_remote(&_sock, &ep)); |
||||
} |
||||
|
||||
static void test_sock_udp_create__only_local_reuse_ep(void) |
||||
{ |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
sock_udp_ep_t ep, ep2; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(0 == sock_udp_create(&_sock2, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(0 == sock_udp_get_local(&_sock, &ep)); |
||||
assert(0 == sock_udp_get_local(&_sock2, &ep2)); |
||||
assert(AF_INET6 == ep.family); |
||||
assert(memcmp(&ipv6_addr_unspecified, &ep.addr.ipv6, |
||||
sizeof(ipv6_addr_t)) == 0); |
||||
assert(SOCK_ADDR_ANY_NETIF == ep.netif); |
||||
assert(_TEST_PORT_LOCAL == ep.port); |
||||
assert(-ENOTCONN == sock_udp_get_remote(&_sock, &ep)); |
||||
assert(AF_INET6 == ep2.family); |
||||
assert(memcmp(&ipv6_addr_unspecified, &ep2.addr.ipv6, |
||||
sizeof(ipv6_addr_t)) == 0); |
||||
assert(SOCK_ADDR_ANY_NETIF == ep2.netif); |
||||
assert(_TEST_PORT_LOCAL == ep2.port); |
||||
assert(-ENOTCONN == sock_udp_get_remote(&_sock, &ep2)); |
||||
sock_udp_close(&_sock2); |
||||
} |
||||
|
||||
static void test_sock_udp_create__only_remote(void) |
||||
{ |
||||
static const ipv6_addr_t remote_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const sock_udp_ep_t remote = { .family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE, |
||||
.addr = { .ipv6 = _TEST_ADDR_REMOTE } }; |
||||
sock_udp_ep_t ep; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, NULL, &remote, SOCK_FLAGS_REUSE_EP)); |
||||
assert(-EADDRNOTAVAIL == sock_udp_get_local(&_sock, &ep)); |
||||
assert(0 == sock_udp_get_remote(&_sock, &ep)); |
||||
assert(AF_INET6 == ep.family); |
||||
assert(memcmp(&remote_addr, &ep.addr.ipv6, sizeof(ipv6_addr_t)) == 0); |
||||
assert(SOCK_ADDR_ANY_NETIF == ep.netif); |
||||
assert(_TEST_PORT_REMOTE == ep.port); |
||||
} |
||||
|
||||
static void test_sock_udp_create__full(void) |
||||
{ |
||||
static const ipv6_addr_t remote_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, .netif = _TEST_NETIF, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
static const sock_udp_ep_t remote = { .family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE, |
||||
.addr = { .ipv6 = _TEST_ADDR_REMOTE } }; |
||||
sock_udp_ep_t ep; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP)); |
||||
assert(0 == sock_udp_get_local(&_sock, &ep)); |
||||
assert(AF_INET6 == ep.family); |
||||
assert(memcmp(&ipv6_addr_unspecified, &ep.addr.ipv6, |
||||
sizeof(ipv6_addr_t)) == 0); |
||||
assert(_TEST_NETIF == ep.netif); |
||||
assert(_TEST_PORT_LOCAL == ep.port); |
||||
assert(0 == sock_udp_get_remote(&_sock, &ep)); |
||||
assert(AF_INET6 == ep.family); |
||||
assert(memcmp(&remote_addr, &ep.addr.ipv6, sizeof(ipv6_addr_t)) == 0); |
||||
assert(SOCK_ADDR_ANY_NETIF == ep.netif); |
||||
assert(_TEST_PORT_REMOTE == ep.port); |
||||
} |
||||
|
||||
static void test_sock_udp_recv__EADDRNOTAVAIL(void) |
||||
{ |
||||
assert(0 == sock_udp_create(&_sock, NULL, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
|
||||
assert(-EADDRNOTAVAIL == sock_udp_recv(&_sock, _test_buffer, |
||||
sizeof(_test_buffer), |
||||
SOCK_NO_TIMEOUT, NULL)); |
||||
} |
||||
|
||||
static void test_sock_udp_recv__EAGAIN(void) |
||||
{ |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, .netif = _TEST_NETIF, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
|
||||
assert(-EAGAIN == sock_udp_recv(&_sock, _test_buffer, sizeof(_test_buffer), |
||||
0, NULL)); |
||||
} |
||||
|
||||
static void test_sock_udp_recv__ENOBUFS(void) |
||||
{ |
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL }; |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE, |
||||
_TEST_PORT_LOCAL, "ABCD", sizeof("ABCD"), _TEST_NETIF)); |
||||
assert(-ENOBUFS == sock_udp_recv(&_sock, _test_buffer, 2, SOCK_NO_TIMEOUT, |
||||
NULL)); |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_recv__EPROTO(void) |
||||
{ |
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_WRONG }; |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL }; |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP)); |
||||
assert(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE, |
||||
_TEST_PORT_LOCAL, "ABCD", sizeof("ABCD"), |
||||
_TEST_NETIF)); |
||||
assert(-EPROTO == sock_udp_recv(&_sock, _test_buffer, sizeof(_test_buffer), |
||||
SOCK_NO_TIMEOUT, NULL)); |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_recv__ETIMEDOUT(void) |
||||
{ |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, .netif = _TEST_NETIF, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
|
||||
puts(" * Calling sock_udp_recv()"); |
||||
assert(-ETIMEDOUT == sock_udp_recv(&_sock, _test_buffer, |
||||
sizeof(_test_buffer), _TEST_TIMEOUT, |
||||
NULL)); |
||||
printf(" * (timed out with timeout %lu)\n", (long unsigned)_TEST_TIMEOUT); |
||||
} |
||||
|
||||
static void test_sock_udp_recv__socketed(void) |
||||
{ |
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL }; |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP)); |
||||
assert(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE, |
||||
_TEST_PORT_LOCAL, "ABCD", sizeof("ABCD"), |
||||
_TEST_NETIF)); |
||||
assert(sizeof("ABCD") == sock_udp_recv(&_sock, _test_buffer, |
||||
sizeof(_test_buffer), |
||||
SOCK_NO_TIMEOUT, NULL)); |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_recv__socketed_with_remote(void) |
||||
{ |
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL }; |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
sock_udp_ep_t result; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP)); |
||||
assert(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE, |
||||
_TEST_PORT_LOCAL, "ABCD", sizeof("ABCD"), |
||||
_TEST_NETIF)); |
||||
assert(sizeof("ABCD") == sock_udp_recv(&_sock, _test_buffer, |
||||
sizeof(_test_buffer), |
||||
SOCK_NO_TIMEOUT, &result)); |
||||
assert(AF_INET6 == result.family); |
||||
assert(memcmp(&result.addr, &src_addr, sizeof(result.addr)) == 0); |
||||
assert(_TEST_PORT_REMOTE == result.port); |
||||
assert(_TEST_NETIF == result.netif); |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_recv__unsocketed(void) |
||||
{ |
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL }; |
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE, |
||||
_TEST_PORT_LOCAL, "ABCD", sizeof("ABCD"), |
||||
_TEST_NETIF)); |
||||
assert(sizeof("ABCD") == sock_udp_recv(&_sock, _test_buffer, |
||||
sizeof(_test_buffer), |
||||
SOCK_NO_TIMEOUT, NULL)); |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_recv__unsocketed_with_remote(void) |
||||
{ |
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL }; |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
sock_udp_ep_t result; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE, |
||||
_TEST_PORT_LOCAL, "ABCD", sizeof("ABCD"), |
||||
_TEST_NETIF)); |
||||
assert(sizeof("ABCD") == sock_udp_recv(&_sock, _test_buffer, |
||||
sizeof(_test_buffer), |
||||
SOCK_NO_TIMEOUT, &result)); |
||||
assert(AF_INET6 == result.family); |
||||
assert(memcmp(&result.addr, &src_addr, sizeof(result.addr)) == 0); |
||||
assert(_TEST_PORT_REMOTE == result.port); |
||||
assert(_TEST_NETIF == result.netif); |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_recv__with_timeout(void) |
||||
{ |
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL }; |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
sock_udp_ep_t result; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE, |
||||
_TEST_PORT_LOCAL, "ABCD", sizeof("ABCD"), |
||||
_TEST_NETIF)); |
||||
assert(sizeof("ABCD") == sock_udp_recv(&_sock, _test_buffer, |
||||
sizeof(_test_buffer), _TEST_TIMEOUT, |
||||
&result)); |
||||
assert(AF_INET6 == result.family); |
||||
assert(memcmp(&result.addr, &src_addr, sizeof(result.addr)) == 0); |
||||
assert(_TEST_PORT_REMOTE == result.port); |
||||
assert(_TEST_NETIF == result.netif); |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_recv__non_blocking(void) |
||||
{ |
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL }; |
||||
static const sock_udp_ep_t local = { .family = AF_INET6, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
sock_udp_ep_t result; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE, |
||||
_TEST_PORT_LOCAL, "ABCD", sizeof("ABCD"), |
||||
_TEST_NETIF)); |
||||
assert(sizeof("ABCD") == sock_udp_recv(&_sock, _test_buffer, |
||||
sizeof(_test_buffer), 0, &result)); |
||||
assert(AF_INET6 == result.family); |
||||
assert(memcmp(&result.addr, &src_addr, sizeof(result.addr)) == 0); |
||||
assert(_TEST_PORT_REMOTE == result.port); |
||||
assert(_TEST_NETIF == result.netif); |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__EAFNOSUPPORT(void) |
||||
{ |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(-EAFNOSUPPORT == sock_udp_send(NULL, "ABCD", sizeof("ABCD"), |
||||
&remote)); |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__EINVAL_addr(void) |
||||
{ |
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE, |
||||
.netif = _TEST_NETIF }; |
||||
static const sock_udp_ep_t remote = { .family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE, |
||||
.netif = _TEST_NETIF }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(-EINVAL == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), &remote)); |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__EINVAL_netif(void) |
||||
{ |
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE, |
||||
.netif = _TEST_NETIF }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE, |
||||
.netif = _TEST_NETIF + 1 }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(-EINVAL == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), &remote)); |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__EINVAL_port(void) |
||||
{ |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6 }; |
||||
|
||||
assert(-EINVAL == sock_udp_send(NULL, "ABCD", sizeof("ABCD"), &remote)); |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__ENOTCONN(void) |
||||
{ |
||||
assert(0 == sock_udp_create(&_sock, NULL, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(-ENOTCONN == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), NULL)); |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__socketed_no_local_no_netif(void) |
||||
{ |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, NULL, &remote, SOCK_FLAGS_REUSE_EP)); |
||||
assert(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), |
||||
NULL)); |
||||
assert(_check_packet(&ipv6_addr_unspecified, &dst_addr, 0, |
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"), |
||||
SOCK_ADDR_ANY_NETIF, true)); |
||||
xtimer_usleep(1000); /* let GNRC stack finish */ |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__socketed_no_netif(void) |
||||
{ |
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_LOCAL }; |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP)); |
||||
assert(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), |
||||
NULL)); |
||||
assert(_check_packet(&src_addr, &dst_addr, _TEST_PORT_LOCAL, |
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"), |
||||
SOCK_ADDR_ANY_NETIF, false)); |
||||
xtimer_usleep(1000); /* let GNRC stack finish */ |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__socketed_no_local(void) |
||||
{ |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.netif = _TEST_NETIF, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, NULL, &remote, SOCK_FLAGS_REUSE_EP)); |
||||
assert(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), |
||||
NULL)); |
||||
assert(_check_packet(&ipv6_addr_unspecified, &dst_addr, 0, |
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"), _TEST_NETIF, |
||||
true)); |
||||
xtimer_usleep(1000); /* let GNRC stack finish */ |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__socketed(void) |
||||
{ |
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_LOCAL }; |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL }, |
||||
.family = AF_INET6, |
||||
.netif = _TEST_NETIF, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP)); |
||||
assert(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), |
||||
NULL)); |
||||
assert(_check_packet(&src_addr, &dst_addr, _TEST_PORT_LOCAL, |
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"), |
||||
_TEST_NETIF, false)); |
||||
xtimer_usleep(1000); /* let GNRC stack finish */ |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__socketed_other_remote(void) |
||||
{ |
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_LOCAL }; |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL }, |
||||
.family = AF_INET6, |
||||
.netif = _TEST_NETIF, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
static const sock_udp_ep_t sock_remote = { .addr = { .ipv6 = _TEST_ADDR_WRONG }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE + _TEST_PORT_LOCAL }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, &sock_remote, SOCK_FLAGS_REUSE_EP)); |
||||
assert(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), |
||||
&remote)); |
||||
assert(_check_packet(&src_addr, &dst_addr, _TEST_PORT_LOCAL, |
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"), |
||||
_TEST_NETIF, false)); |
||||
xtimer_usleep(1000); /* let GNRC stack finish */ |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__unsocketed_no_local_no_netif(void) |
||||
{ |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, NULL, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), |
||||
&remote)); |
||||
assert(_check_packet(&ipv6_addr_unspecified, &dst_addr, 0, |
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"), |
||||
SOCK_ADDR_ANY_NETIF, true)); |
||||
xtimer_usleep(1000); /* let GNRC stack finish */ |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__unsocketed_no_netif(void) |
||||
{ |
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_LOCAL }; |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), |
||||
&remote)); |
||||
assert(_check_packet(&src_addr, &dst_addr, _TEST_PORT_LOCAL, |
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"), |
||||
SOCK_ADDR_ANY_NETIF, false)); |
||||
xtimer_usleep(1000); /* let GNRC stack finish */ |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__unsocketed_no_local(void) |
||||
{ |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.netif = _TEST_NETIF, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, NULL, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), |
||||
&remote)); |
||||
assert(_check_packet(&ipv6_addr_unspecified, &dst_addr, 0, |
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"), _TEST_NETIF, |
||||
true)); |
||||
xtimer_usleep(1000); /* let GNRC stack finish */ |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__unsocketed(void) |
||||
{ |
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_LOCAL }; |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL }, |
||||
.family = AF_INET6, |
||||
.netif = _TEST_NETIF, |
||||
.port = _TEST_PORT_LOCAL }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); |
||||
assert(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), |
||||
&remote)); |
||||
assert(_check_packet(&src_addr, &dst_addr, _TEST_PORT_LOCAL, |
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"), |
||||
_TEST_NETIF, false)); |
||||
xtimer_usleep(1000); /* let GNRC stack finish */ |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__no_sock_no_netif(void) |
||||
{ |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(sizeof("ABCD") == sock_udp_send(NULL, "ABCD", sizeof("ABCD"), |
||||
&remote)); |
||||
assert(_check_packet(&ipv6_addr_unspecified, &dst_addr, 0, |
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"), |
||||
SOCK_ADDR_ANY_NETIF, true)); |
||||
xtimer_usleep(1000); /* let GNRC stack finish */ |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
static void test_sock_udp_send__no_sock(void) |
||||
{ |
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE }; |
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE }, |
||||
.family = AF_INET6, |
||||
.netif = _TEST_NETIF, |
||||
.port = _TEST_PORT_REMOTE }; |
||||
|
||||
assert(sizeof("ABCD") == sock_udp_send(NULL, "ABCD", sizeof("ABCD"), |
||||
&remote)); |
||||
assert(_check_packet(&ipv6_addr_unspecified, &dst_addr, 0, |
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"), |
||||
_TEST_NETIF, true)); |
||||
xtimer_usleep(1000); /* let GNRC stack finish */ |
||||
assert(_check_net()); |
||||
} |
||||
|
||||
int main(void) |
||||
{ |
||||
_net_init(); |
||||
tear_down(); |
||||
#ifdef MODULE_GNRC_SOCK_CHECK_REUSE |
||||
CALL(test_sock_udp_create__EADDRINUSE()); |
||||
#endif |
||||
CALL(test_sock_udp_create__EAFNOSUPPORT()); |
||||
CALL(test_sock_udp_create__EINVAL_addr()); |
||||
CALL(test_sock_udp_create__EINVAL_netif()); |
||||
CALL(test_sock_udp_create__no_endpoints()); |
||||
CALL(test_sock_udp_create__only_local()); |
||||
CALL(test_sock_udp_create__only_local_reuse_ep()); |
||||
CALL(test_sock_udp_create__only_remote()); |
||||
CALL(test_sock_udp_create__full()); |
||||
/* sock_udp_close() is tested in tear_down() */ |
||||
/* sock_udp_get_local() is tested in sock_udp_create() tests */ |
||||
/* sock_udp_get_remote() is tested in sock_udp_create() tests */ |
||||
CALL(test_sock_udp_recv__EADDRNOTAVAIL()); |
||||
CALL(test_sock_udp_recv__EAGAIN()); |
||||
CALL(test_sock_udp_recv__ENOBUFS()); |
||||
CALL(test_sock_udp_recv__EPROTO()); |
||||
CALL(test_sock_udp_recv__ETIMEDOUT()); |
||||
CALL(test_sock_udp_recv__socketed()); |
||||
CALL(test_sock_udp_recv__socketed_with_remote()); |
||||
CALL(test_sock_udp_recv__unsocketed()); |
||||
CALL(test_sock_udp_recv__unsocketed_with_remote()); |
||||
CALL(test_sock_udp_recv__with_timeout()); |
||||
CALL(test_sock_udp_recv__non_blocking()); |
||||
_prepare_send_checks(); |
||||
CALL(test_sock_udp_send__EAFNOSUPPORT()); |
||||
CALL(test_sock_udp_send__EINVAL_addr()); |
||||
CALL(test_sock_udp_send__EINVAL_netif()); |
||||
CALL(test_sock_udp_send__EINVAL_port()); |
||||
CALL(test_sock_udp_send__ENOTCONN()); |
||||
CALL(test_sock_udp_send__socketed_no_local_no_netif()); |
||||
CALL(test_sock_udp_send__socketed_no_netif()); |
||||
CALL(test_sock_udp_send__socketed_no_local()); |
||||
CALL(test_sock_udp_send__socketed()); |
||||
CALL(test_sock_udp_send__socketed_other_remote()); |
||||
CALL(test_sock_udp_send__unsocketed_no_local_no_netif()); |
||||
CALL(test_sock_udp_send__unsocketed_no_netif()); |
||||
CALL(test_sock_udp_send__unsocketed_no_local()); |
||||
CALL(test_sock_udp_send__unsocketed()); |
||||
CALL(test_sock_udp_send__no_sock_no_netif()); |
||||
CALL(test_sock_udp_send__no_sock()); |
||||
|
||||
puts("ALL TESTS SUCCESSFUL"); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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 |
||||
* directory for more details. |
||||
*/ |
||||
|
||||
/**
|
||||
* @{ |
||||
* |
||||
* @file |
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de> |
||||
*/ |
||||
|
||||
|
||||
#include "msg.h" |
||||
#include "net/gnrc/ipv6.h" |
||||
#include "net/gnrc/netif/hdr.h" |
||||
#include "net/gnrc/netreg.h" |
||||
#include "net/gnrc/udp.h" |
||||
#include "net/sock.h" |
||||
#include "sched.h" |
||||
|
||||
#include "stack.h" |
||||
|
||||
#define _MSG_QUEUE_SIZE (4) |
||||
|
||||
static msg_t _msg_queue[_MSG_QUEUE_SIZE]; |
||||
static gnrc_netreg_entry_t _udp_handler; |
||||
|
||||
void _net_init(void) |
||||
{ |
||||
msg_init_queue(_msg_queue, _MSG_QUEUE_SIZE); |
||||
gnrc_netreg_entry_init_pid(&_udp_handler, GNRC_NETREG_DEMUX_CTX_ALL, |
||||
sched_active_pid); |
||||
} |
||||
|
||||
void _prepare_send_checks(void) |
||||
{ |
||||
gnrc_netreg_register(GNRC_NETTYPE_UDP, &_udp_handler); |
||||
} |
||||
|
||||
static gnrc_pktsnip_t *_build_udp_packet(const ipv6_addr_t *src, |
||||
const ipv6_addr_t *dst, |
||||
uint16_t src_port, uint16_t dst_port, |
||||
void *data, size_t data_len, |
||||
uint16_t netif) |
||||
{ |
||||
gnrc_pktsnip_t *netif_hdr, *ipv6, *udp; |
||||
udp_hdr_t *udp_hdr; |
||||
ipv6_hdr_t *ipv6_hdr; |
||||
uint16_t csum = 0; |
||||
|
||||
if ((netif > INT16_MAX) || ((sizeof(udp_hdr_t) + data_len) > UINT16_MAX)) { |
||||
return NULL; |
||||
} |
||||
|
||||
udp = gnrc_pktbuf_add(NULL, NULL, sizeof(udp_hdr_t) + data_len, |
||||
GNRC_NETTYPE_UNDEF); |
||||
if (udp == NULL) { |
||||
return NULL; |
||||
} |
||||
udp_hdr = udp->data; |
||||
udp_hdr->src_port = byteorder_htons(src_port); |
||||
udp_hdr->dst_port = byteorder_htons(dst_port); |
||||
udp_hdr->length = byteorder_htons((uint16_t)udp->size); |
||||
udp_hdr->checksum.u16 = 0; |
||||
memcpy(udp_hdr + 1, data, data_len); |
||||
csum = inet_csum(csum, (uint8_t *)udp->data, udp->size); |
||||
ipv6 = gnrc_ipv6_hdr_build(NULL, src, dst); |
||||
if (ipv6 == NULL) { |
||||
return NULL; |
||||
} |
||||
ipv6_hdr = ipv6->data; |
||||
ipv6_hdr->len = byteorder_htons((uint16_t)udp->size); |
||||
ipv6_hdr->nh = PROTNUM_UDP; |
||||
ipv6_hdr->hl = 64; |
||||
csum = ipv6_hdr_inet_csum(csum, ipv6_hdr, PROTNUM_UDP, (uint16_t)udp->size); |
||||
if (csum == 0xffff) { |
||||
udp_hdr->checksum = byteorder_htons(csum); |
||||
} |
||||
else { |
||||
udp_hdr->checksum = byteorder_htons(~csum); |
||||
} |
||||
LL_APPEND(udp, ipv6); |
||||
netif_hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0); |
||||
if (netif_hdr == NULL) { |
||||
return NULL; |
||||
} |
||||
((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = (kernel_pid_t)netif; |
||||
LL_APPEND(udp, netif_hdr); |
||||
return udp; |
||||
} |
||||
|
||||
|
||||
bool _inject_packet(const ipv6_addr_t *src, const ipv6_addr_t *dst, |
||||
uint16_t src_port, uint16_t dst_port, |
||||
void *data, size_t data_len, uint16_t netif) |
||||
{ |
||||
gnrc_pktsnip_t *pkt = _build_udp_packet(src, dst, src_port, dst_port, |
||||
data, data_len, netif); |
||||
|
||||
if (pkt == NULL) { |
||||
return false; |
||||
} |
||||
return (gnrc_netapi_dispatch_receive(GNRC_NETTYPE_UDP, |
||||
GNRC_NETREG_DEMUX_CTX_ALL, pkt) > 0); |
||||
} |
||||
|
||||
bool _check_net(void) |
||||
{ |
||||
return (gnrc_pktbuf_is_sane() && gnrc_pktbuf_is_empty()); |
||||
} |
||||
|
||||
static inline bool _res(gnrc_pktsnip_t *pkt, bool res) |
||||
{ |
||||
gnrc_pktbuf_release(pkt); |
||||
return res; |
||||
} |
||||
|
||||
bool _check_packet(const ipv6_addr_t *src, const ipv6_addr_t *dst, |
||||
uint16_t src_port, uint16_t dst_port, |
||||
void *data, size_t data_len, uint16_t iface, |
||||
bool random_src_port) |
||||
{ |
||||
gnrc_pktsnip_t *pkt, *ipv6, *udp; |
||||
ipv6_hdr_t *ipv6_hdr; |
||||
udp_hdr_t *udp_hdr; |
||||
msg_t msg; |
||||
|
||||
msg_receive(&msg); |
||||
if (msg.type != GNRC_NETAPI_MSG_TYPE_SND) { |
||||
return false; |
||||
} |
||||
pkt = msg.content.ptr; |
||||
if (iface != SOCK_ADDR_ANY_NETIF) { |
||||
gnrc_netif_hdr_t *netif_hdr; |
||||
|
||||
if (pkt->type != GNRC_NETTYPE_NETIF) { |
||||
return _res(pkt, false); |
||||
} |
||||
netif_hdr = pkt->data; |
||||
if (netif_hdr->if_pid != iface) { |
||||
return _res(pkt, false); |
||||
} |
||||
ipv6 = pkt->next; |
||||
} |
||||
else { |
||||
ipv6 = pkt; |
||||
} |
||||
if (ipv6->type != GNRC_NETTYPE_IPV6) { |
||||
return _res(pkt, false); |
||||
} |
||||
ipv6_hdr = ipv6->data; |
||||
udp = gnrc_pktsnip_search_type(ipv6, GNRC_NETTYPE_UDP); |
||||
if (udp == NULL) { |
||||
return _res(pkt, false); |
||||
} |
||||
udp_hdr = udp->data; |
||||
return _res(pkt, (memcmp(src, &ipv6_hdr->src, sizeof(ipv6_addr_t)) == 0) && |
||||
(memcmp(dst, &ipv6_hdr->dst, sizeof(ipv6_addr_t)) == 0) && |
||||
(ipv6_hdr->nh == PROTNUM_UDP) && |
||||
(random_src_port || (src_port == byteorder_ntohs(udp_hdr->src_port))) && |
||||
(dst_port == byteorder_ntohs(udp_hdr->dst_port)) && |
||||
(udp->next != NULL) && |
||||
(data_len == udp->next->size) && |
||||
(memcmp(data, udp->next->data, data_len) == 0)); |
||||
} |
||||
|
||||
|
||||
/** @} */ |
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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 |
||||
* directory for more details. |
||||
*/ |
||||
|
||||
/**
|
||||
* @defgroup |
||||
* @ingroup |
||||
* @brief |
||||
* @{ |
||||
* |
||||
* @file |
||||
* @brief |
||||
* |
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de> |
||||
*/ |
||||
#ifndef STACK_H_ |
||||
#define STACK_H_ |
||||
|
||||
#include <stdbool.h> |
||||
#include <stdint.h> |
||||
|
||||
#include "net/ipv6/addr.h" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/**
|
||||
* @brief Initializes networking for tests |
||||
*/ |
||||
void _net_init(void); |
||||
|
||||
/**
|
||||
* @brief Does what ever preparations are needed to check the packets sent |
||||
*/ |
||||
void _prepare_send_checks(void); |
||||
|
||||
/**
|
||||
* @brief Injects a received UDP packet into the stack |
||||
* |
||||
* @param[in] src The source address of the UDP packet |
||||
* @param[in] dst The destination address of the UDP packet |
||||
* @param[in] src_port The source port of the UDP packet |
||||
* @param[in] dst_port The destination port of the UDP packet |
||||
* @param[in] data The payload of the UDP packet |
||||
* @param[in] data_len The payload length of the UDP packet |
||||
* @param[in] netif The interface the packet came over |
||||
* |
||||
* @return true, if packet was successfully injected |
||||
* @return false, if an error occured during injection |
||||
*/ |
||||
bool _inject_packet(const ipv6_addr_t *src, const ipv6_addr_t *dst, |
||||
uint16_t src_port, uint16_t dst_port, |
||||
void *data, size_t data_len, uint16_t netif); |
||||
|
||||
/**
|
||||
* @brief Checks networking state (e.g. packet buffer state) |
||||
* |
||||
* @return true, if networking component is still in valid state |
||||
* @return false, if networking component is in an invalid state |
||||
*/ |
||||
bool _check_net(void); |
||||
|
||||
/**
|
||||
* @brief Checks if a UDP packet was sent by the networking component |
||||
* |
||||
* @param[in] src Expected source address of the UDP packet |
||||
* @param[in] dst Expected destination address of the UDP packet |
||||
* @param[in] src_port Expected source port of the UDP packet |
||||
* @param[in] dst_port Expected destination port of the UDP packet |
||||
* @param[in] data Expected payload of the UDP packet |
||||
* @param[in] data_len Expected payload length of the UDP packet |
||||
* @param[in] netif Expected interface the packet is supposed to |
||||
* be send over |
||||
* @param[in] random_src_port Do not check source port, it might be random |
||||
* |
||||
* @return true, if all parameters match as expected |
||||
* @return false, if not. |
||||
*/ |
||||
bool _check_packet(const ipv6_addr_t *src, const ipv6_addr_t *dst, |
||||
uint16_t src_port, uint16_t dst_port, |
||||
void *data, size_t data_len, uint16_t netif, |
||||
bool random_src_port); |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* STACK_H_ */ |
||||
/** @} */ |
@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
# Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de> |
||||
# |
||||
# 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 |
||||
# directory for more details. |
||||
|
||||
import os |
||||
import sys |
||||
|
||||
from datetime import datetime |
||||
|
||||
sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner')) |
||||
import testrunner |
||||
|
||||
class InvalidTimeout(Exception): |
||||
pass |
||||
|
||||
def testfunc(child): |
||||
child.expect_exact(u"Calling test_sock_udp_create__EADDRINUSE()") |
||||
child.expect_exact(u"Calling test_sock_udp_create__EAFNOSUPPORT()") |
||||
child.expect_exact(u"Calling test_sock_udp_create__EINVAL_addr()") |
||||
child.expect_exact(u"Calling test_sock_udp_create__EINVAL_netif()") |
||||
child.expect_exact(u"Calling test_sock_udp_create__no_endpoints()") |
||||
child.expect_exact(u"Calling test_sock_udp_create__only_local()") |
||||
child.expect_exact(u"Calling test_sock_udp_create__only_local_reuse_ep()") |
||||
child.expect_exact(u"Calling test_sock_udp_create__only_remote()") |
||||
child.expect_exact(u"Calling test_sock_udp_create__full()") |
||||
child.expect_exact(u"Calling test_sock_udp_recv__EADDRNOTAVAIL()") |
||||
child.expect_exact(u"Calling test_sock_udp_recv__EAGAIN()") |
||||
child.expect_exact(u"Calling test_sock_udp_recv__ENOBUFS()") |
||||
child.expect_exact(u"Calling test_sock_udp_recv__EPROTO()") |
||||
child.expect_exact(u"Calling test_sock_udp_recv__ETIMEDOUT()") |
||||
child.match # get to ensure program reached that point |
||||
start = datetime.now() |
||||
child.expect_exact(u" * Calling sock_udp_recv()") |
||||
child.expect(u" \\* \\(timed out with timeout (\\d+)\\)") |
||||
exp_diff = int(child.match.group(1)) |
||||
stop = datetime.now() |
||||
diff = (stop - start) |
||||
diff = (diff.seconds * 1000000) + diff.microseconds |
||||
# fail within 5% of expected |
||||
if diff > (exp_diff + (exp_diff * 0.05)) or \ |
||||
diff < (exp_diff - (exp_diff * 0.05)): |
||||
raise InvalidTimeout("Invalid timeout %d (expected %d)" % (diff, exp_diff)); |
||||
else: |
||||
print("Timed out correctly: %d (expected %d)" % (diff, exp_diff)) |
||||
child.expect_exact(u"Calling test_sock_udp_recv__socketed()") |
||||
child.expect_exact(u"Calling test_sock_udp_recv__socketed_with_remote()") |
||||
child.expect_exact(u"Calling test_sock_udp_recv__unsocketed()") |
||||
child.expect_exact(u"Calling test_sock_udp_recv__unsocketed_with_remote()") |
||||
child.expect_exact(u"Calling test_sock_udp_recv__with_timeout()") |
||||
child.expect_exact(u"Calling test_sock_udp_recv__non_blocking()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__EAFNOSUPPORT()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__EINVAL_addr()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__EINVAL_netif()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__EINVAL_port()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__ENOTCONN()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__socketed_no_local_no_netif()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__socketed_no_netif()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__socketed_no_local()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__socketed()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__socketed_other_remote()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__unsocketed_no_local_no_netif()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__unsocketed_no_netif()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__unsocketed_no_local()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__unsocketed()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__no_sock_no_netif()") |
||||
child.expect_exact(u"Calling test_sock_udp_send__no_sock()") |
||||
child.expect_exact(u"ALL TESTS SUCCESSFUL") |
||||
|
||||
if __name__ == "__main__": |
||||
sys.exit(testrunner.run(testfunc)) |
Loading…
Reference in new issue