diff --git a/Makefile.dep b/Makefile.dep index 2c7dd622e48b7..c98b7d8119ae3 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -231,6 +231,10 @@ ifneq (,$(filter uart0,$(USEMODULE))) USEMODULE += posix endif +ifneq (,$(filter posix_sockets,$(USEMODULE))) + USEMODULE += posix +endif + ifneq (,$(filter posix,$(USEMODULE))) USEMODULE += timex USEMODULE += vtimer diff --git a/sys/posix/include/netinet/in.h b/sys/posix/include/netinet/in.h index d951336cfc7a6..9ad29a9a9a33d 100644 --- a/sys/posix/include/netinet/in.h +++ b/sys/posix/include/netinet/in.h @@ -193,8 +193,9 @@ extern "C" { */ #define IPPROTO_IP (PROTNUM_IPV4) /**< Internet Protocol version 4 */ #define IPPROTO_IPV6 (PROTNUM_IPV6) /**< Internet Protocol version 6 */ -#define IPPROTO_ICMP (PROTNUM_ICMP) /**< Internet Protocol version 6 */ -#define IPPROTO_RAW (PROTNUM_IPV6_NONXT) /**< Raw IP packets protocol */ +#define IPPROTO_ICMP (PROTNUM_ICMP) /**< Internet Control Message Protocol */ +#define IPPROTO_ICMPV6 (PROTNUM_ICMPV6) /**< ICMP for IPv6 */ +#define IPPROTO_RAW (PROTNUM_RESERVED) /**< Raw IP packets protocol */ #define IPPROTO_TCP (PROTNUM_TCP) /**< Transmission control protocol */ #define IPPROTO_UDP (PROTNUM_UDP) /**< User datagram protocol */ /** @} */ diff --git a/sys/posix/sockets/posix_sockets.c b/sys/posix/sockets/posix_sockets.c index aaa8c3497d6f7..ae749c147e7d8 100644 --- a/sys/posix/sockets/posix_sockets.c +++ b/sys/posix/sockets/posix_sockets.c @@ -14,6 +14,7 @@ * @todo */ +#include #include #include "fd.h" diff --git a/tests/gnrc_ip6_sockets/Makefile b/tests/gnrc_ip6_sockets/Makefile new file mode 100644 index 0000000000000..4e2c7e2a42249 --- /dev/null +++ b/tests/gnrc_ip6_sockets/Makefile @@ -0,0 +1,13 @@ +APPLICATION = gnrc_ip6_sockets +include ../Makefile.tests_common + +USEMODULE += conn_ip6_gnrc +USEMODULE += ng_icmpv6_echo # include to have system internal handler +USEMODULE += ng_ipv6_default +USEMODULE += od +USEMODULE += posix_sockets +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += vtimer + +include $(RIOTBASE)/Makefile.include diff --git a/tests/gnrc_ip6_sockets/main.c b/tests/gnrc_ip6_sockets/main.c new file mode 100644 index 0000000000000..4c6e7a8bcca20 --- /dev/null +++ b/tests/gnrc_ip6_sockets/main.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2015 Martine Lenders + * + * 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 + */ + +#include +#include +#include +#include +#include +#include + +#include "net/icmpv6.h" +#include "od.h" +#include "shell.h" +#include "thread.h" + +#define RCV_STACKSIZE (THREAD_STACKSIZE_DEFAULT + THREAD_EXTRA_STACKSIZE_PRINTF) +#define RCV_PRIO (THREAD_PRIORITY_MAIN - 5) +#define BUFSIZE (16) + +static char rcv_stack[RCV_STACKSIZE]; +static char rcv_buf[BUFSIZE]; +static char snd_buf[BUFSIZE]; + +static void *rcv(void *arg) +{ + int s; + struct sockaddr_in6 local, addr; + socklen_t addr_len = sizeof(addr); + (void)arg; + if ((s = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { + puts("could not open receive socket"); + return NULL; + } + memcpy(&local, &in6addr_any, sizeof(struct sockaddr_in6)); + if (bind(s, (struct sockaddr *)&local, sizeof(local)) < 0) { + puts("could not bind receive socket"); + close(s); + return NULL; + } + while (1) { + int res = recvfrom(s, rcv_buf, sizeof(rcv_buf), 0, (struct sockaddr *)&addr, &addr_len); + if (res < 0) { + puts("error receiving packet"); + continue; + } + puts("received ICMPv6 packet"); + od_hex_dump(rcv_buf, res, 0); + } + return NULL; +} + +static int snd(int argc, char **argv) +{ + icmpv6_hdr_t *hdr = (icmpv6_hdr_t *)snd_buf; + void *data = snd_buf + sizeof(icmpv6_hdr_t); + int s; + struct sockaddr_in6 local, addr; + const size_t max_size = BUFSIZE - sizeof(icmpv6_hdr_t); + size_t size; + if (argc < 3) { + printf("usage: %s ipv6_addr data\n", argv[0]); + return 1; + } + memset(&addr, 0, sizeof(addr)); + addr.sin6_family = 0; + if (inet_pton(AF_INET6, argv[1], &addr.sin6_addr) < 0) { + printf("usage: %s ipv6_addr data\n", argv[0]); + return 1; + } + if ((s = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { + puts("could not open send socket"); + return 1; + } + memcpy(&local, &in6addr_any, sizeof(struct sockaddr_in6)); + if (bind(s, (struct sockaddr *)&local, sizeof(local)) < 0) { + puts("could not bind send socket"); + close(s); + return 1; + } + hdr->type = ICMPV6_ECHO_REQ; + hdr->code = 0; + hdr->csum.u16 = 0; + size = strlen(argv[2]); + size = (size > max_size) ? max_size : size; + memcpy(data, argv[2], size); + if (sendto(s, snd_buf, size, 0, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + puts("error sending packet"); + } + close(s); + return 0; +} + +static const shell_command_t shell_commands[] = { + { "snd", "send data over ICMPv6 echo request", snd }, + { NULL, NULL, NULL } +}; + +int main(void) +{ + shell_t shell; + thread_create(rcv_stack, sizeof(rcv_stack), RCV_PRIO, CREATE_STACKTEST, + rcv, NULL, "rcv"); + shell_init(&shell, shell_commands, UART0_BUFSIZE, getchar, putchar); + shell_run(&shell); + return 0; +} + +/** @} */