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 #ifndef NETSYS_CLATD_PACKET_CONVERTER_H
16 #define NETSYS_CLATD_PACKET_CONVERTER_H
17 
18 #include <linux/if_tun.h>
19 #include <netinet/icmp6.h>
20 #include <netinet/in.h>
21 #include <netinet/ip.h>
22 #include <netinet/ip6.h>
23 #include <netinet/ip_icmp.h>
24 #include <netinet/tcp.h>
25 #include <netinet/udp.h>
26 #include <string>
27 #include <sys/uio.h>
28 #include <vector>
29 
30 #include "clat_constants.h"
31 #include "clat_utils.h"
32 #include "inet_addr.h"
33 
34 namespace OHOS {
35 namespace nmd {
36 using namespace OHOS::NetManagerStandard;
37 class ClatdPacketConverter {
38 public:
39     ClatdPacketConverter(const uint8_t *inputPacket, size_t inputPacketSize, ClatdConvertType convertType,
40                          const in_addr &v4Addr, const in6_addr &v6Addr, const in6_addr &prefixAddr);
41 
42     int32_t ConvertPacket(bool skip_csum);
43 
44     void GetConvertedPacket(std::vector<iovec> &iovPackets, int &effectivePos);
45 
46 private:
47     int32_t ConvertV4Packet(int pos, const uint8_t *inputPacket, size_t inputPacketSize);
48     int32_t ConvertV4TpPacket(int pos, const iphdr *ipHeader, ip6_hdr *ip6Header, size_t tpLen, uint8_t v6TpProtocol);
49     int32_t ConvertV6Packet(int pos, const uint8_t *inputPacket, size_t inputPacketSize);
50     int32_t ConvertV6TpPacket(int pos, const ip6_hdr *ip6Header, iphdr *ipHeader, size_t tpLen, uint8_t v4TpProtocol);
51     bool IsV4PacketValid(const iphdr *ipHeader, size_t packetSize);
52     bool IsV6PacketValid(const ip6_hdr *ip6Header, size_t packetSize);
53     void WriteIpv6Header(ip6_hdr *ip6Header, uint8_t tpProtocol, const iphdr *ipHeader);
54     void WriteIpv4Header(iphdr *ipHeader, uint8_t tpProtocol, const ip6_hdr *ip6Header);
55     void ConvertV4Address(uint32_t v4Addr, in6_addr &v6Addr);
56     void ConvertV6Address(const in6_addr &v6Addr, uint32_t &v4Addr);
57     size_t WriteFragHeader(ip6_frag *ip6FragHeader, ip6_hdr *ip6Header, const iphdr *ipHeader);
58     void ProcessFragHeader(const ip6_frag *ip6FragHeader, iphdr *ipHeader, uint8_t &v6TpProtocol,
59                            uint8_t &v4TpProtocol);
60     uint32_t CalV4PseudoHeaderChecksum(const iphdr *ipHeader, uint16_t tpLen, uint8_t tpProtocol);
61     uint32_t CalV6PseudoHeaderChecksum(const ip6_hdr *ip6Header, uint32_t tpLen, uint8_t tpProtocol);
62     uint16_t GetIovPacketLength(int pos);
63     int32_t ConvertIcmpPacket(int pos, const icmphdr *icmpHeader, uint32_t checksum, size_t tpLen);
64     int32_t ConvertIcmpv6Packet(int pos, const icmp6_hdr *icmp6Header, size_t tpLen);
65     void ConvertIcmpTypeAndCode(const uint8_t &icmpType, const uint8_t &icmpCode, uint8_t &icmp6Type,
66                                 uint8_t &icmp6Code);
67     void ConvertIcmpV6TypeAndCode(const uint8_t &icmp6Type, const uint8_t &icmp6Code, uint8_t &icmpType,
68                                   uint8_t &icmpCode);
69     uint16_t CalIovPacketChecksum(uint32_t sum, int pos);
70     int32_t ConvertTcpPacket(int pos, const tcphdr *tcpHeader, uint32_t oldChecksum, uint32_t newChecksum,
71                              size_t tpLen);
72     bool IsTcpPacketValid(const tcphdr *packet, size_t packetSize);
73     int32_t ConvertUdpPacket(int pos, const udphdr *udpHeader, uint32_t oldChecksum, uint32_t newChecksum,
74                              size_t tpLen);
75     void WritePayload(int pos, const uint8_t *tpHeader, size_t tpLen);
76     void WriteTunHeader(bool skip_csum);
77 
78     const uint8_t *inputPacket_;
79     size_t inputPacketSize_;
80     ClatdConvertType convertType_;
81     in_addr localV4Addr_;
82     in6_addr localV6Addr_;
83     in6_addr prefixAddr_;
84 
85     std::vector<std::string> iovBufs_;
86     std::vector<size_t> iovBufLens_;
87     int effectivePos_{0};
88 };
89 } // namespace nmd
90 } // namespace OHOS
91 #endif