Skip to content

Commit 5531692

Browse files
jukkarkartben
authored andcommitted
tests: net: socket: udp: Add IP_LOCAL_PORT_RANGE socket option tests
Make sure that the IP_LOCAL_PORT_RANGE socket option works as expected. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent b0b2022 commit 5531692

File tree

3 files changed

+171
-1
lines changed

3 files changed

+171
-1
lines changed

tests/net/socket/udp/prj.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ CONFIG_TEST_RANDOM_GENERATOR=y
2121

2222
CONFIG_MAIN_STACK_SIZE=2048
2323
CONFIG_ZTEST_STACK_SIZE=2048
24-
CONFIG_HEAP_MEM_POOL_SIZE=256
24+
CONFIG_HEAP_MEM_POOL_SIZE=512
2525

2626
CONFIG_ZTEST=y
2727
CONFIG_NET_TEST=y

tests/net/socket/udp/src/main.c

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2925,6 +2925,173 @@ ZTEST(net_socket_udp, test_39_ipv4_multicast_ifindex)
29252925
loopback_enable_address_swap(true);
29262926
}
29272927

2928+
#if defined(CONFIG_NET_CONTEXT_CLAMP_PORT_RANGE)
2929+
2930+
#define PORT_RANGE(lower, upper) \
2931+
(uint32_t)(((uint16_t)(upper) << 16) | (uint16_t)(lower))
2932+
2933+
static void check_port_range(struct sockaddr *my_addr,
2934+
size_t my_addr_len,
2935+
struct sockaddr *local_addr,
2936+
size_t local_addr_len)
2937+
{
2938+
sa_family_t family = AF_UNSPEC;
2939+
uint32_t optval;
2940+
size_t addr_len;
2941+
size_t optlen;
2942+
int sock;
2943+
int ret, err;
2944+
2945+
addr_len = local_addr_len;
2946+
2947+
if (my_addr->sa_family == AF_INET) {
2948+
family = AF_INET;
2949+
} else if (my_addr->sa_family == AF_INET6) {
2950+
family = AF_INET6;
2951+
} else {
2952+
zassert_true(false, "Invalid address family %d",
2953+
my_addr->sa_family);
2954+
}
2955+
2956+
sock = zsock_socket(family, SOCK_DGRAM, IPPROTO_UDP);
2957+
zassert_true(sock >= 0, "Cannot create socket (%d)", -errno);
2958+
2959+
optval = PORT_RANGE(1024, 1500);
2960+
ret = zsock_setsockopt(sock, IPPROTO_IP, IP_LOCAL_PORT_RANGE,
2961+
&optval, sizeof(optval));
2962+
err = -errno;
2963+
zexpect_equal(ret, 0, "setsockopt failed (%d)", err);
2964+
2965+
optval = 0; optlen = 0U;
2966+
ret = zsock_setsockopt(sock, IPPROTO_IP, IP_LOCAL_PORT_RANGE,
2967+
&optval, optlen);
2968+
err = -errno;
2969+
zexpect_equal(ret, -1, "setsockopt failed (%d)", err);
2970+
2971+
optval = 0; optlen = sizeof(uint64_t);
2972+
ret = zsock_setsockopt(sock, IPPROTO_IP, IP_LOCAL_PORT_RANGE,
2973+
&optval, optlen);
2974+
err = -errno;
2975+
zexpect_equal(ret, -1, "setsockopt failed (%d)", err);
2976+
2977+
optval = PORT_RANGE(0, 0);
2978+
ret = zsock_setsockopt(sock, IPPROTO_IP, IP_LOCAL_PORT_RANGE,
2979+
&optval, sizeof(optval));
2980+
zexpect_equal(ret, 0, "setsockopt failed (%d)", err);
2981+
2982+
/* Linux allows setting the invalid port range but that is not
2983+
* then taken into use when we bind the socket.
2984+
*/
2985+
optval = PORT_RANGE(1024, 0);
2986+
ret = zsock_setsockopt(sock, IPPROTO_IP, IP_LOCAL_PORT_RANGE,
2987+
&optval, sizeof(optval));
2988+
zexpect_equal(ret, 0, "setsockopt failed (%d)", err);
2989+
2990+
optval = PORT_RANGE(0, 1024);
2991+
ret = zsock_setsockopt(sock, IPPROTO_IP, IP_LOCAL_PORT_RANGE,
2992+
&optval, sizeof(optval));
2993+
zexpect_equal(ret, 0, "setsockopt failed (%d)", err);
2994+
2995+
/* Then set a valid range and verify that bound socket is using it */
2996+
optval = PORT_RANGE(10000, 10010);
2997+
ret = zsock_setsockopt(sock, IPPROTO_IP, IP_LOCAL_PORT_RANGE,
2998+
&optval, sizeof(optval));
2999+
zexpect_equal(ret, 0, "setsockopt failed (%d)", err);
3000+
3001+
optval = 0; optlen = sizeof(optval);
3002+
ret = zsock_getsockopt(sock, IPPROTO_IP, IP_LOCAL_PORT_RANGE,
3003+
&optval, &optlen);
3004+
zexpect_equal(ret, 0, "setsockopt failed (%d)", err);
3005+
zexpect_equal(optval, PORT_RANGE(10000, 10010), "Invalid port range");
3006+
3007+
ret = zsock_bind(sock, my_addr, my_addr_len);
3008+
err = -errno;
3009+
zexpect_equal(ret, 0, "bind failed (%d)", err);
3010+
3011+
ret = zsock_getsockname(sock, local_addr, &addr_len);
3012+
err = -errno;
3013+
zexpect_equal(ret, 0, "getsockname failed (%d)", err);
3014+
3015+
/* The port should be in the range */
3016+
zexpect_true(ntohs(net_sin(local_addr)->sin_port) >= 10000 &&
3017+
ntohs(net_sin(local_addr)->sin_port) <= 10010,
3018+
"Invalid port %d", ntohs(net_sin(local_addr)->sin_port));
3019+
3020+
(void)zsock_close(sock);
3021+
3022+
/* Try setting invalid range and verify that we do not net a port from that
3023+
* range.
3024+
*/
3025+
sock = zsock_socket(family, SOCK_DGRAM, IPPROTO_UDP);
3026+
zassert_true(sock >= 0, "Cannot create socket (%d)", -errno);
3027+
3028+
optval = PORT_RANGE(1001, 1000);
3029+
ret = zsock_setsockopt(sock, IPPROTO_IP, IP_LOCAL_PORT_RANGE,
3030+
&optval, sizeof(optval));
3031+
err = -errno;
3032+
zexpect_equal(ret, -1, "setsockopt failed (%d)", err);
3033+
zexpect_equal(err, -EINVAL, "Invalid errno (%d)", -err);
3034+
3035+
/* Port range cannot be just one port */
3036+
optval = PORT_RANGE(1001, 1001);
3037+
ret = zsock_setsockopt(sock, IPPROTO_IP, IP_LOCAL_PORT_RANGE,
3038+
&optval, sizeof(optval));
3039+
err = -errno;
3040+
zexpect_equal(ret, -1, "setsockopt failed (%d)", err);
3041+
zexpect_equal(err, -EINVAL, "Invalid errno (%d)", -err);
3042+
3043+
optval = PORT_RANGE(0, 1000);
3044+
ret = zsock_setsockopt(sock, IPPROTO_IP, IP_LOCAL_PORT_RANGE,
3045+
&optval, sizeof(optval));
3046+
err = -errno;
3047+
zexpect_equal(ret, 0, "setsockopt failed (%d)", err);
3048+
3049+
ret = zsock_bind(sock, my_addr, my_addr_len);
3050+
err = -errno;
3051+
zexpect_equal(ret, 0, "bind failed (%d)", err);
3052+
3053+
addr_len = local_addr_len;
3054+
ret = zsock_getsockname(sock, local_addr, &addr_len);
3055+
err = -errno;
3056+
zexpect_equal(ret, 0, "getsockname failed (%d)", err);
3057+
3058+
/* The port should not be in the range */
3059+
zexpect_false(ntohs(net_sin(local_addr)->sin_port) >= 1000 &&
3060+
ntohs(net_sin(local_addr)->sin_port) <= 1001,
3061+
"Invalid port %d", ntohs(net_sin(local_addr)->sin_port));
3062+
3063+
(void)zsock_close(sock);
3064+
}
3065+
#endif
3066+
3067+
ZTEST(net_socket_udp, test_40_clamp_udp_tcp_port_range)
3068+
{
3069+
#if defined(CONFIG_NET_CONTEXT_CLAMP_PORT_RANGE)
3070+
struct sockaddr_in my_addr4 = {
3071+
.sin_family = AF_INET,
3072+
.sin_port = 0,
3073+
.sin_addr = { { { 192, 0, 2, 2 } } },
3074+
};
3075+
struct sockaddr_in6 my_addr6 = {
3076+
.sin6_family = AF_INET6,
3077+
.sin6_port = 0,
3078+
.sin6_addr = in6addr_loopback,
3079+
};
3080+
struct sockaddr_in local_addr4;
3081+
struct sockaddr_in6 local_addr6;
3082+
3083+
/* First try with a IPv4 socket */
3084+
check_port_range((struct sockaddr *)&my_addr4, sizeof(my_addr4),
3085+
(struct sockaddr *)&local_addr4, sizeof(local_addr4));
3086+
3087+
/* Finally try with a IPv6 socket */
3088+
check_port_range((struct sockaddr *)&my_addr6, sizeof(my_addr6),
3089+
(struct sockaddr *)&local_addr6, sizeof(local_addr6));
3090+
#else
3091+
ztest_test_skip();
3092+
#endif
3093+
}
3094+
29283095
static void after(void *arg)
29293096
{
29303097
ARG_UNUSED(arg);

tests/net/socket/udp/testcase.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ tests:
1919
net.socket.udp.pktinfo:
2020
extra_configs:
2121
- CONFIG_NET_CONTEXT_RECV_PKTINFO=y
22+
net.socket.udp.port_range:
23+
extra_configs:
24+
- CONFIG_NET_CONTEXT_CLAMP_PORT_RANGE=y
2225
net.socket.udp.ttl:
2326
extra_configs:
2427
- CONFIG_NET_SOCKETS_PACKET=y

0 commit comments

Comments
 (0)