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