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