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 
16 #ifndef ROUTER_ADVERTISEMENT_DAEMON_H
17 #define ROUTER_ADVERTISEMENT_DAEMON_H
18 
19 #include "netmgr_ext_log_wrapper.h"
20 #include "router_advertisement_params.h"
21 #include <any>
22 #include <arpa/inet.h>
23 #include <atomic>
24 #include <condition_variable>
25 #include <cstring>
26 #include <iostream>
27 #include <map>
28 #include <mutex>
29 #include <netinet/in.h>
30 #include <random>
31 #include <securec.h>
32 #include <set>
33 #include <sstream>
34 #include <string>
35 #include <sys/ioctl.h>
36 #include <sys/socket.h>
37 #include <thread>
38 #include <unistd.h>
39 
40 namespace OHOS {
41 namespace NetManagerStandard {
42 
43 constexpr uint32_t HW_MAC_LENGTH = 6;
44 
45 // eg:11:22:33:44:55:66 or 11-22-33-44-55-66
46 constexpr uint32_t HW_MAC_STR_LENGTH = 17;
47 constexpr uint32_t IPV6_ADDR_LEN = 16;
48 constexpr uint32_t DEFAULT_RTR_INTERVAL_SEC = 600;
49 constexpr uint32_t DEFAULT_LIFETIME = 6 * DEFAULT_RTR_INTERVAL_SEC;
50 constexpr int32_t MAC_SSCANF_SPACE = 3;
51 
52 // www.rfc-editor.org/rfc/rfc4861#section-4.6
53 constexpr uint32_t UNITS_OF_OCTETS = 8;
54 
55 /** ICMPv6 Ra package type, refer to
56 https://tools.ietf.org/html/rfc4861#section-13
57 *   Message name                            ICMPv6 Type
58 *   Router Solicitation                      133
59 *   Router Advertisement                     134
60 *  Option Name                               Type
61 *  Source Link-Layer Address                   1
62 *  Target Link-Layer Address                   2
63 *  Prefix Information                          3
64 *  MTU                                         5
65 */
66 constexpr uint8_t ICMPV6_ND_ROUTER_SOLICIT_TYPE = 133;
67 constexpr uint8_t ICMPV6_ND_ROUTER_ADVERT_TYPE = 134;
68 constexpr uint8_t ND_OPTION_SLLA_TYPE = 1;
69 constexpr uint8_t ND_OPTION_PIO_TYPE = 3;
70 constexpr uint8_t ND_OPTION_MTU_TYPE = 5;
71 constexpr uint8_t ND_OPTION_RDNSS_TYPE = 25;
72 struct DeprecatedInfoTracker {
73     std::vector<IpPrefix> deprecatedPrefixes;
74     std::vector<in6_addr> deprecatedDnses;
75 };
76 
77 #pragma pack(1)
78 struct Icmpv6HeadSt {
79     uint8_t type = ICMPV6_ND_ROUTER_ADVERT_TYPE;
80     uint8_t code = 0;
81     uint16_t checkSum = 0;
82     uint8_t curHopLimit = 0;
83     uint8_t flags = 0;
84     uint16_t routerLifetime = 0;
85     uint32_t reachLifetime = 0;
86     uint32_t retransTimer = 0;
87 };
88 struct Icmpv6SllOpt {
89     uint8_t type = ND_OPTION_SLLA_TYPE;
90     uint8_t len = 0;
91     uint8_t linkAddress[HW_MAC_LENGTH] = {};
92 };
93 struct Icmpv6MtuOpt {
94     uint8_t type = ND_OPTION_MTU_TYPE;
95     uint8_t len = 0;
96     uint16_t res = 0;
97     uint32_t mtu = 0;
98 };
99 struct Icmpv6PrefixInfoOpt {
100     uint8_t type = ND_OPTION_PIO_TYPE;
101     uint8_t len = 0;
102     uint8_t prefixLen = 0;
103     uint8_t flag = 0;
104     uint32_t validLifetime = 0;
105     uint32_t prefLifetime = 0;
106     uint32_t res = 0;
107     uint8_t prefix[IPV6_ADDR_LEN] = {};
108 };
109 struct Icmpv6RdnsOpt {
110     uint8_t type = ND_OPTION_RDNSS_TYPE;
111     uint8_t len = 0;
112     uint16_t res = 0;
113     uint32_t lifetime = 0;
114     uint8_t dnsServer[0] = {};
115 };
116 #pragma pack()
117 class RouterAdvertisementDaemon {
118 public:
119     RouterAdvertisementDaemon();
120     ~RouterAdvertisementDaemon() = default;
121     int32_t Init(const std::string &ifaceName);
122     int32_t StartRa();
123     void StopRa();
124     static void ProcessSendRaPacket(int inputSignal);
125     RaParams GetDeprecatedRaParams(RaParams &oldRa, RaParams &newRa);
126     void BuildNewRa(const RaParams &newRa);
127     static RouterAdvertisementDaemon *pThis;
128 
129 private:
130     bool IsSocketValid();
131     bool CreateRASocket();
132     void CloseRaSocket();
133     void RunRecvRsThread();
134     void HupRaThread();
135     bool MaybeSendRa(sockaddr_in6 &ra);
136     void ResetRaRetryInterval();
137     bool AssembleRaLocked();
138     uint16_t PutRaHeader(uint8_t *raBuf);
139     uint16_t PutRaSlla(uint8_t *raBuf, const std::string &mac);
140     uint16_t PutRaMtu(uint8_t *raBuf, int32_t mtu);
141     uint16_t PutRaPio(uint8_t *raBuf, IpPrefix &ipp);
142     uint16_t PutRaRdnss(uint8_t *raBuf);
143 
144 private:
145     sockaddr_in6 dstIpv6Addr_ = {};
146     int socket_ = -1;
147     std::mutex mutex_;
148     std::thread recvRsThread_;
149     uint8_t sendRaTimes_ = 1;
150     volatile bool stopRaThread_ = false;
151     uint8_t raPacket_[IPV6_MIN_MTU] = {};
152     uint16_t raPacketLength_ = 0;
153     std::shared_ptr<RaParams> raParams_;
154     DeprecatedInfoTracker deprecatedInfoTracker_;
155 };
156 
157 } // namespace NetManagerStandard
158 } // namespace OHOS
159 #endif // ROUTER_ADVERTISEMENT_DAEMON_H
160