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 
38 using namespace testing::ext;
39 
40 static const int BAD_SOCKET_FD = -1;
41 static const int MAX_SIZE = 1024;
42 
43 
44 struct 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 
145 struct 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 
176 class HatsSockoptTest : public testing::Test {
177 public:
178     static void SetUpTestCase();
179     static void TearDownTestCase();
180     void SetUp();
181     void TearDown();
182 private:
183 };
SetUp()184 void HatsSockoptTest::SetUp()
185 {
186 }
TearDown()187 void HatsSockoptTest::TearDown()
188 {
189 }
SetUpTestCase()190 void HatsSockoptTest::SetUpTestCase()
191 {
192 }
TearDownTestCase()193 void 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  */
HWTEST_F(HatsSockoptTest, SetAndGetsockoptSupportOptSuccess_0001, Function | MediumTest | Level1)205 HWTEST_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  */
HWTEST_F(HatsSockoptTest, SetAndGetsockoptSndAndRcvTestSuccess_0002, Function | MediumTest | Level1)244 HWTEST_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  */
HWTEST_F(HatsSockoptTest, GetsockoptTCP_TIMESTAMPTestSuccess_0003, Function | MediumTest | Level1)291 HWTEST_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  */
HWTEST_F(HatsSockoptTest, SetAndGetsockoptIPV6_2292PKTOPTIONSTestSuccess_0004, Function | MediumTest | Level1)323 HWTEST_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  */
HWTEST_F(HatsSockoptTest, SetAndGetsockoptSO_LINGERTestSuccess_0005, Function | MediumTest | Level1)354 HWTEST_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  */
HWTEST_F(HatsSockoptTest, SetAndGetsockoptSO_TIMEOTestSuccess_0006, Function | MediumTest | Level1)390 HWTEST_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  */
HWTEST_F(HatsSockoptTest, SetsockoptSO_FILTERTestSuccess_0007, Function | MediumTest | Level1)426 HWTEST_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  */
HWTEST_F(HatsSockoptTest, SetsockoptTCP_CONGESTIONTestSuccess_0008, Function | MediumTest | Level1)484 HWTEST_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  */
HWTEST_F(HatsSockoptTest, GetsockoptOnlySupportOptSuccess_0009, Function | MediumTest | Level1)515 HWTEST_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  */
HWTEST_F(HatsSockoptTest, SetAndGetsockoptInvalidFdFailed_0010, Function | MediumTest | Level2)545 HWTEST_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