blob: 24f76620990142dc7221e8464d058207205ad020 [file] [log] [blame]
/*
* Copyright (c) 2017 Linaro Limited
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <ztest_assert.h>
#include <net/socket.h>
#define BUF_AND_SIZE(buf) buf, sizeof(buf) - 1
#define STRLEN(buf) (sizeof(buf) - 1)
#define TEST_STR_SMALL "test"
#define ANY_PORT 0
#define SERVER_PORT 4242
#define CLIENT_PORT 9898
static void prepare_sock_v4(const char *addr,
u16_t port,
int *sock,
struct sockaddr_in *sockaddr)
{
int rv;
zassert_not_null(addr, "null addr");
zassert_not_null(sock, "null sock");
zassert_not_null(sockaddr, "null sockaddr");
*sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
zassert_true(*sock >= 0, "socket open failed");
sockaddr->sin_family = AF_INET;
sockaddr->sin_port = htons(port);
rv = inet_pton(AF_INET, addr, &sockaddr->sin_addr);
zassert_equal(rv, 1, "inet_pton failed");
}
static void prepare_sock_v6(const char *addr,
u16_t port,
int *sock,
struct sockaddr_in6 *sockaddr)
{
int rv;
zassert_not_null(addr, "null addr");
zassert_not_null(sock, "null sock");
zassert_not_null(sockaddr, "null sockaddr");
*sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
zassert_true(*sock >= 0, "socket open failed");
sockaddr->sin6_family = AF_INET6;
sockaddr->sin6_port = htons(port);
rv = inet_pton(AF_INET6, addr, &sockaddr->sin6_addr);
zassert_equal(rv, 1, "inet_pton failed");
}
static void test_sendto_recvfrom(int client_sock,
struct sockaddr *client_addr,
socklen_t client_addrlen,
int server_sock,
struct sockaddr *server_addr,
socklen_t server_addrlen)
{
ssize_t sent = 0;
ssize_t recved = 0;
struct sockaddr addr;
socklen_t addrlen;
char rx_buf[30] = {0};
zassert_not_null(client_addr, "null client addr");
zassert_not_null(server_addr, "null server addr");
sent = sendto(client_sock,
TEST_STR_SMALL,
strlen(TEST_STR_SMALL),
0,
server_addr,
server_addrlen);
zassert_equal(sent, strlen(TEST_STR_SMALL), "sendto failed");
addrlen = sizeof(addr);
recved = recvfrom(server_sock,
rx_buf,
sizeof(rx_buf),
0,
&addr,
&addrlen);
zassert_true(recved > 0, "recvfrom fail");
zassert_equal(recved,
strlen(TEST_STR_SMALL),
"unexpected received bytes");
zassert_equal(strncmp(rx_buf, TEST_STR_SMALL, strlen(TEST_STR_SMALL)),
0,
"unexpected data");
zassert_equal(addrlen, client_addrlen, "unexpected addrlen");
/* Check the client port */
if (net_sin(client_addr)->sin_port != ANY_PORT) {
zassert_equal(net_sin(client_addr)->sin_port,
net_sin(&addr)->sin_port,
"unexpected client port");
}
}
void test_v4_sendto_recvfrom(void)
{
int rv;
int client_sock;
int server_sock;
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
prepare_sock_v4(CONFIG_NET_APP_MY_IPV4_ADDR,
ANY_PORT,
&client_sock,
&client_addr);
prepare_sock_v4(CONFIG_NET_APP_MY_IPV4_ADDR,
SERVER_PORT,
&server_sock,
&server_addr);
rv = bind(server_sock,
(struct sockaddr *)&server_addr,
sizeof(server_addr));
zassert_equal(rv, 0, "bind failed");
test_sendto_recvfrom(client_sock,
(struct sockaddr *)&client_addr,
sizeof(client_addr),
server_sock,
(struct sockaddr *)&server_addr,
sizeof(server_addr));
rv = close(client_sock);
zassert_equal(rv, 0, "close failed");
rv = close(server_sock);
zassert_equal(rv, 0, "close failed");
}
void test_v6_sendto_recvfrom(void)
{
int rv;
int client_sock;
int server_sock;
struct sockaddr_in6 client_addr;
struct sockaddr_in6 server_addr;
prepare_sock_v6(CONFIG_NET_APP_MY_IPV6_ADDR,
ANY_PORT,
&client_sock,
&client_addr);
prepare_sock_v6(CONFIG_NET_APP_MY_IPV6_ADDR,
SERVER_PORT,
&server_sock,
&server_addr);
rv = bind(server_sock,
(struct sockaddr *)&server_addr,
sizeof(server_addr));
zassert_equal(rv, 0, "bind failed");
test_sendto_recvfrom(client_sock,
(struct sockaddr *)&client_addr,
sizeof(client_addr),
server_sock,
(struct sockaddr *)&server_addr,
sizeof(server_addr));
rv = close(client_sock);
zassert_equal(rv, 0, "close failed");
rv = close(server_sock);
zassert_equal(rv, 0, "close failed");
}
void test_v4_bind_sendto(void)
{
int rv;
int client_sock;
int server_sock;
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
prepare_sock_v4(CONFIG_NET_APP_MY_IPV4_ADDR,
CLIENT_PORT,
&client_sock,
&client_addr);
prepare_sock_v4(CONFIG_NET_APP_MY_IPV4_ADDR,
SERVER_PORT,
&server_sock,
&server_addr);
rv = bind(client_sock,
(struct sockaddr *)&client_addr,
sizeof(client_addr));
zassert_equal(rv, 0, "bind failed");
rv = bind(server_sock,
(struct sockaddr *)&server_addr,
sizeof(server_addr));
zassert_equal(rv, 0, "bind failed");
test_sendto_recvfrom(client_sock,
(struct sockaddr *)&client_addr,
sizeof(client_addr),
server_sock,
(struct sockaddr *)&server_addr,
sizeof(server_addr));
rv = close(client_sock);
zassert_equal(rv, 0, "close failed");
rv = close(server_sock);
zassert_equal(rv, 0, "close failed");
}
void test_v6_bind_sendto(void)
{
int rv;
int client_sock;
int server_sock;
struct sockaddr_in6 client_addr;
struct sockaddr_in6 server_addr;
prepare_sock_v6(CONFIG_NET_APP_MY_IPV6_ADDR,
CLIENT_PORT,
&client_sock,
&client_addr);
prepare_sock_v6(CONFIG_NET_APP_MY_IPV6_ADDR,
SERVER_PORT,
&server_sock,
&server_addr);
rv = bind(client_sock,
(struct sockaddr *)&client_addr,
sizeof(client_addr));
zassert_equal(rv, 0, "bind failed");
rv = bind(server_sock,
(struct sockaddr *)&server_addr,
sizeof(server_addr));
zassert_equal(rv, 0, "bind failed");
test_sendto_recvfrom(client_sock,
(struct sockaddr *)&client_addr,
sizeof(client_addr),
server_sock,
(struct sockaddr *)&server_addr,
sizeof(server_addr));
rv = close(client_sock);
zassert_equal(rv, 0, "close failed");
rv = close(server_sock);
zassert_equal(rv, 0, "close failed");
}
void test_send_recv_2_sock(void)
{
int sock1, sock2;
struct sockaddr_in bind_addr, conn_addr;
char buf[10];
int len, cmp;
sock1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
sock2 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
bind_addr.sin_family = AF_INET;
bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind_addr.sin_port = htons(55555);
bind(sock1, (struct sockaddr *)&bind_addr, sizeof(bind_addr));
conn_addr.sin_family = AF_INET;
conn_addr.sin_addr.s_addr = htonl(0xc0000201);
conn_addr.sin_port = htons(55555);
connect(sock2, (struct sockaddr *)&conn_addr, sizeof(conn_addr));
send(sock2, BUF_AND_SIZE(TEST_STR_SMALL), 0);
len = recv(sock1, buf, sizeof(buf), 0);
zassert_equal(len, 4, "Invalid recv len");
cmp = memcmp(buf, TEST_STR_SMALL, STRLEN(TEST_STR_SMALL));
zassert_equal(cmp, 0, "Invalid recv data");
}
void test_main(void)
{
ztest_test_suite(socket_udp,
ztest_unit_test(test_send_recv_2_sock),
ztest_unit_test(test_v4_sendto_recvfrom),
ztest_unit_test(test_v6_sendto_recvfrom),
ztest_unit_test(test_v4_bind_sendto),
ztest_unit_test(test_v6_bind_sendto));
ztest_run_test_suite(socket_udp);
}