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