1 /*
2  * Copyright (C) 2021 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 #ifndef OHOS_DHCP_CLIENT_STATEMACHINE_H
16 #define OHOS_DHCP_CLIENT_STATEMACHINE_H
17 
18 #include <thread>
19 #include <string>
20 #include <stdint.h>
21 #include <sys/types.h>
22 #include "dhcp_arp_checker.h"
23 #include "dhcp_client_def.h"
24 #include "dhcp_ipv6_client.h"
25 #include "dhcp_thread.h"
26 
27 #ifndef OHOS_ARCH_LITE
28 #include "common_timer_errors.h"
29 #include "timer.h"
30 #endif
31 
32 namespace OHOS {
33 namespace DHCP {
34 class  DhcpClientStateMachine{
35 public:
36     DhcpClientStateMachine(std::string ifname);
37     virtual ~DhcpClientStateMachine();
38 private:
39     int InitSpecifiedClientCfg(const std::string &ifname, bool isIpv6);
40     int GetClientNetworkInfo(void);
41     int SetIpv4State(int state);
42     int PublishDhcpResultEvent(const char *ifname, const int code, struct DhcpIpResult *result);
43     int GetPacketHeaderInfo(struct DhcpPacket *packet, uint8_t type);
44     int GetPacketCommonInfo(struct DhcpPacket *packet);
45     int AddClientIdToOpts(struct DhcpPacket *packet);
46     int AddHostNameToOpts(struct DhcpPacket *packet);
47     int AddStrToOpts(struct DhcpPacket *packet, int option, std::string &value);
48     int DhcpDiscover(uint32_t transid, uint32_t requestip);
49     int DhcpRequest(uint32_t transid, uint32_t reqip, uint32_t servip);
50     int DhcpReboot(uint32_t transid, uint32_t reqip);
51     int DhcpDecline(uint32_t transid, uint32_t clientIp, uint32_t serverIp);
52     int GetDHCPServerHostName(const struct DhcpPacket *packet, struct DhcpIpResult *result);
53     int ParseNetworkVendorInfo(const struct DhcpPacket *packet, struct DhcpIpResult *result);
54     int GetPacketReadSockFd(void);
55     int GetSigReadSockFd(void);
56     int DhcpRenew(uint32_t transid, uint32_t clientip, uint32_t serverip);
57     int DhcpRelease(uint32_t clientip, uint32_t serverip);
58     int InitConfig(const std::string &ifname, bool isIpv6);
59     void SendReboot(uint32_t targetIp, time_t timestamp);
60     void AddParamaterRequestList(struct DhcpPacket *packet);
61     void DhcpResponseHandle(time_t timestamp, int sockFd);
62     void DhcpAckOrNakPacketHandle(uint8_t type, struct DhcpPacket *packet, time_t timestamp);
63     void ParseDhcpAckPacket(const struct DhcpPacket *packet, time_t timestamp);
64     void ParseDhcpNakPacket(const struct DhcpPacket *packet, time_t timestamp);
65     void DhcpInit(void);
66     bool InitSocketFd(int &sockFdRaw, int &sockFdkernel);
67     void SetSocketMode(uint32_t mode);
68     void ParseNetworkServerIdInfo(const struct DhcpPacket *packet, struct DhcpIpResult *result);
69     void ParseNetworkInfo(const struct DhcpPacket *packet, struct DhcpIpResult *result);
70     void ParseNetworkDnsInfo(const struct DhcpPacket *packet, struct DhcpIpResult *result);
71     void SetIpv4DefaultDns(struct DhcpIpResult *result);
72     void ParseNetworkDnsValue(struct DhcpIpResult *result, uint32_t uData, size_t &len, int &count);
73     void DhcpOfferPacketHandle(uint8_t type, const struct DhcpPacket *packet, time_t timestamp);
74     void DhcpRequestHandle(time_t timestamp);
75     void Rebinding(time_t timestamp);
76     void Requesting(time_t timestamp);
77     void Renewing(time_t timestamp);
78     void Reboot(time_t timestamp);
79     void Declining(time_t timestamp);
80     void AddParamaterRebootList(struct DhcpPacket *packet);
81     void InitSelecting(time_t timestamp);
82     bool SignalReceiver(void);
83     void RunGetIPThreadFunc(const DhcpClientStateMachine &instance);
84     void FormatString(struct DhcpIpResult *result);
85     uint32_t GetRandomId(void);
86     uint32_t GetDhcpTransID(void);
87     void IpConflictDetect();
88     void FastArpDetect();
89     void SlowArpDetect(time_t timestamp);
90     void SlowArpDetectCallback(bool isReachable);
91     bool IsArpReachable(uint32_t timeoutMillis, std::string ipAddress);
92     void SaveIpInfoInLocalFile(const DhcpIpResult ipResult);
93     int32_t GetCachedDhcpResult(std::string targetBssid, IpInfoCached &ipCached);
94     void TryCachedIp();
95     void SetDefaultNetMask(struct DhcpIpResult *result);
96 #ifndef OHOS_ARCH_LITE
97     void GetDhcpOffer(DhcpPacket *getPacket, int64_t timestamp);
98 #endif
99 
100 public:
101 #ifndef OHOS_ARCH_LITE
102     void StartTimer(TimerType type, uint32_t &timerId, int64_t interval, bool once);
103     void StopTimer(uint32_t &timerId);
104     void GetIpTimerCallback();
105     void RenewDelayCallback();
106     void RebindDelayCallback();
107     void RemainingDelayCallback();
108 #endif
109     int StartIpv4Type(const std::string &ifname, bool isIpv6, ActionMode action);
110     int InitStartIpv4Thread(const std::string &ifname, bool isIpv6);
111     void StartIpv4(void);
112     int ExecDhcpRelease(void);
113     int ExecDhcpRenew(void);
114     int ExitIpv4(void);
115     int StopIpv4(void);
116     int InitSignalHandle();
117     int CloseSignalHandle();
118     ActionMode GetAction(void);
119     void SetConfiguration(const RouterCfg routerCfg);
120     void ScheduleLeaseTimers(bool isCachedIp);
121     void CloseAllRenewTimer();
122     int SendStopSignal();
123 private:
124     int m_dhcp4State;
125     int m_sockFd;
126     int m_sigSockFds[NUMBER_TWO];
127     int m_resendTimer;
128     uint32_t m_sentPacketNum;
129     uint32_t m_timeoutTimestamp;
130     int64_t m_renewalTimestamp;
131     int64_t m_renewalTimestampBoot;
132     uint32_t m_leaseTime;
133     uint32_t m_renewalSec;
134     uint32_t m_rebindSec;
135     uint32_t m_requestedIp4;
136     uint32_t m_serverIp4;
137     uint32_t m_socketMode;
138     uint32_t m_transID;
139     DhcpClientCfg m_cltCnf;
140     std::atomic<bool> threadExit_{true};
141     std::string m_ifName;  //对象服务的网卡名称
142     std::unique_ptr<DhcpThread> ipv4Thread_ = nullptr;
143     ActionMode m_action;
144 #ifndef OHOS_ARCH_LITE
145     std::mutex getIpTimerMutex;
146     uint32_t getIpTimerId;
147     uint32_t renewDelayTimerId;
148     uint32_t rebindDelayTimerId;
149     uint32_t remainingDelayTimerId;
150     uint32_t m_slowArpTaskId;
151 #endif
152     std::string m_arpDectionTargetIp;
153     RouterCfg m_routerCfg;
154     uint32_t m_conflictCount;
155     DhcpIpResult m_dhcpIpResult;
156     DhcpArpChecker m_dhcpArpChecker;
157     std::function<void(bool isReachable)> m_slowArpCallback;
158     bool m_slowArpDetecting;
159     int64_t firstSendPacketTime_;
160 };
161 
162 typedef struct{
163     std::string ifName;
164     bool isIpv6;
165     DhcpClientStateMachine *pStaStateMachine;
166     DhcpIpv6Client *pipv6Client;
167 }DhcpClient;
168 }  // namespace DHCP
169 }  // namespace OHOS
170 #endif