1/*
2 * Copyright (C) 2024 HiHope Open Source Organization.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <cerrno>
17#include <cstdio>
18#include <cstdlib>
19#include <string>
20#include <vector>
21#include <fcntl.h>
22#include <unistd.h>
23#include <arpa/inet.h>
24#include <gtest/gtest.h>
25#include <linux/filter.h>
26#include <linux/if_ether.h>
27#include <linux/in6.h>
28#include <linux/netlink.h>
29#include <netinet/in.h>
30#include <netinet/tcp.h>
31#include <sys/stat.h>
32#include <sys/socket.h>
33#include <sys/types.h>
34#include <linux/netfilter_ipv4/ip_tables.h>
35#include <linux/netfilter_ipv6/ip6_tables.h>
36#include "securec.h"
37
38using namespace testing::ext;
39
40static const int BAD_SOCKET_FD = -1;
41static const int MAX_SIZE = 1024;
42
43
44struct SetOptionSupportTest {
45    std::string name;
46    int domain;
47    int type;
48    int optLevel;
49    int optName;
50    int ret;
51    int optVal;
52    int optLen;
53} g_setOpt[] = {
54    {"SO_BINDTODEVICE",     AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_BINDTODEVICE,    0,      0,  0},
55    {"SO_DEBUG",            AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_DEBUG,           0,      1,  4},
56    {"SO_REUSEADDR",        AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_REUSEADDR,       0,      1,  4},
57    {"SO_REUSEPORT",        AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_REUSEPORT,       0,      1,  4},
58    {"SO_BUSY_POLL",        AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_BUSY_POLL,       0,      1,  4},
59    {"SO_DONTROUTE",        AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_DONTROUTE,       0,      1,  4},
60    {"SO_BROADCAST",        AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_BROADCAST,       0,      1,  4},
61    {"SO_SNDBUFFORCE",      AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_SNDBUFFORCE,     0, 0x40000, 4},
62    {"IP_TRANSPARENT",      AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_TRANSPARENT,     0,      1,  4},
63    {"SO_RCVBUFFORCE",      AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_RCVBUFFORCE,     0, 0x40000, 4},
64    {"TCP_REPAIR",          AF_INET,    SOCK_STREAM,    SOL_TCP,        TCP_REPAIR,         0,      1,      4},
65    {"SO_KEEPALIVE",        AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_KEEPALIVE,       0,      1,  4},
66    {"SO_OOBINLINE",        AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_OOBINLINE,       0,      1,  4},
67    {"SO_NO_CHECK",         AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_NO_CHECK,        0,      1,  4},
68    {"SO_PRIORITY",         AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_PRIORITY,        0,      1,  4},
69    {"SO_BSDCOMPAT",        AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_BSDCOMPAT,       0,      0,  4},
70    {"SO_PASSCRED",         AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_PASSCRED,        0,      1,  4},
71    {"SO_TIMESTAMP",        AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_TIMESTAMP,       0,      1,  4},
72    {"SO_TIMESTAMPNS",      AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_TIMESTAMPNS,     0,      1,  4},
73    {"SO_RCVLOWAT",         AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_RCVLOWAT,        0,      1,  4},
74    {"SO_PASSSEC",          AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_PASSSEC,         0,      1,  4},
75    {"SO_MARK",             AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_MARK,            0,    100,  4},
76    {"SO_RXQ_OVFL",         AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_RXQ_OVFL,        0,      1,  4},
77    {"SO_WIFI_STATUS",      AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_WIFI_STATUS,     0,      1,  4},
78    {"SO_NOFCS",            AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_NOFCS,           0,      1,  4},
79    {"SO_SELECT_ERR_QUEUE", AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_SELECT_ERR_QUEUE, 0,     1,  4},
80    {"SO_MAX_PACING_RATE",  AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_MAX_PACING_RATE, 0,      1,  4},
81    {"SO_INCOMING_CPU",     AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_INCOMING_CPU,    0,      1,  4},
82    {"IP_RECVOPTS",         AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_RECVOPTS,        0,      1,  4},
83    {"IP_RECVTOS",          AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_RECVTOS,         0,      1,  4},
84    {"IP_RETOPTS",          AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_RETOPTS,         0,      1,  4},
85    {"IP_MTU_DISCOVER",     AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_MTU_DISCOVER,    0,      1,  4},
86    {"IP_RECVERR",          AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_RECVERR,         0,      1,  4},
87    {"IP_FREEBIND",         AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_FREEBIND,        0,      1,  4},
88    {"IP_PASSSEC",          AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_PASSSEC,         0,      1,  4},
89    {"IP_MINTTL",           AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_MINTTL,          0,      1,  4},
90    {"IP_BIND_ADDRESS_NO_PORT", AF_INET, SOCK_STREAM,   IPPROTO_IP,     IP_BIND_ADDRESS_NO_PORT, 0, 1,  4},
91    {"IP_RECVORIGDSTADDR",  AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_RECVORIGDSTADDR, 0,      1,  4},
92    {"IP_CHECKSUM",         AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_CHECKSUM,        0,      1,  4},
93    {"IP_OPTIONS",          AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_OPTIONS,         0,      1,  4},
94    {"IP_PKTINFO",          AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_PKTINFO,         0,      1,  4},
95    {"IP_RECVTTL",          AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_RECVTTL,         0,      1,  4},
96    {"IP_TOS",              AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_TOS,             0,      0,  4},
97    {"IP_TTL",              AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_TTL,             0,      1,  4},
98    {"IP_MULTICAST_LOOP",   AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_MULTICAST_LOOP,  0,      1,  4},
99    {"IP_MULTICAST_ALL",    AF_INET6,   SOCK_STREAM,    IPPROTO_IP,     IP_MULTICAST_ALL,   0,      1,  4},
100    {"IPV6_V6ONLY",         AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_V6ONLY,        0,      1,  4},
101    {"IPV6_RECVPKTINFO",    AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_RECVPKTINFO,   0,      1,  4},
102    {"IPV6_2292PKTINFO",    AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_2292PKTINFO,   0,      1,  4},
103    {"IPV6_RECVHOPLIMIT",   AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_RECVHOPLIMIT,  0,      1,  4},
104    {"IPV6_2292HOPLIMIT",   AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_2292HOPLIMIT,  0,      1,  4},
105    {"IPV6_RECVRTHDR",      AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_RECVRTHDR,     0,      1,  4},
106    {"IPV6_2292RTHDR",      AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_2292RTHDR,     0,      1,  4},
107    {"IPV6_RECVHOPOPTS",    AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_RECVHOPOPTS,   0,      1,  4},
108    {"IPV6_2292HOPOPTS",    AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_2292HOPOPTS,   0,      1,  4},
109    {"IPV6_RECVDSTOPTS",    AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_RECVDSTOPTS,   0,      1,  4},
110    {"IPV6_2292DSTOPTS",    AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_2292DSTOPTS,   0,      1,  4},
111    {"IPV6_TCLASS",         AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_TCLASS,        0,      1,  4},
112    {"IPV6_RECVTCLASS",     AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_RECVTCLASS,    0,      1,  4},
113    {"IPV6_RECVPATHMTU",    AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_RECVPATHMTU,   0,      1,  4},
114    {"IPV6_TRANSPARENT",    AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_TRANSPARENT,   0,      1,  4},
115    {"IPV6_RECVORIGDSTADDR", AF_INET6,  SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_RECVORIGDSTADDR, 0,    1,  4},
116    {"IPV6_UNICAST_HOPS",   AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_UNICAST_HOPS,   0,     1,  4},
117    {"IPV6_MULTICAST_HOPS", AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_MULTICAST_HOPS, 0,     1,  4},
118    {"IPV6_MULTICAST_LOOP", AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_MULTICAST_LOOP, 0,     1,  4},
119    {"IPV6_MULTICAST_IF",   AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_MULTICAST_IF,   0,     1,  4},
120    {"IPV6_MTU_DISCOVER",   AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_MTU_DISCOVER,   0,     1,  4},
121    {"IPV6_RECVERR",        AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_RECVERR,        0,     1,  4},
122    {"IPV6_ADDR_PREFERENCES", AF_INET6, SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_ADDR_PREFERENCES, 0,   1,  4},
123    {"IPV6_MINHOPCOUNT",    AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_MINHOPCOUNT,    0,     1,  4},
124    {"IPV6_DONTFRAG",       AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_DONTFRAG,       0,     1,  4},
125    {"IPV6_AUTOFLOWLABEL",  AF_INET6,   SOCK_DGRAM,     IPPROTO_IPV6,   IPV6_AUTOFLOWLABEL,  0,     1,  4},
126    {"TCP_NODELAY",         AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_NODELAY,         0,     1,  4},
127    {"TCP_THIN_LINEAR_TIMEOUTS", AF_INET, SOCK_STREAM,  IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, 0,   1,  4},
128    {"TCP_THIN_DUPACK",     AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_THIN_DUPACK,     0,     0,  4},
129    {"TCP_CORK",            AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_CORK,            0,     1,  4},
130    {"TCP_KEEPIDLE",        AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_KEEPIDLE,        0,     1,  4},
131    {"TCP_KEEPINTVL",       AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_KEEPINTVL,       0,     1,  4},
132    {"TCP_KEEPCNT",         AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_KEEPCNT,         0,     1,  4},
133    {"TCP_SYNCNT",          AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_SYNCNT,          0,     1,  4},
134    {"TCP_SAVE_SYN",        AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_SAVE_SYN,        0,     1,  4},
135    {"TCP_LINGER2",         AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_LINGER2,         0,     1,  4},
136    {"TCP_DEFER_ACCEPT",    AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_DEFER_ACCEPT,    0,     1,  4},
137    {"TCP_WINDOW_CLAMP",    AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_WINDOW_CLAMP,    0,     0,  4},
138    {"TCP_QUICKACK",        AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_QUICKACK,        0,     1,  4},
139    {"TCP_USER_TIMEOUT",    AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_USER_TIMEOUT,    0,     1,  4},
140    {"TCP_FASTOPEN",        AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_FASTOPEN,        0,     1,  4},
141    {"TCP_NOTSENT_LOWAT",   AF_INET,    SOCK_STREAM,    IPPROTO_TCP,    TCP_NOTSENT_LOWAT,   0,     1,  4},
142    {"TCP_FASTOPEN_CONNECT", AF_INET,   SOCK_STREAM,    IPPROTO_TCP,    TCP_FASTOPEN_CONNECT, 0,    1,  4},
143};
144
145struct GetOptionOnlySupportTest {
146    std::string name;
147    int domain;
148    int type;
149    int optLevel;
150    int optName;
151    int ret;
152    int optVal;
153    int optLen;
154} g_getOnlyOpt[] = {
155    {"SO_TYPE",             AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_TYPE,            0,      1,  4},
156    {"SO_PROTOCOL",         AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_PROTOCOL,        0,      6,  4},
157    {"SO_DOMAIN",           AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_DOMAIN,          0,      2,  4},
158    {"SO_ERROR",            AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_ERROR,           0,      0,  4},
159    {"IP_HDRINCL",          AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_HDRINCL,         0,      0,  4},
160    {"IP_NODEFRAG",         AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_NODEFRAG,        0,      0,  4},
161    {"IP_UNICAST_IF",       AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_UNICAST_IF,      0,      0,  4},
162    {"IP_MULTICAST_TTL",    AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_MULTICAST_TTL,   0,      1,  4},
163    {"IP_MULTICAST_IF",     AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_MULTICAST_IF,    0,      0,  4},
164    {"IPV6_HOPOPTS",        AF_INET6,   SOCK_STREAM,    SOL_IPV6,       IPV6_HOPOPTS,       0,      0,  0},
165    {"IPV6_RTHDRDSTOPTS",   AF_INET6,   SOCK_DGRAM,     SOL_IPV6,       IPV6_RTHDRDSTOPTS,  0,      0,  0},
166    {"IPV6_RTHDR",          AF_INET6,   SOCK_DGRAM,     SOL_IPV6,       IPV6_RTHDR,         0,      0,  0},
167    {"IPV6_DSTOPTS",        AF_INET6,   SOCK_DGRAM,     SOL_IPV6,       IPV6_DSTOPTS,       0,      0,  0},
168    {"TCP_MAXSEG",          AF_INET,    SOCK_STREAM,    SOL_TCP,        TCP_MAXSEG,         0,    536,  4},
169    {"IP_PKTOPTIONS",       AF_INET,    SOCK_STREAM,    IPPROTO_IP,     IP_PKTOPTIONS,      0,      0,  0},
170    {"TCP_INFO",            AF_INET,    SOCK_STREAM,    IPPROTO_IP,     TCP_INFO,           0,      0,   4},
171    {"TCP_CC_INFO",         AF_INET,    SOCK_STREAM,    IPPROTO_IP,     TCP_CC_INFO,        0,      0,   4},
172    {"SO_SNDLOWAT",         AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_SNDLOWAT,        0,      1,  4},
173    {"SO_ACCEPTCONN",       AF_INET,    SOCK_STREAM,    SOL_SOCKET,     SO_ACCEPTCONN,      0,      0,  4},
174};
175
176class HatsSockoptTest : public testing::Test {
177public:
178    static void SetUpTestCase();
179    static void TearDownTestCase();
180    void SetUp();
181    void TearDown();
182private:
183};
184void HatsSockoptTest::SetUp()
185{
186}
187void HatsSockoptTest::TearDown()
188{
189}
190void HatsSockoptTest::SetUpTestCase()
191{
192}
193void HatsSockoptTest::TearDownTestCase()
194{
195}
196
197/*
198 * @tc.number : SUB_KERNEL_SYSCALL_SOCKOPT_0100
199 * @tc.name   : SetAndGetsockoptSupportOptSuccess_0001
200 * @tc.desc   : setsockopt and getsockopt own support option test success.
201 * @tc.size   : MediumTest
202 * @tc.type   : Function
203 * @tc.level  : Level 1
204 */
205HWTEST_F(HatsSockoptTest, SetAndGetsockoptSupportOptSuccess_0001, Function | MediumTest | Level1)
206{
207    int ret;
208    int fd = -1;
209    int32_t optVal;
210    socklen_t optLen;
211    for (int32_t i = 0; i < sizeof(g_setOpt) / sizeof(g_setOpt[0]); i++) {
212        fd = socket(g_setOpt[i].domain, g_setOpt[i].type, 0);
213        EXPECT_TRUE(fd > 0);
214
215        ret = setsockopt(fd, g_setOpt[i].optLevel, g_setOpt[i].optName, &g_setOpt[i].optVal, g_setOpt[i].optLen);
216        EXPECT_EQ(ret, g_setOpt[i].ret);
217
218        if (g_setOpt[i].optName == SO_SNDBUFFORCE ||
219            g_setOpt[i].optName == SO_RCVBUFFORCE ||
220            g_setOpt[i].optName == IPV6_ADDR_PREFERENCES) {
221            close(fd);
222            continue;
223        }
224        optVal = 0;
225        optLen = g_setOpt[i].optLen;
226        ret = getsockopt(fd, g_setOpt[i].optLevel, g_setOpt[i].optName, &optVal, &optLen);
227        EXPECT_EQ(ret, g_setOpt[i].ret);
228        EXPECT_EQ(optVal, g_setOpt[i].optVal);
229        EXPECT_EQ(optLen, g_setOpt[i].optLen);
230        close(fd);
231    }
232
233    close(fd);
234}
235
236/*
237 * @tc.number : SUB_KERNEL_SYSCALL_SOCKOPT_0200
238 * @tc.name   : SetAndGetsockoptSndAndRcvTestSuccess_0002
239 * @tc.desc   : setsockopt and getsockopt SO_SNDBUF and SO_RCVBUF option test success.
240 * @tc.size   : MediumTest
241 * @tc.type   : Function
242 * @tc.level  : Level 1
243 */
244HWTEST_F(HatsSockoptTest, SetAndGetsockoptSndAndRcvTestSuccess_0002, Function | MediumTest | Level1)
245{
246    int ret;
247    int fd = -1;
248    int32_t optVal;
249    socklen_t optLen;
250
251    fd = socket(AF_INET, SOL_SOCKET, 0);
252    EXPECT_TRUE(fd > 0);
253
254    // setsockopt SO_SNDBUF test success
255    optVal = 0x20000;
256    optLen = sizeof(optVal);
257    ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optVal, optLen);
258    EXPECT_EQ(ret, 0);
259
260    // getsockopt SO_SNDBUF test success
261    optVal = 0;
262    optLen = sizeof(optVal);
263    ret = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optVal, &optLen);
264    EXPECT_EQ(ret, 0);
265    EXPECT_TRUE(optVal > 0);
266
267    // setsockopt SO_RCVBUF test success
268    optVal = 0x20000;
269    optLen = sizeof(optVal);
270    ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optVal, optLen);
271    EXPECT_EQ(ret, 0);
272    EXPECT_TRUE(optVal > 0);
273
274    // getsockopt SO_RCVBUF test success
275    optVal = 0;
276    optLen = sizeof(optVal);
277    ret = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optVal, &optLen);
278    EXPECT_EQ(ret, 0);
279
280    close(fd);
281}
282
283/*
284 * @tc.number : SUB_KERNEL_SYSCALL_SOCKOPT_0300
285 * @tc.name   : SetAndGetsockoptTCP_TIMESTAMPTestSuccess_0003
286 * @tc.desc   : setsockopt SO_TIMESTAMPING and getsockopt TCP_TIMESTAMP option test success.
287 * @tc.size   : MediumTest
288 * @tc.type   : Function
289 * @tc.level  : Level 1
290 */
291HWTEST_F(HatsSockoptTest, GetsockoptTCP_TIMESTAMPTestSuccess_0003, Function | MediumTest | Level1)
292{
293    int ret;
294    int fd = -1;
295    int32_t optVal;
296    socklen_t optLen;
297
298    fd = socket(AF_INET, SOCK_STREAM, 0);
299    EXPECT_TRUE(fd > 0);
300
301    optVal = 1;
302    optLen = sizeof(optVal);
303    ret = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &optVal, optLen);
304    EXPECT_EQ(ret, 0);
305
306    optVal = 0;
307    optLen = sizeof(optVal);
308    ret = getsockopt(fd, IPPROTO_TCP, TCP_TIMESTAMP, &optVal, &optLen);
309    EXPECT_EQ(ret, 0);
310    EXPECT_TRUE(optVal > 0);
311
312    close(fd);
313}
314
315/*
316 * @tc.number : SUB_KERNEL_SYSCALL_SOCKOPT_0400
317 * @tc.name   : SetAndGetsockoptIPV6_2292PKTOPTIONSTestSuccess_0004
318 * @tc.desc   : setsockopt and getsockopt IPV6_2292PKTOPTIONS option test success.
319 * @tc.size   : MediumTest
320 * @tc.type   : Function
321 * @tc.level  : Level 1
322 */
323HWTEST_F(HatsSockoptTest, SetAndGetsockoptIPV6_2292PKTOPTIONSTestSuccess_0004, Function | MediumTest | Level1)
324{
325    int ret;
326    int fd = -1;
327    int32_t optVal;
328    socklen_t optLen;
329
330    fd = socket(AF_INET6, SOCK_STREAM, 0);
331    EXPECT_TRUE(fd > 0);
332
333    optVal = 1;
334    optLen = sizeof(optVal);
335    ret = setsockopt(fd, IPPROTO_IPV6, IPV6_2292PKTOPTIONS, &optVal, optLen);
336    EXPECT_EQ(ret, 0);
337
338    optVal = 0;
339    optLen = sizeof(optVal);
340    ret = getsockopt(fd, IPPROTO_IPV6, IPV6_2292PKTOPTIONS, &optVal, &optLen);
341    EXPECT_EQ(ret, 0);
342
343    close(fd);
344}
345
346/*
347 * @tc.number : SUB_KERNEL_SYSCALL_SOCKOPT_0500
348 * @tc.name   : SetAndGetsockoptSO_LINGERTestSuccess_0005
349 * @tc.desc   : setsockopt and getsockopt SO_LINGER option test success.
350 * @tc.size   : MediumTest
351 * @tc.type   : Function
352 * @tc.level  : Level 1
353 */
354HWTEST_F(HatsSockoptTest, SetAndGetsockoptSO_LINGERTestSuccess_0005, Function | MediumTest | Level1)
355{
356    int ret;
357    int fd = -1;
358    struct linger optVal = {
359        .l_onoff = 1,
360        .l_linger = 1,
361    };
362    socklen_t optLen = sizeof(optVal);
363
364    fd = socket(AF_INET, SOCK_STREAM, 0);
365    EXPECT_TRUE(fd > 0);
366
367    // setsockopt SO_LINGER test success
368    ret = setsockopt(fd, SOL_SOCKET, SO_LINGER, &optVal, optLen);
369    EXPECT_EQ(ret, 0);
370
371    // getsockopt SO_LINGER test success
372    memset_s(&optVal, sizeof(optVal), 0, sizeof(optVal));
373    optLen = sizeof(optVal);
374    ret = getsockopt(fd, SOL_SOCKET, SO_LINGER, &optVal, &optLen);
375    EXPECT_EQ(ret, 0);
376    EXPECT_EQ(optVal.l_onoff, 1);
377    EXPECT_EQ(optVal.l_linger, 1);
378
379    close(fd);
380}
381
382/*
383 * @tc.number : SUB_KERNEL_SYSCALL_SOCKOPT_0600
384 * @tc.name   : SetAndGetsockoptSO_TIMEOTestSuccess_0006
385 * @tc.desc   : setsockopt and getsockopt SO_RCVTIMEO and SO_SNDTIMEO option test success.
386 * @tc.size   : MediumTest
387 * @tc.type   : Function
388 * @tc.level  : Level 1
389 */
390HWTEST_F(HatsSockoptTest, SetAndGetsockoptSO_TIMEOTestSuccess_0006, Function | MediumTest | Level1)
391{
392    int ret;
393    int fd = -1;
394    struct timeval optVal = {
395        .tv_sec = 1,
396        .tv_usec = 1,
397    };
398    socklen_t optLen = sizeof(optVal);
399
400    fd = socket(AF_INET, SOCK_STREAM, 0);
401    EXPECT_TRUE(fd > 0);
402
403    // setsockopt SO_RCVTIMEO test success
404    ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &optVal, optLen);
405    EXPECT_EQ(ret, 0);
406
407    // getsockopt SO_RCVTIMEO test success
408    memset_s(&optVal, sizeof(optVal), -1, sizeof(optVal));
409    optLen = sizeof(optVal);
410    ret = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &optVal, &optLen);
411    EXPECT_EQ(ret, 0);
412    EXPECT_TRUE(optVal.tv_sec != -1);
413    EXPECT_TRUE(optVal.tv_usec != -1);
414
415    close(fd);
416}
417
418/*
419 * @tc.number : SUB_KERNEL_SYSCALL_SOCKOPT_0700
420 * @tc.name   : SetsockoptSO_FILTERTestSuccess_0007
421 * @tc.desc   : setsockopt SO_ATTACH_FILTER and SO_DETACH_FILTER option test success.
422 * @tc.size   : MediumTest
423 * @tc.type   : Function
424 * @tc.level  : Level 1
425 */
426HWTEST_F(HatsSockoptTest, SetsockoptSO_FILTERTestSuccess_0007, Function | MediumTest | Level1)
427{
428    int ret;
429    int fd = -1;
430    struct sock_filter code[] = {
431        { 0x28, 0, 0, 0x0000000c },
432        { 0x15, 0, 8, 0x000086dd },
433        { 0x30, 0, 0, 0x00000014 },
434        { 0x15, 2, 0, 0x00000084 },
435        { 0x15, 1, 0, 0x00000006 },
436        { 0x15, 0, 17, 0x00000011 },
437        { 0x28, 0, 0, 0x00000036 },
438        { 0x15, 14, 0, 0x00000016 },
439        { 0x28, 0, 0, 0x00000038 },
440        { 0x15, 12, 13, 0x00000016 },
441        { 0x15, 0, 12, 0x00000800 },
442        { 0x30, 0, 0, 0x00000017 },
443        { 0x15, 2, 0, 0x00000084 },
444        { 0x15, 1, 0, 0x00000006 },
445        { 0x15, 0, 8, 0x00000011 },
446        { 0x28, 0, 0, 0x00000014 },
447        { 0x45, 6, 0, 0x00001fff },
448        { 0xb1, 0, 0, 0x0000000e },
449        { 0x48, 0, 0, 0x0000000e },
450        { 0x15, 2, 0, 0x00000016 },
451        { 0x48, 0, 0, 0x00000010 },
452        { 0x15, 0, 1, 0x00000016 },
453        { 0x6, 0, 0, 0x00040000 },
454        { 0x6, 0, 0, 0x00000000 },
455    };
456    struct sock_fprog optVal = {
457        .len = sizeof(code) / sizeof(code[0]),
458        .filter = code,
459    };
460    socklen_t optLen = sizeof(optVal);
461
462    fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
463    EXPECT_TRUE(fd > 0);
464
465    // setsockopt SO_ATTACH_FILTER test success
466    ret = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &optVal, optLen);
467    EXPECT_EQ(ret, 0);
468
469    // setsockopt SO_DETACH_FILTER test success
470    ret = setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, &optVal, optLen);
471    EXPECT_EQ(ret, 0);
472
473    close(fd);
474}
475
476/*
477 * @tc.number : SUB_KERNEL_SYSCALL_SOCKOPT_0800
478 * @tc.name   : SetsockoptTCP_CONGESTIONTestSuccess_0008
479 * @tc.desc   : setsockopt and getsockopt TCP_CONGESTION option test success.
480 * @tc.size   : MediumTest
481 * @tc.type   : Function
482 * @tc.level  : Level 1
483 */
484HWTEST_F(HatsSockoptTest, SetsockoptTCP_CONGESTIONTestSuccess_0008, Function | MediumTest | Level1)
485{
486    int ret;
487    int fd = -1;
488    char optVal[MAX_SIZE] = { 0 };
489    socklen_t optLen = sizeof(optVal);
490
491    fd = socket(AF_INET, SOCK_STREAM, 0);
492    EXPECT_TRUE(fd > 0);
493
494    // setsockopt TCP_CONGESTION test success
495    const char *algo = "cubic";
496    ret = setsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, algo, strlen(algo));
497    EXPECT_EQ(ret, 0);
498
499    // getsockopt get algo success
500    ret = getsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, &optVal, &optLen);
501    EXPECT_EQ(ret, 0);
502    EXPECT_STREQ(optVal, algo);
503
504    close(fd);
505}
506
507/*
508 * @tc.number : SUB_KERNEL_SYSCALL_SOCKOPT_0900
509 * @tc.name   : GetsockoptOnlySupportOptSuccess_0009
510 * @tc.desc   : getsockopt only support option test success.
511 * @tc.size   : MediumTest
512 * @tc.type   : Function
513 * @tc.level  : Level 1
514 */
515HWTEST_F(HatsSockoptTest, GetsockoptOnlySupportOptSuccess_0009, Function | MediumTest | Level1)
516{
517    int ret;
518    int fd = -1;
519    int32_t optVal;
520    socklen_t optLen;
521    for (int32_t i = 0; i < sizeof(g_getOnlyOpt) / sizeof(g_getOnlyOpt[0]); i++) {
522        fd = socket(g_getOnlyOpt[i].domain, g_getOnlyOpt[i].type, 0);
523        EXPECT_TRUE(fd > 0);
524
525        optVal = 0;
526        optLen = g_getOnlyOpt[i].optLen;
527        ret = getsockopt(fd, g_getOnlyOpt[i].optLevel, g_getOnlyOpt[i].optName, &optVal, &optLen);
528        EXPECT_EQ(ret, g_getOnlyOpt[i].ret);
529        EXPECT_EQ(optVal, g_getOnlyOpt[i].optVal);
530        EXPECT_EQ(optLen, g_getOnlyOpt[i].optLen);
531        close(fd);
532    }
533
534    close(fd);
535}
536
537/*
538 * @tc.number : SUB_KERNEL_SYSCALL_GETSOCKOPT_1000
539 * @tc.name   : SetAndGetsockoptInvalidFdFailed_0010
540 * @tc.desc   : setsockopt and getsockopt use invalid socket fd test failed.
541 * @tc.size   : MediumTest
542 * @tc.type   : Function
543 * @tc.level  : Level 2
544 */
545HWTEST_F(HatsSockoptTest, SetAndGetsockoptInvalidFdFailed_0010, Function | MediumTest | Level2)
546{
547    int ret;
548    int32_t optVal = 1;
549    socklen_t optLen = sizeof(optVal);
550
551    errno = 0;
552    ret = setsockopt(BAD_SOCKET_FD, IPPROTO_TCP, TCP_TIMESTAMP, &optVal, optLen);
553    EXPECT_EQ(ret, -1);
554    EXPECT_EQ(errno, EBADF);
555
556    errno = 0;
557    ret = setsockopt(STDIN_FILENO, IPPROTO_TCP, TCP_TIMESTAMP, &optVal, optLen);
558    EXPECT_EQ(ret, -1);
559    EXPECT_EQ(errno, ENOTSOCK);
560
561    errno = 0;
562    ret = getsockopt(BAD_SOCKET_FD, IPPROTO_TCP, TCP_TIMESTAMP, &optVal, &optLen);
563    EXPECT_EQ(ret, -1);
564    EXPECT_EQ(errno, EBADF);
565
566    errno = 0;
567    ret = getsockopt(STDIN_FILENO, IPPROTO_TCP, TCP_TIMESTAMP, &optVal, &optLen);
568    EXPECT_EQ(ret, -1);
569    EXPECT_EQ(errno, ENOTSOCK);
570}
571