1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
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 #include <arpa/inet.h>
16 #include <gtest/gtest.h>
17
18 #include "clatd_packet_converter.h"
19 #include "net_manager_constants.h"
20
21 using namespace testing;
22
23 namespace OHOS {
24 namespace nmd {
25 using namespace testing::ext;
26
27 static constexpr const char *V4ADDR = "192.0.0.0";
28 static constexpr const char *V6ADDR_UDP_ICMP = "2408:8456:3242:b272:28fb:90b4:fdc6:ce53";
29 static constexpr const char *V6ADDR_TCP = "2408:8456:3226:d7a4:a265:ca6:72b2:3ef6";
30 static constexpr const char *PREFIXADDR = "2407:c080:7ef:ffff::";
31
32 // clang-format off
33 static const uint8_t V4_UDP_PACKET_TX[] = {
34 0x45, 0x00, 0x00, 0x20, 0x68, 0x69, 0x40, 0x00, 0x40, 0x11, 0x5d, 0xa5, 0xc0, 0x00, 0x00, 0x00,
35 0x8b, 0x09, 0x29, 0xb5, 0x95, 0xd4, 0x14, 0x51, 0x00, 0x0c, 0x70, 0x1d, 0x15, 0xcd, 0x5b, 0x07,
36 };
37
38 static const uint8_t V6_UDP_PACKET_TX[] = {
39 0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x11, 0x40, 0x24, 0x08, 0x84, 0x56, 0x32, 0x42, 0xb2, 0x72,
40 0x28, 0xfb, 0x90, 0xb4, 0xfd, 0xc6, 0xce, 0x53, 0x24, 0x07, 0xc0, 0x80, 0x07, 0xef, 0xff, 0xff,
41 0x00, 0x00, 0x00, 0x00, 0x8b, 0x09, 0x29, 0xb5, 0x95, 0xd4, 0x14, 0x51, 0x00, 0x0c, 0x30, 0xc9,
42 0x15, 0xcd, 0x5b, 0x07
43 };
44
45 static const uint8_t V6_UDP_PACKET_RX[] = {
46 0x69, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x11, 0x29, 0x24, 0x07, 0xc0, 0x80, 0x07, 0xef, 0xff, 0xff,
47 0x00, 0x00, 0x00, 0x00, 0x8b, 0x09, 0x29, 0xb5, 0x24, 0x08, 0x84, 0x56, 0x32, 0x42, 0xb2, 0x72,
48 0x28, 0xfb, 0x90, 0xb4, 0xfd, 0xc6, 0xce, 0x53, 0x14, 0x51, 0x95, 0xd4, 0x00, 0x0c, 0x33, 0x2d,
49 0x36, 0x37, 0x38, 0x39
50 };
51
52 static const uint8_t V4_UDP_PACKET_RX[] = {
53 0x45, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x29, 0x11, 0xdd, 0x0e, 0x8b, 0x09, 0x29, 0xb5,
54 0xc0, 0x00, 0x00, 0x00, 0x14, 0x51, 0x95, 0xd4, 0x00, 0x0c, 0x72, 0x81, 0x36, 0x37, 0x38, 0x39,
55 };
56
57 static const uint8_t V4_TCP_PACKET_TX[] = {
58 0x45, 0x00, 0x00, 0x3c, 0x7a, 0x91, 0x40, 0x00, 0x40, 0x06, 0x4b, 0x6c, 0xc0, 0x00, 0x00, 0x00,
59 0x8b, 0x09, 0x29, 0xb5, 0xca, 0x66, 0x1f, 0x90, 0xd5, 0xd3, 0x06, 0xc0, 0x00, 0x00, 0x00, 0x00,
60 0xa0, 0x02, 0xff, 0xff, 0x37, 0x8b, 0x00, 0x00, 0x02, 0x04, 0x05, 0x34, 0x04, 0x02, 0x08, 0x0a,
61 0x11, 0xa2, 0xc4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x08
62 };
63
64 static const uint8_t V6_TCP_PACKET_TX[] = {
65 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x06, 0x40, 0x24, 0x08, 0x84, 0x56, 0x32, 0x26, 0xd7, 0xa4,
66 0xa2, 0x65, 0x0c, 0xa6, 0x72, 0xb2, 0x3e, 0xf6, 0x24, 0x07, 0xc0, 0x80, 0x07, 0xef, 0xff, 0xff,
67 0x00, 0x00, 0x00, 0x00, 0x8b, 0x09, 0x29, 0xb5, 0xca, 0x66, 0x1f, 0x90, 0xd5, 0xd3, 0x06, 0xc0,
68 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0xff, 0xff, 0xf8, 0x36, 0x00, 0x00, 0x02, 0x04, 0x05, 0x34,
69 0x04, 0x02, 0x08, 0x0a, 0x11, 0xa2, 0xc4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x08,
70 };
71
72 static const uint8_t V6_TCP_PACKET_RX[] = {
73 0x69, 0x00, 0x00, 0x00, 0x00, 0x28, 0x06, 0x2a, 0x24, 0x07, 0xc0, 0x80, 0x07, 0xef, 0xff, 0xff,
74 0x00, 0x00, 0x00, 0x00, 0x8b, 0x09, 0x29, 0xb5, 0x24, 0x08, 0x84, 0x56, 0x32, 0x26, 0xd7, 0xa4,
75 0xa2, 0x65, 0x0c, 0xa6, 0x72, 0xb2, 0x3e, 0xf6, 0x1f, 0x90, 0xca, 0x66, 0x97, 0x37, 0x91, 0xdc,
76 0xd5, 0xd3, 0x06, 0xc1, 0xa0, 0x12, 0xfe, 0x88, 0x15, 0x25, 0x00, 0x00, 0x02, 0x04, 0x04, 0xb0,
77 0x04, 0x02, 0x08, 0x0a, 0x50, 0x73, 0x6b, 0x75, 0x11, 0xa2, 0xc4, 0x08, 0x01, 0x03, 0x03, 0x07
78 };
79
80 static const uint8_t V4_TCP_PACKET_RX[] = {
81 0x45, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x40, 0x00, 0x2a, 0x06, 0xdb, 0xfd, 0x8b, 0x09, 0x29, 0xb5,
82 0xc0, 0x00, 0x00, 0x00, 0x1f, 0x90, 0xca, 0x66, 0x97, 0x37, 0x91, 0xdc, 0xd5, 0xd3, 0x06, 0xc1,
83 0xa0, 0x12, 0xfe, 0x88, 0x54, 0x79, 0x00, 0x00, 0x02, 0x04, 0x04, 0xb0, 0x04, 0x02, 0x08, 0x0a,
84 0x50, 0x73, 0x6b, 0x75, 0x11, 0xa2, 0xc4, 0x08, 0x01, 0x03, 0x03, 0x07
85 };
86
87 static const uint8_t V4_ICMP_PACKET_TX[] = {
88 0x45, 0x00, 0x00, 0x54, 0xec, 0x22, 0x40, 0x00, 0x40, 0x01, 0xd9, 0xc7, 0xc0, 0x00, 0x00, 0x00,
89 0x8b, 0x09, 0x29, 0xb5, 0x08, 0x00, 0x85, 0xc1, 0x00, 0x01, 0x01, 0x00, 0x62, 0x3d, 0x0f, 0x00,
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00
94 };
95
96 static const uint8_t V6_ICMP_PACKET_TX[] = {
97 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3a, 0x40, 0x24, 0x08, 0x84, 0x56, 0x32, 0x42, 0xb2, 0x72,
98 0x28, 0xfb, 0x90, 0xb4, 0xfd, 0xc6, 0xce, 0x53, 0x24, 0x07, 0xc0, 0x80, 0x07, 0xef, 0xff, 0xff,
99 0x00, 0x00, 0x00, 0x00, 0x8b, 0x09, 0x29, 0xb5, 0x80, 0x00, 0x59, 0x33, 0x00, 0x01, 0x01, 0x00,
100 0x62, 0x3d, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
104 };
105
106 static const uint8_t V6_ICMP_PACKET_RX[] = {
107 0x69, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3a, 0x2a, 0x24, 0x07, 0xc0, 0x80, 0x07, 0xef, 0xff, 0xff,
108 0x00, 0x00, 0x00, 0x00, 0x8b, 0x09, 0x29, 0xb5, 0x24, 0x08, 0x84, 0x56, 0x32, 0x42, 0xb2, 0x72,
109 0x28, 0xfb, 0x90, 0xb4, 0xfd, 0xc6, 0xce, 0x53, 0x81, 0x00, 0x58, 0x33, 0x00, 0x01, 0x01, 0x00,
110 0x62, 0x3d, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
114 };
115
116 static const uint8_t V4_ICMP_PACKET_RX[] = {
117 0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, 0x2a, 0x01, 0xdb, 0xea, 0x8b, 0x09, 0x29, 0xb5,
118 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xc1, 0x00, 0x01, 0x01, 0x00, 0x62, 0x3d, 0x0f, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00
123 };
124
125 // clang-format on
126 class ClatdPacketConverterTest : public ::testing::Test {
127 public:
128 void SetUp() override;
129 void TearDown() override;
130 bool IsTranslatedPacketCorrect(std::vector<iovec> iovPackets, const uint8_t *packet);
131
132 in_addr v4Addr_;
133 in6_addr v6Addr_;
134 in6_addr prefixAddr_;
135 };
136
SetUp()137 void ClatdPacketConverterTest::SetUp()
138 {
139 inet_pton(AF_INET, V4ADDR, &v4Addr_.s_addr);
140 inet_pton(AF_INET6, PREFIXADDR, &prefixAddr_);
141 }
142
TearDown()143 void ClatdPacketConverterTest::TearDown() {}
144
IsTranslatedPacketCorrect(std::vector<iovec> iovPackets,const uint8_t * packet)145 bool ClatdPacketConverterTest::IsTranslatedPacketCorrect(std::vector<iovec> iovPackets, const uint8_t *packet)
146 {
147 if (memcmp(iovPackets[CLATD_IPHDR].iov_base, packet, iovPackets[CLATD_IPHDR].iov_len) != 0) {
148 return false;
149 }
150 packet += iovPackets[CLATD_IPHDR].iov_len;
151 if (memcmp(iovPackets[CLATD_TPHDR].iov_base, packet, iovPackets[CLATD_TPHDR].iov_len) != 0) {
152 return false;
153 }
154 packet += iovPackets[CLATD_TPHDR].iov_len;
155 if (memcmp(iovPackets[CLATD_PAYLOAD].iov_base, packet, iovPackets[CLATD_PAYLOAD].iov_len) != 0) {
156 return false;
157 }
158 return true;
159 }
160
161 /**
162 * @tc.name: ClatdPacketConverterTranslateUdpTest001
163 * @tc.desc: Test ClatdPacketConverter translate ipv4 udp packet.
164 * @tc.type: FUNC
165 */
166 HWTEST_F(ClatdPacketConverterTest, ClatdPacketConverterTranslateUdpTest001, TestSize.Level1)
167 {
168 inet_pton(AF_INET6, V6ADDR_UDP_ICMP, &v6Addr_);
169 auto clatdPacketConverter = std::make_unique<ClatdPacketConverter>(
170 V4_UDP_PACKET_TX, sizeof(V4_UDP_PACKET_TX), CONVERT_FROM_V4_TO_V6, v4Addr_, v6Addr_, prefixAddr_);
171 EXPECT_EQ(clatdPacketConverter->ConvertPacket(false), NETMANAGER_SUCCESS);
172
173 std::vector<iovec> iovPackets(CLATD_MAX);
174 int effectivePos = 0;
175 clatdPacketConverter->GetConvertedPacket(iovPackets, effectivePos);
176
177 EXPECT_EQ(IsTranslatedPacketCorrect(iovPackets, V6_UDP_PACKET_TX), true);
178 }
179
180 /**
181 * @tc.name: ClatdPacketConverterTranslateUdpTest002
182 * @tc.desc: Test ClatdPacketConverter translate ipv6 udp packet.
183 * @tc.type: FUNC
184 */
185 HWTEST_F(ClatdPacketConverterTest, ClatdPacketConverterTranslateUdpTest002, TestSize.Level1)
186 {
187 inet_pton(AF_INET6, V6ADDR_UDP_ICMP, &v6Addr_);
188 auto clatdPacketConverter = std::make_unique<ClatdPacketConverter>(
189 V6_UDP_PACKET_RX, sizeof(V6_UDP_PACKET_RX), CONVERT_FROM_V6_TO_V4, v4Addr_, v6Addr_, prefixAddr_);
190 EXPECT_EQ(clatdPacketConverter->ConvertPacket(false), NETMANAGER_SUCCESS);
191
192 std::vector<iovec> iovPackets(CLATD_MAX);
193 int effectivePos = 0;
194 clatdPacketConverter->GetConvertedPacket(iovPackets, effectivePos);
195
196 EXPECT_EQ(IsTranslatedPacketCorrect(iovPackets, V4_UDP_PACKET_RX), true);
197 }
198
199 /**
200 * @tc.name: ClatdPacketConverterTranslateTcpTest001
201 * @tc.desc: Test ClatdPacketConverter translate ipv4 tcp packet.
202 * @tc.type: FUNC
203 */
204 HWTEST_F(ClatdPacketConverterTest, ClatdPacketConverterTranslateTcpTest001, TestSize.Level1)
205 {
206 inet_pton(AF_INET6, V6ADDR_TCP, &v6Addr_);
207 auto clatdPacketConverter = std::make_unique<ClatdPacketConverter>(
208 V4_TCP_PACKET_TX, sizeof(V4_TCP_PACKET_TX), CONVERT_FROM_V4_TO_V6, v4Addr_, v6Addr_, prefixAddr_);
209 EXPECT_EQ(clatdPacketConverter->ConvertPacket(false), NETMANAGER_SUCCESS);
210
211 std::vector<iovec> iovPackets(CLATD_MAX);
212 int effectivePos = 0;
213 clatdPacketConverter->GetConvertedPacket(iovPackets, effectivePos);
214
215 EXPECT_EQ(IsTranslatedPacketCorrect(iovPackets, V6_TCP_PACKET_TX), true);
216 }
217
218 /**
219 * @tc.name: ClatdPacketConverterTranslateTcpTest002
220 * @tc.desc: Test ClatdPacketConverter translate ipv6 tcp packet.
221 * @tc.type: FUNC
222 */
223 HWTEST_F(ClatdPacketConverterTest, ClatdPacketConverterTranslateTcpTest002, TestSize.Level1)
224 {
225 inet_pton(AF_INET6, V6ADDR_TCP, &v6Addr_);
226 auto clatdPacketConverter = std::make_unique<ClatdPacketConverter>(
227 V6_TCP_PACKET_RX, sizeof(V6_TCP_PACKET_RX), CONVERT_FROM_V6_TO_V4, v4Addr_, v6Addr_, prefixAddr_);
228 EXPECT_EQ(clatdPacketConverter->ConvertPacket(false), NETMANAGER_SUCCESS);
229
230 std::vector<iovec> iovPackets(CLATD_MAX);
231 int effectivePos = 0;
232 clatdPacketConverter->GetConvertedPacket(iovPackets, effectivePos);
233
234 EXPECT_EQ(IsTranslatedPacketCorrect(iovPackets, V4_TCP_PACKET_RX), true);
235 }
236
237 /**
238 * @tc.name: ClatdPacketConverterTranslateIcmpTest001
239 * @tc.desc: Test ClatdPacketConverter translate ipv4 icmp packet.
240 * @tc.type: FUNC
241 */
242 HWTEST_F(ClatdPacketConverterTest, ClatdPacketConverterTranslateIcmpTest001, TestSize.Level1)
243 {
244 inet_pton(AF_INET6, V6ADDR_UDP_ICMP, &v6Addr_);
245 auto clatdPacketConverter = std::make_unique<ClatdPacketConverter>(
246 V4_ICMP_PACKET_TX, sizeof(V4_ICMP_PACKET_TX), CONVERT_FROM_V4_TO_V6, v4Addr_, v6Addr_, prefixAddr_);
247 EXPECT_EQ(clatdPacketConverter->ConvertPacket(false), NETMANAGER_SUCCESS);
248
249 std::vector<iovec> iovPackets(CLATD_MAX);
250 int effectivePos = 0;
251 clatdPacketConverter->GetConvertedPacket(iovPackets, effectivePos);
252
253 EXPECT_EQ(IsTranslatedPacketCorrect(iovPackets, V6_ICMP_PACKET_TX), true);
254 }
255
256 /**
257 * @tc.name: ClatdPacketConverterTranslateIcmpTest002
258 * @tc.desc: Test ClatdPacketConverter translate ipv6 icmp packet.
259 * @tc.type: FUNC
260 */
261 HWTEST_F(ClatdPacketConverterTest, ClatdPacketConverterTranslateIcmpTest002, TestSize.Level1)
262 {
263 inet_pton(AF_INET6, V6ADDR_UDP_ICMP, &v6Addr_);
264 auto clatdPacketConverter = std::make_unique<ClatdPacketConverter>(
265 V6_ICMP_PACKET_RX, sizeof(V6_ICMP_PACKET_RX), CONVERT_FROM_V6_TO_V4, v4Addr_, v6Addr_, prefixAddr_);
266 EXPECT_EQ(clatdPacketConverter->ConvertPacket(false), NETMANAGER_SUCCESS);
267
268 std::vector<iovec> iovPackets(CLATD_MAX);
269 int effectivePos = 0;
270 clatdPacketConverter->GetConvertedPacket(iovPackets, effectivePos);
271
272 EXPECT_EQ(IsTranslatedPacketCorrect(iovPackets, V4_ICMP_PACKET_RX), true);
273 }
274 } // namespace nmd
275 } // namespace OHOS