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