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