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 <fcntl.h>
21 #include <unistd.h>
22 #include <vector>
23 #include <arpa/inet.h>
24 #include <gtest/gtest.h>
25 #include <netinet/in.h>
26 #include <sys/stat.h>
27 #include <sys/socket.h>
28 #include <sys/types.h>
29 #include "securec.h"
30
31 using namespace testing::ext;
32
33 class HatsBindTest : public testing::Test {
34 public:
35 static void SetUpTestCase();
36 static void TearDownTestCase();
37 void SetUp();
38 void TearDown();
39 private:
40 };
SetUp()41 void HatsBindTest::SetUp()
42 {
43 }
TearDown()44 void HatsBindTest::TearDown()
45 {
46 }
SetUpTestCase()47 void HatsBindTest::SetUpTestCase()
48 {
49 }
TearDownTestCase()50 void HatsBindTest::TearDownTestCase()
51 {
52 }
53
54 static const int BAD_SOCKET_FD = -1;
55 static const int TEST_PORT = 21356;
56 static const char *TEST_LOCAL_IP = "127.0.0.1";
57 static const char *TEST_BAD_IP = "192.168.10.3";
58
59 /*
60 * @tc.number : SUB_KERNEL_SYSCALL_BIND_0100
61 * @tc.name : BindSockfdTwice_0001
62 * @tc.desc : bind the same socket fd twice failed, errno EINVAL.
63 * @tc.size : MediumTest
64 * @tc.type : Function
65 * @tc.level : Level 2
66 */
67 HWTEST_F(HatsBindTest, BindSockfdTwice_0001, Function | MediumTest | Level2)
68 {
69 int ret;
70 int socketFd = -1;
71 int32_t optVal = 1;
72 struct sockaddr_in serAddr = {
73 .sin_family = AF_INET,
74 .sin_port = htons(TEST_PORT),
75 .sin_addr = {
76 .s_addr = inet_addr(TEST_LOCAL_IP),
77 }
78 };
79
80 socketFd = socket(AF_INET, SOCK_STREAM, 0);
81 EXPECT_TRUE(socketFd > 0);
82
83 ret = setsockopt(socketFd, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(optVal));
84 EXPECT_EQ(ret, 0);
85
86 ret = bind(socketFd, reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(serAddr));
87 EXPECT_EQ(ret, 0);
88
89 errno = 0;
90 ret = bind(socketFd, reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(serAddr));
91 EXPECT_EQ(ret, -1);
92 EXPECT_EQ(errno, EINVAL);
93
94 close(socketFd);
95 }
96
97 /*
98 * @tc.number : SUB_KERNEL_SYSCALL_BIND_0200
99 * @tc.name : BindInvalidSockfdFailed_0002
100 * @tc.desc : bind the invalid socket fd failed.
101 * @tc.size : MediumTest
102 * @tc.type : Function
103 * @tc.level : Level 2
104 */
105 HWTEST_F(HatsBindTest, BindInvalidSockfdFailed_0002, Function | MediumTest | Level2)
106 {
107 int ret;
108 struct sockaddr_in serAddr = {
109 .sin_family = AF_INET,
110 .sin_port = htons(TEST_PORT),
111 .sin_addr = {
112 .s_addr = inet_addr(TEST_LOCAL_IP),
113 }
114 };
115
116 errno = 0;
117 ret = bind(BAD_SOCKET_FD, reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(serAddr));
118 EXPECT_EQ(ret, -1);
119 EXPECT_EQ(errno, EBADF);
120
121 errno = 0;
122 ret = bind(STDIN_FILENO, reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(serAddr));
123 EXPECT_EQ(ret, -1);
124 EXPECT_EQ(errno, ENOTSOCK);
125 }
126
127 /*
128 * @tc.number : SUB_KERNEL_SYSCALL_BIND_0300
129 * @tc.name : BindInvalidIPFailed_0003
130 * @tc.desc : bind the invalid ip addr failed.
131 * @tc.size : MediumTest
132 * @tc.type : Function
133 * @tc.level : Level 2
134 */
135 HWTEST_F(HatsBindTest, BindInvalidIPFailed_0003, Function | MediumTest | Level2)
136 {
137 int ret;
138 int32_t optVal = 1;
139 int socketFd = -1;
140 struct sockaddr_in serAddr = {
141 .sin_family = AF_INET,
142 .sin_port = htons(TEST_PORT),
143 .sin_addr = {
144 .s_addr = inet_addr(TEST_BAD_IP),
145 }
146 };
147
148 socketFd = socket(AF_INET, SOCK_STREAM, 0);
149 EXPECT_TRUE(socketFd > 0);
150
151 ret = setsockopt(socketFd, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(optVal));
152 EXPECT_EQ(ret, 0);
153
154 errno = 0;
155 ret = bind(socketFd, reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(serAddr));
156 EXPECT_EQ(ret, -1);
157 EXPECT_EQ(errno, EADDRNOTAVAIL);
158
159 errno = 0;
160 ret = bind(socketFd, nullptr, sizeof(serAddr));
161 EXPECT_EQ(ret, -1);
162 EXPECT_EQ(errno, EFAULT);
163
164 close(socketFd);
165 }
166
167 /*
168 * @tc.number : SUB_KERNEL_SYSCALL_BIND_0400
169 * @tc.name : BindErrorIPAddrLen_0004
170 * @tc.desc : bind addr len >= sizeof(serAddr) success, otherwise errno EINVAL.
171 * @tc.size : MediumTest
172 * @tc.type : Function
173 * @tc.level : Level 2
174 */
175 HWTEST_F(HatsBindTest, BindErrorIPAddrLen_0004, Function | MediumTest | Level2)
176 {
177 int ret;
178 int32_t optVal = 1;
179 int socketFd = -1;
180 struct sockaddr_in serAddr = {
181 .sin_family = AF_INET,
182 .sin_port = htons(TEST_PORT),
183 .sin_addr = {
184 .s_addr = inet_addr(TEST_LOCAL_IP),
185 }
186 };
187
188 socketFd = socket(AF_INET, SOCK_STREAM, 0);
189 EXPECT_TRUE(socketFd > 0);
190
191 ret = setsockopt(socketFd, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(optVal));
192 EXPECT_EQ(ret, 0);
193
194 errno = 0;
195 ret = bind(socketFd, reinterpret_cast<struct sockaddr *>(&serAddr), -1);
196 EXPECT_EQ(ret, -1);
197 EXPECT_EQ(errno, EINVAL);
198
199 errno = 0;
200 ret = bind(socketFd, reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(serAddr) - 1);
201 EXPECT_EQ(ret, -1);
202 EXPECT_EQ(errno, EINVAL);
203
204 errno = 0;
205 ret = bind(socketFd, reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(serAddr) + 1);
206 EXPECT_EQ(ret, 0);
207
208 close(socketFd);
209 }
210
211 /*
212 * @tc.number : SUB_KERNEL_SYSCALL_BIND_0500
213 * @tc.name : BindUsedPortFailed_0005
214 * @tc.desc : bind the used port, errno EINVAL.
215 * @tc.size : MediumTest
216 * @tc.type : Function
217 * @tc.level : Level 2
218 */
219 HWTEST_F(HatsBindTest, BindUsedPortFailed_0005, Function | MediumTest | Level2)
220 {
221 int ret;
222 int socketFd = -1;
223 int socketFd2 = -1;
224 int32_t optVal = 1;
225 struct sockaddr_in serAddr = {
226 .sin_family = AF_INET,
227 .sin_port = htons(TEST_PORT),
228 .sin_addr = {
229 .s_addr = inet_addr(TEST_LOCAL_IP),
230 }
231 };
232
233 socketFd = socket(AF_INET, SOCK_STREAM, 0);
234 EXPECT_TRUE(socketFd > 0);
235
236 ret = setsockopt(socketFd, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(optVal));
237 EXPECT_EQ(ret, 0);
238
239 errno = 0;
240 ret = bind(socketFd, reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(serAddr));
241 EXPECT_EQ(ret, 0);
242 EXPECT_EQ(errno, 0);
243
244 socketFd2 = socket(AF_INET, SOCK_STREAM, 0);
245 EXPECT_TRUE(socketFd > 0);
246
247 errno = 0;
248 ret = bind(socketFd2, reinterpret_cast<struct sockaddr *>(&serAddr), sizeof(serAddr));
249 EXPECT_EQ(ret, -1);
250 EXPECT_EQ(errno, EADDRINUSE);
251
252 close(socketFd);
253 close(socketFd2);
254 }
255