From 0cacaa84854fb64c7baea997a16d39711da76e51 Mon Sep 17 00:00:00 2001 From: Fagan Date: Wed, 7 Jul 2021 10:43:10 +0800 Subject: [PATCH 1/3] add dhcp client ipv4 function. --- .../wifi_standard/src/wifi_logger.h | 1 + ohos.build | 7 + .../wifi_standard/wifi_framework/BUILD.gn | 7 + .../wifi_framework/common/log/wifi_log_tags.h | 1 + .../wifi_framework/common/log/wifi_logger.h | 2 + .../wifi_framework/dhcp_manage/BUILD.gn | 51 + .../dhcp_manage/dhcp_client/BUILD.gn | 53 + .../dhcp_client/include/dhcp_client.h | 61 + .../dhcp_client/include/dhcp_define.h | 244 ++++ .../dhcp_client/include/dhcp_function.h | 41 + .../dhcp_client/include/dhcp_ipv4.h | 34 + .../dhcp_client/include/dhcp_options.h | 41 + .../dhcp_client/include/dhcp_socket.h | 36 + .../dhcp_manage/dhcp_client/src/dhcp_client.c | 89 ++ .../dhcp_client/src/dhcp_function.c | 397 ++++++ .../dhcp_manage/dhcp_client/src/dhcp_ipv4.c | 1138 +++++++++++++++++ .../dhcp_manage/dhcp_client/src/dhcp_main.c | 364 ++++++ .../dhcp_client/src/dhcp_options.c | 379 ++++++ .../dhcp_manage/dhcp_client/src/dhcp_socket.c | 381 ++++++ .../include/dhcp_client_service_impl.h | 197 +++ .../dhcp_manage/include/dhcp_define.h | 158 +++ .../dhcp_manage/include/dhcp_func.h | 60 + .../include/dhcp_server_service_impl.h | 271 ++++ .../dhcp_manage/include/dhcp_service.h | 184 +++ .../interfaces/i_dhcp_client_service.h | 105 ++ .../interfaces/i_dhcp_result_notify.h | 59 + .../interfaces/i_dhcp_server_service.h | 136 ++ .../dhcp_manage/interfaces/i_dhcp_service.h | 182 +++ .../src/dhcp_client_service_impl.cpp | 629 +++++++++ .../dhcp_manage/src/dhcp_func.cpp | 561 ++++++++ .../src/dhcp_server_service_impl.cpp | 896 +++++++++++++ .../dhcp_manage/src/dhcp_service.cpp | 205 +++ .../wifi_internal_event_dispatcher.cpp | 44 +- .../wifi_manage/wifi_scan/scan_common.h | 12 +- .../wifi_manage/wifi_scan/scan_monitor.cpp | 2 +- .../wifi_manage/wifi_scan/scan_service.cpp | 2 +- .../wifi_manage/wifi_sta/BUILD.gn | 2 +- .../wifi_sta/net_conf/if_config.cpp | 38 +- .../wifi_manage/wifi_sta/net_conf/if_config.h | 10 +- .../wifi_manage/wifi_sta/sta_define.h | 21 - .../wifi_manage/wifi_sta/sta_dhcp_server.cpp | 316 ----- .../wifi_manage/wifi_sta/sta_dhcp_server.h | 170 --- .../wifi_sta/sta_network_check.cpp | 4 +- .../wifi_manage/wifi_sta/sta_network_check.h | 3 +- .../wifi_sta/sta_state_machine.cpp | 242 ++-- .../wifi_manage/wifi_sta/sta_state_machine.h | 56 +- 46 files changed, 7222 insertions(+), 670 deletions(-) create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/BUILD.gn create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/BUILD.gn create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_client.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_define.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_function.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_ipv4.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_options.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_socket.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_client.c create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_function.c create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_ipv4.c create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_main.c create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_options.c create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_socket.c create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_client_service_impl.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_define.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_func.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_server_service_impl.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_service.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_client_service.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_result_notify.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_server_service.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_service.h create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_client_service_impl.cpp create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_func.cpp create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_server_service_impl.cpp create mode 100644 services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_service.cpp delete mode 100644 services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_dhcp_server.cpp delete mode 100644 services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_dhcp_server.h diff --git a/interfaces/innerkits/native_cpp/wifi_standard/src/wifi_logger.h b/interfaces/innerkits/native_cpp/wifi_standard/src/wifi_logger.h index 82d84e647..00e62e8f8 100644 --- a/interfaces/innerkits/native_cpp/wifi_standard/src/wifi_logger.h +++ b/interfaces/innerkits/native_cpp/wifi_standard/src/wifi_logger.h @@ -25,6 +25,7 @@ const unsigned int LOG_ID_WIFI_HOTSPOT = LOG_ID_WIFI | 0x01; const unsigned int LOG_ID_WIFI_SCAN = LOG_ID_WIFI | 0x02; const unsigned int LOG_ID_WIFI_P2P = LOG_ID_WIFI | 0x03; const unsigned int LOG_ID_WIFI_AWARE = LOG_ID_WIFI | 0x04; +const unsigned int LOG_ID_WIFI_DHCP = LOG_ID_WIFI | 0x05; #define DEFINE_WIFILOG_LABEL(name) \ static constexpr OHOS::HiviewDFX::HiLogLabel WIFI_LOG_LABEL = {LOG_CORE, OHOS::Wifi::LOG_ID_WIFI, name}; diff --git a/ohos.build b/ohos.build index 38d917899..4aab5cc76 100755 --- a/ohos.build +++ b/ohos.build @@ -5,6 +5,7 @@ "module_list": [ "//foundation/communication/wifi/interfaces/innerkits/native_cpp/wifi_standard/src:wifi_sdk", "//foundation/communication/wifi/services/wifi_standard/wifi_framework:wifi_manage", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework:dhcp_manage", "//foundation/communication/wifi/services/wifi_standard/wifi_hal:wifi_hal_service", "//foundation/communication/wifi/services/wifi_standard/wifi_framework:wifi_system_ability", "//foundation/communication/wifi/services/wifi_standard/sa_profile:wifi_standard_sa_profile" @@ -38,6 +39,12 @@ } ] }, + "dhcp_manage": { + "module_list": [ + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage:dhcp_manager_service", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client:dhcp_client_service" + ] + }, "wifi_hal_service": [ { "type": "so", diff --git a/services/wifi_standard/wifi_framework/BUILD.gn b/services/wifi_standard/wifi_framework/BUILD.gn index d1ae18dad..84e80d5ea 100644 --- a/services/wifi_standard/wifi_framework/BUILD.gn +++ b/services/wifi_standard/wifi_framework/BUILD.gn @@ -31,3 +31,10 @@ group("wifi_manage") { "//foundation/communication/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta:wifi_sta_service", ] } + +group("dhcp_manage") { + deps = [ + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage:dhcp_manager_service", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client:dhcp_client_service" + ] +} \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/common/log/wifi_log_tags.h b/services/wifi_standard/wifi_framework/common/log/wifi_log_tags.h index f10c5a001..0a38123a9 100644 --- a/services/wifi_standard/wifi_framework/common/log/wifi_log_tags.h +++ b/services/wifi_standard/wifi_framework/common/log/wifi_log_tags.h @@ -23,6 +23,7 @@ const unsigned int LOG_ID_WIFI_HOTSPOT = LOG_ID_WIFI | 0x01; const unsigned int LOG_ID_WIFI_SCAN = LOG_ID_WIFI | 0x02; const unsigned int LOG_ID_WIFI_P2P = LOG_ID_WIFI | 0x03; const unsigned int LOG_ID_WIFI_AWARE = LOG_ID_WIFI | 0x04; +const unsigned int LOG_ID_WIFI_DHCP = LOG_ID_WIFI | 0x05; } // namespace Wifi } // namespace OHOS #endif \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/common/log/wifi_logger.h b/services/wifi_standard/wifi_framework/common/log/wifi_logger.h index cc855b0bb..92d8051e4 100644 --- a/services/wifi_standard/wifi_framework/common/log/wifi_logger.h +++ b/services/wifi_standard/wifi_framework/common/log/wifi_logger.h @@ -31,6 +31,8 @@ namespace Wifi { static constexpr OHOS::HiviewDFX::HiLogLabel WIFI_LOG_LABEL = {LOG_CORE, OHOS::Wifi::LOG_ID_WIFI_P2P, name}; #define DEFINE_WIFILOG_AWARE_LABEL(name) \ static constexpr OHOS::HiviewDFX::HiLogLabel WIFI_LOG_LABEL = {LOG_CORE, OHOS::Wifi::LOG_ID_WIFI_AWARE, name}; +#define DEFINE_WIFILOG_DHCP_LABEL(name) \ + static constexpr OHOS::HiviewDFX::HiLogLabel WIFI_LOG_LABEL = {LOG_CORE, OHOS::Wifi::LOG_ID_WIFI_DHCP, name}; #define WIFI_LOGF(...) (void)OHOS::HiviewDFX::HiLog::Fatal(WIFI_LOG_LABEL, ##__VA_ARGS__) #define WIFI_LOGE(...) (void)OHOS::HiviewDFX::HiLog::Error(WIFI_LOG_LABEL, ##__VA_ARGS__) diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/BUILD.gn b/services/wifi_standard/wifi_framework/dhcp_manage/BUILD.gn new file mode 100644 index 000000000..8448953ba --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_shared_library("dhcp_manager_service") { + install_enable = true + sources = [ + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_service.cpp", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_client_service_impl.cpp", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_server_service_impl.cpp", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_func.cpp" + ] + + include_dirs = [ + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/common/log", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/include", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/interfaces", + "//utils/native/base/include" + ] + + deps = [ + "//utils/native/base:utils" + ] + + cflags_cc = [ "-std=c++17", + "-Wall", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog" + ] + ldflags = [ + "-fPIC", + "-Wl,-E", + ] + + part_name = "wifi_standard" + subsystem_name = "communication" +} + diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/BUILD.gn b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/BUILD.gn new file mode 100644 index 000000000..1365faf22 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/BUILD.gn @@ -0,0 +1,53 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_executable("dhcp_client_service") { + install_enable = true + sources = [ + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_main.c", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_client.c", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_ipv4.c", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_function.c", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_socket.c", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_options.c" + ] + + include_dirs = [ + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/common/log", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include", + "//utils/native/base/include" + ] + + deps = [ + "//utils/native/base:utils" + ] + + cflags_cc = [ + "-fno-rtti", + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + defines = [ + ] + + part_name = "wifi_standard" + subsystem_name = "communication" +} + +group("dhcp_client"){ + deps = [ + ":dhcp_client_service" + ] +} \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_client.h b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_client.h new file mode 100644 index 000000000..1bb0acede --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_client.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_DHCPC_H +#define OHOS_DHCPC_H + +#include "dhcp_define.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define WORKDIR "/data/dhcp/" +#define DHCPC_NAME "dhcp_client_service" +#define DHCPC_CONF "dhcp_client_service.conf" +#define DHCPC_PID "dhcp_client_service.pid" +#define DHCPC_VERSION "1.0" + +enum DHCP_IP_TYPE { + DHCP_IP_TYPE_NONE = 0, + DHCP_IP_TYPE_ALL = 1, + DHCP_IP_TYPE_V4 = 2, + DHCP_IP_TYPE_V6 = 3 +}; + +struct DhcpClientCfg { + char workdir[DIR_MAX_LEN]; + char conf_file[DIR_MAX_LEN]; + char pid_file[DIR_MAX_LEN]; + char result_file[DIR_MAX_LEN]; + char interface[INFNAME_SIZE]; /* The name of the interface to use */ + int ifindex; /* Index number of the interface to use */ + unsigned int ipaddr4; /* ipv4 of the interface to use */ + unsigned int iptype; + unsigned char hwaddr[MAC_ADDR_LEN]; /* HWaddr of the interface to use */ + + unsigned char *clientid; /* Optional client id to use */ + unsigned char *hostname; /* Optional hostname to use */ + bool timeoutExit; /* Send packet timed out */ +}; +extern struct DhcpClientCfg gClientCfg; + +int StartProcess(void); +int StopProcess(const char *pidFile); +int GetProStatus(const char *pidFile); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_define.h b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_define.h new file mode 100644 index 000000000..5c67cc662 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_define.h @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_DHCP_DEFINE_H +#define OHOS_DHCP_DEFINE_H + + +#include +#include +#include + +#include "wifi_log.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NUMBER_ONE 1 +#define NUMBER_TWO 2 +#define NUMBER_THREE 3 +#define NUMBER_FOUR 4 +#define NUMBER_FIVE 5 + +#define T1 0.5 +#define T2 0.875 +#define TIME_INTERVAL_MAX 1 +#define SENDPACKET_MAXNUM 3 +#define TIMEOUT_TIMES_MAX 4 +#define TIMEOUT_WAIT_SEC 1 +#define TIMEOUT_ONE_WAIT_SEC 1 +#define TIMEOUT_TWO_WAIT_SEC 10 +#define TIMEOUT_THREE_WAIT_SEC 30 +#define TIMEOUT_MORE_WAIT_SEC 60 +#define ONE_HOURS_SEC 3600 +#define LEASETIME_DEFAULT 1 +#define SLEEP_TIME_200_MS 200 * 1000 +#define SLEEP_TIME_500_MS 500 * 1000 + +#define MAC_ADDR_LEN 6 +#define MAC_ADDR_CHAR_NUM 3 +#define ETHERNET_TYPE 0x01 +#define ETHERNET_LEN 6 +#define VENDOR_MAX_LEN 64 +#define MAGIC_COOKIE 0x63825363 +#define BROADCAST_FLAG 0x8000 +#define MAC_BCAST_ADDR "\xff\xff\xff\xff\xff\xff" +#define SIGNED_INTEGER_MAX 0x7FFFFFFF +#define PID_MAX_LEN 16 +#define DEFAULT_UMASK 027 +#define DIR_MAX_LEN 256 +#define INFNAME_SIZE 16 /* Length of interface name */ + +/* dhcp4 state */ +#define INIT_SELECTING 0 +#define REQUESTING 1 +#define BOUND 2 +#define RENEWING 3 +#define REBINDING 4 +#define INIT_REBOOT 5 +#define RENEW_REQUESTED 6 +#define RELEASED 7 + +/* UDP port numbers for BOOTP */ +#define BOOTP_SERVER 67 +#define BOOTP_CLIENT 68 + +/* BOOTP message type */ +#define BOOT_REQUEST 1 +#define BOOT_REPLY 2 + +/* DHCP packet type */ +#define DHCP_DISCOVER 1 +#define DHCP_OFFER 2 +#define DHCP_REQUEST 3 +#define DHCP_DECLINE 4 +#define DHCP_ACK 5 +#define DHCP_NAK 6 +#define DHCP_RELEASE 7 +#define DHCP_INFORM 8 +#define DHCP_FORCERENEW 9 + +/* dhcp return code */ +enum EnumErrCode { + /* success */ + DHCP_OPT_SUCCESS = 0, + /* failed */ + DHCP_OPT_FAILED, + /* null pointer */ + DHCP_OPT_NULL, + /* timeout */ + DHCP_OPT_TIMEOUT, + /* error */ + DHCP_OPT_ERROR, + /* none */ + DHCP_OPT_NONE, +}; + +/* socket return code */ +enum EnumSocketErrCode { + /* success */ + SOCKET_OPT_SUCCESS = 0, + /* failed */ + SOCKET_OPT_FAILED = -1, + /* error */ + SOCKET_OPT_ERROR = -2 +}; + +/* socket mode */ +enum EnumSocketMode { + SOCKET_MODE_INVALID = 0, + SOCKET_MODE_RAW = 1, + SOCKET_MODE_KERNEL = 2 +}; + +/* DHCP options */ +enum EnumDhcpOption { + DHO_PAD = 0, + DHO_SUBNETMASK = 1, + DHO_ROUTER = 3, + DHO_DNSSERVER = 6, + DHO_HOSTNAME = 12, + DHO_DNSDOMAIN = 15, + DHO_MTU = 26, + DHO_BROADCAST = 28, + DHO_STATICROUTE = 33, + DHO_NISDOMAIN = 40, + DHO_NISSERVER = 41, + DHO_NTPSERVER = 42, + DHO_VENDOR = 43, + DHO_IPADDRESS = 50, + DHO_LEASETIME = 51, + DHO_OPTSOVERLOADED = 52, + DHO_MESSAGETYPE = 53, + DHO_SERVERID = 54, + DHO_PARAMETERREQUESTLIST = 55, + DHO_MESSAGE = 56, + DHO_MAXMESSAGESIZE = 57, + DHO_RENEWALTIME = 58, + DHO_REBINDTIME = 59, + DHO_VENDORCLASSID = 60, + DHO_CLIENTID = 61, + DHO_USERCLASS = 77, /* RFC 3004 */ + DHO_RAPIDCOMMIT = 80, /* RFC 4039 */ + DHO_FQDN = 81, + DHO_AUTHENTICATION = 90, /* RFC 3118 */ + DHO_AUTOCONFIGURE = 116, /* RFC 2563 */ + DHO_DNSSEARCH = 119, /* RFC 3397 */ + DHO_CSR = 121, /* RFC 3442 */ + DHO_VIVCO = 124, /* RFC 3925 */ + DHO_VIVSO = 125, /* RFC 3925 */ + DHO_FORCERENEW_NONCE = 145, /* RFC 6704 */ + DHO_MUDURL = 161, /* draft-ietf-opsawg-mud */ + DHO_SIXRD = 212, /* RFC 5969 */ + DHO_MSCSR = 249, /* MS code for RFC 3442 */ + DHO_END = 255 +}; + +enum DHCP_OPTION_DATA_TYPE { + DHCP_OPTION_DATA_INVALID = 0, + DHCP_OPTION_DATA_U8, + DHCP_OPTION_DATA_U16, + DHCP_OPTION_DATA_S16, + DHCP_OPTION_DATA_U32, + DHCP_OPTION_DATA_S32, + DHCP_OPTION_DATA_IP, + DHCP_OPTION_DATA_IP_PAIR, + DHCP_OPTION_DATA_IP_LIST, + DHCP_OPTION_DATA_IP_STRING +}; + +/* Sizes for DhcpPacket Fields */ +#define DHCP_CHADDR_MAX_BYTES 16 +#define DHCP_SNAME_MAX_BYTES 64 +#define DHCP_FILE_MAX_BYTES 128 +#define DHCP_OPT_MAX_BYTES 308 +#define DHCP_OPT_CODE_INDEX 0 +#define DHCP_OPT_LEN_INDEX 1 +#define DHCP_OPT_DATA_INDEX 2 +#define DHCP_OPT_CODE_BYTES 1 +#define DHCP_OPT_LEN_BYTES 1 +#define DHCP_UINT8_BYTES 1 +#define DHCP_UINT16_BYTES 2 +#define DHCP_UINT32_BYTES 4 +#define DHCP_UINT32_DOUBLE_BYTES 8 +#define DHCP_UINT16_BITS 16 +#define DHCP_REQ_CODE_NUM 10 + +#define OPTION_FIELD 0 +#define FILE_FIELD 1 +#define SNAME_FIELD 2 + +/* DhcpPacket Fields */ +struct DhcpPacket { + uint8_t op; /* message type */ + uint8_t htype; /* hardware address type */ + uint8_t hlen; /* hardware address length */ + uint8_t hops; /* should be zero in client message */ + uint32_t xid; /* transaction id */ + uint16_t secs; /* elapsed time in sec. from boot */ + uint16_t flags; /* such as broadcast flag */ + uint32_t ciaddr; /* (previously allocated) client IP */ + uint32_t yiaddr; /* 'your' client IP address */ + uint32_t siaddr; /* next server IP, should be zero in client's messages */ + uint32_t giaddr; /* relay agent (gateway) IP, should be zero in client's messages */ + uint8_t chaddr[DHCP_CHADDR_MAX_BYTES]; /* client's hardware address */ + uint8_t sname[DHCP_SNAME_MAX_BYTES]; /* server host name */ + uint8_t file[DHCP_FILE_MAX_BYTES]; /* boot file name */ + int32_t cookie; /* magic cookie */ + uint8_t options[DHCP_OPT_MAX_BYTES]; /* dhcp options, Size: 312 - cookie */ +}; + +struct UdpDhcpPacket { + struct iphdr ip; + struct udphdr udp; + struct DhcpPacket data; +}; + +struct DhcpResult { + char strYiaddr[INET_ADDRSTRLEN]; /* your (client) IP */ + char strOptServerId[INET_ADDRSTRLEN]; /* dhcp option DHO_SERVERID */ + char strOptSubnet[INET_ADDRSTRLEN]; /* dhcp option DHO_SUBNETMASK */ + char strOptDns1[INET_ADDRSTRLEN]; /* dhcp option DHO_DNSSERVER */ + char strOptDns2[INET_ADDRSTRLEN]; /* dhcp option DHO_DNSSERVER */ + char strOptRouter1[INET_ADDRSTRLEN]; /* dhcp option DHO_ROUTER */ + char strOptRouter2[INET_ADDRSTRLEN]; /* dhcp option DHO_ROUTER */ + char strOptVendor[DHCP_FILE_MAX_BYTES]; /* dhcp option DHO_VENDOR */ + uint32_t uOptLeasetime; /* dhcp option DHO_LEASETIME */ +}; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_function.h b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_function.h new file mode 100644 index 000000000..6f4675c89 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_function.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_FUNCTION_H +#define OHOS_FUNCTION_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +bool Ip4StrConToInt(const char *strIp, uint32_t *uIp, bool bHost); +char *Ip4IntConToStr(uint32_t uIp, bool bHost); +bool Ip6StrConToChar(const char *strIp, uint8_t chIp[], size_t chlen); + +const char *HwaddrNtoa(const unsigned char *hwaddr, size_t hwlen, char *buf, size_t buflen); +int GetLocalInterface(const char *ifname, int *ifindex, unsigned char *hwaddr, uint32_t *ifaddr4); +int GetLocalIp(const char *ifname, uint32_t *ifaddr4); +int SetLocalInterface(const char *ifname, uint32_t ifaddr4); + +int InitPidfile(const char *pidDir, const char *pidFile); +pid_t GetPID(const char *pidFile); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_ipv4.h b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_ipv4.h new file mode 100644 index 000000000..826e44ff8 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_ipv4.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_IP4_H +#define OHOS_IP4_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int InitSignalHandle(void); +int DhcpDiscover(uint32_t transid, uint32_t requestip); +int DhcpRequest(uint32_t transid, uint32_t reqip, uint32_t servip); +int DhcpRenew(uint32_t transid, uint32_t clientip, uint32_t serverip); +int DhcpRelease(uint32_t clientip, uint32_t serverip); +int StartIpv4(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_options.h b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_options.h new file mode 100644 index 000000000..93ec109eb --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_options.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_OPTIONS_H +#define OHOS_OPTIONS_H + + +#include +#include + +#include "dhcp_define.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint8_t GetDhcpOptionDataLen(const uint8_t code); +const uint8_t *GetDhcpOption(const struct DhcpPacket *packet, int code, size_t *length); +bool GetDhcpOptionUint8(const struct DhcpPacket *packet, int code, uint8_t *data); +bool GetDhcpOptionUint32(const struct DhcpPacket *packet, int code, uint32_t *data); +bool GetDhcpOptionUint32n(const struct DhcpPacket *packet, int code, uint32_t *data1, uint32_t *data2); +char *GetDhcpOptionString(const struct DhcpPacket *packet, int code); +int GetEndOptionIndex(uint8_t *optionptr); +int AddOptionString(uint8_t *optionptr, uint8_t *optionstr, int optionstrLen); +int AddSimpleOption(uint8_t *optionptr, uint8_t code, uint32_t data); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_socket.h b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_socket.h new file mode 100644 index 000000000..e76dca897 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_socket.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_SOCKET_H +#define OHOS_SOCKET_H + + +#include "dhcp_define.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int CreateRawSocket(int ifindex); +int CreateSocket(const char *ifname, uint32_t ip, int port); +int SendToDhcpPacket( + const struct DhcpPacket *sendPacket, uint32_t srcIp, uint32_t destIp, const uint8_t *destHwaddr, int ifindex); +int SendDhcpPacket(struct DhcpPacket *sendPacket, uint32_t srcIp, uint32_t destIp); +int GetDhcpRawPacket(struct DhcpPacket *getPacket, int fd); +int GetDhcpPacket(struct DhcpPacket *getPacket, int fd); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_client.c b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_client.c new file mode 100644 index 000000000..a34d667d8 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_client.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "dhcp_client.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "securec.h" +#include "dhcp_function.h" +#include "dhcp_ipv4.h" + +#undef LOG_TAG +#define LOG_TAG "WifiDhcpClient" + +/* Default options. */ +struct DhcpClientCfg gClientCfg = {"", "", "", "", "", 0, 0, DHCP_IP_TYPE_NONE, {'\0'}, NULL, NULL, false}; + +int StartProcess(void) +{ + if (InitSignalHandle() != DHCP_OPT_SUCCESS) { + LOGE("StartProcess() failed, InitSignalHandle error!\n"); + return DHCP_OPT_FAILED; + } + + if ((gClientCfg.iptype == DHCP_IP_TYPE_ALL) || (gClientCfg.iptype == DHCP_IP_TYPE_V6)) { + /* Handle dhcp v6. */ + } + + if ((gClientCfg.iptype == DHCP_IP_TYPE_ALL) || (gClientCfg.iptype == DHCP_IP_TYPE_V4)) { + /* Handle dhcp v4. */ + StartIpv4(); + } + + return DHCP_OPT_SUCCESS; +} + +int StopProcess(const char *pidFile) +{ + LOGI("StopProcess() enter, pidFile:%{public}s.\n", pidFile); + + pid_t pid = GetPID(pidFile); + if (pid <= 0) { + LOGW("StopProcess() GetPID pidFile:%{public}s, pid == -1!\n", pidFile); + return DHCP_OPT_SUCCESS; + } + + LOGI("StopProcess() sending signal SIGTERM to process:%{public}d.\n", pid); + if (-1 == kill(pid, SIGTERM)) { + if (ESRCH == errno) { + LOGW("StopProcess() pidFile:%{public}s,pid:%{public}d is not exist.\n", pidFile, pid); + unlink(pidFile); + return DHCP_OPT_SUCCESS; + } + LOGE("StopProcess() cmd: [kill %{public}d] failed, kill error:%{public}s!\n", pid, strerror(errno)); + return DHCP_OPT_FAILED; + } + + LOGI("StopProcess() end.\n"); + unlink(pidFile); + return DHCP_OPT_SUCCESS; +} + +int GetProStatus(const char *pidFile) +{ + pid_t pid = GetPID(pidFile); + if (pid <= 0) { + LOGI("GetProStatus() %{public}s pid:%{public}d, %{public}s is not running.\n", pidFile, pid, DHCPC_NAME); + return 0; + } + LOGI("GetProStatus() %{public}s pid:%{public}d, %{public}s is running.\n", pidFile, pid, DHCPC_NAME); + return 1; +} diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_function.c b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_function.c new file mode 100644 index 000000000..5c2d5fc83 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_function.c @@ -0,0 +1,397 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "dhcp_function.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "securec.h" +#include "dhcp_define.h" + +#undef LOG_TAG +#define LOG_TAG "WifiDhcpFunction" + + +bool Ip4StrConToInt(const char *strIp, uint32_t *uIp, bool bHost) +{ + if ((strIp == NULL) || (strlen(strIp) <= 0)) { + LOGE("Ip4StrConToInt failed, strIp == NULL or \"\"!\n"); + return false; + } + + struct in_addr addr4; + int nRet = inet_pton(AF_INET, strIp, &addr4); + if (nRet != 1) { + LOGE("Ip4StrConToInt strIp:%{public}s failed, inet_pton nRet:%{public}d!\n", strIp, nRet); + if (nRet == 0) { + LOGE("Ip4StrConToInt strIp:%{public}s not in presentation format!\n", strIp); + } else { + LOGE("Ip4StrConToInt strIp:%{public}s inet_pton does not contain a valid address family!\n", strIp); + } + return false; + } + + if (bHost) { + *uIp = ntohl(addr4.s_addr); + } else { + *uIp = addr4.s_addr; + } + + return true; +} + +char *Ip4IntConToStr(uint32_t uIp, bool bHost) +{ + char bufIp4[INET_ADDRSTRLEN] = {0}; + struct in_addr addr4; + if (bHost) { + addr4.s_addr = htonl(uIp); + } else { + addr4.s_addr = uIp; + } + const char *p = inet_ntop(AF_INET, &addr4, bufIp4, INET_ADDRSTRLEN); + if (p == NULL) { + LOGE("Ip4IntConToStr uIp:%{public}u failed, inet_ntop p == NULL!\n", uIp); + return NULL; + } + + char *strIp = (char *)malloc(INET_ADDRSTRLEN); + if (strIp == NULL) { + LOGE("Ip4IntConToStr uIp:%{public}u failed, strIp malloc failed!\n", uIp); + return NULL; + } + if (strncpy_s(strIp, INET_ADDRSTRLEN, bufIp4, strlen(bufIp4)) != EOK) { + LOGE("Ip4IntConToStr uIp:%{public}u failed, strIp strncpy_s failed!\n", uIp); + return NULL; + } + + return strIp; +} + +bool Ip6StrConToChar(const char *strIp, uint8_t chIp[], size_t chlen) +{ + if ((strIp == NULL) || (strlen(strIp) <= 0)) { + LOGE("Ip6StrConToChar failed, strIp == NULL or \"\"!\n"); + return false; + } + + struct in6_addr addr6; + if (memset_s(&addr6, sizeof(addr6), 0, sizeof(addr6)) != EOK) { + return false; + } + int nRet = inet_pton(AF_INET6, strIp, &addr6); + if (nRet != 1) { + LOGE("Ip6StrConToChar strIp:%{public}s failed, inet_pton nRet:%{public}d!\n", strIp, nRet); + if (nRet == 0) { + LOGE("Ip6StrConToChar strIp:%{public}s not in presentation format!\n", strIp); + } else { + LOGE("Ip6StrConToChar strIp:%{public}s inet_pton does not contain a valid address family!\n", strIp); + } + return false; + } + + LOGI("Ip6StrConToChar strIp:%{public}s -> \n", strIp); + for (size_t i = 0; i < chlen; i++) { + LOGI("Ip6StrConToChar addr6.s6_addr: %{public}zu - %{public}02x\n", i, addr6.s6_addr[i]); + chIp[i] = addr6.s6_addr[i]; + } + + return true; +} + +const char *HwaddrNtoa(const unsigned char *hwaddr, size_t hwlen, char *buf, size_t buflen) +{ + const unsigned char *hp = NULL; + const unsigned char *ep = NULL; + char *p = NULL; + + if (buf == NULL || hwlen == 0) { + return NULL; + } + + if (hwlen * MAC_ADDR_CHAR_NUM > buflen) { + return NULL; + } + + hp = (const unsigned char *)hwaddr; + ep = hp + hwlen; + p = buf; + + while (hp < ep) { + if (hp != hwaddr) { + *p++ = ':'; + } + p += snprintf_s(p, MAC_ADDR_CHAR_NUM, MAC_ADDR_CHAR_NUM - 1, "%.2x", *hp++); + } + *p++ = '\0'; + return buf; +} + +int GetLocalInterface(const char *ifname, int *ifindex, unsigned char *hwaddr, uint32_t *ifaddr4) +{ + if ((ifname == NULL) || (strlen(ifname) <= 0)) { + LOGE("GetLocalInterface() failed, ifname == NULL or \"\"!\n"); + return DHCP_OPT_FAILED; + } + + int fd; + struct ifreq iface; + struct sockaddr_in *pSockIn = NULL; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + LOGE("GetLocalInterface() ifname:%{public}s failed, socket err:%{public}s!\n", ifname, strerror(errno)); + return DHCP_OPT_FAILED; + } + + if (memset_s(&iface, sizeof(iface), 0, sizeof(iface)) != EOK) { + LOGE("GetLocalInterface() ifname:%{public}s failed, memset_s error!\n", ifname); + return DHCP_OPT_FAILED; + } + if (strncpy_s(iface.ifr_name, sizeof(iface.ifr_name), ifname, strlen(ifname)) != EOK) { + LOGE("GetLocalInterface() ifname:%{public}s failed, strncpy_s error!\n", ifname); + return DHCP_OPT_FAILED; + } + + if (ioctl(fd, SIOCGIFINDEX, &iface) != 0) { + LOGE("GetLocalInterface() %{public}s failed, SIOCGIFINDEX err:%{public}s!\n", ifname, strerror(errno)); + close(fd); + return DHCP_OPT_FAILED; + } + *ifindex = iface.ifr_ifindex; + + if (ioctl(fd, SIOCGIFHWADDR, &iface) != 0) { + LOGE("GetLocalInterface() %{public}s failed, SIOCGIFHWADDR err:%{public}s!\n", ifname, strerror(errno)); + close(fd); + return DHCP_OPT_FAILED; + } + if (memcpy_s(hwaddr, MAC_ADDR_LEN, iface.ifr_hwaddr.sa_data, MAC_ADDR_LEN) != EOK) { + LOGE("GetLocalInterface() ifname:%{public}s failed, memcpy_s error!\n", ifname); + return DHCP_OPT_FAILED; + } + + if (ifaddr4 != NULL) { + if (ioctl(fd, SIOCGIFADDR, &iface) < 0) { + LOGE("GetLocalInterface() %{public}s failed, SIOCGIFADDR err:%{public}s!\n", ifname, strerror(errno)); + close(fd); + return DHCP_OPT_FAILED; + } + pSockIn = (struct sockaddr_in *)&iface.ifr_addr; + *ifaddr4 = pSockIn->sin_addr.s_addr; + } + + close(fd); + return DHCP_OPT_SUCCESS; +} + +int GetLocalIp(const char *ifname, uint32_t *ifaddr4) +{ + if ((ifname == NULL) || (strlen(ifname) <= 0)) { + LOGE("GetLocalIp() failed, ifname == NULL or \"\"!\n"); + return DHCP_OPT_FAILED; + } + + struct ifaddrs *ifaddr = NULL, *ifa = NULL; + int family, s; + char strIp[NI_MAXHOST]; + + if (getifaddrs(&ifaddr) == -1) { + LOGE("GetLocalIp() ifname:%{public}s failed, getifaddrs error:%{public}s!\n", ifname, strerror(errno)); + return DHCP_OPT_FAILED; + } + + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (strcmp(ifa->ifa_name, ifname) != 0) { + continue; + } + + if (ifa->ifa_addr == NULL) { + LOGE("GetLocalIp() ifname:%{public}s failed, ifa->ifa_addr == NULL!\n", ifname); + continue; + } + + family = ifa->ifa_addr->sa_family; + if ((family != AF_INET) && (family != AF_INET6)) { + continue; + } + + if (memset_s(strIp, sizeof(strIp), 0, sizeof(strIp)) != EOK) { + return DHCP_OPT_FAILED; + } + s = getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), + strIp, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); + if (s != 0) { + LOGE("GetLocalIp() %{public}s failed, getnameinfo error:%{public}s!\n", ifname, gai_strerror(s)); + return DHCP_OPT_FAILED; + } + + /* Output all ip with ifa_name is ifname and family is AF_INET or AF_INET6. */ + if (family == AF_INET) { + uint32_t hostIp = 0; + if (!Ip4StrConToInt(strIp, &hostIp, true)) { + LOGE("GetLocalIp() %{public}s failed, Ip4StrConToInt strIp:%{public}s error!\n", ifname, strIp); + return DHCP_OPT_FAILED; + } + LOGI("GetLocalIp() %{public}s, AF_INET str:%{public}s -> host:%{public}u.\n", ifname, strIp, hostIp); + *ifaddr4 = hostIp; + } else { + LOGI("GetLocalIp() %{public}s, AF_INET6 strIp:%{public}s.\n", ifname, strIp); + } + } + + freeifaddrs(ifaddr); + return DHCP_OPT_SUCCESS; +} + +int SetLocalInterface(const char *ifname, uint32_t ifaddr4) +{ + if ((ifname == NULL) || (strlen(ifname) <= 0)) { + LOGE("SetLocalInterface() failed, ifname == NULL or \"\"!\n"); + return DHCP_OPT_FAILED; + } + + char *cIp = Ip4IntConToStr(ifaddr4, true); + if (cIp == NULL) { + LOGE("SetLocalInterface() %{public}s failed, Ip4IntConToStr addr4:%{public}u failed!\n", ifname, ifaddr4); + return DHCP_OPT_FAILED; + } + LOGI("SetLocalInterface() %{public}s, ifaddr4:%{public}u -> %{public}s.\n", ifname, ifaddr4, cIp); + free(cIp); + + int fd; + struct ifreq ifr; + struct sockaddr_in sin; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + LOGE("SetLocalInterface() ifname:%{public}s failed, socket error:%{public}s!\n", ifname, strerror(errno)); + return DHCP_OPT_FAILED; + } + + if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) { + return DHCP_OPT_FAILED; + } + if (strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), ifname, strlen(ifname)) != EOK) { + return DHCP_OPT_FAILED; + } + + if (memset_s(&sin, sizeof(sin), 0, sizeof(sin)) != EOK) { + return DHCP_OPT_FAILED; + } + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(ifaddr4); + if (memcpy_s(&ifr.ifr_addr, sizeof(ifr.ifr_addr), &sin, sizeof(struct sockaddr)) != EOK) { + return DHCP_OPT_FAILED; + } + + /* Similar to the system command: ifconfig ifname ifaddr4. */ + if (ioctl(fd, SIOCSIFADDR, &ifr) < 0) { + LOGE("SetLocalInterface() %{public}s failed, SIOCSIFADDR err:%{public}s!\n", ifname, strerror(errno)); + close(fd); + return DHCP_OPT_FAILED; + } + + close(fd); + return DHCP_OPT_SUCCESS; +} + +int InitPidfile(const char *pidDir, const char *pidFile) +{ + if ((pidDir == NULL) || (strlen(pidDir) <= 0) || (pidFile == NULL) || (strlen(pidFile) <= 0)) { + LOGE("InitPidfile() failed, pidDir or pidFile == NULL or \"\"!\n"); + return DHCP_OPT_FAILED; + } + LOGI("InitPidfile() pidDir:%{public}s, pidFile:%{public}s.\n", pidDir, pidFile); + unlink(pidFile); + + int fd; + if ((fd = open(pidFile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) { + LOGE("InitPidfile() failed, open pidFile:%{public}s error:%{public}s!\n", pidFile, strerror(errno)); + return DHCP_OPT_FAILED; + } + + char buf[PID_MAX_LEN] = {0}; + if (snprintf_s(buf, PID_MAX_LEN, PID_MAX_LEN - 1, "%d", getpid()) < 0) { + LOGE("InitPidfile() pidFile:%{public}s failed, snprintf error:%{public}s!\n", pidFile, strerror(errno)); + close(fd); + return DHCP_OPT_FAILED; + } + ssize_t bytes; + if ((bytes = write(fd, buf, strlen(buf))) <= 0) { + LOGE("InitPidfile() failed, write pidFile:%{public}s error:%{public}s, bytes:%{public}zu!\n", + pidFile, strerror(errno), bytes); + close(fd); + return DHCP_OPT_FAILED; + } + LOGI("InitPidfile() buf:%{public}s write pidFile:%{public}s, bytes:%{public}zu!\n", buf, pidFile, bytes); + close(fd); + + if (chdir(pidDir) != 0) { + LOGE("InitPidfile() failed, chdir pidDir:%{public}s error:%{public}s!\n", pidDir, strerror(errno)); + return DHCP_OPT_FAILED; + } + + /* Set default permissions for the specified client process id files and directories. */ + umask(DEFAULT_UMASK); + + /* Change attribs to the specified client process id files: 644 (user=rw, group=r, other=r). */ + chmod(pidFile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + + return DHCP_OPT_SUCCESS; +} + +pid_t GetPID(const char *pidFile) +{ + /* Check pidFile is or not exists. */ + struct stat sb; + if (stat(pidFile, &sb) != 0) { + LOGW("GetPID() pidFile:%{public}s stat error:%{public}s!\n", pidFile, strerror(errno)); + return -1; + } + LOGI("GetPID() pidFile:%{public}s stat st_size:%{public}d.\n", pidFile, (int)sb.st_size); + + int fd; + if ((fd = open(pidFile, O_RDONLY)) < 0) { + LOGE("GetPID() failed, open pidFile:%{public}s error!\n", pidFile); + return -1; + } + + lseek(fd, 0, SEEK_SET); + + char buf[PID_MAX_LEN] = {0}; + ssize_t bytes; + if ((bytes = read(fd, buf, sb.st_size)) < 0) { + LOGE("GetPID() failed, read pidFile:%{public}s error, bytes:%{public}zu!\n", pidFile, bytes); + close(fd); + return -1; + } + LOGI("GetPID() read pidFile:%{public}s, buf:%{public}s, bytes:%{public}zu.\n", pidFile, buf, bytes); + close(fd); + + return atoi(buf); +} diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_ipv4.c b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_ipv4.c new file mode 100644 index 000000000..3470d2212 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_ipv4.c @@ -0,0 +1,1138 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "dhcp_ipv4.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "securec.h" +#include "dhcp_client.h" +#include "dhcp_options.h" +#include "dhcp_socket.h" +#include "dhcp_function.h" + +#undef LOG_TAG +#define LOG_TAG "WifiDhcpIpv4" + +/* static defined */ +static int g_dhcp4State = INIT_SELECTING; +static int sockFd = -1; +static int sentPacketNum = 0; +static int sigSockFds[NUMBER_TWO]; +static uint32_t timeoutTimestamp = 0; +static uint32_t renewalTimestamp = 0; +static uint32_t leaseTime = 0; +static uint32_t renewalSec = 0; +static uint32_t rebindSec = 0; +static uint32_t requestedIp4 = 0; +static uint32_t serverIp4 = 0; +static uint32_t socketMode = SOCKET_MODE_INVALID; +static uint32_t transID = 0; + + +/* Send signals. */ +static void SignalHandler(int signum) +{ + switch (signum) { + case SIGTERM: + /* Send signal SIGTERM. */ + case SIGUSR1: + /* Send signal SIGUSR1. */ + case SIGUSR2: + /* Send signal SIGUSR2. */ + send(sigSockFds[1], &signum, sizeof(signum), MSG_DONTWAIT); + break; + default: + break; + } +} + +/* Set the socket mode. */ +static void SetSocketMode(uint32_t mode) +{ + close(sockFd); + sockFd = -1; + socketMode = mode; + LOGI("SetSocketMode() the socket mode %{public}s.\n", (mode == SOCKET_MODE_RAW) ? "raw" + : ((mode == SOCKET_MODE_KERNEL) ? "kernel" : "not valid")); +} + +/* Execution dhcp release. */ +static void ExecDhcpRelease(void) +{ + /* Ensure that we've received dhcp ack packet completely. */ + if ((g_dhcp4State == BOUND) || (g_dhcp4State == RENEWING) || (g_dhcp4State == REBINDING)) { + /* Unicast dhcp release packet. */ + DhcpRelease(requestedIp4, serverIp4); + } + + g_dhcp4State = RELEASED; + SetSocketMode(SOCKET_MODE_INVALID); + + /* Ensure that the function select() is always blocked and don't need to receive ip from dhcp server. */ + timeoutTimestamp = SIGNED_INTEGER_MAX; + + LOGI("ExecDhcpRelease() enter released state...\n"); +} + +/* Execution dhcp renew. */ +static void ExecDhcpRenew(void) +{ + /* Set socket mode and dhcp ipv4 state, make sure dhcp packets can be sent normally. */ + switch (g_dhcp4State) { + case INIT_SELECTING: + LOGI("ExecDhcpRenew() dhcp ipv4 old state:INIT_SELECTING, no need change state.\n"); + break; + case REQUESTING: + case RENEW_REQUESTED: + case RELEASED: + LOGI("ExecDhcpRenew() dhcp ipv4 old state:%{public}d, init state:INIT_SELECTING.\n", g_dhcp4State); + /* Init socket mode and dhcp ipv4 state. */ + g_dhcp4State = INIT_SELECTING; + SetSocketMode(SOCKET_MODE_RAW); + break; + case BOUND: + /* Set socket mode, send unicast packet. */ + SetSocketMode(SOCKET_MODE_KERNEL); + case RENEWING: + case REBINDING: + LOGI("ExecDhcpRenew() dhcp ipv4 old state:%{public}d, set state:RENEW_REQUESTED.\n", g_dhcp4State); + /* Set dhcp ipv4 state, send request packet. */ + g_dhcp4State = RENEW_REQUESTED; + break; + default: + break; + } + + /* Start record again, go back to init state. */ + sentPacketNum = 0; + timeoutTimestamp = 0; + + LOGI("ExecDhcpRenew() a dhcp renew is executed...\n"); +} + +/* Add dhcp option paramater request list. */ +static void AddParamaterRequestList(struct DhcpPacket *packet) +{ + int end = GetEndOptionIndex(packet->options); + int i; + int len = 0; + uint8_t arrReqCode[DHCP_REQ_CODE_NUM] = { + DHO_SUBNETMASK, DHO_ROUTER, DHO_DNSSERVER, DHO_HOSTNAME, DHO_DNSDOMAIN, DHO_BROADCAST}; + + packet->options[end + DHCP_OPT_CODE_INDEX] = DHO_PARAMETERREQUESTLIST; + for (i = 0; i < DHCP_REQ_CODE_NUM; i++) { + if ((arrReqCode[i] > DHO_PAD) && (arrReqCode[i] < DHO_END)) { + packet->options[end + DHCP_OPT_DATA_INDEX + len++] = arrReqCode[i]; + } + } + packet->options[end + DHCP_OPT_LEN_INDEX] = len; + packet->options[end + DHCP_OPT_DATA_INDEX + len] = DHO_END; +} + +/* Init packet common info. */ +static void GetPacketCommonInfo(struct DhcpPacket *packet, uint8_t type) +{ + if (memset_s(packet, sizeof(struct DhcpPacket), 0, sizeof(struct DhcpPacket)) != EOK) { + return; + } + + switch (type) { + case DHCP_DISCOVER: + case DHCP_REQUEST: + case DHCP_RELEASE: + case DHCP_INFORM: + packet->op = BOOT_REQUEST; + break; + case DHCP_OFFER: + case DHCP_ACK: + case DHCP_NAK: + packet->op = BOOT_REPLY; + break; + default: + break; + } + packet->htype = ETHERNET_TYPE; + packet->hlen = ETHERNET_LEN; + packet->cookie = htonl(MAGIC_COOKIE); + packet->options[0] = DHO_END; + + AddSimpleOption(packet->options, DHO_MESSAGETYPE, type); +} + +/* Create a random xid. */ +static uint32_t GetTransId(void) +{ + static int initialized; + if (initialized == 0) { + int fd; + uint32_t seed; + + fd = open("/dev/urandom", 0); + if ((fd < 0) || read(fd, &seed, sizeof(seed)) < 0) { + LOGE("GetTransId() could not load seed from /dev/urandom, error:%{public}s!\n", strerror(errno)); + seed = time(0); + } + if (fd >= 0) { + close(fd); + } + srandom(seed); + initialized++; + } + return random(); +} + +/* Init the socket fd. */ +static void InitSocketFd(void) +{ + if ((sockFd < 0) && (socketMode != SOCKET_MODE_INVALID)) { + if (socketMode == SOCKET_MODE_RAW) { + sockFd = CreateRawSocket(gClientCfg.ifindex); + } else { + sockFd = CreateSocket(gClientCfg.interface, INADDR_ANY, BOOTP_CLIENT); + } + + if (sockFd < 0) { + /* Init failed: couldn't listen on socket. */ + LOGE("InitSocketFd() sockFd:%{public}d failed, couldn't listen on socket, error:%{public}s!\n", + sockFd, strerror(errno)); + unlink(gClientCfg.pid_file); + unlink(gClientCfg.result_file); + exit(EXIT_SUCCESS); + } + } +} + +static void InitSelecting(time_t timestamp) +{ + if (sentPacketNum >= SENDPACKET_MAXNUM * TIMEOUT_TIMES_MAX) { + /* Send packet timed out, now exit process. */ + LOGW("InitSelecting() send packet timed out %{public}d times, now exit process!\n", sentPacketNum); + timeoutTimestamp = timestamp + TIMEOUT_MORE_WAIT_SEC; + sentPacketNum = 0; + gClientCfg.timeoutExit = true; + return; + } + + uint32_t uTimeoutSec; + if (sentPacketNum < SENDPACKET_MAXNUM) { + if (sentPacketNum == 0) { + transID = GetTransId(); + } + uTimeoutSec = TIMEOUT_WAIT_SEC; + } else { + uTimeoutSec = + (sentPacketNum < SENDPACKET_MAXNUM * NUMBER_TWO) + ? TIMEOUT_ONE_WAIT_SEC + : ((sentPacketNum < SENDPACKET_MAXNUM * NUMBER_THREE) ? TIMEOUT_TWO_WAIT_SEC : TIMEOUT_THREE_WAIT_SEC); + } + + /* Broadcast dhcp discover packet. */ + DhcpDiscover(transID, requestedIp4); + + timeoutTimestamp = timestamp + uTimeoutSec; + LOGI("InitSelecting() DhcpDiscover sentPacketNum:%{public}d,timeoutSec:%{public}u,timestamp:%{public}u.\n", + sentPacketNum, + uTimeoutSec, + timeoutTimestamp); + + sentPacketNum++; +} + +static void Requesting(time_t timestamp) +{ + if (sentPacketNum >= SENDPACKET_MAXNUM * TIMEOUT_TIMES_MAX) { + /* Send packet timed out, now enter init state. */ + g_dhcp4State = INIT_SELECTING; + SetSocketMode(SOCKET_MODE_RAW); + sentPacketNum = 0; + timeoutTimestamp = timestamp; + return; + } + + if (g_dhcp4State == RENEW_REQUESTED) { + /* Unicast dhcp request packet in the renew state. */ + DhcpRenew(transID, requestedIp4, serverIp4); + } else { + /* Broadcast dhcp request packet in the requesting state. */ + DhcpRequest(transID, requestedIp4, serverIp4); + } + + uint32_t uTimeoutSec; + if (sentPacketNum < SENDPACKET_MAXNUM) { + uTimeoutSec = TIMEOUT_WAIT_SEC; + } else { + uTimeoutSec = + (sentPacketNum < SENDPACKET_MAXNUM * NUMBER_TWO) + ? TIMEOUT_ONE_WAIT_SEC + : ((sentPacketNum < SENDPACKET_MAXNUM * NUMBER_THREE) ? TIMEOUT_TWO_WAIT_SEC : TIMEOUT_THREE_WAIT_SEC); + } + timeoutTimestamp = timestamp + uTimeoutSec; + LOGI("Requesting() DhcpRequest sentPacketNum:%{public}d,timeoutSec:%{public}u,timeoutTimestamp:%{public}u.\n", + sentPacketNum, + uTimeoutSec, + timeoutTimestamp); + + sentPacketNum++; +} + +static void Renewing(time_t timestamp) +{ + if ((renewalSec + TIME_INTERVAL_MAX) < rebindSec) { + /* Cur time is between renewal and rebind time, unicast dhcp request packet in the renew state. */ + DhcpRenew(transID, requestedIp4, serverIp4); + + /* Set a new renewal time. */ + renewalSec += (rebindSec - renewalSec) / NUMBER_TWO; + timeoutTimestamp = renewalTimestamp + renewalSec; + LOGI("Renewing() DhcpRenew unicast renewalTime:%{public}u,renewal:%{public}u,timeoutTime:%{public}u, " + "rebind:%{public}u.\n", + renewalTimestamp, + renewalSec, + timeoutTimestamp, + rebindSec); + } else { + /* Cur time reaches rebind time, now enter rebinding state. */ + g_dhcp4State = REBINDING; + LOGI("Renewing() cur time reaches rebind time, now enter rebinding state...\n"); + timeoutTimestamp = timestamp + (rebindSec - renewalSec); + LOGI("Renewing() timestamp:%{public}d,rebind:%{public}u,renewal:%{public}u, timeoutTime:%{public}u.\n", + (int)timestamp, rebindSec, renewalSec, timeoutTimestamp); + } +} + +static void Rebinding(time_t timestamp) +{ + if ((rebindSec + TIME_INTERVAL_MAX) < leaseTime) { + /* Cur time is between rebind and lease time, broadcast dhcp request packet in the rebind state. */ + DhcpRenew(transID, requestedIp4, 0); + + /* Set a new rebind time. */ + rebindSec += (leaseTime - rebindSec) / NUMBER_TWO; + timeoutTimestamp = renewalTimestamp + rebindSec; + LOGI("Rebinding() DhcpRenew broadcast renewalTime:%{public}u,rebind:%{public}u,timeoutTime:%{public}u, " + "lease:%{public}u.\n", + renewalTimestamp, + rebindSec, + timeoutTimestamp, + leaseTime); + } else { + /* Cur time reaches lease time, send packet timed out, now enter init state. */ + LOGI("Rebinding() 555 cur time reaches lease time, now enter init state...\n"); + g_dhcp4State = INIT_SELECTING; + SetSocketMode(SOCKET_MODE_RAW); + sentPacketNum = 0; + timeoutTimestamp = timestamp; + return; + } +} + +static void DhcpRequestHandle(time_t timestamp) +{ + switch (g_dhcp4State) { + case INIT_SELECTING: + InitSelecting(timestamp); + break; + case RENEW_REQUESTED: + case REQUESTING: + Requesting(timestamp); + break; + case BOUND: + /* Now the renewal time run out, ready to enter renewing state. */ + LOGI("DhcpRequestHandle() 333 the renewal time run out, ready to enter renewing state...\n"); + g_dhcp4State = RENEWING; + SetSocketMode(SOCKET_MODE_KERNEL); + case RENEWING: + Renewing(timestamp); + break; + case REBINDING: + Rebinding(timestamp); + break; + case RELEASED: + /* Ensure that the function select() is always blocked and don't need to receive ip from dhcp server. */ + timeoutTimestamp = SIGNED_INTEGER_MAX; + break; + default: + break; + } +} + +static void DhcpOfferPacketHandle(uint8_t type, const struct DhcpPacket *packet, time_t timestamp) +{ + if (type != DHCP_OFFER) { + LOGE("DhcpOfferPacketHandle() type:%{public}d error!\n", type); + return; + } + + if (packet == NULL) { + LOGE("DhcpOfferPacketHandle() type:%{public}d error, packet == NULL!\n", type); + return; + } + + uint32_t u32Data = 0; + if (!GetDhcpOptionUint32(packet, DHO_SERVERID, &u32Data)) { + LOGE("DhcpOfferPacketHandle() type:%{public}d error, GetDhcpOptionUint32 DHO_SERVERID failed!\n", type); + return; + } + + transID = packet->xid; + requestedIp4 = packet->yiaddr; + serverIp4 = htonl(u32Data); + + char *pReqIp = Ip4IntConToStr(requestedIp4, false); + if (pReqIp != NULL) { + LOGI( + "DhcpOfferPacketHandle() receive DHCP_OFFER, xid:%{public}u, requestIp: host %{public}u->%{public}s.\n", + transID, + ntohl(requestedIp4), + pReqIp); + free(pReqIp); + } + char *pSerIp = Ip4IntConToStr(serverIp4, false); + if (pSerIp != NULL) { + LOGI("DhcpOfferPacketHandle() receive DHCP_OFFER, serverIp: host %{public}u->%{public}s.\n", + ntohl(serverIp4), + pSerIp); + free(pSerIp); + } + + /* Receive dhcp offer packet finished, next send dhcp request packet. */ + g_dhcp4State = REQUESTING; + sentPacketNum = 0; + timeoutTimestamp = timestamp; +} + +static void FormatString(struct DhcpResult *result) +{ + if (result == NULL) { + LOGE("FormatString() error, result == NULL!\n"); + return; + } + + if (strlen(result->strYiaddr) <= 0) { + if (strncpy_s(result->strYiaddr, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { + return; + } + } + if (strlen(result->strOptServerId) <= 0) { + if (strncpy_s(result->strOptServerId, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { + return; + } + } + if (strlen(result->strOptSubnet) <= 0) { + if (strncpy_s(result->strOptSubnet, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { + return; + } + } + if (strlen(result->strOptDns1) <= 0) { + if (strncpy_s(result->strOptDns1, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { + return; + } + } + if (strlen(result->strOptDns2) <= 0) { + if (strncpy_s(result->strOptDns2, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { + return; + } + } + if (strlen(result->strOptRouter1) <= 0) { + if (strncpy_s(result->strOptRouter1, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { + return; + } + } + if (strlen(result->strOptRouter2) <= 0) { + if (strncpy_s(result->strOptRouter2, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { + return; + } + } + if (strlen(result->strOptVendor) <= 0) { + if (strncpy_s(result->strOptVendor, DHCP_FILE_MAX_BYTES, "*", DHCP_FILE_MAX_BYTES - 1) != EOK) { + return; + } + } +} + +static void WriteDhcpResult(struct DhcpResult *result) +{ + if (result == NULL) { + LOGE("WriteDhcpResult() error, result == NULL!\n"); + return; + } + + /* Format dhcp result. */ + FormatString(result); + + uint32_t curTime = (uint32_t)time(NULL); + LOGI("WriteDhcpResult() " + "result->strYiaddr:%{public}s,strOptServerId:%{public}s,strOptSubnet:%{public}s,uOptLeasetime:%{public}u," + " curTime:%{public}u.\n", + result->strYiaddr, + result->strOptServerId, + result->strOptSubnet, + result->uOptLeasetime, + curTime); + FILE *pFile = fopen(gClientCfg.result_file, "w+"); + if (pFile == NULL) { + LOGE("WriteDhcpResult fopen %{public}s err:%{public}s!\n", gClientCfg.result_file, strerror(errno)); + return; + } + + /* Lock the writing file. */ + if (flock(fileno(pFile), LOCK_EX) != 0) { + LOGE("WriteDhcpResult() flock file:%{public}s LOCK_EX failed, error:%{public}s!\n", + gClientCfg.result_file, strerror(errno)); + fclose(pFile); + return; + } + + /* Format: IP4 timestamp cliIp servIp subnet dns1 dns2 router1 router2 vendor lease. */ + int nBytes = fprintf(pFile, "IP4 %u %s %s %s %s %s %s %s %s %u\n", curTime, + result->strYiaddr, result->strOptServerId, result->strOptSubnet, result->strOptDns1, result->strOptDns2, + result->strOptRouter1, result->strOptRouter2, result->strOptVendor, result->uOptLeasetime); + if (nBytes <= 0) { + LOGE("WriteDhcpResult() fprintf %{public}s error:%{public}s!\n", gClientCfg.result_file, strerror(errno)); + fclose(pFile); + return; + } + LOGI("WriteDhcpResult() fprintf %{public}s success, nBytes:%{public}d.\n", gClientCfg.result_file, nBytes); + + /* Unlock the writing file. */ + if (flock(fileno(pFile), LOCK_UN) != 0) { + LOGE("WriteDhcpResult() flock file:%{public}s LOCK_UN failed, error:%{public}s!\n", + gClientCfg.result_file, + strerror(errno)); + fclose(pFile); + return; + } + + if (fclose(pFile) != 0) { + LOGE("WriteDhcpResult() fclose %{public}s error:%{public}s!\n", gClientCfg.result_file, strerror(errno)); + return; + } +} + +static void ParseOtherNetworkInfo(const struct DhcpPacket *packet, struct DhcpResult *result) +{ + if ((packet == NULL) || (result == NULL)) { + LOGE("ParseOtherNetworkInfo() error, packet == NULL or result == NULL!\n"); + return; + } + + uint32_t u32Data = 0; + uint32_t u32Data2 = 0; + if (GetDhcpOptionUint32n(packet, DHO_DNSSERVER, &u32Data, &u32Data2)) { + char *pDnsIp = Ip4IntConToStr(u32Data, true); + if (pDnsIp != NULL) { + LOGI("ParseOtherNetworkInfo() recv DHCP_ACK 6, dns1: %{public}u->%{public}s.\n", u32Data, pDnsIp); + if (strncpy_s(result->strOptDns1, INET_ADDRSTRLEN, pDnsIp, INET_ADDRSTRLEN - 1) != EOK) { + free(pDnsIp); + return; + } + free(pDnsIp); + pDnsIp = NULL; + } + if ((u32Data2 > 0) && ((pDnsIp = Ip4IntConToStr(u32Data2, true)) != NULL)) { + LOGI("ParseOtherNetworkInfo() recv DHCP_ACK 6, dns2: %{public}u->%{public}s.\n", u32Data2, pDnsIp); + if (strncpy_s(result->strOptDns2, INET_ADDRSTRLEN, pDnsIp, INET_ADDRSTRLEN - 1) != EOK) { + free(pDnsIp); + return; + } + free(pDnsIp); + } + } +} + +static void ParseNetworkInfo(const struct DhcpPacket *packet, struct DhcpResult *result) +{ + if ((packet == NULL) || (result == NULL)) { + LOGE("ParseNetworkInfo() error, packet == NULL or result == NULL!\n"); + return; + } + + uint32_t u32Data = 0; + if (GetDhcpOptionUint32(packet, DHO_SUBNETMASK, &u32Data)) { + char *pSubIp = Ip4IntConToStr(u32Data, true); + if (pSubIp != NULL) { + LOGI("ParseNetworkInfo() recv DHCP_ACK 1, subnetmask: %{public}u->%{public}s.\n", u32Data, pSubIp); + if (strncpy_s(result->strOptSubnet, INET_ADDRSTRLEN, pSubIp, INET_ADDRSTRLEN - 1) != EOK) { + free(pSubIp); + return; + } + free(pSubIp); + } + } + + u32Data = 0; + uint32_t u32Data2 = 0; + if (GetDhcpOptionUint32n(packet, DHO_ROUTER, &u32Data, &u32Data2)) { + char *pRouterIp = Ip4IntConToStr(u32Data, true); + if (pRouterIp != NULL) { + LOGI("ParseNetworkInfo() recv DHCP_ACK 3, router1: %{public}u->%{public}s.\n", u32Data, pRouterIp); + if (strncpy_s(result->strOptRouter1, INET_ADDRSTRLEN, pRouterIp, INET_ADDRSTRLEN - 1) != EOK) { + free(pRouterIp); + return; + } + free(pRouterIp); + pRouterIp = NULL; + } + if ((u32Data2 > 0) && ((pRouterIp = Ip4IntConToStr(u32Data2, true)) != NULL)) { + LOGI("ParseNetworkInfo() recv DHCP_ACK 3, router2: %{public}u->%{public}s.\n", u32Data2, pRouterIp); + if (strncpy_s(result->strOptRouter2, INET_ADDRSTRLEN, pRouterIp, INET_ADDRSTRLEN - 1) != EOK) { + free(pRouterIp); + return; + } + free(pRouterIp); + } + } + + ParseOtherNetworkInfo(packet, result); +} + +static void SyncDhcpResult(const struct DhcpPacket *packet, struct DhcpResult *result) +{ + if ((packet == NULL) || (result == NULL)) { + LOGE("SyncDhcpResult() error, packet == NULL or result == NULL!\n"); + return; + } + + char *pVendor = GetDhcpOptionString(packet, DHO_VENDOR); + if (pVendor == NULL) { + LOGW("SyncDhcpResult() recv DHCP_ACK 43, pVendor is NULL!\n"); + } else { + LOGI("SyncDhcpResult() recv DHCP_ACK 43, pVendor is %{public}s.\n", pVendor); + if (strncpy_s(result->strOptVendor, DHCP_FILE_MAX_BYTES, pVendor, DHCP_FILE_MAX_BYTES - 1) != EOK) { + free(pVendor); + return; + } + free(pVendor); + } + + /* Set the specified client process interface network info. */ + if (SetLocalInterface(gClientCfg.interface, ntohl(requestedIp4)) != DHCP_OPT_SUCCESS) { + LOGE("SyncDhcpResult() error, SetLocalInterface yiaddr:%{public}s failed!\n", result->strYiaddr); + return; + } + + /* Wirte to the file. */ + WriteDhcpResult(result); +} + +static void ParseDhcpAckPacket(const struct DhcpPacket *packet, time_t timestamp) +{ + if (packet == NULL) { + return; + } + + struct DhcpResult dhcpResult; + if (memset_s(&dhcpResult, sizeof(struct DhcpResult), 0, sizeof(struct DhcpResult)) != EOK) { + return; + } + + /* Set default leasetime. */ + leaseTime = LEASETIME_DEFAULT * ONE_HOURS_SEC; + requestedIp4 = packet->yiaddr; + uint32_t u32Data = 0; + if (GetDhcpOptionUint32(packet, DHO_LEASETIME, &u32Data)) { + leaseTime = u32Data; + LOGI("ParseDhcpAckPacket() recv DHCP_ACK 51, lease:%{public}u.\n", leaseTime); + } + renewalSec = leaseTime * T1; /* First renewal seconds. */ + rebindSec = leaseTime * T2; /* Second rebind seconds. */ + renewalTimestamp = timestamp; /* Record begin renewing or rebinding timestamp. */ + dhcpResult.uOptLeasetime = leaseTime; + + u32Data = 0; + if (!GetDhcpOptionUint32(packet, DHO_SERVERID, &u32Data)) { + LOGW("ParseDhcpAckPacket() GetDhcpOptionUint32 DHO_SERVERID failed!\n"); + } else { + serverIp4 = htonl(u32Data); + } + + LOGI("recv DHCP_ACK 51, lease:%{public}u,new:%{public}u,bind:%{public}u.\n", leaseTime, renewalSec, rebindSec); + char *pReqIp = Ip4IntConToStr(requestedIp4, false); + if (pReqIp != NULL) { + LOGI("ParseDhcpAckPacket() recv DHCP_ACK yiaddr: %{public}u->%{public}s.\n", ntohl(requestedIp4), pReqIp); + if (strncpy_s(dhcpResult.strYiaddr, INET_ADDRSTRLEN, pReqIp, INET_ADDRSTRLEN - 1) != EOK) { + free(pReqIp); + return; + } + free(pReqIp); + } + char *pSerIp = Ip4IntConToStr(serverIp4, false); + if (pSerIp != NULL) { + LOGI("ParseDhcpAckPacket() recv DHCP_ACK 54, serid: %{public}u->%{public}s.\n", ntohl(serverIp4), pSerIp); + if (strncpy_s(dhcpResult.strOptServerId, INET_ADDRSTRLEN, pSerIp, INET_ADDRSTRLEN - 1) != EOK) { + free(pSerIp); + return; + } + free(pSerIp); + } + + /* Parse the specified client process interface network info. */ + ParseNetworkInfo(packet, &dhcpResult); + + /* Sync the specified client process interface network info to the file. */ + SyncDhcpResult(packet, &dhcpResult); + + /* Receive dhcp ack packet finished, leaseTime * T1 later enter renewing state. */ + g_dhcp4State = BOUND; + SetSocketMode(SOCKET_MODE_INVALID); + timeoutTimestamp = timestamp + renewalSec; +} + +static void DhcpAckOrNakPacketHandle(uint8_t type, struct DhcpPacket *packet, time_t timestamp) +{ + if ((type != DHCP_ACK) && (type != DHCP_NAK)) { + LOGE("DhcpAckOrNakPacketHandle() type:%{public}d error!\n", type); + return; + } + + if (packet == NULL) { + LOGE("DhcpAckOrNakPacketHandle() type:%{public}d error, packet == NULL!\n", type); + return; + } + + if (type == DHCP_NAK) { + /* If receive dhcp nak packet, init g_dhcp4State, resend dhcp discover packet. */ + LOGI("DhcpAckOrNakPacketHandle() receive DHCP_NAK 53, init g_dhcp4State, resend dhcp discover packet!\n"); + g_dhcp4State = INIT_SELECTING; + SetSocketMode(SOCKET_MODE_RAW); + requestedIp4 = 0; + sentPacketNum = 0; + timeoutTimestamp = timestamp; + + /* Avoid excessive network traffic. */ + LOGI("DhcpAckOrNakPacketHandle() receive DHCP_NAK 53, avoid excessive network traffic, need sleep!\n"); + sleep(NUMBER_THREE); + return; + } + + LOGI("DhcpAckOrNakPacketHandle() recv DHCP_ACK 53.\n"); + + /* Parse received dhcp ack packet. */ + ParseDhcpAckPacket(packet, timestamp); +} + +static void DhcpResponseHandle(time_t timestamp) +{ + struct DhcpPacket packet; + int getLen; + uint8_t u8Message = 0; + + if (socketMode == SOCKET_MODE_RAW) { + getLen = GetDhcpRawPacket(&packet, sockFd); + } else { + getLen = GetDhcpPacket(&packet, sockFd); + } + + if (getLen < 0) { + if ((getLen == SOCKET_OPT_ERROR) && (errno != EINTR)) { + LOGE("DhcpResponseHandle() get packet read error, reopening socket!\n"); + /* Reopen sockFd. */ + SetSocketMode(socketMode); + } + LOGE("DhcpResponseHandle() get packet failed, error:%{public}s!\n", strerror(errno)); + return; + } + LOGI("DhcpResponseHandle() get packet success, getLen:%{public}d.\n", getLen); + + /* Check packet data. */ + if (packet.xid != transID) { + LOGW("DhcpResponseHandle() get xid:%{public}u and transID:%{public}u not same!\n", packet.xid, transID); + return; + } + if (!GetDhcpOptionUint8(&packet, DHO_MESSAGETYPE, &u8Message)) { + LOGE("DhcpResponseHandle() GetDhcpOptionUint8 DHO_MESSAGETYPE failed!\n"); + return; + } + + switch (g_dhcp4State) { + case INIT_SELECTING: + DhcpOfferPacketHandle(u8Message, &packet, timestamp); + break; + case RENEW_REQUESTED: + case REQUESTING: + case RENEWING: + case REBINDING: + DhcpAckOrNakPacketHandle(u8Message, &packet, timestamp); + break; + case BOUND: + case RELEASED: + LOGW("DhcpResponseHandle() g_dhcp4State is BOUND or RELEASED, ignore all packets!\n"); + break; + default: + break; + } +} + +/* Receive signals. */ +static void SignalReceiver(void) +{ + int signum; + if (read(sigSockFds[0], &signum, sizeof(signum)) < 0) { + LOGE("SignalReceiver() failed, sigSockFds[0]:%{public}d read error:%{public}s!\n", + sigSockFds[0], strerror(errno)); + return; + } + + switch (signum) { + case SIGTERM: + LOGW("SignalReceiver() SIGTERM!\n"); + SetSocketMode(SOCKET_MODE_INVALID); + unlink(gClientCfg.pid_file); + unlink(gClientCfg.result_file); + exit(EXIT_SUCCESS); + break; + case SIGUSR1: + LOGW("SignalReceiver() SIGUSR1!\n"); + ExecDhcpRelease(); + break; + case SIGUSR2: + LOGW("SignalReceiver() SIGUSR2!\n"); + ExecDhcpRenew(); + break; + default: + break; + } +} + + +/* Init signal handle function. */ +int InitSignalHandle(void) +{ + /* Create signal socket fd. */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sigSockFds) != 0) { + LOGE("InitSignalHandle() failed, socketpair error str:%{public}s!\n", strerror(errno)); + return DHCP_OPT_FAILED; + } + + /* Register signal handlers. */ + if (signal(SIGTERM, SignalHandler) == SIG_ERR) { + LOGE("InitSignalHandle() failed, signal SIGTERM error str:%{public}s!\n", strerror(errno)); + return DHCP_OPT_FAILED; + } + + if (signal(SIGUSR1, SignalHandler) == SIG_ERR) { + LOGE("InitSignalHandle() failed, signal SIGUSR1 error str:%{public}s!\n", strerror(errno)); + return DHCP_OPT_FAILED; + } + + if (signal(SIGUSR2, SignalHandler) == SIG_ERR) { + LOGE("InitSignalHandle() failed, signal SIGUSR2 error str:%{public}s!\n", strerror(errno)); + return DHCP_OPT_FAILED; + } + + return DHCP_OPT_SUCCESS; +} + +/* Broadcast dhcp discover packet, discover dhcp servers that can provide ip address. */ +int DhcpDiscover(uint32_t transid, uint32_t requestip) +{ + LOGI("DhcpDiscover() enter, transid:%{public}u,requestip:%{public}u.\n", transid, requestip); + struct DhcpPacket packet; + + /* Init packet common info. */ + GetPacketCommonInfo(&packet, DHCP_DISCOVER); + + /* Add packet client_cfg info. */ + if (memcpy_s(packet.chaddr, sizeof(packet.chaddr), gClientCfg.hwaddr, MAC_ADDR_LEN) != EOK) { + return -1; + } + int nClientIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + gClientCfg.clientid[DHCP_OPT_LEN_INDEX]; + AddOptionString(packet.options, gClientCfg.clientid, nClientIdLen); + + /* Add packet vendor info, vendor format: pro-version. */ + char buf[VENDOR_MAX_LEN - DHCP_OPT_CODE_BYTES - DHCP_OPT_LEN_BYTES] = {0}; + unsigned char vendorId[VENDOR_MAX_LEN] = {0}; + unsigned char *pVendorId = vendorId; + int nRes = snprintf_s(buf, + VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, + VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX - 1, + "%s-%s", + DHCPC_NAME, + DHCPC_VERSION); + if (nRes < 0) { + return -1; + } + pVendorId[DHCP_OPT_CODE_INDEX] = DHO_VENDOR; + pVendorId[DHCP_OPT_LEN_INDEX] = strlen(buf); + if (strncpy_s((char *)pVendorId + DHCP_OPT_DATA_INDEX, VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, buf, strlen(buf)) != + EOK) { + return -1; + } + if (strlen((char *)vendorId) > 0) { + int nVendorIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + pVendorId[DHCP_OPT_LEN_INDEX]; + AddOptionString(packet.options, vendorId, nVendorIdLen); + } + + /* Init packet non-default info. */ + packet.xid = transid; + if (requestip > 0) { + AddSimpleOption(packet.options, DHO_IPADDRESS, requestip); + } + + AddParamaterRequestList(&packet); + + /* Begin broadcast dhcp discover packet. */ + LOGI("DhcpDiscover() discover, begin broadcast discover packet...\n"); + return SendToDhcpPacket(&packet, INADDR_ANY, INADDR_BROADCAST, (uint8_t *)MAC_BCAST_ADDR, gClientCfg.ifindex); +} + +/* Broadcast dhcp request packet, tell dhcp servers that which ip address to choose. */ +int DhcpRequest(uint32_t transid, uint32_t reqip, uint32_t servip) +{ + /* Init packet common info. */ + struct DhcpPacket packet; + GetPacketCommonInfo(&packet, DHCP_REQUEST); + + /* Add packet client_cfg info. */ + if (memcpy_s(packet.chaddr, sizeof(packet.chaddr), gClientCfg.hwaddr, MAC_ADDR_LEN) != EOK) { + return -1; + } + int nClientIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + gClientCfg.clientid[DHCP_OPT_LEN_INDEX]; + AddOptionString(packet.options, gClientCfg.clientid, nClientIdLen); + + /* Add packet vendor info, vendor format: pro-version. */ + char buf[VENDOR_MAX_LEN - DHCP_OPT_CODE_BYTES - DHCP_OPT_LEN_BYTES] = {0}; + unsigned char vendorId[VENDOR_MAX_LEN] = {0}; + unsigned char *pVendorId = vendorId; + + int nRes = snprintf_s(buf, + VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, + VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX - 1, + "%s-%s", + DHCPC_NAME, + DHCPC_VERSION); + if (nRes < 0) { + return -1; + } + pVendorId[DHCP_OPT_CODE_INDEX] = DHO_VENDOR; + pVendorId[DHCP_OPT_LEN_INDEX] = strlen(buf); + if (strncpy_s((char *)pVendorId + DHCP_OPT_DATA_INDEX, VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, buf, strlen(buf)) != + EOK) { + return -1; + } + if (strlen((char *)vendorId) > 0) { + int nVendorIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + pVendorId[DHCP_OPT_LEN_INDEX]; + AddOptionString(packet.options, vendorId, nVendorIdLen); + } + + /* Init packet non-default info. */ + packet.xid = transid; + AddSimpleOption(packet.options, DHO_IPADDRESS, reqip); + AddSimpleOption(packet.options, DHO_SERVERID, servip); + + AddParamaterRequestList(&packet); + + /* Begin broadcast dhcp request packet. */ + char *pReqIp = Ip4IntConToStr(reqip, false); + if (pReqIp != NULL) { + LOGI("DhcpRequest() broadcast req packet, reqip: host %{public}u->%{public}s.\n", ntohl(reqip), pReqIp); + free(pReqIp); + } + char *pSerIp = Ip4IntConToStr(servip, false); + if (pSerIp != NULL) { + LOGI("DhcpRequest() broadcast reqt packet, servIp: host %{public}u->%{public}s.\n", ntohl(servip), pSerIp); + free(pSerIp); + } + + return SendToDhcpPacket(&packet, INADDR_ANY, INADDR_BROADCAST, (uint8_t *)MAC_BCAST_ADDR, gClientCfg.ifindex); +} + +/* Unicast or broadcast dhcp request packet, request to extend the lease from the dhcp server. */ +int DhcpRenew(uint32_t transid, uint32_t clientip, uint32_t serverip) +{ + struct DhcpPacket packet; + struct in_addr serverAddr; + + /* Init packet common info. */ + GetPacketCommonInfo(&packet, DHCP_REQUEST); + + /* Add packet client_cfg info. */ + if (memcpy_s(packet.chaddr, sizeof(packet.chaddr), gClientCfg.hwaddr, MAC_ADDR_LEN) != EOK) { + return -1; + } + int nClientIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + gClientCfg.clientid[DHCP_OPT_LEN_INDEX]; + AddOptionString(packet.options, gClientCfg.clientid, nClientIdLen); + + /* Add packet vendor info, vendor format: pro-version. */ + char buf[VENDOR_MAX_LEN - DHCP_OPT_CODE_BYTES - DHCP_OPT_LEN_BYTES] = {0}; + unsigned char vendorId[VENDOR_MAX_LEN] = {0}; + unsigned char *pVendorId = vendorId; + + int nRes = snprintf_s(buf, + VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, + VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX - 1, + "%s-%s", + DHCPC_NAME, + DHCPC_VERSION); + if (nRes < 0) { + return -1; + } + pVendorId[DHCP_OPT_CODE_INDEX] = DHO_VENDOR; + pVendorId[DHCP_OPT_LEN_INDEX] = strlen(buf); + if (strncpy_s((char *)pVendorId + DHCP_OPT_DATA_INDEX, VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, buf, strlen(buf)) != + EOK) { + return -1; + } + if (strlen((char *)vendorId) > 0) { + int nVendorIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + pVendorId[DHCP_OPT_LEN_INDEX]; + AddOptionString(packet.options, vendorId, nVendorIdLen); + } + + /* Init packet non-default info. */ + packet.xid = transid; + packet.ciaddr = clientip; + + AddParamaterRequestList(&packet); + + serverAddr.s_addr = serverip; + if (serverip == 0) { + /* Begin broadcast dhcp request packet. */ + LOGI("DhcpRenew() rebind, begin broadcast req packet, serverip:%{public}s...\n", inet_ntoa(serverAddr)); + return SendToDhcpPacket(&packet, INADDR_ANY, INADDR_BROADCAST, (uint8_t *)MAC_BCAST_ADDR, gClientCfg.ifindex); + } + + /* Begin unicast dhcp request packet. */ + LOGI("DhcpRenew() renew, begin unicast request packet, serverip:%{public}s...\n", inet_ntoa(serverAddr)); + return SendDhcpPacket(&packet, clientip, serverip); +} + +/* Unicast dhcp release packet, releasing an ip address in Use from the dhcp server. */ +int DhcpRelease(uint32_t clientip, uint32_t serverip) +{ + struct DhcpPacket packet; + struct in_addr requestAddr, serverAddr; + + /* Init packet common info. */ + GetPacketCommonInfo(&packet, DHCP_RELEASE); + + /* Add packet client_cfg info. */ + if (memcpy_s(packet.chaddr, sizeof(packet.chaddr), gClientCfg.hwaddr, MAC_ADDR_LEN) != EOK) { + return -1; + } + int nClientIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + gClientCfg.clientid[DHCP_OPT_LEN_INDEX]; + AddOptionString(packet.options, gClientCfg.clientid, nClientIdLen); + + /* Add packet vendor info, vendor format: pro-version. */ + char buf[VENDOR_MAX_LEN - DHCP_OPT_CODE_BYTES - DHCP_OPT_LEN_BYTES] = {0}; + unsigned char vendorId[VENDOR_MAX_LEN] = {0}; + unsigned char *pVendorId = vendorId; + + int nRes = snprintf_s(buf, + VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, + VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX - 1, + "%s-%s", + DHCPC_NAME, + DHCPC_VERSION); + if (nRes < 0) { + return -1; + } + pVendorId[DHCP_OPT_CODE_INDEX] = DHO_VENDOR; + pVendorId[DHCP_OPT_LEN_INDEX] = strlen(buf); + if (strncpy_s((char *)pVendorId + DHCP_OPT_DATA_INDEX, VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, buf, strlen(buf)) != + EOK) { + return -1; + } + if (strlen((char *)vendorId) > 0) { + int nVendorIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + pVendorId[DHCP_OPT_LEN_INDEX]; + AddOptionString(packet.options, vendorId, nVendorIdLen); + } + + /* Init packet non-default info. */ + packet.xid = GetTransId(); + AddSimpleOption(packet.options, DHO_IPADDRESS, clientip); + AddSimpleOption(packet.options, DHO_SERVERID, serverip); + + requestAddr.s_addr = clientip; + serverAddr.s_addr = serverip; + + /* Begin unicast dhcp release packet. */ + LOGI("DhcpRelease() release, begin unicast release packet, clientip:%{public}s,", inet_ntoa(requestAddr)); + LOGI("serverip:%{public}s...\n", inet_ntoa(serverAddr)); + return SendDhcpPacket(&packet, clientip, serverip); +} + +int StartIpv4(void) +{ + int nRet, nMaxFds; + fd_set exceptfds; + struct timeval timeout; + time_t curTimestamp; + + /* Init dhcp ipv4 state. */ + g_dhcp4State = INIT_SELECTING; + SetSocketMode(SOCKET_MODE_RAW); + + for (; ;) { + LOGI("StartIpv4() for enter...\n"); + + if (gClientCfg.timeoutExit) { + LOGW("StartIpv4() send packet timed out, now break!\n"); + break; + } + + FD_ZERO(&exceptfds); + timeout.tv_sec = timeoutTimestamp - time(NULL); + timeout.tv_usec = 0; + + InitSocketFd(); + + if (sockFd >= 0) { + FD_SET(sockFd, &exceptfds); + } + FD_SET(sigSockFds[0], &exceptfds); + + if (timeout.tv_sec <= 0) { + LOGI("StartIpv4() already timed out, need send or resend packet...\n"); + nRet = 0; + } else { + LOGI("StartIpv4() waiting on select...\n"); + nMaxFds = (sigSockFds[0] > sockFd) ? sigSockFds[0] : sockFd; + nRet = select(nMaxFds + 1, &exceptfds, NULL, NULL, &timeout); + } + if (nRet < 0) { + if ((nRet == -1) && (errno == EINTR)) { + LOGW("StartIpv4() select err:%{public}s, a signal was caught!\n", strerror(errno)); + } else { + LOGE("StartIpv4() failed, select maxFds:%{public}d error:%{public}s!\n", nMaxFds, strerror(errno)); + } + continue; + } + + curTimestamp = time(NULL); + if (nRet == 0) { + DhcpRequestHandle(curTimestamp); + } else if ((socketMode != SOCKET_MODE_INVALID) && FD_ISSET(sockFd, &exceptfds)) { + DhcpResponseHandle(curTimestamp); + } else if (FD_ISSET(sigSockFds[0], &exceptfds)) { + SignalReceiver(); + } else { + LOGW("StartIpv4() nRet:%{public}d, socketMode:%{public}d, continue select...\n", nRet, socketMode); + } + } + return gClientCfg.timeoutExit ? StopProcess(gClientCfg.pid_file) : DHCP_OPT_SUCCESS; +} \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_main.c b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_main.c new file mode 100644 index 000000000..ab4df293e --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_main.c @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "securec.h" +#include "dhcp_client.h" +#include "dhcp_function.h" + +#undef LOG_TAG +#define LOG_TAG "WifiDhcpMain" + +/* Static declared. */ +static int Usage(void); +static int RunChildProcess(void); +static int CreateDaemon(void); +static int CheckClientProParam(int argc, char *argv[]); +static int GetClientOption(int argc, char *argv[]); +static int InitSpecifiedClientCfg(int argc, char *argv[]); +static int ExecClientProAction(const char *action); +static int GetClientNetworkInfo(void); + +/* Static defined. */ +static int Usage(void) +{ + printf("\nUsage: dhcp_client_service ACTION INTERFACE [OPTION]\n"); + printf(" ACTION = start|stop|status|help|ver\n"); + printf(" start - start INTERFACE's network interface service\n"); + printf(" stop - stop INTERFACE's network interface service\n"); + printf(" status - show INTERFACE's service status and exit\n"); + printf(" help - displays usage info, INTERFACE is optional\n"); + printf(" ver - displays client version, INTERFACE is optional\n"); + printf(" INTERFACE = ifname, eg: wlan0\n"); + printf(" OPTION = -w |-a or -4 or -6\n"); + printf(" -w - specify the client's working directory\n"); + printf(" -a - handle dhcp v4 and v6\n"); + printf(" -4 - only handle dhcp v4\n"); + printf(" -6 - only handle dhcp v6\n"); + printf("\n========== running process operate ==========\n"); + printf(" send dhcp release packet = kill -USR1 \n"); + printf(" send dhcp renew packet = kill -USR2 \n\n"); + return DHCP_OPT_SUCCESS; +} + +static int RunChildProcess(void) +{ + if (setpgrp() == -1) { + LOGE("RunChildProcess() can not change process group, return!\n"); + return DHCP_OPT_FAILED; + } + + signal(SIGHUP, SIG_IGN); + + /* Ensure we can never get a controlling terminal. */ + pid_t childPid; + switch (childPid = fork()) { + case -1: + LOGE("RunChildProcess() fork grandchild failed, return!\n"); + return DHCP_OPT_FAILED; + case 0: + /* Grandchild process continue run. */ + break; + default: + /* Child process exit now. */ + exit(EXIT_SUCCESS); + } + LOGI("RunChildProcess() child: fork grand suc, childPid:%{public}d,pid():%{public}d,ppid():%{public}d.\n", + childPid, getpid(), getppid()); + return DHCP_OPT_SUCCESS; +} + +static int CreateDaemon(void) +{ + LOGI("CreateDaemon() enter, pid:%{public}d, ppid:%{public}d.\n", getpid(), getppid()); + + /* A daemon process need close all open files. */ + fclose(stdin); + fclose(stdout); + fclose(stderr); + + /* Ensure that the process is not a fork subprocess, init process id is 1. */ + if (getppid() == 1) { + LOGI("CreateDaemon() getppid() == 1, the process's parent is already init process!\n"); + /* Set default permissions for files and directories. */ + umask(DEFAULT_UMASK); + return DHCP_OPT_SUCCESS; + } + + pid_t pid; + switch (pid = fork()) { + case -1: + LOGE("CreateDaemon() fork first child failed, return!\n"); + return DHCP_OPT_FAILED; + case 0: + if (RunChildProcess() != DHCP_OPT_SUCCESS) { + LOGE("CreateDaemon() RunChildProcess failed, return!\n"); + return DHCP_OPT_FAILED; + }; + /* Child process continue run. */ + break; + default: + /* Parent process exit now. */ + exit(EXIT_SUCCESS); + } + + /* We have forked, setpgrp, forked once more, from now on, we are a daemon process. */ + LOGI("CreateDaemon() grandchild continue run, pid:%{public}d,getpid():%{public}d,getppid():%{public}d.\n", + pid, getpid(), getppid()); + umask(DEFAULT_UMASK); + return DHCP_OPT_SUCCESS; +} + +static int CheckClientProParam(int argc, char *argv[]) +{ + if (argc <= NUMBER_ONE) { + printf("CheckClientProParam() argc:%d error, please input valid ACTION!\n", argc); + Usage(); + return -1; + } + + /* Check client process param ACTION "help","ver". */ + const char *cmdParam = argv[NUMBER_ONE]; + if (strncasecmp(cmdParam, "help", NUMBER_FOUR) == 0) { + Usage(); + return 1; + } else if (strncasecmp(cmdParam, "ver", NUMBER_THREE) == 0) { + printf("%s, version %s\n", DHCPC_NAME, DHCPC_VERSION); + return 1; + } else { + /* Check client process param ACTION "start","stop","status". */ + if ((strncasecmp(cmdParam, "start", NUMBER_FIVE) != 0) && (strncasecmp(cmdParam, "stop", NUMBER_FOUR) != 0) + && (strncasecmp(cmdParam, "status", NUMBER_FIVE) != 0)) { + printf("CheckClientProParam() argv[1]:%s error, please input valid ACTION!\n", cmdParam); + Usage(); + return -1; + } + /* Check client process running argc. */ + if (argc <= NUMBER_TWO) { + printf("CheckClientProParam() argc:%d error, please input valid INTERFACE!\n", argc); + Usage(); + return -1; + } + } + return 0; +} + +static int GetClientOption(int argc, char *argv[]) +{ + int ch; + while ((ch = getopt(argc - NUMBER_TWO, argv + NUMBER_TWO, "w:a46")) != -1) { + switch (ch) { + case 'w': /* Specify the client's working directory. */ + LOGI("GetClientOption() cur workdir:%{public}s, optarg:%{public}s\n", gClientCfg.workdir, optarg); + if (strncpy_s(gClientCfg.workdir, sizeof(gClientCfg.workdir), optarg, DIR_MAX_LEN - 1) != EOK) { + return -1; + } + break; + case 'a': /* Handle dhcp v4 and v6. */ + gClientCfg.iptype = DHCP_IP_TYPE_ALL; + break; + case '4': /* Only handle dhcp v4. */ + LOGI("GetClientOption() cur iptype:%{public}u, optarg:%{public}s\n", gClientCfg.iptype, optarg); + gClientCfg.iptype = DHCP_IP_TYPE_V4; + break; + case '6': /* Only handle dhcp v6. */ + gClientCfg.iptype = DHCP_IP_TYPE_V6; + break; + default: + printf("GetClientOption() please input valid OPTION!\n"); + Usage(); + return -1; + } + } + return 0; +} + +static int InitSpecifiedClientCfg(int argc, char *argv[]) +{ + if ((strncpy_s(gClientCfg.workdir, sizeof(gClientCfg.workdir), WORKDIR, DIR_MAX_LEN - 1) != EOK) || + (strncpy_s(gClientCfg.interface, sizeof(gClientCfg.interface), argv[NUMBER_TWO], INFNAME_SIZE - 1) != EOK)) { + return -1; + } + gClientCfg.iptype = DHCP_IP_TYPE_ALL; + if ((argc > NUMBER_THREE) && (GetClientOption(argc, argv) != 0)) { + return -1; + } + + if (strlen(gClientCfg.workdir) > 0) { + int n = snprintf_s(gClientCfg.conf_file, + DIR_MAX_LEN, DIR_MAX_LEN - 1, "%s%s", gClientCfg.workdir, DHCPC_CONF); + if (n < 0) { + return -1; + } + n = snprintf_s(gClientCfg.pid_file, + DIR_MAX_LEN, DIR_MAX_LEN - 1, "%s%s.pid", gClientCfg.workdir, gClientCfg.interface); + if (n < 0) { + return -1; + } + n = snprintf_s(gClientCfg.result_file, + DIR_MAX_LEN, DIR_MAX_LEN - 1, "%s%s.result", gClientCfg.workdir, gClientCfg.interface); + if (n < 0) { + return -1; + } + } + LOGI("InitSpecifiedClientCfg() " + "gClientCfg.workdir:%{public}s,conf_file:%{public}s,pid_file:%{public}s,result_file:%{public}s, " + "iptype:%{public}d\n", + gClientCfg.workdir, + gClientCfg.conf_file, + gClientCfg.pid_file, + gClientCfg.result_file, + gClientCfg.iptype); + return 0; +} + +static int ExecClientProAction(const char *action) +{ + /* Stop the specified network interface service. */ + if (strncasecmp(action, "stop", NUMBER_FOUR) == 0) { + if (StopProcess(gClientCfg.pid_file) != DHCP_OPT_SUCCESS) { + LOGI("ExecClientProAction() StopProcess pid_file:%{public}s not success.\n", gClientCfg.pid_file); + } else { + LOGI("ExecClientProAction() StopProcess pid_file:%{public}s success.\n", gClientCfg.pid_file); + } + return 1; + } + + /* Get the specified client process running status. */ + int proStatus = GetProStatus(gClientCfg.pid_file); + if (strncasecmp(action, "status", NUMBER_FIVE) == 0) { + LOGI("ExecClientProAction() action:%{public}s GetProStatus proStatus:%{public}d.\n", action, proStatus); + return 1; + } + + /* Check the specified client process param ACTION. */ + if (strncasecmp(action, "start", NUMBER_FIVE) != 0) { + LOGE("ExecClientProAction() argv[1]:%{public}s error, please input valid ACTION!\n", action); + Usage(); + return -1; + } + if (proStatus == 1) { + LOGI("ExecClientProAction() the specified client process is already started!\n"); + return 1; + } + + /* Create a daemon process. */ + if (CreateDaemon() != DHCP_OPT_SUCCESS) { + LOGE("ExecClientProAction() CreateDaemon failed!\n"); + return -1; + } + + /* Init the specified client process id info. */ + if (InitPidfile(gClientCfg.workdir, gClientCfg.pid_file) != DHCP_OPT_SUCCESS) { + LOGE("ExecClientProAction() InitPidfile failed, interface:%{public}s.\n", gClientCfg.interface); + return -1; + } + + return 0; +} + +static int GetClientNetworkInfo(void) +{ + if (GetLocalInterface(gClientCfg.interface, &gClientCfg.ifindex, gClientCfg.hwaddr, NULL) != DHCP_OPT_SUCCESS) { + LOGE("GetClientNetworkInfo() GetLocalInterface failed, interface:%{public}s.\n", gClientCfg.interface); + return -1; + } + char macAddr[MAC_ADDR_LEN * MAC_ADDR_CHAR_NUM]; + if (memset_s(macAddr, sizeof(macAddr), 0, sizeof(macAddr)) != EOK) { + return -1; + } + HwaddrNtoa(gClientCfg.hwaddr, MAC_ADDR_LEN, macAddr, sizeof(macAddr)); + LOGI("GetClientNetworkInfo() gClientCfg.interface:%{public}s -> ifindex:%{private}d,hwaddr:%{private}s.\n", + gClientCfg.interface, gClientCfg.ifindex, macAddr); + + if (GetLocalIp(gClientCfg.interface, &gClientCfg.ipaddr4) != DHCP_OPT_SUCCESS) { + LOGE("GetClientNetworkInfo() failed, gClientCfg.interface:%{public}s.\n", gClientCfg.interface); + return -1; + } + char *cIp = Ip4IntConToStr(gClientCfg.ipaddr4, true); + if (cIp == NULL) { + LOGE("GetClientNetworkInfo() Ip4IntConToStr gClientCfg.ipaddr4 failed!\n"); + return -1; + } + LOGI("GetClientNetworkInfo() GetLocalIp interface:%{public}s -> ipaddr4:%{private}u - %{private}s.\n", + gClientCfg.interface, gClientCfg.ipaddr4, cIp); + free(cIp); + + /* Generate clientid for the specified client process interface. */ + if (gClientCfg.clientid == NULL) { + gClientCfg.clientid = malloc(DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + MAC_ADDR_LEN + 1); + if (gClientCfg.clientid == NULL) { + LOGE("GetClientNetworkInfo() gClientCfg.clientid malloc failed!\n"); + return -1; + } + gClientCfg.clientid[DHCP_OPT_CODE_INDEX] = DHO_CLIENTID; + gClientCfg.clientid[DHCP_OPT_LEN_INDEX] = MAC_ADDR_LEN + 1; + /* Generate format: 1 + hwaddr. */ + gClientCfg.clientid[DHCP_OPT_DATA_INDEX] = NUMBER_ONE; + if (memcpy_s(gClientCfg.clientid + DHCP_OPT_DATA_INDEX + 1, + MAC_ADDR_LEN, + gClientCfg.hwaddr, + MAC_ADDR_LEN) != EOK) { + return -1; + } + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + /* Check client process running param ACTION. */ + int nCheck = CheckClientProParam(argc, argv); + if (nCheck != 0) { + return (nCheck == 1) ? EXIT_SUCCESS : EXIT_FAILURE; + } + + /* Init the specified client process config. */ + if (InitSpecifiedClientCfg(argc, argv) != 0) { + return EXIT_FAILURE; + } + + /* Exec the specified client process ACTION. */ + const char *cmdParam = argv[NUMBER_ONE]; + int nExec = ExecClientProAction(cmdParam); + if (nExec != 0) { + return (nExec == 1) ? EXIT_SUCCESS : EXIT_FAILURE; + } + + /* Get the specified client process interface network info. */ + int nGet = GetClientNetworkInfo(); + if (nGet != 0) { + return (nGet == 1) ? EXIT_SUCCESS : EXIT_FAILURE; + } + + /* Start the specified network interface service. */ + if (StartProcess() != DHCP_OPT_SUCCESS) { + LOGE("main() StartProcess failed!\n"); + return EXIT_FAILURE; + } + + LOGI("main() end, argc:%{public}d.\n", argc); + return EXIT_SUCCESS; +} diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_options.c b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_options.c new file mode 100644 index 000000000..e16feef50 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_options.c @@ -0,0 +1,379 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "dhcp_options.h" + +#include +#include +#include + +#include "securec.h" + +#undef LOG_TAG +#define LOG_TAG "WifiDhcpOptions" + + +static bool CheckOptSoverloaded(const struct DhcpPacket *packet, int code, int maxLen, int *over, int *index) +{ + if (packet == NULL) { + LOGE("CheckOptSoverloaded failed, packet == NULL!\n"); + return false; + } + + const uint8_t *pOption = packet->options; + if (*index + DHCP_OPT_LEN_INDEX + pOption[*index + DHCP_OPT_LEN_INDEX] >= maxLen) { + LOGW("CheckOptSoverloaded code:%{public}d,*index:%{public}d more than max bytes:%{public}d!\n", + code, *index, maxLen); + return false; + } + *over = pOption[*index + DHCP_OPT_DATA_INDEX + DHCP_OPT_CODE_INDEX]; + *index += pOption[DHCP_OPT_LEN_INDEX] + DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES; + return true; +} + +static int GetDhcpOptionData(const struct DhcpPacket *packet, int code, int index, int maxLen) +{ + if (packet == NULL) { + LOGE("GetDhcpOptionData failed, packet == NULL!\n"); + return DHCP_OPT_FAILED; + } + + if (index >= maxLen) { + LOGW("GetDhcpOptionData code:%{public}d,index:%{public}d more than max bytes:%{public}d!\n", + code, index, maxLen); + return DHCP_OPT_FAILED; + } + + const uint8_t *pOption = packet->options; + if (pOption[index + DHCP_OPT_CODE_INDEX] != code) { + return DHCP_OPT_NONE; + } + + if (index + DHCP_OPT_LEN_INDEX + pOption[index + DHCP_OPT_LEN_INDEX] >= maxLen) { + LOGW("GetDhcpOptionData failed, options data too long, code:%{public}d,index:%{public}d!\n", code, index); + return DHCP_OPT_FAILED; + } + + return DHCP_OPT_SUCCESS; +} + +static uint8_t GetDhcpOptionCodeType(const uint8_t code) +{ + if ((code <= DHO_PAD) || (code >= DHO_END)) { + LOGE("GetDhcpOptionCodeType error, code:%{public}d is error!\n", code); + return DHCP_OPTION_DATA_INVALID; + } + + uint8_t nDataType = DHCP_OPTION_DATA_INVALID; + switch (code) { + case DHO_MESSAGETYPE: + nDataType = DHCP_OPTION_DATA_U8; + break; + case DHO_MTU: + nDataType = DHCP_OPTION_DATA_U16; + break; + case DHO_LEASETIME: + nDataType = DHCP_OPTION_DATA_U32; + break; + case DHO_SUBNETMASK: + case DHO_BROADCAST: + case DHO_IPADDRESS: + case DHO_SERVERID: + nDataType = DHCP_OPTION_DATA_IP; + break; + case DHO_ROUTER: + case DHO_DNSSERVER: + case DHO_NTPSERVER: + nDataType = DHCP_OPTION_DATA_IP_LIST; + break; + case DHO_HOSTNAME: + case DHO_DNSDOMAIN: + case DHO_MESSAGE: + nDataType = DHCP_OPTION_DATA_IP_STRING; + break; + default: + LOGE("GetDhcpOptionCodeType failed, code:%{public}d is invalid!\n", code); + break; + } + + return nDataType; +} + +uint8_t GetDhcpOptionDataLen(const uint8_t code) +{ + uint8_t nDataType = GetDhcpOptionCodeType(code); + if (nDataType == DHCP_OPTION_DATA_INVALID) { + LOGE("GetDhcpOptionDataLen code:%{public}d error, GetDhcpOptionCodeType invalid!\n", code); + return 0; + } + + uint8_t nDataLen = 0; + switch (nDataType) { + case DHCP_OPTION_DATA_U8: + nDataLen = DHCP_UINT8_BYTES; + break; + case DHCP_OPTION_DATA_U16: + nDataLen = DHCP_UINT16_BYTES; + break; + case DHCP_OPTION_DATA_U32: + nDataLen = DHCP_UINT32_BYTES; + break; + case DHCP_OPTION_DATA_IP: + nDataLen = DHCP_UINT32_BYTES; + break; + case DHCP_OPTION_DATA_IP_PAIR: + nDataLen = DHCP_UINT32_DOUBLE_BYTES; + break; + default: + LOGE("GetDhcpOptionDataLen code:%{public}d failed, nDataType:%{public}d is invalid!\n", + code, nDataType); + break; + } + + return nDataLen; +} + +/* Get an option with bounds checking (warning, not aligned). */ +const uint8_t *GetDhcpOption(const struct DhcpPacket *packet, int code, size_t *length) +{ + *length = 0; + if (packet == NULL) { + LOGE("GetDhcpOption failed, packet == NULL!\n"); + return NULL; + } + + const uint8_t *pOption = packet->options; + int i = 0, maxLen = DHCP_OPT_MAX_BYTES, over = 0, done = 0, curr = OPTION_FIELD, getRet; + while (done == 0) { + getRet = GetDhcpOptionData(packet, code, i, maxLen); + if (getRet == DHCP_OPT_SUCCESS) { + *length = pOption[i + DHCP_OPT_LEN_INDEX]; + return pOption + i + DHCP_OPT_DATA_INDEX; + } else if (getRet == DHCP_OPT_FAILED) { + return NULL; + } + + switch (pOption[i + DHCP_OPT_CODE_INDEX]) { + case DHO_PAD: + i++; + break; + case DHO_OPTSOVERLOADED: + if (!CheckOptSoverloaded(packet, code, maxLen, &over, &i)) { + return NULL; + } + break; + case DHO_END: + if ((curr == OPTION_FIELD) && (over & FILE_FIELD)) { + pOption = packet->file; + i = 0; + maxLen = DHCP_FILE_MAX_BYTES; + curr = FILE_FIELD; + } else if ((curr == FILE_FIELD) && (over & SNAME_FIELD)) { + pOption = packet->sname; + i = 0; + maxLen = DHCP_SNAME_MAX_BYTES; + curr = SNAME_FIELD; + } else { + done = 1; + } + break; + default: + i += DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + pOption[i + DHCP_OPT_LEN_INDEX]; + break; + } + } + LOGW("GetDhcpOption options no find code:%{public}d, i:%{public}d!\n", code, i); + return NULL; +} + +bool GetDhcpOptionUint8(const struct DhcpPacket *packet, int code, uint8_t *data) +{ + size_t len = 0; + const uint8_t *p = GetDhcpOption(packet, code, &len); + if (p == NULL) { + LOGW("GetDhcpOptionUint8 GetDhcpOption NULL, code:%{public}d!\n", code); + return false; + } + if (len < (ssize_t)sizeof(uint8_t)) { + LOGE("GetDhcpOptionUint8 failed, len:%{public}zu less data:%{public}zu, code:%{public}d!\n", + len, sizeof(uint8_t), code); + return false; + } + if (memcpy_s(data, sizeof(data), p, sizeof(uint8_t)) != EOK) { + return false; + } + return true; +} + +bool GetDhcpOptionUint32(const struct DhcpPacket *packet, int code, uint32_t *data) +{ + size_t len = 0; + const uint8_t *p = GetDhcpOption(packet, code, &len); + if (p == NULL) { + LOGW("GetDhcpOptionUint32 GetDhcpOption NULL, code:%{public}d!\n", code); + return false; + } + uint32_t uData = 0; + if (len < (ssize_t)sizeof(uData)) { + LOGE("GetDhcpOptionUint32 failed, len:%{public}zu less uData:%{public}zu, code:%{public}d!\n", + len, sizeof(uData), code); + return false; + } + if (memcpy_s(&uData, sizeof(uData), p, sizeof(uData)) != EOK) { + return false; + } + if (uData > 0) { + *data = ntohl(uData); + } + return true; +} + +bool GetDhcpOptionUint32n(const struct DhcpPacket *packet, int code, uint32_t *data1, uint32_t *data2) +{ + size_t len = 0; + const uint8_t *p = GetDhcpOption(packet, code, &len); + if (p == NULL) { + LOGW("GetDhcpOptionUint32n GetDhcpOption NULL, code:%{public}d!\n", code); + return false; + } + uint32_t uData = 0; + if ((len < (ssize_t)sizeof(uData)) || (len % (ssize_t)sizeof(uData) != 0)) { + LOGE("GetDhcpOptionUint32n failed, len:%{public}zu is not %{public}zu * n, code:%{public}d!\n", + len, sizeof(uData), code); + return false; + } + if (memcpy_s(&uData, sizeof(uData), p, sizeof(uData)) != EOK) { + return false; + } + if (uData > 0) { + *data1 = ntohl(uData); + } + if (len > (ssize_t)sizeof(uData)) { + p += sizeof(uData); + uData = 0; + if (memcpy_s(&uData, sizeof(uData), p, sizeof(uData)) != EOK) { + return false; + } + if (uData > 0) { + *data2 = ntohl(uData); + } + } + return true; +} + +char *GetDhcpOptionString(const struct DhcpPacket *packet, int code) +{ + size_t len; + const uint8_t *p = GetDhcpOption(packet, code, &len); + if ((p == NULL) || (*p == '\0')) { + LOGW("GetDhcpOptionString GetDhcpOption NULL, code:%{public}d!\n", code); + return NULL; + } + if (len < (ssize_t)sizeof(uint8_t)) { + LOGE("GetDhcpOptionString failed, len:%{public}zu less data:%{public}zu, code:%{public}d!\n", + len, sizeof(uint8_t), code); + return NULL; + } + + char *s = (char *)malloc(sizeof(char) * (len + 1)); + if (s) { + if (memcpy_s(s, len + 1, p, len) != EOK) { + return NULL; + } + s[len] = '\0'; + } + return s; +} + +/* Get option end index (no bounds checking) */ +int GetEndOptionIndex(uint8_t *optionptr) +{ + int i = 0; + while (optionptr[i] != DHO_END) { + if (optionptr[i] == DHO_PAD) { + i++; + } else { + i += optionptr[i + DHCP_OPT_LEN_INDEX] + DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES; + } + } + return i; +} + +/* add an option string to the options (an option string contains an option code,length, then data) */ +int AddOptionString(uint8_t *optionptr, uint8_t *optionstr, int optionstrLen) +{ + int optStrLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + optionstr[DHCP_OPT_LEN_INDEX]; + if (optionstrLen != optStrLen) { + LOGE("AddOptionString() code:%{public}u optionstrLen:%{public}d no equal optStrLen:%{public}d!\n", + optionstr[DHCP_OPT_CODE_INDEX], optionstrLen, optStrLen); + return 0; + } + + /* end position + optionstr length + option code/length + end option */ + int end = GetEndOptionIndex(optionptr); + if ((end + optionstrLen + 1) >= DHCP_OPT_MAX_BYTES) { + LOGE("AddOptionString() code:%{public}u did not fit into the packet!\n", optionstr[DHCP_OPT_CODE_INDEX]); + return 0; + } + + LOGI("AddOptionString() adding option code %{public}u.\n", optionstr[DHCP_OPT_CODE_INDEX]); + if (memcpy_s(optionptr + end, optionstrLen + 1, optionstr, optionstrLen) != EOK) { + return 0; + } + optionptr[end + optionstrLen] = DHO_END; + return optionstrLen; +} + +/* add a one to four byte option to a packet */ +int AddSimpleOption(uint8_t *optionptr, uint8_t code, uint32_t data) +{ + uint8_t length = 0; + uint8_t option[DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + DHCP_UINT32_BYTES]; + uint8_t *u8; + uint16_t *u16; + uint32_t *u32; + uint32_t aligned; + u8 = (uint8_t *)&aligned; + u16 = (uint16_t *)&aligned; + u32 = &aligned; + + length = GetDhcpOptionDataLen(code); + if (length == 0) { + LOGE("AddSimpleOption() code:%{public}d failed, GetDhcpOptionDataLen length:0!\n", code); + return 0; + } + + option[DHCP_OPT_CODE_INDEX] = code; + option[DHCP_OPT_LEN_INDEX] = length; + + switch (length) { + case DHCP_UINT8_BYTES: + *u8 = data; + break; + case DHCP_UINT16_BYTES: + *u16 = data; + break; + case DHCP_UINT32_BYTES: + *u32 = data; + break; + default: + LOGE("AddSimpleOption() length:%{public}u error, break!\n", length); + break; + } + if (memcpy_s(option + DHCP_OPT_DATA_INDEX, sizeof(uint32_t), &aligned, length) != EOK) { + return 0; + } + int nLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + option[DHCP_OPT_LEN_INDEX]; + return AddOptionString(optionptr, option, nLen); +} diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_socket.c b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_socket.c new file mode 100644 index 000000000..6c863d95c --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_socket.c @@ -0,0 +1,381 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "dhcp_socket.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "securec.h" +#include "dhcp_client.h" + +#undef LOG_TAG +#define LOG_TAG "WifiDhcpSocket" + + +static uint16_t CheckSum(u_int16_t *addr, int count) +{ + /* Compute Internet Checksum for "count" bytes beginning at location "addr". */ + register int32_t sum = 0; + u_int16_t *source = addr; + + while (count > 1) { + /* This is the inner loop */ + sum += *source++; + count -= DHCP_UINT16_BYTES; + } + + /* Add left-over byte, if any */ + if (count > 0) { + /* Make sure that the left-over byte is added correctly both + * with little and big endian hosts */ + u_int16_t tmp; + *(unsigned char *)(&tmp) = *(unsigned char *)source; + sum += tmp; + } + /* Fold 32-bit sum to 16 bits */ + while (sum >> DHCP_UINT16_BITS) + sum = (sum & 0xffff) + (sum >> DHCP_UINT16_BITS); + + return ~sum; +} + +/* raw socket can receive data frames or data packets from the local network interface */ +int CreateRawSocket(int ifindex) +{ + LOGI("CreateRawSocket() ifindex:%{public}d.\n", ifindex); + + int fd; + struct sockaddr_ll sock; + + if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) { + LOGE("CreateRawSocket() ifindex:%{public}d failed, socket error:%{public}s.\n", ifindex, strerror(errno)); + return -1; + } + + sock.sll_family = AF_PACKET; + sock.sll_protocol = htons(ETH_P_IP); + sock.sll_ifindex = ifindex; + if (bind(fd, (struct sockaddr *)&sock, sizeof(sock)) < 0) { + LOGE("CreateRawSocket() ifindex:%{public}d failed, bind error:%{public}s.\n", ifindex, strerror(errno)); + close(fd); + return -1; + } + + return fd; +} + +/* kernel socket can receive data frames or data packets from the local network interface, ip and port */ +int CreateSocket(const char *ifname, uint32_t ip, int port) +{ + LOGI("CreateSocket() ifname:%{public}s, ip:0x%{public}08x, port:%{public}d.\n", ifname, ip, port); + + struct ifreq interface; + int fd; + struct sockaddr_in addr; + int n = 1; + + if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + LOGE("CreateSocket() ifname:%{public}s failed, socket error:%{public}s.\n", ifname, strerror(errno)); + return -1; + } + + if (memset_s(&addr, sizeof(addr), 0, sizeof(addr)) != EOK) { + return -1; + } + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = ip; + addr.sin_port = htons(port); + + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&n, sizeof(n)) == -1) { + close(fd); + return -1; + } + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *)&n, sizeof(n)) == -1) { + close(fd); + return -1; + } + + if (strncpy_s(interface.ifr_ifrn.ifrn_name, sizeof(interface.ifr_ifrn.ifrn_name), ifname, IFNAMSIZ) != EOK) { + return -1; + } + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0) { + close(fd); + return -1; + } + + if (bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) { + close(fd); + return -1; + } + + return fd; +} + +/* Constuct a ip/udp header for a packet, and specify the source and dest hardware address */ +int SendToDhcpPacket( + const struct DhcpPacket *sendPacket, uint32_t srcIp, uint32_t destIp, const uint8_t *destHwaddr, int ifindex) +{ + int fd; + int result; + struct sockaddr_ll dest; + struct UdpDhcpPacket packet; + + if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) { + LOGE("socket call failed: %{public}s!\n", strerror(errno)); + return -1; + } + + if ((memset_s(&dest, sizeof(dest), 0, sizeof(dest)) != EOK) + || (memset_s(&packet, sizeof(packet), 0, sizeof(packet)) != EOK)) { + return -1; + } + + dest.sll_family = AF_PACKET; + dest.sll_protocol = htons(ETH_P_IP); + dest.sll_ifindex = ifindex; + dest.sll_halen = MAC_ADDR_LEN; + if (memcpy_s(dest.sll_addr, sizeof(dest.sll_addr), destHwaddr, MAC_ADDR_LEN) != EOK) { + return -1; + } + if (bind(fd, (struct sockaddr *)&dest, sizeof(struct sockaddr_ll)) < 0) { + LOGE("bind call failed: %{public}s!\n", strerror(errno)); + close(fd); + return -1; + } + + packet.ip.protocol = IPPROTO_UDP; + packet.ip.saddr = srcIp; + packet.ip.daddr = destIp; + packet.udp.source = htons(BOOTP_CLIENT); + packet.udp.dest = htons(BOOTP_SERVER); + packet.udp.len = htons(sizeof(packet.udp) + sizeof(struct DhcpPacket)); /* cheat on the psuedo-header */ + packet.ip.tot_len = packet.udp.len; + if (memcpy_s(&(packet.data), sizeof(struct DhcpPacket), sendPacket, sizeof(struct DhcpPacket)) != EOK) { + return -1; + } + packet.udp.check = CheckSum((u_int16_t *)&packet, sizeof(struct UdpDhcpPacket)); + + packet.ip.tot_len = htons(sizeof(struct UdpDhcpPacket)); + packet.ip.ihl = sizeof(packet.ip) >> DHCP_UINT16_BYTES; + packet.ip.version = IPVERSION; + packet.ip.ttl = IPDEFTTL; + packet.ip.check = CheckSum((u_int16_t *)&(packet.ip), sizeof(packet.ip)); + + result = sendto(fd, &packet, sizeof(struct UdpDhcpPacket), 0, (struct sockaddr *)&dest, sizeof(dest)); + if (result <= 0) { + LOGE("write on socket failed: %{public}s!\n", strerror(errno)); + } + close(fd); + return result; +} + +/* Let the kernel do all the work for packet generation */ +int SendDhcpPacket(struct DhcpPacket *sendPacket, uint32_t srcIp, uint32_t destIp) +{ + int fd; + int n = 1; + int result; + struct sockaddr_in src; + struct sockaddr_in dest; + + if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + return -1; + } + + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&n, sizeof(n)) == -1) { + return -1; + } + + if ((memset_s(&src, sizeof(src), 0, sizeof(src)) != EOK) + || (memset_s(&dest, sizeof(dest), 0, sizeof(dest)) != EOK)) { + return -1; + } + + src.sin_family = AF_INET; + src.sin_port = htons(BOOTP_CLIENT); + src.sin_addr.s_addr = srcIp; + if (bind(fd, (struct sockaddr *)&src, sizeof(struct sockaddr)) == -1) { + return -1; + } + + dest.sin_family = AF_INET; + dest.sin_port = htons(BOOTP_SERVER); + dest.sin_addr.s_addr = destIp; + if (connect(fd, (struct sockaddr *)&dest, sizeof(struct sockaddr)) == -1) { + return -1; + } + + result = write(fd, sendPacket, sizeof(struct DhcpPacket)); + close(fd); + return result; +} + +static int CheckReadBytes(const int count, const int totLen) +{ + if (count < 0) { + LOGE("CheckReadBytes() couldn't read on raw listening socket, count:%{public}d, error:%{public}s!\n", + count, strerror(errno)); + /* The specified network interface service may be down. */ + sleep(NUMBER_ONE); + return SOCKET_OPT_ERROR; + } + + int nCommonSize = sizeof(struct iphdr) + sizeof(struct udphdr); + if (count < nCommonSize) { + LOGE("CheckReadBytes() read size:%{public}d less than common size:%{public}d!\n", count, nCommonSize); + return SOCKET_OPT_FAILED; + } + + if (count < totLen) { + LOGE("CheckReadBytes() count:%{public}d less than totLen:%{public}d, packet is Truncated!\n", count, totLen); + return SOCKET_OPT_FAILED; + } + + LOGI("CheckReadBytes() success, count:%{public}d, totLen:%{public}d.\n", count, totLen); + return SOCKET_OPT_SUCCESS; +} + +static int CheckUdpPacket(struct UdpDhcpPacket *packet, const int totLen) +{ + if (packet == NULL) { + LOGE("CheckUdpPacket() failed, packet == NULL!\n"); + return SOCKET_OPT_FAILED; + } + + int nSize = (int)sizeof(struct UdpDhcpPacket); + if (totLen > nSize) { + LOGE("CheckUdpPacket() failed, totLen:%{public}d error, nSize:%{public}d!\n", totLen, nSize); + return SOCKET_OPT_FAILED; + } + + if ((packet->ip.protocol != IPPROTO_UDP) || (packet->ip.version != IPVERSION)) { + LOGE("CheckUdpPacket() failed, packet->ip.protocol:%{public}d or version:%{public}u error!\n", + packet->ip.protocol, packet->ip.version); + return SOCKET_OPT_FAILED; + } + + uint32_t uIhl = (uint32_t)(sizeof(packet->ip) >> DHCP_UINT16_BYTES); + if (packet->ip.ihl != uIhl) { + LOGE("CheckUdpPacket() failed, packet->ip.ihl:%{public}u error, uIhl:%{public}u!\n", packet->ip.ihl, uIhl); + return SOCKET_OPT_FAILED; + } + + if (packet->udp.dest != htons(BOOTP_CLIENT)) { + LOGE("CheckUdpPacket() failed, packet->udp.dest:%{public}d error, htons:%{public}d!\n", + packet->udp.dest, htons(BOOTP_CLIENT)); + return SOCKET_OPT_FAILED; + } + + uint16_t uLen = (uint16_t)(totLen - (int)sizeof(packet->ip)); + if (ntohs(packet->udp.len) != uLen) { + LOGE("CheckUdpPacket() failed, packet->udp.len:%{public}d error, uLen:%{public}d!\n", packet->udp.len, uLen); + return SOCKET_OPT_FAILED; + } + + LOGI("CheckUdpPacket() success, totLen:%{public}d.\n", totLen); + return SOCKET_OPT_SUCCESS; +} + +int GetDhcpRawPacket(struct DhcpPacket *getPacket, int fd) +{ + struct UdpDhcpPacket packet; + int bytes, nRet; + u_int16_t check; + u_int32_t source, dest; + + if (memset_s(&packet, sizeof(struct UdpDhcpPacket), 0, sizeof(struct UdpDhcpPacket)) != EOK) { + return SOCKET_OPT_FAILED; + } + + /* Check and get udp dhcp packet bytes. */ + bytes = read(fd, &packet, sizeof(struct UdpDhcpPacket)); + if ((nRet = CheckReadBytes(bytes, (int)ntohs(packet.ip.tot_len))) != SOCKET_OPT_SUCCESS) { + usleep(SLEEP_TIME_200_MS); + return nRet; + } + + /* Check udp packet. */ + bytes = (int)ntohs(packet.ip.tot_len); + if ((nRet = CheckUdpPacket(&packet, bytes)) != SOCKET_OPT_SUCCESS) { + usleep(SLEEP_TIME_500_MS); + return nRet; + } + + /* Check packet ip sum. */ + check = packet.ip.check; + packet.ip.check = 0; + if (check != CheckSum((u_int16_t *)&(packet.ip), sizeof(packet.ip))) { + LOGE("GetDhcpRawPacket() CheckSum packet.ip.check failed!\n"); + return SOCKET_OPT_ERROR; + } + + /* Check packet udp sum. */ + check = packet.udp.check; + packet.udp.check = 0; + source = packet.ip.saddr; + dest = packet.ip.daddr; + if (memset_s(&packet.ip, sizeof(packet.ip), 0, sizeof(packet.ip)) != EOK) { + return SOCKET_OPT_FAILED; + } + packet.ip.protocol = IPPROTO_UDP; + packet.ip.saddr = source; + packet.ip.daddr = dest; + packet.ip.tot_len = packet.udp.len; + if (check && (check != CheckSum((u_int16_t *)&packet, bytes))) { + LOGE("GetDhcpRawPacket() CheckSum packet.udp.check failed!\n"); + return SOCKET_OPT_FAILED; + } + + int nDhcpPacket = bytes - (int)(sizeof(packet.ip) + sizeof(packet.udp)); + if (memcpy_s(getPacket, sizeof(struct DhcpPacket), &(packet.data), nDhcpPacket) != EOK) { + LOGE("GetDhcpRawPacket() memcpy_s packet.data failed!\n"); + return SOCKET_OPT_FAILED; + } + if (ntohl(getPacket->cookie) != MAGIC_COOKIE) { + LOGE("GetDhcpRawPacket() cook:%{public}x error, COOK:%{public}x!\n", ntohl(getPacket->cookie), MAGIC_COOKIE); + return SOCKET_OPT_FAILED; + } + return nDhcpPacket; +} + +int GetDhcpPacket(struct DhcpPacket *getPacket, int fd) +{ + int bytes; + + if (memset_s(getPacket, sizeof(struct DhcpPacket), 0, sizeof(struct DhcpPacket)) != EOK) { + return SOCKET_OPT_FAILED; + } + bytes = read(fd, getPacket, sizeof(struct DhcpPacket)); + if (bytes < 0) { + LOGE("GetDhcpPacket() couldn't read on kernel listening socket, error:%{public}s!\n", strerror(errno)); + return SOCKET_OPT_ERROR; + } + + if (ntohl(getPacket->cookie) != MAGIC_COOKIE) { + LOGE("GetDhcpPacket() received bogus message (bad magic)!\n"); + return SOCKET_OPT_FAILED; + } + + LOGI("GetDhcpPacket() received a packet, bytes:%{public}d.\n", bytes); + return bytes; +} diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_client_service_impl.h b/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_client_service_impl.h new file mode 100644 index 000000000..2ff862cd4 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_client_service_impl.h @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DHCP_CLIENT_SERVICE_IMPL_H +#define OHOS_DHCP_CLIENT_SERVICE_IMPL_H + +#include +#include +#include +#include + +#include "i_dhcp_client_service.h" +#include "dhcp_define.h" + + +namespace OHOS { +namespace Wifi { +struct DhcpResultReq { + int timeouts; + int getTimestamp; + IDhcpResultNotify *pResultNotify; + + DhcpResultReq() + { + timeouts = RECEIVER_TIMEOUT; + getTimestamp = 0; + pResultNotify = nullptr; + } +}; +class DhcpClientServiceImpl : public IDhcpClientService { +public: + /** + * @Description : Construct a new dhcp client service object. + * + */ + DhcpClientServiceImpl(); + + /** + * @Description : Destroy the dhcp client service object. + * + */ + ~DhcpClientServiceImpl() override; + + /** + * @Description : Start dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param bIpv6 - can or not get ipv6 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int StartDhcpClient(const std::string& ifname, bool bIpv6) override; + + /** + * @Description : Stop dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param bIpv6 - can or not get ipv6 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int StopDhcpClient(const std::string& ifname, bool bIpv6) override; + + /** + * @Description : Get dhcp client service running status of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : 0 - not start, 1 - normal started, -1 - not normal. + */ + int GetDhcpStatus(const std::string& ifname) override; + + /** + * @Description : Obtain the dhcp result of specified interface asynchronously. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param dhcp - dhcp result notify [in] + * @param timeouts - timeout interval [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int GetDhcpResult(const std::string& ifname, IDhcpResultNotify *pResultNotify, int timeouts) override; + + /** + * @Description : Obtain the dhcp info of specified interface synchronously. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param dhcp - dhcp info [out] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int GetDhcpInfo(const std::string& ifname, DhcpServiceInfo& dhcp) override; + + /** + * @Description : Renew dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int RenewDhcpClient(const std::string& ifname) override; + + /** + * @Description : Release dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int ReleaseDhcpClient(const std::string& ifname) override; + +private: + /** + * @Description : Start dhcp result handle threads. + * + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int InitDhcpMgrThread(); + /** + * @Description : Exit dhcp result handle threads and recv msg threads. + * + */ + void ExitDhcpMgrThread(); + /** + * @Description : Check dhcp result req is or not timeout. + * + */ + void CheckTimeout(); + /** + * @Description : Handle dhcp result. + * + * @param second - sleep second number [out] + */ + void DhcpResultHandle(uint32_t &second); + /** + * @Description : Dhcp result handle threads execution function. + * + */ + void RunDhcpResultHandleThreadFunc(); + /** + * @Description : Dhcp recv msg threads execution function. + * + * @param ifname - interface name, eg:wlan0 [in] + */ + void RunDhcpRecvMsgThreadFunc(const std::string& ifname); + /** + * @Description : Handle dhcp packet info. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param packetResult - dhcp packet result [in] + * @param success - get success is true, get failed is false [in] + */ + void DhcpPacketInfoHandle(const std::string& ifname, struct DhcpPacketResult &packetResult, bool success = true); + /** + * @Description : Fork child process function for start or stop dhcp process. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param bIpv6 - can or not get ipv6 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int ForkExecChildProcess(const std::string& ifname, bool bIpv6, bool bStart = false); + /** + * @Description : Fork parent process function for handle dhcp function. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param bIpv6 - can or not get ipv6 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int ForkExecParentProcess(const std::string& ifname, bool bIpv6, bool bStart = false, pid_t pid = 0); + + /** + * @Description : Get the dhcp client process pid of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : The dhcp client process pid. + */ + pid_t GetDhcpClientProPid(const std::string& ifname); + +private: + std::mutex mResultNotifyMutex; + std::mutex mRecvMsgThreadMutex; + bool isExitDhcpResultHandleThread; + std::thread *pDhcpResultHandleThread; + std::map m_mapDhcpRecvMsgThread; + + std::map m_mapDhcpInfo; + std::map m_mapDhcpResult; + std::map> m_mapDhcpResultNotify; +}; +} // namespace Wifi +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_define.h b/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_define.h new file mode 100644 index 000000000..a6999c1dc --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_define.h @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DHCP_DEFINE_H +#define OHOS_DHCP_DEFINE_H + +#include +#include +#include + + +namespace OHOS { +namespace Wifi { +const int ETH_MAC_ADDR_INDEX_0 = 0; +const int ETH_MAC_ADDR_INDEX_1 = 1; +const int ETH_MAC_ADDR_INDEX_2 = 2; +const int ETH_MAC_ADDR_INDEX_3 = 3; +const int ETH_MAC_ADDR_INDEX_4 = 4; +const int ETH_MAC_ADDR_INDEX_5 = 5; +const int ETH_MAC_ADDR_LEN = 6; +const int ETH_MAC_ADDR_CHAR_NUM = 3; +const int IP_SIZE = 18; +const int LEASETIME_DEFAULT = 12; +const int RECEIVER_TIMEOUT = 6; +const int DHCP_RESULT_NUM = 11; +const int DHCP_NUMBER_ONE = 1; +const int DHCP_NUMBER_TWO = 2; +const int DHCP_NUMBER_THREE = 3; +const int DHCP_NUMBER_FOUR = 4; +const int DHCP_NUMBER_FIVE = 5; +const int DHCP_NUMBER_EIGHT = 8; +const int DHCP_FILE_MAX_BYTES = 128; +const int FILE_LINE_MAX_SIZE = 1024; +const int DHCP_SER_ARGSNUM = 6; +const int DHCP_CLI_ARGSNUM = 5; +const int SLEEP_TIME_200_MS = 200 * 1000; +const int SLEEP_TIME_500_MS = 500 * 1000; +const int PID_MAX_LEN = 16; +const int DEFAULT_UMASK = 027; +const std::string IP4_SEPARATOR("."); +const std::string IP6_SEPARATOR(":"); +const std::string DHCP_WORK_DIR("/data/dhcp/"); +const std::string DHCP_CLIENT_PID_FILETYPE(".pid"); +const std::string DHCP_RESULT_FILETYPE(".result"); +const std::string DHCP_CLIENT_FILE("/system/bin/dhcp_client_service"); +const std::string DHCP_SERVER_FILE("/system/bin/dhcpd"); +const std::string DHCP_SERVER_CONFIG_FILE("/data/dhcp/dhcpd.conf"); +const std::string DHCP_SERVER_CONFIG_DIR("/data/dhcp/dhcpd.d/"); +const std::string DHCP_SERVER_LEASES_FILE("/data/dhcp/dhcpd.leases"); +const std::string DHCP_SERVER_CFG_IPV4("#ipv4"); +const std::string DHCP_SERVER_CFG_IPV6("#ipv6"); + +typedef enum enumErrCode { + /* success */ + DHCP_OPT_SUCCESS = 0, + /* failed */ + DHCP_OPT_FAILED, + /* null pointer */ + DHCP_OPT_NULL, + /* timeout */ + DHCP_OPT_TIMEOUT, + /* error */ + DHCP_OPT_ERROR, +} DhcpErrCode; + + +struct DhcpResult { + int iptype; /* 0-ipv4,1-ipv6 */ + bool isOptSuc; /* get result */ + std::string strYourCli; /* your (client) IP */ + std::string strServer; /* dhcp server IP */ + std::string strSubnet; /* your (client) subnet mask */ + std::string strDns1; /* your (client) DNS server1 */ + std::string strDns2; /* your (client) DNS server2 */ + std::string strRouter1; /* your (client) router1 */ + std::string strRouter2; /* your (client) router2 */ + std::string strVendor; /* your (client) vendor */ + uint32_t uLeaseTime; /* your (client) IP lease time (s) */ + uint32_t uAddTime; /* dhcp result add time */ + uint32_t uGetTime; /* dhcp result get time */ + + DhcpResult() + { + iptype = -1; + isOptSuc = false; + strYourCli = ""; + strServer = ""; + strSubnet = ""; + strDns1 = ""; + strDns2 = ""; + strRouter1 = ""; + strRouter2 = ""; + strVendor = ""; + uLeaseTime = 0; + uAddTime = 0; + uGetTime = 0; + } +}; + +struct DhcpPacketResult { + char strYiaddr[INET_ADDRSTRLEN]; /* your (client) IP */ + char strOptServerId[INET_ADDRSTRLEN]; /* dhcp option DHO_SERVERID */ + char strOptSubnet[INET_ADDRSTRLEN]; /* dhcp option DHO_SUBNETMASK */ + char strOptDns1[INET_ADDRSTRLEN]; /* dhcp option DHO_DNSSERVER */ + char strOptDns2[INET_ADDRSTRLEN]; /* dhcp option DHO_DNSSERVER */ + char strOptRouter1[INET_ADDRSTRLEN]; /* dhcp option DHO_ROUTER */ + char strOptRouter2[INET_ADDRSTRLEN]; /* dhcp option DHO_ROUTER */ + char strOptVendor[DHCP_FILE_MAX_BYTES]; /* dhcp option DHO_VENDOR */ + uint32_t uOptLeasetime; /* dhcp option DHO_LEASETIME */ + uint32_t uAddTime; /* dhcp result add time */ +}; + +struct DhcpServiceInfo { + bool enableIPv6; /* true:ipv4 and ipv6,false:ipv4 */ + int clientRunStatus; /* dhcp client service status */ + pid_t clientProPid; /* dhcp client process pid */ + std::string serverIp; /* dhcp server IP */ + + DhcpServiceInfo() + { + enableIPv6 = true; + clientRunStatus = -1; + clientProPid = 0; + serverIp = ""; + } +}; + +struct DhcpRange { + int iptype; /* 0-ipv4,1-ipv6 */ + int leaseHours; /* lease hours */ + std::string strTagName; /* dhcp-range tag name */ + std::string strStartip; /* dhcp-range start ip */ + std::string strEndip; /* dhcp-range end ip */ + + DhcpRange() + { + iptype = -1; + leaseHours = LEASETIME_DEFAULT; + strTagName = ""; + strStartip = ""; + strEndip = ""; + } +}; +} // namespace Wifi +} // namespace OHOS +#endif /* OHOS_DHCP_DEFINE_H */ diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_func.h b/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_func.h new file mode 100644 index 000000000..99f1cca26 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_func.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FUNCTION_H +#define OHOS_FUNCTION_H + +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp_define.h" + + +namespace OHOS { +namespace Wifi { +class DhcpFunc { +public: + DhcpFunc() {} + ~DhcpFunc() {} + + static std::string IpToDot(unsigned int nIp); + static unsigned int IPtoInt(const std::string& strIp); + static bool Ip4StrConToInt(const std::string& strIp, uint32_t& uIp); + static std::string Ip4IntConToStr(uint32_t uIp); + static bool Ip6StrConToChar(const std::string& strIp, uint8_t chIp[]); + static std::string Ip6CharConToStr(uint8_t chIp[], int size); + static bool CheckIpStr(const std::string& strIp); + static int GetLocalIp(const std::string ethInf, std::string& localIp); + static int GetLocalMac(const std::string ethInf, std::string& ethMac); + + static bool IsExistFile(const std::string& filename); + static bool CreateFile(const std::string& filename, const std::string& filedata); + static bool RemoveFile(const std::string& filename); + static bool AddFileLineData(const std::string& filename, const std::string& prevdata, const std::string& linedata); + static bool DelFileLineData(const std::string& filename, const std::string& linedata); + static bool ModifyFileLineData(const std::string& filename, const std::string& srcdata, const std::string& dstdata); + static int FormatString(struct DhcpPacketResult &result); + static int GetDhcpPacketResult(const std::string& filename, struct DhcpPacketResult &result); + static int InitPidfile(const std::string& piddir, const std::string& pidfile); + static pid_t GetPID(const std::string& pidfile); +}; +} // namespace Wifi +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_server_service_impl.h b/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_server_service_impl.h new file mode 100644 index 000000000..dc256ccd7 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_server_service_impl.h @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DHCP_SERVER_SERVICE_IMPL_H +#define OHOS_DHCP_SERVER_SERVICE_IMPL_H + +#include +#include +#include +#include +#include +#include +#include + +#include "i_dhcp_server_service.h" +#include "dhcp_define.h" + + +namespace OHOS { +namespace Wifi { +class DhcpServerServiceImpl : public IDhcpServerService { +public: + /** + * @Description : Construct a new dhcp server service object. + * + */ + DhcpServerServiceImpl(); + + /** + * @Description : Destroy the dhcp server service object. + * + */ + ~DhcpServerServiceImpl() override; + + /** + * @Description : Start dhcp server service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int StartDhcpServer(const std::string& ifname) override; + + /** + * @Description : Stop dhcp server service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int StopDhcpServer(const std::string& ifname) override; + + /** + * @Description : Get dhcp server service running status. + * + * @Return : 0 - not start, 1 - normal started. + */ + int GetServerStatus(void) override; + + /** + * @Description : Add or update dhcp ip address pool. + * + * @param tagName - ip address pool tag name [in] + * @param range - ip address range [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int PutDhcpRange(const std::string& tagName, const DhcpRange& range) override; + + /** + * @Description : Remove dhcp ip address pool. + * + * @param tagName - ip address pool tag name [in] + * @param range - ip address range [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int RemoveDhcpRange(const std::string& tagName, const DhcpRange& range) override; + + /** + * @Description : Remove all dhcp ip address pool. + * + * @param tagName - ip address pool tag name [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int RemoveAllDhcpRange(const std::string& tagName) override; + + /** + * @Description : Set dhcp ip address pool of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param range - ip address range [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int SetDhcpRange(const std::string& ifname, const DhcpRange& range) override; + + /** + * @Description : Set dhcp ip address pool of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param tagName - ip address pool tag name [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int SetDhcpRange(const std::string& ifname, const std::string& tagName) override; + + /** + * @Description : Get dhcp server lease info. + * + * @param leases - lease info [out] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int GetLeases(std::vector& leases) override; + + /** + * @Description : Obtain the abnormal exit status of dhcp server process. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param pResultNotify - pointer to dhcp result notify [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int GetDhcpSerProExit(const std::string& ifname, IDhcpResultNotify *pResultNotify) override; + + /** + * @Description : Reload dhcp server config. + * + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int ReConf(void) override; + +private: + /** + * @Description : Fork parent process function. + * + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int ForkParentProcess(); + + /** + * @Description : Fork child process function for start dhcp server process. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int ForkExecProcess(const std::string& ifname = "reload cfg"); + + /** + * @Description : Stop dhcp server process. + * + * @param server_pid - process id [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int StopServer(const pid_t& server_pid); + + /** + * @Description : Check and update dhcp server config of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int CheckAndUpdateConf(const std::string& ifname); + + /** + * @Description : Delete dhcp server config of specified interface and reload all config. + * + * @param if_filename - interface file name, eg:wlan0.conf [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int DeleteInfConf(const std::string& if_filename); + + /** + * @Description : Check invalid or already exist in dhcp range. + * + * @param range - ip address range [in] + * @Return : true - yes, false - no. + */ + bool CheckIpAddrRange(const DhcpRange& range); + + /** + * @Description : Check ip address range is or not conflict. + * + * @param srcRange - already exist in ip address range [in] + * @param addRange - need add ip address range [in] + * @Return : true - yes, false - no. + */ + bool CheckDhcpRangeConflict(const DhcpRange& srcRange, const DhcpRange& addRange); + + /** + * @Description : Check ip address range list is or not same. + * + * @param tagRange - tag ip address range list [in] + * @param infRange - interface ip address range list [in] + * @Return : true - same, false - not same. + */ + bool CheckTagDhcpRange(std::list &tagRange, std::list &infRange); + + /** + * @Description : Exit dhcp process exit abnormal notify thread. + * + */ + void ExitDhcpMgrThreadFunc(); + + /** + * @Description : Dhcp server process exit abnormal notify. + * + */ + void RunDhcpSerProExitThreadFunc(); + + /** + * @Description : Register the SIGCHID signal. + * + */ + void RegisterSignal() const; + + /** + * @Description : Unregister the SIGCHID signal. + * + */ + void UnregisterSignal() const; + + /** + * @Description : Add the specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int AddSpecifiedInterface(const std::string& ifname); + + /** + * @Description : Delete the specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int DelSpecifiedInterface(const std::string& ifname); + + /** + * @Description : Receives the SIGCHLD signal of the dhcp server process. + * + */ + static void SigChildHandler(int signum); + + /** + * @Description : Get dhcp server process id. + * + * @Return : dhcp server process id. + */ + static pid_t GetServerPid(); + +private: + static bool mProExitSig; /* dhcp server process exit signal */ + static bool mStopServer; /* dhcp server process normal exit */ + static pid_t mPidDhcpServer; /* dhcp server process id */ + std::set m_setInterfaces; /* the started specified interfaces */ + std::map> m_mapTagDhcpRange; /* dhcp server can be used ip range */ + std::map> m_mapInfDhcpRange; /* dhcp server using ip range */ + std::map m_mapDhcpSerExitNotify; + + bool bDhcpSerProExitThread; + std::thread *pDhcpSerProExitThread; +}; +} // namespace Wifi +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_service.h b/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_service.h new file mode 100644 index 000000000..ba54a08a9 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_service.h @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DHCP_SERVICE_H +#define OHOS_DHCP_SERVICE_H + +#include "i_dhcp_service.h" +#include "dhcp_define.h" +#include "dhcp_client_service_impl.h" +#include "dhcp_server_service_impl.h" + + +namespace OHOS { +namespace Wifi { +class DhcpService : public IDhcpService { +public: + /** + * @Description : Construct a new dhcp service object. + * + */ + DhcpService(); + + /** + * @Description : Destroy the dhcp service object. + * + */ + ~DhcpService() override; + + /** + * @Description : Start dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param bIpv6 - can or not get ipv6 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int StartDhcpClient(const std::string& ifname, bool bIpv6) override; + + /** + * @Description : Stop dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param bIpv6 - can or not get ipv6 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int StopDhcpClient(const std::string& ifname, bool bIpv6) override; + + /** + * @Description : Obtain the dhcp result of specified interface asynchronously. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param dhcp - dhcp result notify [in] + * @param timeouts - timeout interval [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int GetDhcpResult(const std::string& ifname, IDhcpResultNotify *pResultNotify, int timeouts) override; + + /** + * @Description : Obtain the dhcp info of specified interface synchronously. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param dhcp - dhcp info [out] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int GetDhcpInfo(const std::string& ifname, DhcpServiceInfo& dhcp) override; + + /** + * @Description : Renew dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int RenewDhcpClient(const std::string& ifname) override; + + /** + * @Description : Release dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int ReleaseDhcpClient(const std::string& ifname) override; + + /** + * @Description : Start dhcp server service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int StartDhcpServer(const std::string& ifname) override; + + /** + * @Description : Stop dhcp server service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int StopDhcpServer(const std::string& ifname) override; + + /** + * @Description : Get dhcp server service running status. + * + * @Return : 0 - not start, 1 - normal started. + */ + int GetServerStatus(void) override; + + /** + * @Description : Add or update dhcp ip address pool. + * + * @param tagName - ip address pool tag name [in] + * @param range - ip address range [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int PutDhcpRange(const std::string& tagName, const DhcpRange& range) override; + + /** + * @Description : Remove dhcp ip address pool. + * + * @param tagName - ip address pool tag name [in] + * @param range - ip address range [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int RemoveDhcpRange(const std::string& tagName, const DhcpRange& range) override; + + /** + * @Description : Remove all dhcp ip address pool. + * + * @param tagName - ip address pool tag name [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int RemoveAllDhcpRange(const std::string& tagName) override; + + /** + * @Description : Set dhcp ip address pool of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param range - ip address range [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int SetDhcpRange(const std::string& ifname, const DhcpRange& range) override; + + /** + * @Description : Set dhcp ip address pool of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param tagName - ip address pool tag name [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int SetDhcpRange(const std::string& ifname, const std::string& tagName) override; + + /** + * @Description : Get dhcp server lease info. + * + * @param leases - lease info [out] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int GetLeases(std::vector& leases) override; + + /** + * @Description : Obtain the abnormal exit status of dhcp server process. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param pResultNotify - pointer to dhcp result notify [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + int GetDhcpSerProExit(const std::string& ifname, IDhcpResultNotify *pResultNotify) override; + +private: + std::unique_ptr m_pClientService; + std::unique_ptr m_pServerService; +}; +} // namespace Wifi +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_client_service.h b/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_client_service.h new file mode 100644 index 000000000..10d17cf55 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_client_service.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DHCP_CLIENT_SERVICE_INTERFACE_H +#define OHOS_DHCP_CLIENT_SERVICE_INTERFACE_H + +#include "i_dhcp_result_notify.h" +#include "dhcp_define.h" + +namespace OHOS { +namespace Wifi { +class IDhcpClientService { +public: + /** + * @Description : Construct a new dhcp client base service object. + * + */ + IDhcpClientService() + { + } + + /** + * @Description : Destroy the dhcp client base service object. + * + */ + virtual ~IDhcpClientService() + { + } + + /** + * @Description : Start dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param bIpv6 - can or not get ipv6 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int StartDhcpClient(const std::string& ifname, bool bIpv6) = 0; + + /** + * @Description : Stop dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param bIpv6 - can or not get ipv6 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int StopDhcpClient(const std::string& ifname, bool bIpv6) = 0; + + /** + * @Description : Get dhcp client service running status of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : 0 - not start, 1 - normal started, -1 - not normal. + */ + virtual int GetDhcpStatus(const std::string& ifname) = 0; + + /** + * @Description : Obtain the dhcp result of specified interface asynchronously. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param dhcp - dhcp result notify [in] + * @param timeouts - timeout interval [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int GetDhcpResult(const std::string& ifname, IDhcpResultNotify *pResultNotify, int timeouts) = 0; + + /** + * @Description : Obtain the dhcp info of specified interface synchronously. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param dhcp - dhcp info [out] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int GetDhcpInfo(const std::string& ifname, DhcpServiceInfo& dhcp) = 0; + + /** + * @Description : Renew dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int RenewDhcpClient(const std::string& ifname) = 0; + + /** + * @Description : Release dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int ReleaseDhcpClient(const std::string& ifname) = 0; +}; +} // namespace Wifi +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_result_notify.h b/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_result_notify.h new file mode 100644 index 000000000..2cc03bab5 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_result_notify.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DHCP_RESULT_NOTIFY_INTERFACE_H +#define OHOS_DHCP_RESULT_NOTIFY_INTERFACE_H + +#include "dhcp_define.h" + + +namespace OHOS { +namespace Wifi { +class IDhcpResultNotify { +public: + /** + * @Description : Destroy the dhcp result notify base object. + * + */ + virtual ~IDhcpResultNotify() {} + + /** + * @Description : Get success the dhcp result of specified interface. + * + * @param status - success : DHCP_OPT_SUCCESS, failed : DHCP_OPT_FAILED, timeout : DHCP_OPT_TIMEOUT [in] + * @param ifname - interface name, eg:wlan0 [in] + * @param result - dhcp result [in] + */ + virtual void OnSuccess(int status, const std::string& ifname, DhcpResult& result) = 0; + + /** + * @Description : Get failed the dhcp result of specified interface. + * + * @param status - success : DHCP_OPT_SUCCESS, failed : DHCP_OPT_FAILED, timeout : DHCP_OPT_TIMEOUT [in] + * @param ifname - interface name, eg:wlan0 [in] + * @param reason - failed reason [in] + */ + virtual void OnFailed(int status, const std::string& ifname, const std::string& reason) = 0; + + /** + * @Description : Get the abnormal exit notify of dhcp server process. + * + * @param ifname - interface name, eg:wlan0 [in] + */ + virtual void OnSerExitNotify(const std::string& ifname) = 0; +}; +} // namespace Wifi +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_server_service.h b/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_server_service.h new file mode 100644 index 000000000..5945fd267 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_server_service.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DHCP_SERVER_SERVICE_INTERFACE_H +#define OHOS_DHCP_SERVER_SERVICE_INTERFACE_H + +#include "i_dhcp_result_notify.h" +#include "dhcp_define.h" + + +namespace OHOS { +namespace Wifi { +class IDhcpServerService { +public: + /** + * @Description : Construct a new dhcp server base service object. + * + */ + IDhcpServerService() + { + } + + /** + * @Description : Destroy the dhcp server base service object. + * + */ + virtual ~IDhcpServerService() + { + } + + /** + * @Description : Start dhcp server service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int StartDhcpServer(const std::string& ifname) = 0; + + /** + * @Description : Stop dhcp server service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int StopDhcpServer(const std::string& ifname) = 0; + + /** + * @Description : Get dhcp server service running status. + * + * @Return : 0 - not start, 1 - normal started. + */ + virtual int GetServerStatus(void) = 0; + + /** + * @Description : Add or update dhcp ip address pool. + * + * @param tagName - ip address pool tag name [in] + * @param range - ip address range [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int PutDhcpRange(const std::string& tagName, const DhcpRange& range) = 0; + + /** + * @Description : Remove dhcp ip address pool. + * + * @param tagName - ip address pool tag name [in] + * @param range - ip address range [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int RemoveDhcpRange(const std::string& tagName, const DhcpRange& range) = 0; + + /** + * @Description : Remove all dhcp ip address pool. + * + * @param tagName - ip address pool tag name [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int RemoveAllDhcpRange(const std::string& tagName) = 0; + + /** + * @Description : Set dhcp ip address pool of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param range - ip address range [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int SetDhcpRange(const std::string& ifname, const DhcpRange& range) = 0; + + /** + * @Description : Set dhcp ip address pool of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param tagName - ip address pool tag name [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int SetDhcpRange(const std::string& ifname, const std::string& tagName) = 0; + + /** + * @Description : Get dhcp server lease info. + * + * @param leases - lease info [out] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int GetLeases(std::vector& leases) = 0; + + /** + * @Description : Obtain the abnormal exit status of dhcp server process. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param pResultNotify - pointer to dhcp result notify [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int GetDhcpSerProExit(const std::string& ifname, IDhcpResultNotify *pResultNotify) = 0; + + /** + * @Description : Reload dhcp server config. + * + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int ReConf(void) = 0; +}; +} // namespace Wifi +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_service.h b/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_service.h new file mode 100644 index 000000000..5c7d36c52 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_service.h @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DHCP_SERVICE_INTERFACE_H +#define OHOS_DHCP_SERVICE_INTERFACE_H + +#include "i_dhcp_result_notify.h" +#include "dhcp_define.h" + + +namespace OHOS { +namespace Wifi { +class IDhcpService { +public: + /** + * @Description : Construct a new dhcp base service object. + * + */ + IDhcpService() + { + } + + /** + * @Description : Destroy the dhcp base service object. + * + */ + virtual ~IDhcpService() + { + } + + /** + * @Description : Start dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param bIpv6 - can or not get ipv6 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int StartDhcpClient(const std::string& ifname, bool bIpv6) = 0; + + /** + * @Description : Stop dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param bIpv6 - can or not get ipv6 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int StopDhcpClient(const std::string& ifname, bool bIpv6) = 0; + + /** + * @Description : Obtain the dhcp result of specified interface asynchronously. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param dhcp - dhcp result notify [in] + * @param timeouts - timeout interval [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int GetDhcpResult(const std::string& ifname, IDhcpResultNotify *pResultNotify, int timeouts) = 0; + + /** + * @Description : Obtain the dhcp info of specified interface synchronously. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param dhcp - dhcp info [out] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int GetDhcpInfo(const std::string& ifname, DhcpServiceInfo& dhcp) = 0; + + /** + * @Description : Renew dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int RenewDhcpClient(const std::string& ifname) = 0; + + /** + * @Description : Release dhcp client service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int ReleaseDhcpClient(const std::string& ifname) = 0; + + /** + * @Description : Start dhcp server service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int StartDhcpServer(const std::string& ifname) = 0; + + /** + * @Description : Stop dhcp server service of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int StopDhcpServer(const std::string& ifname) = 0; + + /** + * @Description : Get dhcp server service running status. + * + * @Return : 0 - not start, 1 - normal started. + */ + virtual int GetServerStatus(void) = 0; + + /** + * @Description : Add or update dhcp ip address pool. + * + * @param tagName - ip address pool tag name [in] + * @param range - ip address range [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int PutDhcpRange(const std::string& tagName, const DhcpRange& range) = 0; + + /** + * @Description : Remove dhcp ip address pool. + * + * @param tagName - ip address pool tag name [in] + * @param range - ip address range [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int RemoveDhcpRange(const std::string& tagName, const DhcpRange& range) = 0; + + /** + * @Description : Remove all dhcp ip address pool. + * + * @param tagName - ip address pool tag name [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int RemoveAllDhcpRange(const std::string& tagName) = 0; + + /** + * @Description : Set dhcp ip address pool of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param range - ip address range [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int SetDhcpRange(const std::string& ifname, const DhcpRange& range) = 0; + + /** + * @Description : Set dhcp ip address pool of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param tagName - ip address pool tag name [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int SetDhcpRange(const std::string& ifname, const std::string& tagName) = 0; + + /** + * @Description : Get dhcp server lease info. + * + * @param leases - lease info [out] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int GetLeases(std::vector& leases) = 0; + + /** + * @Description : Obtain the abnormal exit status of dhcp server process. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param pResultNotify - pointer to dhcp result notify [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. + */ + virtual int GetDhcpSerProExit(const std::string& ifname, IDhcpResultNotify *pResultNotify) = 0; +}; +} // namespace Wifi +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_client_service_impl.cpp b/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_client_service_impl.cpp new file mode 100644 index 000000000..25310825e --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_client_service_impl.cpp @@ -0,0 +1,629 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "dhcp_client_service_impl.h" + +#include +#include +#include + +#include "dhcp_func.h" +#include "securec.h" +#include "wifi_logger.h" + +DEFINE_WIFILOG_DHCP_LABEL("DhcpClientServiceImpl"); + +namespace OHOS { +namespace Wifi { +DhcpClientServiceImpl::DhcpClientServiceImpl() +{ + isExitDhcpResultHandleThread = false; + pDhcpResultHandleThread = nullptr; + m_mapDhcpRecvMsgThread.clear(); + + m_mapDhcpInfo.clear(); + m_mapDhcpResult.clear(); + m_mapDhcpResultNotify.clear(); + + InitDhcpMgrThread(); +} + +DhcpClientServiceImpl::~DhcpClientServiceImpl() +{ + ExitDhcpMgrThread(); +} + +int DhcpClientServiceImpl::InitDhcpMgrThread() +{ + pDhcpResultHandleThread = new std::thread(&DhcpClientServiceImpl::RunDhcpResultHandleThreadFunc, this); + if (pDhcpResultHandleThread == nullptr) { + WIFI_LOGE("DhcpClientServiceImpl::InitDhcpMgrThread() init pDhcpResultHandleThread failed!\n"); + return DHCP_OPT_FAILED; + } + + return DHCP_OPT_SUCCESS; +} + +void DhcpClientServiceImpl::ExitDhcpMgrThread() +{ + isExitDhcpResultHandleThread = true; + + if (pDhcpResultHandleThread != nullptr) { + pDhcpResultHandleThread->join(); + delete pDhcpResultHandleThread; + pDhcpResultHandleThread = nullptr; + } + + if (!m_mapDhcpResultNotify.empty()) { + WIFI_LOGE("ExitDhcpMgrThread() error, m_mapDhcpResultNotify is not empty!\n"); + m_mapDhcpResultNotify.clear(); + } + + if (!m_mapDhcpRecvMsgThread.empty()) { + WIFI_LOGE("ExitDhcpMgrThread() error, m_mapDhcpRecvMsgThread is not empty!\n"); + for (auto &mapThread : m_mapDhcpRecvMsgThread) { + int nStatus = GetDhcpStatus(mapThread.first); + WIFI_LOGE("ExitDhcpMgrThread() ifname:%{public}s, status:%{public}d!\n", + (mapThread.first).c_str(), nStatus); + } + } +} + +void DhcpClientServiceImpl::CheckTimeout() +{ + uint32_t tempTime = 0; + uint32_t curTime = (uint32_t)time(NULL); + for (auto &itemNotify : m_mapDhcpResultNotify) { + std::string ifname = itemNotify.first; + WIFI_LOGI("CheckTimeout() ifname:%{public}s, notify1 second size:%{public}d.\n", + ifname.c_str(), + (int)itemNotify.second.size()); + auto iterReq = itemNotify.second.begin(); + while (iterReq != itemNotify.second.end()) { + if ((*iterReq == nullptr) || ((*iterReq)->pResultNotify == nullptr)) { + WIFI_LOGE("DhcpClientServiceImpl::CheckTimeout() error, *iterReq or pResultNotify is nullptr!\n"); + return; + } + tempTime = (*iterReq)->getTimestamp + (*iterReq)->timeouts; + if (tempTime <= curTime) { + /* get dhcp result timeout */ + WIFI_LOGW("CheckTimeout() ifname:%{public}s get timeout, getTime:%{public}u,timeout:%{public}d, " + "curTime:%{public}u!\n", + ifname.c_str(), + (*iterReq)->getTimestamp, + (*iterReq)->timeouts, + curTime); + (*iterReq)->pResultNotify->OnFailed(DHCP_OPT_TIMEOUT, ifname, "get dhcp result timeout!"); + delete *iterReq; + iterReq = itemNotify.second.erase(iterReq); + } else { + ++iterReq; + } + } + } +} + +void DhcpClientServiceImpl::DhcpResultHandle(uint32_t &second) +{ + std::unique_lock lock(mResultNotifyMutex); + if (m_mapDhcpResultNotify.empty()) { + second = SLEEP_TIME_200_MS; + return; + } + + /* Check timeout */ + CheckTimeout(); + auto iterNotify = m_mapDhcpResultNotify.begin(); + while (iterNotify != m_mapDhcpResultNotify.end()) { + /* Check dhcp result notify size */ + std::string ifname = iterNotify->first; + if (iterNotify->second.size() <= 0) { + iterNotify = m_mapDhcpResultNotify.erase(iterNotify); + WIFI_LOGI("DhcpResultHandle() ifname:%{public}s, dhcp result notify size:0, erase!\n", ifname.c_str()); + continue; + } + + /* Check dhcp result */ + auto iterDhcpResult = m_mapDhcpResult.find(ifname); + if (iterDhcpResult == m_mapDhcpResult.end()) { + WIFI_LOGI("DhcpResultHandle() ifname:%{public}s, dhcp result is getting...\n", ifname.c_str()); + ++iterNotify; + continue; + } + + auto iterReq = iterNotify->second.begin(); + while (iterReq != iterNotify->second.end()) { + if ((*iterReq == nullptr) || ((*iterReq)->pResultNotify == nullptr)) { + WIFI_LOGE("DhcpResultHandle() %{public}s iterReq or pResultNotify is nullptr!\n", ifname.c_str()); + second = SLEEP_TIME_500_MS; + return; + } + + /* Handle dhcp result notify */ + WIFI_LOGI("DhcpResultHandle() ifname:%{public}s, isOptSuc:%{public}d.\n", + ifname.c_str(), (iterDhcpResult->second).isOptSuc); + if ((iterDhcpResult->second).isOptSuc) { + /* get dhcp result success */ + WIFI_LOGI("DhcpResultHandle() ifname:%{public}s get dhcp result success!\n", ifname.c_str()); + (*iterReq)->pResultNotify->OnSuccess(DHCP_OPT_SUCCESS, ifname, iterDhcpResult->second); + } else { + /* get dhcp result failed */ + WIFI_LOGE("DhcpResultHandle() ifname:%{public}s get dhcp result failed!\n", ifname.c_str()); + (*iterReq)->pResultNotify->OnFailed(DHCP_OPT_FAILED, ifname, "get dhcp result failed!"); + } + delete *iterReq; + iterReq = iterNotify->second.erase(iterReq); + } + + ++iterNotify; + } + + WIFI_LOGI("DhcpResultHandle() dhcp result notify finished.\n"); + second = SLEEP_TIME_500_MS; +} + +void DhcpClientServiceImpl::RunDhcpResultHandleThreadFunc() +{ + for (; ;) { + if (isExitDhcpResultHandleThread) { + WIFI_LOGI("RunDhcpResultHandleThreadFunc() isExitDhcpResultHandleThread:1, break!\n"); + break; + } + + uint32_t uSleepSec = SLEEP_TIME_500_MS; + DhcpResultHandle(uSleepSec); + usleep(uSleepSec); + } + + WIFI_LOGI("DhcpClientServiceImpl::RunDhcpResultHandleThreadFunc() end!\n"); +} + +void DhcpClientServiceImpl::RunDhcpRecvMsgThreadFunc(const std::string &ifname) +{ + if (ifname.empty()) { + WIFI_LOGE("DhcpClientServiceImpl::RunDhcpRecvMsgThreadFunc() error, ifname is empty!\n"); + return; + } + + struct DhcpPacketResult result; + std::string strResultFile = DHCP_WORK_DIR + ifname + DHCP_RESULT_FILETYPE; + for (; ;) { + /* Check break condition. */ + auto iter = this->m_mapDhcpInfo.find(ifname); + if ((iter != this->m_mapDhcpInfo.end()) && ((iter->second).clientRunStatus) != 1) { + WIFI_LOGI("RunDhcpRecvMsgThreadFunc() Status != 1, need break, ifname:%{public}s.\n", ifname.c_str()); + break; + } + + /* Check dhcp result file is or not exist. */ + if (!DhcpFunc::IsExistFile(strResultFile)) { + usleep(SLEEP_TIME_200_MS); + continue; + } + + if (memset_s(&result, sizeof(result), 0, sizeof(result)) != EOK) { + return; + } + int nGetRet = DhcpFunc::GetDhcpPacketResult(strResultFile, result); + if (nGetRet == DHCP_OPT_SUCCESS) { + /* Get success, add or reload dhcp packet info. */ + this->DhcpPacketInfoHandle(ifname, result); + usleep(SLEEP_TIME_500_MS); + } else if (nGetRet == DHCP_OPT_FAILED) { + /* Get failed, print dhcp packet info. */ + this->DhcpPacketInfoHandle(ifname, result, false); + usleep(SLEEP_TIME_500_MS); + } else { + /* Get null, continue get dhcp packet info. */ + WIFI_LOGI("RunDhcpRecvMsgThreadFunc() GetDhcpPacketResult NULL, ifname:%{public}s.\n", ifname.c_str()); + usleep(SLEEP_TIME_200_MS); + } + + continue; + } +} + +void DhcpClientServiceImpl::DhcpPacketInfoHandle( + const std::string &ifname, struct DhcpPacketResult &packetResult, bool success) +{ + if (ifname.empty()) { + WIFI_LOGE("DhcpClientServiceImpl::DhcpPacketInfoHandle() error, ifname is empty!\n"); + return; + } + + DhcpResult result; + auto iterResult = m_mapDhcpResult.find(ifname); + if (!success) { + /* get failed */ + if (iterResult != m_mapDhcpResult.end()) { + iterResult->second = result; + } else { + m_mapDhcpResult.emplace(std::make_pair(ifname, result)); + } + return; + } + + /* Check dhcp result add time */ + if ((iterResult != m_mapDhcpResult.end()) && ((iterResult->second).uAddTime == packetResult.uAddTime)) { + return; + } + WIFI_LOGI("DhcpPacketInfoHandle() DhcpResult %{public}s old %{public}u no equal new %{public}u, need update...\n", + ifname.c_str(), (iterResult->second).uAddTime, packetResult.uAddTime); + + /* get success, add or reload dhcp packet info */ + auto iterInfo = m_mapDhcpInfo.find(ifname); + if (iterInfo != m_mapDhcpInfo.end()) { + m_mapDhcpInfo[ifname].serverIp = packetResult.strOptServerId; + WIFI_LOGI("DhcpPacketInfoHandle() m_mapDhcpInfo find ifname:%{public}s.\n", ifname.c_str()); + } + + result.iptype = 0; + result.isOptSuc = true; + result.strYourCli = packetResult.strYiaddr; + result.strServer = packetResult.strOptServerId; + result.strSubnet = packetResult.strOptSubnet; + result.strDns1 = packetResult.strOptDns1; + result.strDns2 = packetResult.strOptDns2; + result.strRouter1 = packetResult.strOptRouter1; + result.strRouter2 = packetResult.strOptRouter2; + result.strVendor = packetResult.strOptVendor; + result.uLeaseTime = packetResult.uOptLeasetime; + result.uAddTime = packetResult.uAddTime; + result.uGetTime = (uint32_t)time(NULL); + + if (iterResult != m_mapDhcpResult.end()) { + iterResult->second = result; + } else { + m_mapDhcpResult.emplace(std::make_pair(ifname, result)); + } + WIFI_LOGI("DhcpPacketInfoHandle %{public}s, type:%{public}d, opt:%{public}d, cli:%{public}s, server:%{public}s, " + "strSubnet:%{public}s, strDns1:%{public}s, strDns2:%{public}s, strRouter1:%{public}s, strRouter2:%{public}s, " + "strVendor:%{public}s, uLeaseTime:%{public}u, uAddTime:%{public}u, uGetTime:%{public}u.\n", + ifname.c_str(), result.iptype, result.isOptSuc, result.strYourCli.c_str(), result.strServer.c_str(), + result.strSubnet.c_str(), result.strDns1.c_str(), result.strDns2.c_str(), result.strRouter1.c_str(), + result.strRouter2.c_str(), result.strVendor.c_str(), result.uLeaseTime, result.uAddTime, result.uGetTime); +} + +int DhcpClientServiceImpl::ForkExecChildProcess(const std::string &ifname, bool bIpv6, bool bStart) +{ + if (bIpv6) { + /* get ipv4 and ipv6 */ + if (bStart) { + const char *args[DHCP_CLI_ARGSNUM] = {DHCP_CLIENT_FILE.c_str(), "start", ifname.c_str(), "-a", nullptr}; + if (execv(args[0], const_cast(args)) == -1) { + WIFI_LOGE("execv start v4 v6 failed,strerror(errno):%{public}s,ifname:%{public}s\n", + strerror(errno), ifname.c_str()); + } + } else { + const char *args[DHCP_CLI_ARGSNUM] = {DHCP_CLIENT_FILE.c_str(), "stop", ifname.c_str(), "-a", nullptr}; + if (execv(args[0], const_cast(args)) == -1) { + WIFI_LOGE("execv stop v4 v6 failed,strerror(errno):%{public}s,ifname:%{public}s\n", + strerror(errno), ifname.c_str()); + } + } + } else { + /* only get ipv4 */ + if (bStart) { + const char *args[DHCP_CLI_ARGSNUM] = {DHCP_CLIENT_FILE.c_str(), "start", ifname.c_str(), "-4", nullptr}; + if (execv(args[0], const_cast(args)) == -1) { + WIFI_LOGE("execv start v4 failed,strerror(errno):%{public}s,ifname:%{public}s\n", + strerror(errno), ifname.c_str()); + } + } else { + const char *args[DHCP_CLI_ARGSNUM] = {DHCP_CLIENT_FILE.c_str(), "stop", ifname.c_str(), "-4", nullptr}; + if (execv(args[0], const_cast(args)) == -1) { + WIFI_LOGE("execv stop v4 failed,strerror(errno):%{public}s,ifname:%{public}s\n", + strerror(errno), ifname.c_str()); + } + } + } + _exit(-1); +} + +int DhcpClientServiceImpl::ForkExecParentProcess(const std::string &ifname, bool bIpv6, bool bStart, pid_t pid) +{ + if (bStart) { + /* check and new receive dhcp packet msg thread */ + std::unique_lock lock(mRecvMsgThreadMutex); + auto iterRecvMsgThread = m_mapDhcpRecvMsgThread.find(ifname); + if (iterRecvMsgThread != m_mapDhcpRecvMsgThread.end()) { + WIFI_LOGE("ForkExecParentProcess() RecvMsgThread exist ifname:%{public}s, need erase!\n", ifname.c_str()); + return DHCP_OPT_FAILED; + } + std::thread *pThread = new std::thread(&DhcpClientServiceImpl::RunDhcpRecvMsgThreadFunc, this, ifname); + if (pThread == nullptr) { + WIFI_LOGE("ForkExecParentProcess() init pThread failed, ifname:%{public}s.\n", ifname.c_str()); + return DHCP_OPT_FAILED; + } + m_mapDhcpRecvMsgThread.emplace(std::make_pair(ifname, pThread)); + /* normal started, update dhcp client service running status */ + auto iter = m_mapDhcpInfo.find(ifname); + if (iter != m_mapDhcpInfo.end()) { + m_mapDhcpInfo[ifname].enableIPv6 = bIpv6; + m_mapDhcpInfo[ifname].clientRunStatus = 1; + m_mapDhcpInfo[ifname].clientProPid = pid; + } else { + DhcpServiceInfo dhcpInfo; + dhcpInfo.enableIPv6 = bIpv6; + dhcpInfo.clientRunStatus = 1; + dhcpInfo.clientProPid = pid; + m_mapDhcpInfo.emplace(std::make_pair(ifname, dhcpInfo)); + } + } else { + /* destroy recv msg thread */ + auto iter = m_mapDhcpInfo.find(ifname); + if (iter != m_mapDhcpInfo.end()) { + /* not start */ + m_mapDhcpInfo[ifname].clientRunStatus = 0; + m_mapDhcpInfo[ifname].clientProPid = 0; + std::unique_lock lock(mRecvMsgThreadMutex); + auto iterRecvMsgThreadMap = m_mapDhcpRecvMsgThread.find(ifname); + if (iterRecvMsgThreadMap == m_mapDhcpRecvMsgThread.end()) { + WIFI_LOGI("ForkExecParentProcess() RecvMsgThread already del ifname:%{public}s.\n", ifname.c_str()); + return DHCP_OPT_SUCCESS; + } + if (iterRecvMsgThreadMap->second != nullptr) { + iterRecvMsgThreadMap->second->join(); + delete iterRecvMsgThreadMap->second; + iterRecvMsgThreadMap->second = nullptr; + WIFI_LOGI("ForkExecParentProcess() destroy RecvThread success, ifname:%{public}s.\n", ifname.c_str()); + } + WIFI_LOGI("ForkExecParentProcess() m_mapDhcpRecvMsgThread erase ifname:%{public}s.\n", ifname.c_str()); + m_mapDhcpRecvMsgThread.erase(iterRecvMsgThreadMap); + } + } + + return DHCP_OPT_SUCCESS; +} + +pid_t DhcpClientServiceImpl::GetDhcpClientProPid(const std::string& ifname) +{ + if (ifname.empty()) { + WIFI_LOGE("GetDhcpClientProPid() error, ifname is empty!\n"); + return 0; + } + + auto iter = m_mapDhcpInfo.find(ifname); + if (iter == m_mapDhcpInfo.end()) { + WIFI_LOGI("GetDhcpClientProPid() m_mapDhcpInfo no find ifname:%{public}s.\n", ifname.c_str()); + return 0; + } + + std::string pidFile = DHCP_WORK_DIR + ifname + DHCP_CLIENT_PID_FILETYPE; + pid_t newPid = DhcpFunc::GetPID(pidFile); + if ((newPid > 0) && (newPid != (iter->second).clientProPid)) { + WIFI_LOGI("GetDhcpClientProPid() GetPID %{public}s new pid:%{public}d, old pid:%{public}d, need update.\n", + pidFile.c_str(), newPid, (iter->second).clientProPid); + m_mapDhcpInfo[ifname].clientProPid = newPid; + } + + WIFI_LOGI("GetDhcpClientProPid() m_mapDhcpInfo find ifname:%{public}s, pid:%{public}d.\n", + ifname.c_str(), m_mapDhcpInfo[ifname].clientProPid); + return m_mapDhcpInfo[ifname].clientProPid; +} + +int DhcpClientServiceImpl::StartDhcpClient(const std::string &ifname, bool bIpv6) +{ + if (ifname.empty()) { + WIFI_LOGE("DhcpClientServiceImpl::StartDhcpClient() error, ifname is empty!\n"); + return DHCP_OPT_FAILED; + } + + WIFI_LOGI("enter StartDhcpClient()...ifname:%{public}s, bIpv6:%{public}d.\n", ifname.c_str(), bIpv6); + + /* check config */ + /* check dhcp client service running status */ + int nStatus = GetDhcpStatus(ifname); + if (nStatus == 1) { + WIFI_LOGI("StartDhcpClient() running status:%{public}d, service already started, ifname:%{public}s.\n", + nStatus, ifname.c_str()); + /* reload config */ + return DHCP_OPT_SUCCESS; + } + + /* start dhcp client service */ + pid_t pid; + if ((pid = vfork()) < 0) { + WIFI_LOGE("StartDhcpClient() vfork() failed, pid:%{public}d.\n", pid); + return DHCP_OPT_FAILED; + } + if (pid == 0) { + /* Child process */ + ForkExecChildProcess(ifname, bIpv6, true); + } else { + /* Parent process */ + WIFI_LOGI("StartDhcpClient() vfork %{public}d success, parent:%{public}d, begin waitpid...\n", pid, getpid()); + pid_t pidRet = waitpid(pid, nullptr, 0); + if (pidRet == pid) { + WIFI_LOGI("StartDhcpClient() waitpid child:%{public}d success.\n", pid); + } else { + WIFI_LOGE("StartDhcpClient() waitpid child:%{public}d failed, pidRet:%{public}d!\n", pid, pidRet); + } + + return ForkExecParentProcess(ifname, bIpv6, true, pid); + } + + return DHCP_OPT_SUCCESS; +} + +int DhcpClientServiceImpl::StopDhcpClient(const std::string &ifname, bool bIpv6) +{ + if (ifname.empty()) { + WIFI_LOGE("DhcpClientServiceImpl::StopDhcpClient() error, ifname is empty!\n"); + return DHCP_OPT_FAILED; + } + + WIFI_LOGI("enter StopDhcpClient()...ifname:%{public}s, bIpv6:%{public}d.\n", ifname.c_str(), bIpv6); + + /* check dhcp client service running status */ + bool bExecParentProcess = true; + int nStatus = GetDhcpStatus(ifname); + if (nStatus == 0) { + WIFI_LOGI("StopDhcpClient() status:%{public}d, service already stopped, ifname:%{public}s.\n", + nStatus, ifname.c_str()); + return DHCP_OPT_SUCCESS; + } else if (nStatus == -1) { + WIFI_LOGI("StopDhcpClient() status:%{public}d, service not start or started, not need ExecParentProcess, " + "ifname:%{public}s.\n", nStatus, ifname.c_str()); + bExecParentProcess = false; + } + + /* stop dhcp client service */ + pid_t pid; + if ((pid = vfork()) < 0) { + WIFI_LOGE("StopDhcpClient() vfork() failed, pid:%{public}d.\n", pid); + return DHCP_OPT_FAILED; + } + if (pid == 0) { + /* Child process */ + ForkExecChildProcess(ifname, bIpv6); + return DHCP_OPT_SUCCESS; + } else { + /* Parent process */ + WIFI_LOGI("StopDhcpClient() vfork %{public}d success, parent:%{public}d, begin waitpid...\n", pid, getpid()); + pid_t pidRet = waitpid(pid, nullptr, 0); + if (pidRet == pid) { + WIFI_LOGI("StopDhcpClient() waitpid child:%{public}d success.\n", pid); + } else { + WIFI_LOGE("StopDhcpClient() waitpid child:%{public}d failed, pidRet:%{public}d!\n", pid, pidRet); + } + + return bExecParentProcess ? ForkExecParentProcess(ifname, bIpv6) : DHCP_OPT_SUCCESS; + } +} + +int DhcpClientServiceImpl::GetDhcpStatus(const std::string &ifname) +{ + if (ifname.empty()) { + WIFI_LOGE("DhcpClientServiceImpl::GetDhcpStatus() error, ifname is empty!\n"); + return -1; + } + + auto iter = m_mapDhcpInfo.find(ifname); + if (iter == m_mapDhcpInfo.end()) { + WIFI_LOGI("DhcpClientServiceImpl::GetDhcpStatus() m_mapDhcpInfo no find ifname:%{public}s.\n", ifname.c_str()); + return -1; + } + + WIFI_LOGI("GetDhcpStatus() m_mapDhcpInfo find ifname:%{public}s, clientRunStatus:%{public}d.\n", + ifname.c_str(), + (iter->second).clientRunStatus); + return (iter->second).clientRunStatus; +} + +int DhcpClientServiceImpl::GetDhcpResult(const std::string &ifname, IDhcpResultNotify *pResultNotify, int timeouts) +{ + if (ifname.empty()) { + WIFI_LOGE("DhcpClientServiceImpl::GetDhcpResult() error, ifname is empty!\n"); + return DHCP_OPT_FAILED; + } + + if (pResultNotify == nullptr) { + WIFI_LOGE("GetDhcpResult() ifname:%{public}s error, pResultNotify is nullptr!\n", ifname.c_str()); + return DHCP_OPT_FAILED; + } + + DhcpResultReq *pResultReq = new DhcpResultReq; + pResultReq->timeouts = timeouts; + pResultReq->getTimestamp = (uint32_t)time(NULL); + pResultReq->pResultNotify = pResultNotify; + + std::unique_lock lock(mResultNotifyMutex); + auto iter = m_mapDhcpResultNotify.find(ifname); + if (iter != m_mapDhcpResultNotify.end()) { + iter->second.push_back(pResultReq); + } else { + std::list listDhcpResultReq; + listDhcpResultReq.push_back(pResultReq); + m_mapDhcpResultNotify.emplace(std::make_pair(ifname, listDhcpResultReq)); + } + + WIFI_LOGI("GetDhcpResult() ifname:%{public}s,timeouts:%{public}d, result push_back!\n", ifname.c_str(), timeouts); + + return DHCP_OPT_SUCCESS; +} + +int DhcpClientServiceImpl::GetDhcpInfo(const std::string &ifname, DhcpServiceInfo &dhcp) +{ + if (ifname.empty()) { + WIFI_LOGE("DhcpClientServiceImpl::GetDhcpInfo() error, ifname is empty!\n"); + return DHCP_OPT_FAILED; + } + + auto iter = m_mapDhcpInfo.find(ifname); + if (iter != m_mapDhcpInfo.end()) { + dhcp = iter->second; + } else { + WIFI_LOGE("GetDhcpInfo() failed, m_mapDhcpInfo no find ifname:%{public}s.\n", ifname.c_str()); + } + + return DHCP_OPT_SUCCESS; +} + +int DhcpClientServiceImpl::RenewDhcpClient(const std::string &ifname) +{ + WIFI_LOGI("enter DhcpClientServiceImpl::RenewDhcpClient()...ifname:%{public}s.\n", ifname.c_str()); + int nStatus = GetDhcpStatus(ifname); + if (nStatus != 1) { + WIFI_LOGW("RenewDhcpClient() dhcp client service not started, now start ifname:%{public}s.\n", ifname.c_str()); + + /* Start dhcp client service */ + return StartDhcpClient(ifname, m_mapDhcpInfo[ifname].enableIPv6); + } + + /* Send dhcp renew packet : kill -USR2 */ + pid_t pid = GetDhcpClientProPid(ifname); + if (pid <= 0) { + WIFI_LOGW("RenewDhcpClient() dhcp client process pid:%{public}d error, ifname:%{public}s!\n", + pid, ifname.c_str()); + return DHCP_OPT_FAILED; + } + + if (kill(pid, SIGUSR2) == -1) { + WIFI_LOGE("RenewDhcpClient() kill [%{public}d] failed:%{public}s, ifname:%{public}s!\n", + pid, strerror(errno), ifname.c_str()); + return DHCP_OPT_FAILED; + } + WIFI_LOGI("RenewDhcpClient() kill [%{public}d] success, ifname:%{public}s.\n", pid, ifname.c_str()); + return DHCP_OPT_SUCCESS; +} + +int DhcpClientServiceImpl::ReleaseDhcpClient(const std::string &ifname) +{ + WIFI_LOGI("enter DhcpClientServiceImpl::ReleaseDhcpClient()...ifname:%{public}s.\n", ifname.c_str()); + int nStatus = GetDhcpStatus(ifname); + if (nStatus != 1) { + WIFI_LOGE("ReleaseDhcpClient() failed, dhcp client service not started, ifname:%{public}s!\n", ifname.c_str()); + return DHCP_OPT_FAILED; + } + + /* Send dhcp release packet : kill -USR1 */ + pid_t pid = GetDhcpClientProPid(ifname); + if (pid <= 0) { + WIFI_LOGW("ReleaseDhcpClient() dhcp client process pid:%{public}d error, ifname:%{public}s!\n", + pid, ifname.c_str()); + return DHCP_OPT_FAILED; + } + + if (kill(pid, SIGUSR1) == -1) { + WIFI_LOGE("ReleaseDhcpClient() kill [%{public}d] failed:%{public}s, ifname:%{public}s!\n", + pid, strerror(errno), ifname.c_str()); + return DHCP_OPT_FAILED; + } + WIFI_LOGI("ReleaseDhcpClient() kill [%{public}d] success, ifname:%{public}s.\n", pid, ifname.c_str()); + return DHCP_OPT_SUCCESS; +} +} // namespace Wifi +} // namespace OHOS diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_func.cpp b/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_func.cpp new file mode 100644 index 000000000..33eab64f5 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_func.cpp @@ -0,0 +1,561 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "dhcp_func.h" + +#include +#include +#include +#include +#include +#include + +#include "securec.h" +#include "wifi_logger.h" + +DEFINE_WIFILOG_DHCP_LABEL("DhcpFunc"); + +namespace OHOS { +namespace Wifi { +std::string DhcpFunc::IpToDot(unsigned int nIp) +{ + in_addr addr; + addr.s_addr = htonl(nIp); + std::string strip = inet_ntoa(addr); + return strip; +} + +unsigned int DhcpFunc::IPtoInt(const std::string& strIp) +{ + in_addr addr; + unsigned int intIp = 0; + if (inet_aton(strIp.c_str(), &addr) == 1) { + intIp = ntohl(addr.s_addr); + } + return intIp; +} + +bool DhcpFunc::Ip4StrConToInt(const std::string& strIp, uint32_t& uIp) +{ + if (strIp.empty()) { + WIFI_LOGE("Ip4StrConToInt error, strIp is empty()!\n"); + return false; + } + + struct in_addr addr4; + int nRet = inet_pton(AF_INET, strIp.c_str(), &addr4); + if (nRet != 1) { + WIFI_LOGE("Ip4StrConToInt strIp:%{public}s failed, nRet:%{public}d!\n", strIp.c_str(), nRet); + if (nRet == 0) { + WIFI_LOGE("Ip4StrConToInt strIp:%{public}s not in presentation format!\n", strIp.c_str()); + } else { + WIFI_LOGE("Ip4StrConToInt strIp:%{public}s inet_pton not contain a valid address!\n", strIp.c_str()); + } + return false; + } + + uIp = ntohl(addr4.s_addr); + WIFI_LOGI("Ip4StrConToInt strIp:%{public}s -> uIp:%{public}u.\n", strIp.c_str(), uIp); + + return true; +} + +std::string DhcpFunc::Ip4IntConToStr(uint32_t uIp) +{ + if (uIp == 0) { + WIFI_LOGE("Ip4IntConToStr uIp is 0!\n"); + return NULL; + } + + std::string strIp = ""; + char bufIp4[INET_ADDRSTRLEN] = {0}; + struct in_addr addr4; + addr4.s_addr = htonl(uIp); + if (inet_ntop(AF_INET, &addr4, bufIp4, INET_ADDRSTRLEN) == NULL) { + WIFI_LOGE("Ip4IntConToStr uIp:%{public}u failed, inet_ntop NULL!\n", uIp); + } else { + strIp = bufIp4; + WIFI_LOGI("Ip4IntConToStr uIp:%{public}u -> strIp:%{public}s.\n", uIp, strIp.c_str()); + } + + return strIp; +} + +bool DhcpFunc::Ip6StrConToChar(const std::string& strIp, uint8_t chIp[]) +{ + if (strIp.empty()) { + WIFI_LOGE("Ip6StrConToChar param error, strIp is empty()!\n"); + return false; + } + + struct in6_addr addr6; + if (memset_s(&addr6, sizeof(addr6), 0, sizeof(addr6)) != EOK) { + return false; + } + int nRet = inet_pton(AF_INET6, strIp.c_str(), &addr6); + if (nRet != 1) { + WIFI_LOGE("Ip6StrConToChar inet_pton strIp:%{public}s failed, nRet:%{public}d!\n", strIp.c_str(), nRet); + if (nRet == 0) { + WIFI_LOGE("Ip6StrConToChar strIp:%{public}s not in presentation format!\n", strIp.c_str()); + } else { + WIFI_LOGE("Ip6StrConToChar strIp:%{public}s inet_pton not contain a valid address!\n", strIp.c_str()); + } + return false; + } + + for (size_t i = 0; i < sizeof(struct in6_addr); i++) { + chIp[i] = addr6.s6_addr[i]; + } + + return true; +} + +std::string DhcpFunc::Ip6CharConToStr(uint8_t chIp[], int size) +{ + if (size <= 0) { + WIFI_LOGE("Ip6CharConToStr param error, size:%{public}d!\n", size); + return ""; + } + + std::string strIp = ""; + char bufIp6[INET6_ADDRSTRLEN] = {0}; + struct in6_addr addr6; + if (memcpy_s(addr6.s6_addr, sizeof(addr6.s6_addr), &chIp, size) != EOK) { + return ""; + } + if (inet_ntop(AF_INET6, &addr6, bufIp6, INET6_ADDRSTRLEN) == NULL) { + WIFI_LOGE("Ip6CharConToStr chIp failed, inet_ntop NULL!\n"); + } else { + strIp = bufIp6; + WIFI_LOGI("Ip6CharConToStr chIp -> strIp:%{public}s.\n", strIp.c_str()); + } + + return strIp; +} + +bool DhcpFunc::CheckIpStr(const std::string& strIp) +{ + if (strIp.empty()) { + WIFI_LOGE("CheckIpStr param error, strIp is empty()!\n"); + return false; + } + + bool bIp4 = false; + bool bIp6 = false; + std::string::size_type idx = strIp.find(IP4_SEPARATOR); + if (idx != std::string::npos) { + bIp4 = true; + } + idx = strIp.find(IP6_SEPARATOR); + if (idx != std::string::npos) { + bIp6 = true; + } + if ((!bIp4 && !bIp6) || (bIp4 && bIp6)) { + WIFI_LOGE("CheckIpStr strIp:%{public}s error, bIp4:%{public}d,bIp6:%{public}d!\n", strIp.c_str(), bIp4, bIp6); + return false; + } + + if (bIp4) { + uint32_t uIp = 0; + if (!Ip4StrConToInt(strIp, uIp)) { + WIFI_LOGE("CheckIpStr Ip4StrConToInt failed, strIp:%{public}s.\n", strIp.c_str()); + return false; + } + } else { + uint8_t addr6[sizeof(struct in6_addr)] = {0}; + if (!Ip6StrConToChar(strIp, addr6)) { + WIFI_LOGE("CheckIpStr Ip6StrConToChar failed, strIp:%{public}s.\n", strIp.c_str()); + return false; + } + } + + return true; +} + +int DhcpFunc::GetLocalIp(const std::string ethInf, std::string& localIp) +{ + int sd; + struct sockaddr_in sin; + struct ifreq ifr; + + sd = socket(AF_INET, SOCK_DGRAM, 0); + if (-1 == sd) { + WIFI_LOGE("GetLocalIp socket ethInf:%{public}s,strerror:%{public}s!\n", ethInf.c_str(), strerror(errno)); + return -1; + } + + if (strncpy_s(ifr.ifr_name, IFNAMSIZ, ethInf.c_str(), IFNAMSIZ - 1) != EOK) { + return -1; + } + ifr.ifr_name[IFNAMSIZ - 1] = 0; + + // if error: No such device + if (ioctl(sd, SIOCGIFADDR, &ifr) < 0) { + WIFI_LOGE("GetLocalIp ioctl ethInf:%{public}s,strerror:%{public}s!\n", ethInf.c_str(), strerror(errno)); + close(sd); + return -1; + } + + if (memcpy_s(&sin, sizeof(sin), &ifr.ifr_addr, sizeof(sin)) != EOK) { + return -1; + } + char ip[IP_SIZE] = { 0 }; + if (snprintf_s(ip, IP_SIZE, IP_SIZE - 1, "%{public}s", inet_ntoa(sin.sin_addr)) < 0) { + WIFI_LOGE("GetLocalIp snprintf_s ethInf:%{public}s,strerror:%{public}s!\n", ethInf.c_str(), strerror(errno)); + close(sd); + return -1; + } + localIp = ip; + close(sd); + return 0; +} + +int DhcpFunc::GetLocalMac(const std::string ethInf, std::string& ethMac) +{ + struct ifreq ifr; + int sd = 0; + + bzero(&ifr, sizeof(struct ifreq)); + if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + WIFI_LOGE("GetLocalMac socket ethInf:%{public}s,strerror:%{public}s!\n", ethInf.c_str(), strerror(errno)); + return -1; + } + + if (strncpy_s(ifr.ifr_name, IFNAMSIZ, ethInf.c_str(), IFNAMSIZ - 1) != EOK) { + return -1; + } + + if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0) { + WIFI_LOGE("GetLocalMac ioctl ethInf:%{public}s,strerror:%{public}s!\n", ethInf.c_str(), strerror(errno)); + close(sd); + return -1; + } + + char mac[ETH_MAC_ADDR_LEN * ETH_MAC_ADDR_CHAR_NUM] = { 0 }; + int nRes = snprintf_s(mac, + ETH_MAC_ADDR_LEN * ETH_MAC_ADDR_CHAR_NUM, + ETH_MAC_ADDR_LEN * ETH_MAC_ADDR_CHAR_NUM - 1, + "%02x:%02x:%02x:%02x:%02x:%02x", + (unsigned char)ifr.ifr_hwaddr.sa_data[ETH_MAC_ADDR_INDEX_0], + (unsigned char)ifr.ifr_hwaddr.sa_data[ETH_MAC_ADDR_INDEX_1], + (unsigned char)ifr.ifr_hwaddr.sa_data[ETH_MAC_ADDR_INDEX_2], + (unsigned char)ifr.ifr_hwaddr.sa_data[ETH_MAC_ADDR_INDEX_3], + (unsigned char)ifr.ifr_hwaddr.sa_data[ETH_MAC_ADDR_INDEX_4], + (unsigned char)ifr.ifr_hwaddr.sa_data[ETH_MAC_ADDR_INDEX_5]); + if (nRes < 0) { + WIFI_LOGE("GetLocalMac snprintf_s ethInf:%{public}s,strerror:%{public}s!\n", ethInf.c_str(), strerror(errno)); + close(sd); + return -1; + } + ethMac = mac; + close(sd); + return 0; +} + +bool DhcpFunc::IsExistFile(const std::string& filename) +{ + bool bExist = false; + std::fstream ioFile; + ioFile.open(filename.c_str(), std::ios::in); + if (ioFile) { + bExist = true; + } + ioFile.close(); + + return bExist; +} + +bool DhcpFunc::CreateFile(const std::string& filename, const std::string& filedata) +{ + std::ofstream outFile; + outFile.open(filename.c_str()); + outFile.flush(); + outFile << filedata << std::endl; + outFile.close(); + return true; +} + +bool DhcpFunc::RemoveFile(const std::string& filename) +{ + if (std::remove(filename.c_str()) != 0) { + WIFI_LOGE("RemoveFile filename:%{public}s failed!\n", filename.c_str()); + return false; + } + WIFI_LOGI("RemoveFile filename:%{public}s success.\n", filename.c_str()); + return true; +} + +bool DhcpFunc::AddFileLineData(const std::string& filename, const std::string& prevdata, const std::string& linedata) +{ + bool bAdd = false; + std::ifstream inFile; + inFile.open(filename.c_str()); + std::string strFileData = ""; + std::string strTemp = ""; + char tmpLineData[1024] = {0}; + while (inFile.getline(tmpLineData, sizeof(tmpLineData))) { + strTemp = tmpLineData; + strFileData += strTemp; + strFileData += "\n"; + if (strTemp == prevdata) { + strFileData += linedata; + bAdd = true; + } + } + inFile.close(); + + if (bAdd) { + std::ofstream outFile; + outFile.open(filename.c_str()); + outFile.flush(); + WIFI_LOGI("AddFileLineData Reflush filename:%{public}s, strFileData:%{public}s.\n", + filename.c_str(), strFileData.c_str()); + outFile << strFileData; + outFile.close(); + } + return true; +} + +bool DhcpFunc::DelFileLineData(const std::string& filename, const std::string& linedata) +{ + bool bDel = false; + std::ifstream inFile; + inFile.open(filename.c_str()); + std::string strFileData = ""; + std::string strTemp = ""; + char tmpLineData[1024] = {0}; + while (inFile.getline(tmpLineData, sizeof(tmpLineData))) { + strTemp = tmpLineData; + if (strTemp != linedata) { + strFileData += strTemp; + strFileData += "\n"; + } else { + bDel = true; + } + } + inFile.close(); + + if (bDel) { + std::ofstream outFile; + outFile.open(filename.c_str()); + outFile.flush(); + WIFI_LOGI("DelFileLineData Reflush filename:%{public}s, strFileData:%{public}s.\n", + filename.c_str(), strFileData.c_str()); + outFile << strFileData; + outFile.close(); + } + return true; +} + +bool DhcpFunc::ModifyFileLineData(const std::string& filename, const std::string& srcdata, const std::string& dstdata) +{ + bool bModify = false; + std::ifstream inFile; + inFile.open(filename.c_str()); + std::string strFileData = ""; + std::string strTemp = ""; + char tmpLineData[1024] = {0}; + while (inFile.getline(tmpLineData, sizeof(tmpLineData))) { + strTemp = tmpLineData; + if (strTemp != srcdata) { + strFileData += strTemp; + strFileData += "\n"; + } else { + strFileData += dstdata; + strFileData += "\n"; + bModify = true; + } + } + inFile.close(); + + if (bModify) { + std::ofstream outFile; + outFile.open(filename.c_str()); + outFile.flush(); + WIFI_LOGI("ModifyFileLineData Reflush filename:%{public}s, strFileData:%{public}s.\n", + filename.c_str(), strFileData.c_str()); + outFile << strFileData; + outFile.close(); + } + return true; +} + +int DhcpFunc::FormatString(struct DhcpPacketResult &result) +{ + if (strncmp(result.strYiaddr, "*", 1) == 0) { + if (memset_s(result.strYiaddr, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) { + return -1; + } + } + if (strncmp(result.strOptServerId, "*", 1) == 0) { + if (memset_s(result.strOptServerId, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) { + return -1; + } + } + if (strncmp(result.strOptSubnet, "*", 1) == 0) { + if (memset_s(result.strOptSubnet, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) { + return -1; + } + } + if (strncmp(result.strOptDns1, "*", 1) == 0) { + if (memset_s(result.strOptDns1, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) { + return -1; + } + } + if (strncmp(result.strOptDns2, "*", 1) == 0) { + if (memset_s(result.strOptDns2, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) { + return -1; + } + } + if (strncmp(result.strOptRouter1, "*", 1) == 0) { + if (memset_s(result.strOptRouter1, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) { + return -1; + } + } + if (strncmp(result.strOptRouter2, "*", 1) == 0) { + if (memset_s(result.strOptRouter2, INET_ADDRSTRLEN, 0, INET_ADDRSTRLEN) != EOK) { + return -1; + } + } + if (strncmp(result.strOptVendor, "*", 1) == 0) { + if (memset_s(result.strOptVendor, DHCP_FILE_MAX_BYTES, 0, DHCP_FILE_MAX_BYTES) != EOK) { + return -1; + } + } + return 0; +} + +int DhcpFunc::GetDhcpPacketResult(const std::string& filename, struct DhcpPacketResult &result) +{ + FILE *pFile = fopen(filename.c_str(), "r"); + if (pFile == nullptr) { + WIFI_LOGE("GetDhcpPacketResult() fopen %{public}s fail, err:%{public}s!\n", filename.c_str(), strerror(errno)); + return DHCP_OPT_FAILED; + } + + char strIpFlag[DHCP_NUMBER_EIGHT]; + if (memset_s(strIpFlag, sizeof(strIpFlag), 0, sizeof(strIpFlag)) != EOK) { + return DHCP_OPT_FAILED; + } + /* Format: IpFlag AddTime cliIp servIp subnet dns1 dns2 router1 router2 vendor lease */ + int nRes = fscanf_s(pFile, "%s %u %s %s %s %s %s %s %s %s %u\n", strIpFlag, DHCP_NUMBER_EIGHT, &result.uAddTime, + result.strYiaddr, INET_ADDRSTRLEN, result.strOptServerId, INET_ADDRSTRLEN, result.strOptSubnet, INET_ADDRSTRLEN, + result.strOptDns1, INET_ADDRSTRLEN, result.strOptDns2, INET_ADDRSTRLEN, result.strOptRouter1, INET_ADDRSTRLEN, + result.strOptRouter2, INET_ADDRSTRLEN, result.strOptVendor, DHCP_FILE_MAX_BYTES, &result.uOptLeasetime); + if (nRes == EOF) { + WIFI_LOGE("GetDhcpPacketResult() fscanf %{public}s err:%{public}s!\n", filename.c_str(), strerror(errno)); + fclose(pFile); + return DHCP_OPT_FAILED; + } else if (nRes == 0) { + WIFI_LOGW("GetDhcpPacketResult() fscanf file:%{public}s nRes:0 NULL!\n", filename.c_str()); + fclose(pFile); + return DHCP_OPT_NULL; + } else if (nRes != DHCP_RESULT_NUM) { + WIFI_LOGE("GetDhcpPacketResult() fscanf file:%{public}s nRes:%{public}d ERROR!\n", filename.c_str(), nRes); + fclose(pFile); + return DHCP_OPT_FAILED; + } + + if (fclose(pFile) != 0) { + WIFI_LOGE("GetDhcpPacketResult() fclose file:%{public}s failed, error:%{public}s!\n", + filename.c_str(), strerror(errno)); + return DHCP_OPT_FAILED; + } + + /* Format dhcp packet result */ + if (FormatString(result) != 0) { + WIFI_LOGE("GetDhcpPacketResult() file:%{public}s failed, FormatString result error!\n", filename.c_str()); + return DHCP_OPT_FAILED; + } + + return DHCP_OPT_SUCCESS; +} + +int DhcpFunc::InitPidfile(const std::string& piddir, const std::string& pidfile) +{ + if (piddir.empty() || pidfile.empty()) { + WIFI_LOGE("InitPidfile() failed, piddir or pidfile is empty!\n"); + return DHCP_OPT_FAILED; + } + WIFI_LOGI("InitPidfile() piddir:%{public}s, pidfile:%{public}s.\n", piddir.c_str(), pidfile.c_str()); + unlink(pidfile.c_str()); + + int fd; + if ((fd = open(pidfile.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) { + WIFI_LOGE("InitPidfile() failed, open pidfile:%{public}s err:%{public}s!\n", pidfile.c_str(), strerror(errno)); + return DHCP_OPT_FAILED; + } + + char buf[PID_MAX_LEN] = {0}; + if (snprintf(buf, PID_MAX_LEN, "%d", getpid()) < 0) { + WIFI_LOGE("InitPidfile() %{public}s failed, snprintf error:%{public}s!\n", pidfile.c_str(), strerror(errno)); + close(fd); + return DHCP_OPT_FAILED; + } + ssize_t bytes; + if ((bytes = write(fd, buf, strlen(buf))) <= 0) { + WIFI_LOGE("InitPidfile() failed, write pidfile:%{public}s error:%{public}s, bytes:%{public}zu!\n", + pidfile.c_str(), strerror(errno), bytes); + close(fd); + return DHCP_OPT_FAILED; + } + WIFI_LOGI("InitPidfile() pid:%{public}s write %{public}s, bytes:%{public}zu!\n", buf, pidfile.c_str(), bytes); + close(fd); + + if (chdir(piddir.c_str()) != 0) { + WIFI_LOGE("InitPidfile() failed, chdir piddir:%{public}s err:%{public}s!\n", piddir.c_str(), strerror(errno)); + return DHCP_OPT_FAILED; + } + + /* Set default permissions for the specified client process id files and directories. */ + umask(DEFAULT_UMASK); + + /* Change attribs to the specified client process id files: 644 (user=rw, group=r, other=r). */ + chmod(pidfile.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + + return DHCP_OPT_SUCCESS; +} + +pid_t DhcpFunc::GetPID(const std::string& pidfile) +{ + /* Check pidfile is or not exists. */ + struct stat sb; + if (stat(pidfile.c_str(), &sb) != 0) { + WIFI_LOGW("GetPID() pidfile:%{public}s stat:%{public}s!\n", pidfile.c_str(), strerror(errno)); + return -1; + } + WIFI_LOGI("GetPID() pidfile:%{public}s stat st_size:%{public}d.\n", pidfile.c_str(), (int)sb.st_size); + + int fd; + if ((fd = open(pidfile.c_str(), O_RDONLY)) < 0) { + WIFI_LOGE("GetPID() failed, open pidfile:%{public}s error!\n", pidfile.c_str()); + return -1; + } + + lseek(fd, 0, SEEK_SET); + + char buf[PID_MAX_LEN] = {0}; + ssize_t bytes; + if ((bytes = read(fd, buf, sb.st_size)) < 0) { + WIFI_LOGE("GetPID() failed, read pidfile:%{public}s error, bytes:%{public}zu!\n", pidfile.c_str(), bytes); + close(fd); + return -1; + } + WIFI_LOGI("GetPID() read pidfile:%{public}s, buf:%{public}s, bytes:%{public}zu.\n", pidfile.c_str(), buf, bytes); + close(fd); + + return atoi(buf); +} +} // namespace Wifi +} // namespace OHOS \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_server_service_impl.cpp b/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_server_service_impl.cpp new file mode 100644 index 000000000..edd37a0cc --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_server_service_impl.cpp @@ -0,0 +1,896 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "dhcp_server_service_impl.h" + +#include + +#include "dhcp_func.h" +#include "wifi_logger.h" + +DEFINE_WIFILOG_DHCP_LABEL("DhcpServerServiceImpl"); + +namespace OHOS { +namespace Wifi { +bool DhcpServerServiceImpl::mProExitSig = false; +bool DhcpServerServiceImpl::mStopServer = false; +pid_t DhcpServerServiceImpl::mPidDhcpServer = 0; + +DhcpServerServiceImpl::DhcpServerServiceImpl() +{ + WIFI_LOGI("DhcpServerServiceImpl::DhcpServerServiceImpl()...\n"); + m_setInterfaces.clear(); + m_mapTagDhcpRange.clear(); + m_mapInfDhcpRange.clear(); + m_mapDhcpSerExitNotify.clear(); + bDhcpSerProExitThread = false; + pDhcpSerProExitThread = nullptr; +} + +DhcpServerServiceImpl::~DhcpServerServiceImpl() +{ + WIFI_LOGI("DhcpServerServiceImpl::~DhcpServerServiceImpl()...\n"); + auto iterInterfaces = m_setInterfaces.begin(); + while (iterInterfaces != m_setInterfaces.end()) { + if (StopDhcpServer(*iterInterfaces) != DHCP_OPT_SUCCESS) { + WIFI_LOGE("~StartDhcpServer() StopDhcpServer ifname:%{public}s failed!\n", (*iterInterfaces).c_str()); + } else { + WIFI_LOGW("~StartDhcpServer() StopDhcpServer ifname:%{public}s success.\n", (*iterInterfaces).c_str()); + } + m_setInterfaces.erase(iterInterfaces++); + } + + ExitDhcpMgrThreadFunc(); +} + +int DhcpServerServiceImpl::StartDhcpServer(const std::string &ifname) +{ + if (ifname.empty()) { + WIFI_LOGE("DhcpServerServiceImpl::StartDhcpServer() error, ifname is empty!\n"); + return DHCP_OPT_FAILED; + } + + WIFI_LOGI("enter DhcpServerServiceImpl::StartDhcpServer()...ifname:%{public}s.\n", ifname.c_str()); + + /* check and update interface config file */ + if (CheckAndUpdateConf(ifname) != DHCP_OPT_SUCCESS) { + WIFI_LOGE("StartDhcpServer() CheckAndUpdateConf failed, ifname:%{public}s.\n", ifname.c_str()); + return DHCP_OPT_FAILED; + } + + /* Add the specified interface. */ + if (AddSpecifiedInterface(ifname) != DHCP_OPT_SUCCESS) { + WIFI_LOGE("StartDhcpServer() AddSpecifiedInterface failed, ifname:%{public}s.\n", ifname.c_str()); + return DHCP_OPT_FAILED; + } + + if (mPidDhcpServer != 0) { + WIFI_LOGI("StartDhcpServer() ifname:%{public}s, pro:%{public}s already started, pid:%{public}d, reload config.", + ifname.c_str(), + DHCP_SERVER_FILE.c_str(), + mPidDhcpServer); + + /* reload dhcp server config */ + return ReConf(); + } + + /* start dhcp server process */ + pid_t pid_server; + if ((pid_server = vfork()) < 0) { + WIFI_LOGE("StartDhcpServer() vfork() failed, pid_server:%{public}d!\n", pid_server); + return DHCP_OPT_FAILED; + } + if (pid_server == 0) { + /* Child process */ + ForkExecProcess(ifname); + } else { + /* Parent process */ + mProExitSig = false; + mStopServer = false; + mPidDhcpServer = pid_server; + ForkParentProcess(); + } + + return DHCP_OPT_SUCCESS; +} + +int DhcpServerServiceImpl::StopDhcpServer(const std::string &ifname) +{ + if (ifname.empty()) { + WIFI_LOGE("StopDhcpServer() error, ifname is empty!\n"); + return DHCP_OPT_FAILED; + } + if (mPidDhcpServer == 0) { + WIFI_LOGI("StopDhcpServer() %{public}s, %{public}s already stop.\n", ifname.c_str(), DHCP_SERVER_FILE.c_str()); + return DHCP_OPT_SUCCESS; + } + bool bStopDhcpServer = false; + bool bReloadServerCfg = false; + if (m_mapInfDhcpRange.empty()) { + bStopDhcpServer = true; + } else { + auto iterRangeMap = m_mapInfDhcpRange.find(ifname); + if (iterRangeMap != m_mapInfDhcpRange.end()) { + std::string strInfFile = DHCP_SERVER_CONFIG_DIR + ifname + ".conf"; + if (DeleteInfConf(strInfFile) != DHCP_OPT_SUCCESS) { + WIFI_LOGE("StopDhcpServer() DeleteInfConf failed, ifname:%{public}s.\n", ifname.c_str()); + return DHCP_OPT_FAILED; + } + + if (m_mapInfDhcpRange.size() == 1) { + WIFI_LOGI("StopDhcpServer() ifname:%{public}s, only the if service, now StopServer.\n", ifname.c_str()); + bStopDhcpServer = true; + } else { + bReloadServerCfg = true; + } + m_mapInfDhcpRange.erase(iterRangeMap); + } + } + if (RemoveAllDhcpRange(ifname) != DHCP_OPT_SUCCESS) { + return DHCP_OPT_FAILED; + } + if (bStopDhcpServer) { + if (StopServer(mPidDhcpServer) != DHCP_OPT_SUCCESS) { + return DHCP_OPT_FAILED; + } + mPidDhcpServer = 0; + } else { + /* reload dhcp server config */ + if (bReloadServerCfg && (ReConf() != DHCP_OPT_SUCCESS)) { + WIFI_LOGE("StopDhcpServer() ReConf failed, ifname:%{public}s.\n", ifname.c_str()); + return DHCP_OPT_FAILED; + } + } + + /* Del the specified interface. */ + if (DelSpecifiedInterface(ifname) != DHCP_OPT_SUCCESS) { + return DHCP_OPT_FAILED; + } + return DHCP_OPT_SUCCESS; +} + +int DhcpServerServiceImpl::GetServerStatus() +{ + if (mPidDhcpServer == 0) { + WIFI_LOGI("GetServerStatus() pro:%{public}s not start.\n", DHCP_SERVER_FILE.c_str()); + return 0; + } + WIFI_LOGI("GetServerStatus() pro:%{public}s normal started.\n", DHCP_SERVER_FILE.c_str()); + return 1; +} + +int DhcpServerServiceImpl::PutDhcpRange(const std::string &tagName, const DhcpRange &range) +{ + if (tagName.empty()) { + WIFI_LOGE("DhcpServerServiceImpl::PutDhcpRange() error, tagName is empty!\n"); + return DHCP_OPT_FAILED; + } + if ((range.iptype == -1) || range.strStartip.empty() || range.strEndip.empty()) { + WIFI_LOGE("PutDhcpRange() tagName:%{public}s failed, range.iptype:%{public}d or strStartip:%{public}s or " + "strEndip:%{public}s error!\n", + tagName.c_str(), + range.iptype, + range.strStartip.c_str(), + range.strEndip.c_str()); + return DHCP_OPT_FAILED; + } + + WIFI_LOGI("enter PutDhcpRange() tagName:%{public}s.\n", tagName.c_str()); + + /* check invalid and already exist in dhcp range */ + if (!CheckIpAddrRange(range)) { + WIFI_LOGE("PutDhcpRange() CheckIpAddrRange failed, tagName:%{public}s!\n", tagName.c_str()); + return DHCP_OPT_FAILED; + } + + /* add dhcp range */ + auto iterRangeMap = m_mapTagDhcpRange.find(tagName); + if (iterRangeMap != m_mapTagDhcpRange.end()) { + for (auto iterRange : iterRangeMap->second) { + if ((iterRange.iptype == range.iptype) && (iterRange.strStartip == range.strStartip) && + (iterRange.strEndip == range.strEndip)) { + WIFI_LOGE("PutDhcpRange() tagName:%{public}s failed, " + "range.iptype:%{public}d,strStartip:%{public}s,strEndip:%{public}s already exist!\n", + tagName.c_str(), + range.iptype, + range.strStartip.c_str(), + range.strEndip.c_str()); + return DHCP_OPT_FAILED; + } + } + iterRangeMap->second.push_back(range); + WIFI_LOGI("PutDhcpRange() m_mapTagDhcpRange find tagName:%{public}s, need push_back.\n", tagName.c_str()); + } else { + std::list listDhcpRange; + listDhcpRange.push_back(range); + m_mapTagDhcpRange.emplace(std::make_pair(tagName, listDhcpRange)); + WIFI_LOGI("PutDhcpRange() m_mapTagDhcpRange no find tagName:%{public}s, need emplace.\n", tagName.c_str()); + } + + return DHCP_OPT_SUCCESS; +} + +int DhcpServerServiceImpl::RemoveDhcpRange(const std::string &tagName, const DhcpRange &range) +{ + if (tagName.empty()) { + WIFI_LOGE("DhcpServerServiceImpl::RemoveDhcpRange() error, tagName is empty!\n"); + return DHCP_OPT_FAILED; + } + if ((range.iptype == -1) || range.strStartip.empty() || range.strEndip.empty()) { + WIFI_LOGE("RemoveDhcpRange() tagName:%{public}s failed, range.iptype:%{public}d or strStartip:%{public}s or " + "strEndip:%{public}s error!\n", + tagName.c_str(), + range.iptype, + range.strStartip.c_str(), + range.strEndip.c_str()); + return DHCP_OPT_FAILED; + } + + /* remove dhcp range */ + auto iterRangeMap = m_mapTagDhcpRange.find(tagName); + if (iterRangeMap != m_mapTagDhcpRange.end()) { + auto iterRange = m_mapTagDhcpRange[tagName].begin(); + while (iterRange != m_mapTagDhcpRange[tagName].end()) { + if ((iterRange->iptype == range.iptype) && (iterRange->strStartip == range.strStartip) && + (iterRange->strEndip == range.strEndip)) { + m_mapTagDhcpRange[tagName].erase(iterRange++); + WIFI_LOGI("RemoveDhcpRange() find tagName:%{public}s, " + "range.iptype:%{public}d,strStartip:%{public}s,strEndip:%{public}s, erase.\n", + tagName.c_str(), + range.iptype, + range.strStartip.c_str(), + range.strEndip.c_str()); + return DHCP_OPT_SUCCESS; + } + iterRange++; + } + WIFI_LOGE("RemoveDhcpRange() find tagName:%{public}s, second no find range, erase failed!\n", tagName.c_str()); + } else { + WIFI_LOGE("RemoveDhcpRange no find tagName:%{public}s, erase failed!\n", tagName.c_str()); + } + + return DHCP_OPT_FAILED; +} + +int DhcpServerServiceImpl::RemoveAllDhcpRange(const std::string &tagName) +{ + if (tagName.empty()) { + WIFI_LOGE("DhcpServerServiceImpl::RemoveAllDhcpRange() error, tagName is empty!\n"); + return DHCP_OPT_FAILED; + } + + /* remove all dhcp range */ + auto iterRangeMap = m_mapTagDhcpRange.find(tagName); + if (iterRangeMap != m_mapTagDhcpRange.end()) { + m_mapTagDhcpRange.erase(iterRangeMap); + WIFI_LOGI("RemoveAllDhcpRange() find tagName:%{public}s, erase success.\n", tagName.c_str()); + } else { + WIFI_LOGI("RemoveAllDhcpRange() no find tagName:%{public}s, not need erase!\n", tagName.c_str()); + } + + return DHCP_OPT_SUCCESS; +} + +int DhcpServerServiceImpl::SetDhcpRange(const std::string &ifname, const DhcpRange &range) +{ + if (ifname.empty()) { + WIFI_LOGE("DhcpServerServiceImpl::SetDhcpRange() error, ifname is empty!\n"); + return DHCP_OPT_FAILED; + } + if ((range.iptype == -1) || range.strStartip.empty() || range.strEndip.empty()) { + WIFI_LOGE("SetDhcpRange() ifname:%{public}s failed, range.iptype:%{public}d or strStartip:%{public}s or " + "strEndip:%{public}s error!\n", + ifname.c_str(), range.iptype, range.strStartip.c_str(), range.strEndip.c_str()); + return DHCP_OPT_FAILED; + } + + /* check dhcp server service status */ + int nStatus = GetServerStatus(); + if (nStatus != 1) { + WIFI_LOGE("SetDhcpRange() ifname:%{public}s failed, dhcp status:%{public}d error!\n", ifname.c_str(), nStatus); + return DHCP_OPT_FAILED; + } + + /* put dhcp range */ + if (PutDhcpRange(ifname, range) != DHCP_OPT_SUCCESS) { + WIFI_LOGE("SetDhcpRange() PutDhcpRange failed, ifname:%{public}s.\n", ifname.c_str()); + return DHCP_OPT_FAILED; + } + + /* check and add dhcp range */ + auto iterRangeMap = m_mapInfDhcpRange.find(ifname); + if (iterRangeMap != m_mapInfDhcpRange.end()) { + for (auto iterRange : iterRangeMap->second) { + if ((iterRange.iptype == range.iptype) && (iterRange.strStartip == range.strStartip) && + (iterRange.strEndip == range.strEndip)) { + WIFI_LOGE("SetDhcpRange() ifname:%{public}s failed, " + "range.iptype:%{public}d,strStartip:%{public}s,strEndip:%{public}s already exist!\n", + ifname.c_str(), range.iptype, range.strStartip.c_str(), range.strEndip.c_str()); + return DHCP_OPT_FAILED; + } + } + iterRangeMap->second.push_back(range); + WIFI_LOGI("SetDhcpRange() m_mapInfDhcpRange find ifname:%{public}s, second need push_back.\n", ifname.c_str()); + } else { + std::list listDhcpRange; + listDhcpRange.push_back(range); + m_mapInfDhcpRange.emplace(std::make_pair(ifname, listDhcpRange)); + WIFI_LOGI("SetDhcpRange() m_mapInfDhcpRange no find ifname:%{public}s, need emplace.\n", ifname.c_str()); + } + + /* update or reload interface config file */ + if (CheckAndUpdateConf(ifname) != DHCP_OPT_SUCCESS) { + WIFI_LOGE("SetDhcpRange() CheckAndUpdateConf failed, ifname:%{public}s.\n", ifname.c_str()); + return DHCP_OPT_FAILED; + } + + /* reload dhcp server config */ + return ReConf(); +} + +int DhcpServerServiceImpl::SetDhcpRange(const std::string &ifname, const std::string &tagName) +{ + if (ifname.empty() || tagName.empty()) { + WIFI_LOGE("SetDhcpRange() failed, ifname or tagName is empty!\n"); + return DHCP_OPT_FAILED; + } + auto iterTag = m_mapTagDhcpRange.find(tagName); + if (iterTag == m_mapTagDhcpRange.end()) { + WIFI_LOGE("SetDhcpRange() failed, m_mapTagDhcpRange no find tagName:%{public}s.\n", tagName.c_str()); + return DHCP_OPT_FAILED; + } + if ((iterTag->second).empty()) { + WIFI_LOGE("SetDhcpRange() failed, m_mapTagDhcpRange second is empty, tagName:%{public}s.\n", tagName.c_str()); + return DHCP_OPT_FAILED; + } + + /* check dhcp server service status */ + int nStatus = GetServerStatus(); + if (nStatus != 1) { + WIFI_LOGE("SetDhcpRange() ifname:%{public}s,tagName:%{public}s failed,dhcp status:%{public}d!\n", + ifname.c_str(), tagName.c_str(), nStatus); + return DHCP_OPT_FAILED; + } + + /* check and add dhcp range */ + auto iterRangeMap = m_mapInfDhcpRange.find(ifname); + if (iterRangeMap != m_mapInfDhcpRange.end()) { + /* check dhcp range is already exist */ + if (CheckTagDhcpRange(iterTag->second, iterRangeMap->second)) { + WIFI_LOGE("SetDhcpRange() ifname:%{public}s,tagName:%{public}s failed, dhcp range is same!\n", + ifname.c_str(), tagName.c_str()); + return DHCP_OPT_FAILED; + } + + for (auto iterTagValue : iterTag->second) { + iterRangeMap->second.push_back(iterTagValue); + WIFI_LOGI("SetDhcpRange() find ifname:%{public}s, second need push tagName:%{public}s.\n", + ifname.c_str(), tagName.c_str()); + } + } else { + m_mapInfDhcpRange.emplace(std::make_pair(ifname, iterTag->second)); + WIFI_LOGI("SetDhcpRange() no find ifname:%{public}s,tagName:%{public}s, need emplace.\n", + ifname.c_str(), tagName.c_str()); + } + + /* update or reload interface config file */ + if (CheckAndUpdateConf(ifname) != DHCP_OPT_SUCCESS) { + WIFI_LOGE("SetDhcpRange() CheckAndUpdateConf failed, ifname:%{public}s,tagName:%{public}s!\n", + ifname.c_str(), tagName.c_str()); + return DHCP_OPT_FAILED; + } + + /* reload dhcp server config */ + return ReConf(); +} + +int DhcpServerServiceImpl::GetLeases(std::vector &leases) +{ + if (!DhcpFunc::IsExistFile(DHCP_SERVER_LEASES_FILE)) { + WIFI_LOGE("GetLeases() failed, dhcp leasefile:%{public}s no exist!\n", DHCP_SERVER_LEASES_FILE.c_str()); + return DHCP_OPT_FAILED; + } + + leases.clear(); + + std::ifstream inFile; + inFile.open(DHCP_SERVER_LEASES_FILE); + std::string strTemp = ""; + char tmpLineData[FILE_LINE_MAX_SIZE] = {0}; + while (inFile.getline(tmpLineData, sizeof(tmpLineData))) { + strTemp = tmpLineData; + leases.push_back(strTemp); + } + inFile.close(); + + WIFI_LOGI("GetLeases() leases.size:%{public}d.\n", (int)leases.size()); + return DHCP_OPT_SUCCESS; +} + +int DhcpServerServiceImpl::GetDhcpSerProExit(const std::string &ifname, IDhcpResultNotify *pResultNotify) +{ + if (ifname.empty()) { + WIFI_LOGE("DhcpServerServiceImpl::GetDhcpSerProExit() error, ifname is empty!\n"); + return DHCP_OPT_FAILED; + } + + if (pResultNotify == nullptr) { + WIFI_LOGE("DhcpServerServiceImpl::GetDhcpSerProExit() error, pResultNotify = nullptr!\n"); + return DHCP_OPT_FAILED; + } + + auto iterExitNotify = m_mapDhcpSerExitNotify.find(ifname); + if (iterExitNotify == m_mapDhcpSerExitNotify.end()) { + WIFI_LOGI("GetDhcpSerProExit() SerExitNotify no find ifname:%{public}s, need emplace.\n", ifname.c_str()); + m_mapDhcpSerExitNotify.emplace(std::make_pair(ifname, pResultNotify)); + } else { + WIFI_LOGW("GetDhcpSerProExit() SerExitNotify find ifname:%{public}s, not need emplace!\n", ifname.c_str()); + } + + if (pDhcpSerProExitThread == nullptr) { + pDhcpSerProExitThread = new std::thread(&DhcpServerServiceImpl::RunDhcpSerProExitThreadFunc, this); + if (pDhcpSerProExitThread == nullptr) { + WIFI_LOGE("DhcpServerServiceImpl::GetDhcpSerProExit() init pDhcpSerProExitThread failed!\n"); + return DHCP_OPT_FAILED; + } + WIFI_LOGI("DhcpServerServiceImpl::GetDhcpSerProExit() init pDhcpSerProExitThread success.\n"); + } + + return DHCP_OPT_SUCCESS; +} + +int DhcpServerServiceImpl::ReConf() +{ + if (mPidDhcpServer == 0) { + WIFI_LOGE("ReConf() failed, %{public}s not start, config can not reload!\n", DHCP_SERVER_FILE.c_str()); + return DHCP_OPT_FAILED; + } + + WIFI_LOGI("enter ReConf(), now restart server:[ %{public}s ], mPidDhcpServer:%{public}d.\n", + DHCP_SERVER_FILE.c_str(), mPidDhcpServer); + + /* stop dhcp server process */ + if (StopServer(mPidDhcpServer) != DHCP_OPT_SUCCESS) { + WIFI_LOGE("ReConf() failed, StopServer mPidDhcpServer:%{public}d error!\n", mPidDhcpServer); + return DHCP_OPT_FAILED; + } + mPidDhcpServer = 0; + + sleep(DHCP_NUMBER_ONE); + + /* restart dhcp server process for load config */ + pid_t pid_server; + if ((pid_server = vfork()) < 0) { + WIFI_LOGE("ReConf() failed, vfork() pid_server:%{public}d error!\n", pid_server); + return DHCP_OPT_FAILED; + } + if (pid_server == 0) { + /* Child process */ + ForkExecProcess(); + } else { + /* Parent process */ + mProExitSig = false; + mStopServer = false; + mPidDhcpServer = pid_server; + ForkParentProcess(); + } + + return DHCP_OPT_SUCCESS; +} + +int DhcpServerServiceImpl::ForkParentProcess() +{ + WIFI_LOGI("enter ForkParentProcess() server:[ %{public}s ], mPidDhcpServer:%{public}d.\n", + DHCP_SERVER_FILE.c_str(), mPidDhcpServer); + RegisterSignal(); + return DHCP_OPT_SUCCESS; +} + +int DhcpServerServiceImpl::ForkExecProcess(const std::string &ifname) +{ + WIFI_LOGI("enter ForkExecProcess() server:[ %{public}s ], ifname:%{public}s.\n", + DHCP_SERVER_FILE.c_str(), ifname.c_str()); + const char *args[DHCP_SER_ARGSNUM] = { + DHCP_SERVER_FILE.c_str(), + "--keep-in-foreground", + "--bind-interfaces", + "-C", + DHCP_SERVER_CONFIG_FILE.c_str(), + nullptr + }; + if (execv(args[0], const_cast(args)) == -1) { + WIFI_LOGE("execv start failed,errno:%{public}d,strerror(errno):%{public}s,ifname:%{public}s!\n", + errno, strerror(errno), ifname.c_str()); + } else { + WIFI_LOGI("execv start success, ifname:%{public}s!\n", ifname.c_str()); + } + _exit(-1); + + return DHCP_OPT_SUCCESS; +} + +int DhcpServerServiceImpl::StopServer(const pid_t &server_pid) +{ + mStopServer = true; + UnregisterSignal(); + if (kill(server_pid, SIGTERM) == -1) { + if (ESRCH == errno) { + /* Normal. The subprocess is dead. The SIGCHLD signal triggers the stop hotspot. */ + WIFI_LOGI("StopServer() kill [%{public}d] success, pro pid no exist, pro:%{public}s.\n", + server_pid, DHCP_SERVER_FILE.c_str()); + return DHCP_OPT_SUCCESS; + } + WIFI_LOGE("StopServer() kill [%{public}d] failed, strerror(errno):%{public}s!\n", server_pid, strerror(errno)); + return DHCP_OPT_FAILED; + } + if (waitpid(server_pid, nullptr, 0) == -1) { + WIFI_LOGE("StopServer() waitpid [%{public}d] failed, strerror(errno):%{public}s!\n", + server_pid, strerror(errno)); + return DHCP_OPT_FAILED; + } + WIFI_LOGI("StopServer() waitpid [%{public}d] success, pro:%{public}s!\n", server_pid, DHCP_SERVER_FILE.c_str()); + return DHCP_OPT_SUCCESS; +} + +int DhcpServerServiceImpl::CheckAndUpdateConf(const std::string &ifname) +{ + if (ifname.empty()) { + WIFI_LOGE("DhcpServerServiceImpl::CheckAndUpdateConf() error, ifname is empty!\n"); + return DHCP_OPT_FAILED; + } + + /* delete temp interface config */ + std::string strInfFile = DHCP_SERVER_CONFIG_DIR + ifname + ".conf"; + if (DeleteInfConf(strInfFile) != DHCP_OPT_SUCCESS) { + WIFI_LOGE("CheckAndUpdateConf() DeleteInfConf failed, ifname:%{public}s!\n", ifname.c_str()); + return DHCP_OPT_FAILED; + } + + auto iterRangeMap = m_mapInfDhcpRange.find(ifname); + if ((iterRangeMap == m_mapInfDhcpRange.end()) || (iterRangeMap->second).empty()) { + return DHCP_OPT_SUCCESS; + } + + std::string strMac = ""; + if (DhcpFunc::GetLocalMac(ifname.c_str(), strMac) != 0) { + WIFI_LOGE("CheckAndUpdateConf() ifname:%{public}s failed, GetLocalMac error!\n", ifname.c_str()); + return DHCP_OPT_FAILED; + } + + std::string strIpv4 = ""; + std::string strIpv6 = ""; + bool bValidRange = false; + for (auto iterRange : iterRangeMap->second) { + if (((iterRange.iptype != 0) && (iterRange.iptype != 1)) || (iterRange.leaseHours <= 0) || + (iterRange.strStartip.length() <= 0) || (iterRange.strEndip.length() <= 0)) { + WIFI_LOGE("CheckAndUpdateConf() failed, " + "iptype:%{public}d,leaseHours:%{public}d,strStartip:%{public}s,strEndip:%{public}s error!\n", + iterRange.iptype, iterRange.leaseHours, iterRange.strStartip.c_str(), iterRange.strEndip.c_str()); + continue; + } + + std::string strTag = ""; + if (iterRange.strTagName.length() > 0) { + strTag = "set:" + iterRange.strTagName + ","; + } + if (iterRange.iptype == 0) { + strIpv4 += "dhcp-range=" + strTag + iterRange.strStartip + "," + iterRange.strEndip + ","; + strIpv4 += std::to_string(iterRange.leaseHours) + "h" + "\n"; + } else { + strIpv6 += "dhcp-range=" + strTag + iterRange.strStartip + "," + iterRange.strEndip + ","; + strIpv6 += std::to_string(iterRange.leaseHours) + "h" + "\n"; + } + bValidRange = true; + } + + if (bValidRange) { + /* interface data */ + std::string strInf = "interface=" + ifname + "\n" + "dhcp-host=" + strMac + "," + ifname + "\n\n"; + strInf += DHCP_SERVER_CFG_IPV4 + "\n" + strIpv4 + "\n" + DHCP_SERVER_CFG_IPV6 + "\n" + strIpv6 + "\n"; + DhcpFunc::CreateFile(strInfFile, strInf); + } + + return DHCP_OPT_SUCCESS; +} + +int DhcpServerServiceImpl::DeleteInfConf(const std::string &if_filename) +{ + if (if_filename.empty()) { + WIFI_LOGE("DhcpServerServiceImpl::DeleteInfConf() error, if_filename is empty!\n"); + return DHCP_OPT_FAILED; + } + if (DhcpFunc::IsExistFile(if_filename)) { + return DhcpFunc::RemoveFile(if_filename) ? DHCP_OPT_SUCCESS : DHCP_OPT_FAILED; + } + WIFI_LOGI("DeleteInfConf() if_filename:%{public}s no exist, not need delete.\n", if_filename.c_str()); + return DHCP_OPT_SUCCESS; +} + +bool DhcpServerServiceImpl::CheckIpAddrRange(const DhcpRange &range) +{ + if (((range.iptype != 0) && (range.iptype != 1)) || range.strStartip.empty() || range.strEndip.empty()) { + WIFI_LOGE("CheckIpAddrRange() range.iptype:%{public}d,strStartip:%{public}s,strEndip:%{public}s error!\n", + range.iptype, range.strStartip.c_str(), range.strEndip.c_str()); + return false; + } + + if (range.iptype == 0) { + uint32_t uStartIp = 0; + if (!DhcpFunc::Ip4StrConToInt(range.strStartip, uStartIp)) { + WIFI_LOGE("CheckIpAddrRange() Ip4StrConToInt failed, range.iptype:%{public}d,strStartip:%{public}s!\n", + range.iptype, range.strStartip.c_str()); + return false; + } + uint32_t uEndIp = 0; + if (!DhcpFunc::Ip4StrConToInt(range.strEndip, uEndIp)) { + WIFI_LOGE("CheckIpAddrRange() Ip4StrConToInt failed, range.iptype:%{public}d,strEndip:%{public}s!\n", + range.iptype, range.strEndip.c_str()); + return false; + } + /* check ip4 start and end ip */ + if (uStartIp >= uEndIp) { + WIFI_LOGE("CheckIpAddrRange() failed, uStartIp:%{public}u not less uEndIp:%{public}u!\n", uStartIp, uEndIp); + return false; + } + } else { + uint8_t uStartIp6[sizeof(struct in6_addr)] = {0}; + if (!DhcpFunc::Ip6StrConToChar(range.strStartip, uStartIp6)) { + return false; + } + uint8_t uEndIp6[sizeof(struct in6_addr)] = {0}; + if (!DhcpFunc::Ip6StrConToChar(range.strEndip, uEndIp6)) { + return false; + } + /* check ip6 start and end ip */ + } + + /* check range already exist in m_mapTagDhcpRange */ + for (auto tagRange : m_mapTagDhcpRange) { + for (auto dhcpRange : tagRange.second) { + if (dhcpRange.iptype != range.iptype) { + continue; + } + + if (CheckDhcpRangeConflict(dhcpRange, range)) { + WIFI_LOGE("CheckIpAddrRange() Conflict yes, type:%{public}d,Start:%{public}s,End:%{public}s error!\n", + range.iptype, range.strStartip.c_str(), range.strEndip.c_str()); + return false; + } + } + } + + return true; +} + +bool DhcpServerServiceImpl::CheckDhcpRangeConflict(const DhcpRange &srcRange, const DhcpRange &addRange) +{ + if (srcRange.iptype != addRange.iptype) { + WIFI_LOGI("CheckDhcpRangeConflict() no, src:%{public}d,add:%{public}d.\n", srcRange.iptype, addRange.iptype); + return false; + } + + if (addRange.iptype == 0) { + /* check ip4 */ + uint32_t uSrcStartIp = 0; + if (!DhcpFunc::Ip4StrConToInt(srcRange.strStartip, uSrcStartIp)) { + return false; + } + uint32_t uSrcEndIp = 0; + if (!DhcpFunc::Ip4StrConToInt(srcRange.strEndip, uSrcEndIp)) { + return false; + } + if (uSrcStartIp >= uSrcEndIp) { + WIFI_LOGE("CheckDhcpRangeConflict() Start:%{public}u not less End:%{public}u!\n", uSrcStartIp, uSrcEndIp); + return false; + } + + uint32_t uAddStartIp = 0; + if (!DhcpFunc::Ip4StrConToInt(addRange.strStartip, uAddStartIp)) { + WIFI_LOGE("CheckDhcpRangeConflict() Ip4StrConToInt failed, iptype:%{public}d,strStartip:%{public}s!\n", + addRange.iptype, addRange.strStartip.c_str()); + return false; + } + uint32_t uAddEndIp = 0; + if (!DhcpFunc::Ip4StrConToInt(addRange.strEndip, uAddEndIp)) { + WIFI_LOGE("CheckDhcpRangeConflict() Ip4StrConToInt failed, iptype:%{public}d,strEndip:%{public}s!\n", + addRange.iptype, addRange.strEndip.c_str()); + return false; + } + if (uAddStartIp >= uAddEndIp) { + WIFI_LOGE("CheckDhcpRangeConflict() Start:%{public}u not less End:%{public}u!\n", uAddStartIp, uAddEndIp); + return false; + } + + if (!((uAddStartIp > uSrcEndIp) || (uAddEndIp < uSrcStartIp))) { + WIFI_LOGI("CheckDhcpRangeConflict yes,srcRange.iptype:%{public}d, " + "strStartip:%{public}s-uSrcStartIp:%{public}u, strEndip:%{public}s-uSrcEndIp:%{public}u, " + "addRange.strStartip:%{public}s-uAddStartIp:%{public}u, strEndip:%{public}s-uAddEndIp:%{public}u.\n", + srcRange.iptype, srcRange.strStartip.c_str(), uSrcStartIp, srcRange.strEndip.c_str(), + uSrcEndIp, addRange.strStartip.c_str(), uAddStartIp, addRange.strEndip.c_str(), uAddEndIp); + return true; + } + WIFI_LOGI("CheckDhcpRangeConflict() no, srcRange.iptype:%{public}d.\n", srcRange.iptype); + } else { + /* check ip6 */ + } + + return false; +} + +bool DhcpServerServiceImpl::CheckTagDhcpRange(std::list &tagRange, std::list &infRange) +{ + for (auto iterTagValue : tagRange) { + for (auto iterInfValue : infRange) { + if ((iterInfValue.iptype == iterTagValue.iptype) && (iterInfValue.strStartip == iterTagValue.strStartip) && + (iterInfValue.strEndip == iterTagValue.strEndip)) { + WIFI_LOGE("CheckTagDhcpRange() failed, iterTagValue.iptype:%{public}d, strStartip:%{public}s, " + "strEndip:%{public}s already exist!\n", + iterTagValue.iptype, + iterTagValue.strStartip.c_str(), + iterTagValue.strEndip.c_str()); + return true; + } + } + } + return false; +} + +void DhcpServerServiceImpl::RunDhcpSerProExitThreadFunc() +{ + for (;;) { + if (bDhcpSerProExitThread) { + WIFI_LOGI("RunDhcpSerProExitThreadFunc() bDhcpSerProExitThread:true, break!\n"); + break; + } + if (m_mapDhcpSerExitNotify.empty()) { + sleep(DHCP_NUMBER_ONE); + continue; + } + if (!mProExitSig || mStopServer) { + WIFI_LOGI("RunDhcpSerProExitThreadFunc() has notify reqs, but sig:%{public}d, stop:%{public}d.", + mProExitSig, mStopServer); + usleep(SLEEP_TIME_500_MS); + continue; + } + + /* If the dhcp server process exits abnormally, notify other modules. */ + WIFI_LOGI("RunDhcpSerProExitThreadFunc() other modules have notify reqs, now begin notify...\n"); + auto iterNotify = m_mapDhcpSerExitNotify.begin(); + while (iterNotify != m_mapDhcpSerExitNotify.end()) { + std::string ifname = iterNotify->first; + if (iterNotify->second == nullptr) { + WIFI_LOGE("RunDhcpSerProExitThreadFunc() ifname:%{public}s error, ptr is nullptr!\n", ifname.c_str()); + iterNotify = m_mapDhcpSerExitNotify.erase(iterNotify); + continue; + } + + /* notify other modules */ + WIFI_LOGI("RunDhcpSerProExitThreadFunc() notify other modules.\n"); + iterNotify->second->OnSerExitNotify(ifname); + iterNotify = m_mapDhcpSerExitNotify.erase(iterNotify); + } + + WIFI_LOGI("RunDhcpSerProExitThreadFunc() dhcp ser pro exit notify finished.\n"); + sleep(DHCP_NUMBER_ONE); + continue; + } + + WIFI_LOGI("DhcpServerServiceImpl::RunDhcpSerProExitThreadFunc() end!\n"); +} + +void DhcpServerServiceImpl::ExitDhcpMgrThreadFunc() +{ + bDhcpSerProExitThread = true; + if (pDhcpSerProExitThread != nullptr) { + pDhcpSerProExitThread->join(); + delete pDhcpSerProExitThread; + pDhcpSerProExitThread = nullptr; + } + + if (!m_mapDhcpSerExitNotify.empty()) { + m_mapDhcpSerExitNotify.clear(); + } +} + +void DhcpServerServiceImpl::RegisterSignal() const +{ + struct sigaction newAction {}; + + if (sigfillset(&newAction.sa_mask) == -1) { + WIFI_LOGE("DhcpServerServiceImpl::RegisterSignal() failed, sigfillset error:%{public}s!", strerror(errno)); + } + + if (sigdelset(&newAction.sa_mask, SIGCHLD) == -1) { + WIFI_LOGE("DhcpServerServiceImpl::RegisterSignal() sigdelset SIGCHLD error:%{public}s!", strerror(errno)); + } + + newAction.sa_handler = SigChildHandler; + newAction.sa_flags = SA_RESTART; + newAction.sa_restorer = nullptr; + + if (sigaction(SIGCHLD, &newAction, nullptr) == -1) { + WIFI_LOGE("DhcpServerServiceImpl::RegisterSignal() sigaction SIGCHLD error:%{public}s!", strerror(errno)); + } +} + +void DhcpServerServiceImpl::UnregisterSignal() const +{ + struct sigaction newAction {}; + + if (sigemptyset(&newAction.sa_mask) == -1) { + WIFI_LOGE("DhcpServerServiceImpl::UnregisterSignal() failed, sigemptyset error:%{public}s!", strerror(errno)); + } + + newAction.sa_handler = SIG_DFL; + newAction.sa_flags = SA_RESTART; + newAction.sa_restorer = nullptr; + + if (sigaction(SIGCHLD, &newAction, nullptr) == -1) { + WIFI_LOGE("DhcpServerServiceImpl::UnregisterSignal() sigaction SIGCHLD error:%{public}s!", strerror(errno)); + } +} + +int DhcpServerServiceImpl::AddSpecifiedInterface(const std::string& ifname) +{ + if (ifname.empty()) { + WIFI_LOGE("AddSpecifiedInterface() error, ifname is empty!\n"); + return DHCP_OPT_FAILED; + } + + if (m_setInterfaces.find(ifname) == m_setInterfaces.end()) { + m_setInterfaces.insert(ifname); + WIFI_LOGI("AddSpecifiedInterface() m_setInterfaces add ifname:%{public}s success.\n", ifname.c_str()); + } else { + WIFI_LOGI("AddSpecifiedInterface() m_setInterfaces already exists ifname:%{public}s.\n", ifname.c_str()); + } + + return DHCP_OPT_SUCCESS; +} + +int DhcpServerServiceImpl::DelSpecifiedInterface(const std::string& ifname) +{ + if (ifname.empty()) { + WIFI_LOGE("DelSpecifiedInterface() error, ifname is empty!\n"); + return DHCP_OPT_FAILED; + } + + if (m_setInterfaces.find(ifname) != m_setInterfaces.end()) { + m_setInterfaces.erase(ifname); + WIFI_LOGI("DelSpecifiedInterface() m_setInterfaces del ifname:%{public}s success.\n", ifname.c_str()); + } else { + WIFI_LOGI("DelSpecifiedInterface() m_setInterfaces not exists ifname:%{public}s.\n", ifname.c_str()); + } + + return DHCP_OPT_SUCCESS; +} + +void DhcpServerServiceImpl::SigChildHandler(int signum) +{ + if (signum == SIGCHLD) { + /* Received signal SIGCHLD, wait the dhcp server process pid status. */ + pid_t childPid = waitpid(GetServerPid(), nullptr, WUNTRACED | WNOHANG); + if (childPid == GetServerPid()) { + WIFI_LOGW("SigChildHandler() the dhcp server process received SIGCHLD."); + mProExitSig = true; + } + } +} + +pid_t DhcpServerServiceImpl::GetServerPid() +{ + return mPidDhcpServer; +} +} // namespace Wifi +} // namespace OHOS diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_service.cpp b/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_service.cpp new file mode 100644 index 000000000..e25d94fd9 --- /dev/null +++ b/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_service.cpp @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "dhcp_service.h" +#include "wifi_logger.h" + +DEFINE_WIFILOG_DHCP_LABEL("DhcpService"); + +namespace OHOS { +namespace Wifi { +DhcpService::DhcpService() : m_pClientService(nullptr), m_pServerService(nullptr) +{ + WIFI_LOGI("DhcpService::DhcpService()...\n"); +} + +DhcpService::~DhcpService() +{ + WIFI_LOGI("DhcpService::~DhcpService()...\n"); +} + +int DhcpService::StartDhcpClient(const std::string& ifname, bool bIpv6) +{ + if (m_pClientService == nullptr) { + m_pClientService = std::make_unique(); + if (m_pClientService == nullptr) { + WIFI_LOGE("DhcpService::StartDhcpClient() std::make_unique() failed!\n"); + return DHCP_OPT_FAILED; + } + } + + return m_pClientService->StartDhcpClient(ifname, bIpv6); +} + +int DhcpService::StopDhcpClient(const std::string& ifname, bool bIpv6) +{ + if (m_pClientService == nullptr) { + m_pClientService = std::make_unique(); + if (m_pClientService == nullptr) { + WIFI_LOGE("DhcpService::StopDhcpClient() std::make_unique() failed!\n"); + return DHCP_OPT_FAILED; + } + } + + return m_pClientService->StopDhcpClient(ifname, bIpv6); +} + +int DhcpService::GetDhcpResult(const std::string& ifname, IDhcpResultNotify *pResultNotify, int timeouts) +{ + if (m_pClientService == nullptr) { + WIFI_LOGE("DhcpService::GetDhcpResult() error, m_pClientService = nullptr!\n"); + return DHCP_OPT_FAILED; + } + + return m_pClientService->GetDhcpResult(ifname, pResultNotify, timeouts); +} + +int DhcpService::GetDhcpInfo(const std::string& ifname, DhcpServiceInfo& dhcp) +{ + if (m_pClientService == nullptr) { + WIFI_LOGE("DhcpService::GetDhcpInfo() error, m_pClientService = nullptr!\n"); + return DHCP_OPT_FAILED; + } + + return m_pClientService->GetDhcpInfo(ifname, dhcp); +} + +int DhcpService::RenewDhcpClient(const std::string& ifname) +{ + if (m_pClientService == nullptr) { + WIFI_LOGE("DhcpService::RenewDhcpClient() error, m_pClientService = nullptr!\n"); + return DHCP_OPT_FAILED; + } + + return m_pClientService->RenewDhcpClient(ifname); +} + +int DhcpService::ReleaseDhcpClient(const std::string& ifname) +{ + if (m_pClientService == nullptr) { + WIFI_LOGE("DhcpService::ReleaseDhcpClient() error, m_pClientService = nullptr!\n"); + return DHCP_OPT_FAILED; + } + + return m_pClientService->ReleaseDhcpClient(ifname); +} + +int DhcpService::StartDhcpServer(const std::string& ifname) +{ + if (m_pServerService == nullptr) { + m_pServerService = std::make_unique(); + if (m_pServerService == nullptr) { + WIFI_LOGE("DhcpService::StartDhcpServer() std::make_unique() failed!\n"); + return DHCP_OPT_FAILED; + } + } + + return m_pServerService->StartDhcpServer(ifname); +} + +int DhcpService::StopDhcpServer(const std::string& ifname) +{ + if (m_pServerService == nullptr) { + m_pServerService = std::make_unique(); + if (m_pServerService == nullptr) { + WIFI_LOGE("DhcpService::StopDhcpServer() std::make_unique() failed!\n"); + return DHCP_OPT_FAILED; + } + } + + return m_pServerService->StopDhcpServer(ifname); +} + +int DhcpService::GetServerStatus() +{ + if (m_pServerService == nullptr) { + WIFI_LOGE("DhcpService::GetServerStatus() error, m_pServerService = nullptr!\n"); + return DHCP_OPT_FAILED; + } + + return m_pServerService->GetServerStatus(); +} + +int DhcpService::PutDhcpRange(const std::string& tagName, const DhcpRange& range) +{ + if (m_pServerService == nullptr) { + WIFI_LOGE("DhcpService::PutDhcpRange() error, m_pServerService = nullptr!\n"); + return DHCP_OPT_FAILED; + } + + return m_pServerService->PutDhcpRange(tagName, range); +} + +int DhcpService::RemoveDhcpRange(const std::string& tagName, const DhcpRange& range) +{ + if (m_pServerService == nullptr) { + WIFI_LOGE("DhcpService::RemoveDhcpRange() error, m_pServerService = nullptr!\n"); + return DHCP_OPT_FAILED; + } + + return m_pServerService->RemoveDhcpRange(tagName, range); +} + +int DhcpService::RemoveAllDhcpRange(const std::string& tagName) +{ + if (m_pServerService == nullptr) { + WIFI_LOGE("DhcpService::RemoveAllDhcpRange() error, m_pServerService = nullptr!\n"); + return DHCP_OPT_FAILED; + } + + return m_pServerService->RemoveAllDhcpRange(tagName); +} + +int DhcpService::SetDhcpRange(const std::string& ifname, const DhcpRange& range) +{ + if (m_pServerService == nullptr) { + WIFI_LOGE("DhcpService::SetDhcpRange() error, m_pServerService = nullptr!\n"); + return DHCP_OPT_FAILED; + } + + return m_pServerService->SetDhcpRange(ifname, range); +} + +int DhcpService::SetDhcpRange(const std::string& ifname, const std::string& tagName) +{ + if (m_pServerService == nullptr) { + WIFI_LOGE("DhcpService::SetDhcpRange() error, m_pServerService = nullptr!\n"); + return DHCP_OPT_FAILED; + } + + return m_pServerService->SetDhcpRange(ifname, tagName); +} + +int DhcpService::GetLeases(std::vector& leases) +{ + if (m_pServerService == nullptr) { + WIFI_LOGE("DhcpService::GetLeases() error, m_pServerService = nullptr!\n"); + return DHCP_OPT_FAILED; + } + + return m_pServerService->GetLeases(leases); +} + +int DhcpService::GetDhcpSerProExit(const std::string& ifname, IDhcpResultNotify *pResultNotify) +{ + if (m_pServerService == nullptr) { + WIFI_LOGE("DhcpService::GetDhcpSerProExit() error, m_pServerService = nullptr!\n"); + return DHCP_OPT_FAILED; + } + + return m_pServerService->GetDhcpSerProExit(ifname, pResultNotify); +} +} // namespace Wifi +} // namespace OHOS \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_internal_event_dispatcher.cpp b/services/wifi_standard/wifi_framework/wifi_manage/wifi_internal_event_dispatcher.cpp index 1f773d378..2cd5c943d 100644 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_internal_event_dispatcher.cpp +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_internal_event_dispatcher.cpp @@ -260,31 +260,45 @@ void WifiInternalEventDispatcher::DealStaCallbackMsg(WifiInternalEventDispatcher void WifiInternalEventDispatcher::PublishConnectionStateChangedEvent(int state, const WifiLinkedInfo &info) { - std::string eventData = "Idle"; - switch (info.connState) { - case ConnState::CONNECTING: + std::string eventData = "Other"; + switch (state) { + case int(OHOS::Wifi::ConnectionState::CONNECT_CONNECTING): eventData = "Connecting"; break; - case ConnState::AUTHENTICATING: - eventData = "Authenticating"; + case int(OHOS::Wifi::ConnectionState::CONNECT_OBTAINING_IP): + eventData = "OBtaingIp"; break; - case ConnState::OBTAINING_IPADDR: - eventData = "ObtainingIpaddress"; + case int(OHOS::Wifi::ConnectionState::CONNECT_OBTAINING_IP_FAIL): + eventData = "OBtaingIpFail"; break; - case ConnState::CONNECTED: - eventData = "Connected"; + case int(OHOS::Wifi::ConnectionState::CONNECT_AP_CONNECTED): + eventData = "ApConnecting"; break; - case ConnState::SUSPENDED: - eventData = "Suspended"; + case int(OHOS::Wifi::ConnectionState::CONNECT_CHECK_PORTAL): + eventData = "Connecting"; + break; + case int(OHOS::Wifi::ConnectionState::CONNECT_NETWORK_ENABLED): + eventData = "NetworkEnabled"; break; - case ConnState::DISCONNECTING: - eventData = "Disconnecting"; + case int(OHOS::Wifi::ConnectionState::CONNECT_NETWORK_DISABLED): + eventData = "NetworkDisabled"; break; - case ConnState::DISCONNECTED: + case int(OHOS::Wifi::ConnectionState::DISCONNECT_DISCONNECTING): + eventData = "DisconnectDisconnecting"; + break; + case int(OHOS::Wifi::ConnectionState::DISCONNECT_DISCONNECTED): eventData = "Disconnected"; break; - default: + case int(OHOS::Wifi::ConnectionState::CONNECT_PASSWORD_WRONG): + eventData = "ConnectPasswordWrong"; break; + case int(OHOS::Wifi::ConnectionState::CONNECT_CONNECTING_TIMEOUT): + eventData = "ConnectingTimeout"; + break; + default: { + eventData = "UnknownState"; + break; + } } if (!WifiCommonEventHelper::PublishConnectionStateChangedEvent(state, eventData)) { WIFI_LOGE("failed to publish connection state changed event!"); diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_common.h b/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_common.h index 700831f2f..6cff0f9e9 100755 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_common.h +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_common.h @@ -170,7 +170,7 @@ enum ScanStatus { SCAN_STATUS_INVALID /* Invalid value */ }; -/* Scan Result */ +/* Scan Info */ struct InterScanInfo { std::string bssid; /* Access point address */ std::string ssid; /* Network Name */ @@ -187,11 +187,11 @@ struct InterScanInfo { InterScanInfo() { - frequency = 0; - band = 0; - rssi = 0; - securityType = WifiSecurity::INVALID; - timestamp = 0; + frequency = 0; + band = 0; + rssi = 0; + securityType = WifiSecurity::INVALID; + timestamp = 0; } }; diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_monitor.cpp b/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_monitor.cpp index 61ac759a5..041eced38 100755 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_monitor.cpp +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_monitor.cpp @@ -15,7 +15,7 @@ #include "scan_monitor.h" #include "wifi_logger.h" -DEFINE_WIFILOG_SCAN_LABEL("ScanStateMachine"); +DEFINE_WIFILOG_SCAN_LABEL("ScanMonitor"); namespace OHOS { namespace Wifi { diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_service.cpp b/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_service.cpp index c685550a6..07bddcea3 100755 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_service.cpp +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_scan/scan_service.cpp @@ -16,7 +16,7 @@ #include "scan_service.h" #include "wifi_logger.h" -DEFINE_WIFILOG_SCAN_LABEL("ScanStateMachine"); +DEFINE_WIFILOG_SCAN_LABEL("ScanService"); namespace OHOS { namespace Wifi { diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/BUILD.gn b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/BUILD.gn index fd89d3e14..24335352a 100644 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/BUILD.gn +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/BUILD.gn @@ -25,7 +25,6 @@ ohos_shared_library("wifi_sta_service") { "//foundation/communication/wifi/services/wifi_standard/wifi_framework/common/log/log_helper.c", "//foundation/communication/wifi/services/wifi_standard/wifi_framework/common/net_helper/http_request.cpp", "//foundation/communication/wifi/services/wifi_standard/wifi_framework/common/net_helper/ip_tools.cpp", - "sta_dhcp_server.cpp", "sta_network_check.cpp", "sta_network_speed.cpp", "sta_interface.cpp", @@ -73,6 +72,7 @@ ohos_shared_library("wifi_sta_service") { deps = [ "//foundation/communication/wifi/services/wifi_standard/wifi_framework/wifi_manage:wifi_manager_service", "//foundation/communication/wifi/services/wifi_standard/wifi_framework/wifi_manage/idl_client:wifi_idl_client", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage:dhcp_manager_service", "//utils/native/base:utils", ] diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/net_conf/if_config.cpp b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/net_conf/if_config.cpp index 59c04c1cb..32dcca500 100755 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/net_conf/if_config.cpp +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/net_conf/if_config.cpp @@ -14,6 +14,7 @@ */ #include +#include #include #include #include @@ -73,28 +74,21 @@ bool IfConfig::ExecCommand(const std::vector &vecCommandArg) * @Description : Set the network card address, routing, DNS * @Return success:0 failed:-1 */ -int IfConfig::SetIfAddr(const DhcpResult &dhcpResult) +int IfConfig::SetIfAddr(const DhcpResult &dhcpResult, int ipType) { - int ret = -1; - const int ipTypeNum = 2; - for (int i = 0; i < ipTypeNum; i++) { - if (dhcpResult[i].isOptSuc) { - ret = 0; - - SetNetDns(IFNAME, dhcpResult[i].dns, dhcpResult[i].dns2); - - FlushIpAddr(IFNAME, dhcpResult[i].iptype); - - AddIpAddr(IFNAME, dhcpResult[i].ip, dhcpResult[i].subnet, dhcpResult[i].iptype); - - AddIfRoute(IFNAME, dhcpResult[i].ip, dhcpResult[i].subnet, dhcpResult[i].gateWay, dhcpResult[i].iptype); - } - } - - if (ret == 0) { - LOGI("set addr succeed!"); - } - return ret; + LOGD("ipType=%d, ip=%s, gateway=%s, subnet=%s, strDns1=%s, strDns2=%s", + dhcpResult.iptype, + dhcpResult.strYourCli.c_str(), + dhcpResult.strSubnet.c_str(), + dhcpResult.strRouter1.c_str(), + dhcpResult.strDns1.c_str(), + dhcpResult.strDns2.c_str()); + SetNetDns(IFNAME, dhcpResult.strDns1, dhcpResult.strDns2); + FlushIpAddr(IFNAME, ipType); + AddIpAddr(IFNAME, dhcpResult.strYourCli, dhcpResult.strSubnet, ipType); + AddIfRoute(IFNAME, dhcpResult.strYourCli, dhcpResult.strSubnet, dhcpResult.strRouter1, ipType); + LOGI("set addr succeed!"); + return 0; } /** @@ -397,4 +391,4 @@ void IfConfig::SetProxy( return; } } // namespace Wifi -} // namespace OHOS +} // namespace OHOS \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/net_conf/if_config.h b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/net_conf/if_config.h index 0f57ca43d..7c3ecf5d6 100755 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/net_conf/if_config.h +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/net_conf/if_config.h @@ -17,6 +17,7 @@ #include #include "wifi_log.h" +#include "dhcp_define.h" #include "sta_define.h" namespace OHOS { @@ -28,7 +29,14 @@ public: static IfConfig &GetInstance(); - int SetIfAddr(const DhcpResult &dhcpResult); + /** + * @Description : Set the If Addr object + * + * @param dhcpInfo - dhcp information[in] + * @param ipType - ip type[in] + * @return int + */ + int SetIfAddr(const DhcpResult &dhcpInfo, int ipType); void SetNetDns(const std::string &ifName, const std::string &dns1, const std::string &dns2); diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_define.h b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_define.h index 71243031f..e80333a2c 100644 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_define.h +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_define.h @@ -74,27 +74,6 @@ typedef enum EnumStaIpType { IPTYPE_BUTT, } StaIpType; -typedef struct TagDhcpResult { - int iptype; - bool isOptSuc; - std::string ip; - std::string gateWay; - std::string subnet; - std::string dns; - std::string dns2; - - TagDhcpResult() - { - iptype = 0; - isOptSuc = false; - subnet = "255.255.255.0"; - dns = "8.8.8.8"; - dns2 = "8.8.4.4"; - } -} DhcpResult[2]; - -typedef std::function DhcpResultHandler; - typedef enum EnumStaNetState { NETWORK_STATE_UNKNOW, NETWORK_STATE_WORKING, diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_dhcp_server.cpp b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_dhcp_server.cpp deleted file mode 100644 index 9e4c373b5..000000000 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_dhcp_server.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "sta_dhcp_server.h" -#include "securec.h" -#include "if_config.h" -#include "wifi_logger.h" -DEFINE_WIFILOG_LABEL("StaDhcpServer"); - -const std::string IPV4_DNS1 = "8.8.8.8"; -const std::string IPV4_DNS2 = "8.8.4.4"; -const std::string IPV6_DNS1 = "2400:3200::1"; -const std::string IPV6_DNS2 = "2400:3200:baba::1"; - - -namespace OHOS { -namespace Wifi { -const int IP_SIZE = 2; - -StaDhcpServer::StaDhcpServer(DhcpResultHandler handler) -{ - pDealDhcpThread = nullptr; - dhcpResultHandler = handler; - isWakeDhcp = false; - isExitDhcpThread = false; - serverSockfd = -1; - mIpType = IPTYPE_IPV4; - ipNumber = IP_SIZE; - - memset_s(args, sizeof(args), 0, sizeof(args)); -} - -StaDhcpServer::~StaDhcpServer() -{ - WIFI_LOGI("StaDhcpServer::~StaDhcpServer enter"); - ExitDhcpThread(); - WIFI_LOGI("StaDhcpServer::~StaDhcpServer complete"); -} - -void StaDhcpServer::RunDhcpThreadFunc() -{ - WIFI_LOGE("enter runDhcpThreadFunc\n"); - if (StartDhcpServer() != 0) { - WIFI_LOGE("startDhcpServer error\n"); - return; - } - - while (1) { - std::unique_lock lck(mMutex); - while (!isWakeDhcp) { - WIFI_LOGE("waiting for sigal\n"); - mCondition.wait(lck); - } - WIFI_LOGE("unlock and start dhcp client\n"); - if (isExitDhcpThread) { - break; - } - - SetDhcpParam(); - ForkForDhcp(); - if (dhcpResultHandler) { - dhcpResultHandler(result); - } - - isWakeDhcp = false; - } - if (serverSockfd >= 0) { - close(serverSockfd); - serverSockfd = -1; - } - WIFI_LOGI("dhcp thread over\n"); -} - -void StaDhcpServer::SetDhcpParam() -{ - int argsIndex = 0; - memset_s(args, sizeof(args), 0, sizeof(args)); - if (mIpType == IPTYPE_IPV4) { - ipNumber = 1; - args[argsIndex] = const_cast(DHCP_CLIENT_FILE); - args[++argsIndex] = const_cast("-4"); - args[++argsIndex] = nullptr; - } else if (mIpType == IPTYPE_IPV6) { - ipNumber = 1; - args[argsIndex] = const_cast(DHCP_CLIENT_FILE); - args[++argsIndex] = const_cast("-6"); - args[++argsIndex] = nullptr; - } else { - ipNumber = IP_SIZE; - args[argsIndex] = const_cast(DHCP_CLIENT_FILE); - args[++argsIndex] = nullptr; - } -} -ErrCode StaDhcpServer::StartDhcpServer() -{ - unlink(SOCKFD_PATH); - struct sockaddr_un serverAddr; - serverAddr.sun_family = AF_UNIX; - if (strcpy_s(serverAddr.sun_path, sizeof(serverAddr.sun_path), SOCKFD_PATH) != EOK) { - return ErrCode::WIFI_OPT_FAILED; - } - serverSockfd = socket(AF_UNIX, SOCK_STREAM, 0); - if (serverSockfd < 0) { - WIFI_LOGE("startDhcpServer: failed to create server socket!"); - return ErrCode::WIFI_OPT_FAILED; - } - bool bFlag = false; - do { - struct timeval timeout; - timeout.tv_sec = DHCP_ACCEPT_DELAY; - timeout.tv_usec = 0; - if (setsockopt(serverSockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) == -1) { - WIFI_LOGE("startDhcpServer: failed to set accept timeout!"); - break; - } - - if (bind(serverSockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) { - WIFI_LOGE("startDhcpServer: failed to bind dhcp server socket!"); - break; - } - if (listen(serverSockfd, MAX_LISTEN) < 0) { - WIFI_LOGE("startDhcpServer: failed to listen!"); - break; - } - bFlag = true; - } while (0); - if (!bFlag) { - close(serverSockfd); - serverSockfd = -1; - return ErrCode::WIFI_OPT_FAILED; - } - return ErrCode::WIFI_OPT_SUCCESS; -} - -ErrCode StaDhcpServer::CheckDhcpInfo(int &dhcpResultIndex) -{ - if (mReceive.iptype > StaIpType::IPTYPE_IPV6) { - WIFI_LOGE("CheckDhcpInfo ip type error\n"); - dhcpResultIndex = StaIpType::IPTYPE_IPV4; - return ErrCode::WIFI_OPT_FAILED; - } else if (mReceive.iptype == StaIpType::IPTYPE_IPV4) { - WIFI_LOGE("CheckDhcpInfo ip type ipv4\n"); - dhcpResultIndex = StaIpType::IPTYPE_IPV4; - } else { - WIFI_LOGE("CheckDhcpInfo ip type ipv6\n"); - dhcpResultIndex = StaIpType::IPTYPE_IPV6; - } - - if (mReceive.datasize != (sizeof(mReceive.iptype) + strlen(mReceive.ip) + strlen(mReceive.gateway) + - strlen(mReceive.subnet) + strlen(mReceive.dns) + sizeof(mReceive.leasetime))) { - WIFI_LOGE("CheckDhcpInfo datasize error\n"); - return ErrCode::WIFI_OPT_FAILED; - } - - return ErrCode::WIFI_OPT_SUCCESS; -} - -void StaDhcpServer::EnableIpv6() const -{ - std::vector enableIpv6Cmd; - enableIpv6Cmd.clear(); - enableIpv6Cmd.push_back(SYSTEM_COMMAND_ECHO); - enableIpv6Cmd.push_back(SYSTEM_COMMAND_IPV6_ALL_PATH); - IfConfig::GetInstance().ExecCommand(enableIpv6Cmd); - - enableIpv6Cmd.clear(); - enableIpv6Cmd.push_back(SYSTEM_COMMAND_ECHO); - enableIpv6Cmd.push_back(SYSTEM_COMMAND_IPV6_WLAN0_PATH); - IfConfig::GetInstance().ExecCommand(enableIpv6Cmd); - - enableIpv6Cmd.clear(); - enableIpv6Cmd.push_back(SYSTEM_COMMAND_ECHO); - enableIpv6Cmd.push_back(SYSTEM_COMMAND_IPV6_DEFAULT_PATH); - IfConfig::GetInstance().ExecCommand(enableIpv6Cmd); -} - -void StaDhcpServer::StartDhcpClient() -{ - /* Enable IPv6. */ - EnableIpv6(); - - /* The subprocess starts the DHCP_CLIENT_FILE process. */ - if (execv(args[0], const_cast(args))) { - WIFI_LOGE("execv %s failed!\n", args[0]); - } - _exit(-1); -} - -void StaDhcpServer::CreateSocketServer() -{ - int clientSockfd, dhcpResultIndex; - struct sockaddr_un clientAddr; - socklen_t clientLen = sizeof(clientAddr); - - for (int index = 0; index < ipNumber; index++) { - clientSockfd = accept(serverSockfd, (struct sockaddr *)&clientAddr, &clientLen); - if (clientSockfd == -1) { - WIFI_LOGE("startDhcpClient accept failed\n"); - continue; - } - - if (memset_s(&mReceive, sizeof(Packet), 0, sizeof(Packet)) != EOK) { - close(clientSockfd); - continue; - } - if (read(clientSockfd, &mReceive, sizeof(Packet)) < 0) { - close(clientSockfd); - continue; - } - - if (CheckDhcpInfo(dhcpResultIndex) != 0) { - close(clientSockfd); - continue; - } - - if (dhcpResultIndex <= 0) { - close(clientSockfd); - continue; - } - - /* Notification state machine */ - result[dhcpResultIndex].isOptSuc = true; - result[dhcpResultIndex].ip = mReceive.ip; - result[dhcpResultIndex].iptype = mReceive.iptype; - result[dhcpResultIndex].gateWay = mReceive.gateway; - result[dhcpResultIndex].subnet = mReceive.subnet; - if (dhcpResultIndex == static_cast(StaIpType::IPTYPE_IPV4)) { - result[dhcpResultIndex].dns = IPV4_DNS1; - result[dhcpResultIndex].dns2 = IPV4_DNS2; - } else { - result[dhcpResultIndex].dns = IPV6_DNS1; - result[dhcpResultIndex].dns2 = IPV6_DNS1; - } - close(clientSockfd); - } - - KillDhcpClient(); -} - -ErrCode StaDhcpServer::ForkForDhcp() -{ - pid_t pid = fork(); - if (pid < 0) { - WIFI_LOGE("In StaDhcpServer fork failed."); - return ErrCode::WIFI_OPT_FAILED; - } else if (pid == 0) { - StartDhcpClient(); - } else { - CreateSocketServer(); - } - return ErrCode::WIFI_OPT_SUCCESS; -} - -void StaDhcpServer::KillDhcpClient() const -{ - FILE *pp = popen("./dhcpc -x", "r"); - if (pp == nullptr) { - WIFI_LOGE("In StaDhcpServer openDhcpClient popen failed!\n"); - return; - } - - pclose(pp); - pp = nullptr; -} - -ErrCode StaDhcpServer::InitDhcpThread() -{ - pDealDhcpThread = new (std::nothrow)std::thread(&StaDhcpServer::RunDhcpThreadFunc, this); - if (pDealDhcpThread == nullptr) { - WIFI_LOGE("In StaDhcpServer create message start Dhcp server thread failed!"); - return ErrCode::WIFI_OPT_FAILED; - } - return ErrCode::WIFI_OPT_SUCCESS; -} - -void StaDhcpServer::SignalDhcpThread(int ipType) -{ - mIpType = ipType; - std::unique_lock lck(mMutex); - isWakeDhcp = true; - mCondition.notify_one(); -} - -void StaDhcpServer::ExitDhcpThread() -{ - { - std::unique_lock lck(mMutex); - isWakeDhcp = true; - isExitDhcpThread = true; - mCondition.notify_one(); - } - - if (serverSockfd >= 0) { - close(serverSockfd); - serverSockfd = -1; - } - - if (pDealDhcpThread != nullptr) { - pDealDhcpThread->join(); - delete pDealDhcpThread; - pDealDhcpThread = nullptr; - } -} -} // namespace Wifi -} // namespace OHOS \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_dhcp_server.h b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_dhcp_server.h deleted file mode 100644 index 6825fcc70..000000000 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_dhcp_server.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef OHOS_WIFI_DHCP_SERVER_H -#define OHOS_WIFI_DHCP_SERVER_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "wifi_errcode.h" -#include "wifi_log.h" -#include "sta_define.h" - -#define SOCKFD_PATH "/data/dhcp/sta_dhcp.sock" -#define DHCP_CLIENT_FILE "./dhcpc" - -const std::string SYSTEM_COMMAND_ECHO = "echo 0 >"; -const std::string SYSTEM_COMMAND_IPV6_ALL_PATH = "/proc/sys/net/ipv6/conf/all/disable_ipv6"; -const std::string SYSTEM_COMMAND_IPV6_WLAN0_PATH = "/proc/sys/net/ipv6/conf/wlan0/disable_ipv6"; -const std::string SYSTEM_COMMAND_IPV6_DEFAULT_PATH = "/proc/sys/net/ipv6/conf/default/disable_ipv6"; - -static const int MAX_LISTEN = 2; -static const int IPTYPE_SIZE = 20; -static const int GETIP_SIZE = 64; -static const int GATEWAY_SIZE = 64; -static const int SUBNET_SIZE = 64; -static const int DNS_SIZE = 64; -static const int INIT_CRC = 0x0000; -static const int DEFAULT_BIT = 8; -static const int DHCP_ACCEPT_DELAY = 3; - -namespace OHOS { -namespace Wifi { -class Packet { -public: - Packet() - { - iptype = 0; - datasize = 0; - check = 0; - leasetime = 0; - } - - ~Packet() - {} - - unsigned char iptype; - unsigned short datasize; - unsigned short check; - unsigned int leasetime; - char ip[GETIP_SIZE] = {0}; - char gateway[GATEWAY_SIZE] = {0}; - char subnet[SUBNET_SIZE] = {0}; - char dns[DNS_SIZE] = {0}; -}; - -class StaDhcpServer { -public: - explicit StaDhcpServer(DhcpResultHandler handler); - ~StaDhcpServer(); - /** - * @Description Start a thread. - * - * @Return success:0 failed:-1 - */ - ErrCode InitDhcpThread(); - /** - * @Description : wake up the DHCP processing thread. - * - * @param ipType - Type of IP to be obtained [in] - */ - void SignalDhcpThread(int ipType); - - DhcpResultHandler dhcpResultHandler; - -private: - Packet mReceive; - std::thread *pDealDhcpThread; - int mIpType; - int serverSockfd; - char *args[3]; - DhcpResult result; - int ipNumber; - /** - * @Description Thread execution function - * - */ - void RunDhcpThreadFunc(); - /** - * @Description : Set the Dhcp Param. - * - */ - void SetDhcpParam(); - /** - * @Description Setting Socket Listening on the Socket Server - * - * @Return success : WIFI_OPT_SUCCESS, failed : WIFI_OPT_FAILED - */ - ErrCode StartDhcpServer(); - /** - * @Description Verify DHCP transmission information. - * - * @param dhcpResultIndex - Structure array subscript 0:ipv4 1:ipv6 [in] - * @Return success : WIFI_OPT_SUCCESS, failed : WIFI_OPT_FAILED - */ - ErrCode CheckDhcpInfo(int &dhcpResultIndex); - /** - * @Description Enable ipv6 - * - */ - void EnableIpv6() const; - /** - * @Description Create Socket Server and receives messages such as - * DHCP IP address, subnet mask, gateway, and DNS. - */ - void CreateSocketServer(); - /** - * @Description fork a process - * - * @Return success: WIFI_OPT_SUCCESS, failed : WIFI_OPT_FAILED - */ - - ErrCode ForkForDhcp(); - /** - * @Description Starts the DHCP client program - */ - void StartDhcpClient(); - /** - * @Description Kill the DHCP client program. - * - */ - void KillDhcpClient() const; - /** - * @Description Exit the DHCP thread. Releasing Thread Resources on the DHCP Server. - * - */ - void ExitDhcpThread(); - -private: - std::mutex mMutex; - std::condition_variable mCondition; - /* Wakeup flag */ - bool isWakeDhcp; - /* exit the thread flag */ - bool isExitDhcpThread; -}; -} // namespace Wifi -} // namespace OHOS -#endif \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_network_check.cpp b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_network_check.cpp index 6ec421bff..d9926f680 100644 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_network_check.cpp +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_network_check.cpp @@ -27,7 +27,6 @@ StaNetworkCheck::StaNetworkCheck(NetStateHandler handle) lastNetState = NETWORK_STATE_UNKNOW; isStopNetCheck = true; isExitNetCheckThread = false; - currentIpType = -1; } StaNetworkCheck::~StaNetworkCheck() @@ -104,11 +103,10 @@ void StaNetworkCheck::StopNetCheckThread() isStopNetCheck = true; } -void StaNetworkCheck::SignalNetCheckThread(int ipType) +void StaNetworkCheck::SignalNetCheckThread() { WIFI_LOGI("enter SignalNetCheckThread!\n"); lastNetState = NETWORK_STATE_UNKNOW; - currentIpType = ipType; isStopNetCheck = false; std::unique_lock lck(mMutex); mCondition.notify_one(); diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_network_check.h b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_network_check.h index 70254858d..7bc323a95 100644 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_network_check.h +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_network_check.h @@ -47,7 +47,7 @@ public: * * @param ipType - Type of IP to be obtained [in] */ - void SignalNetCheckThread(int ipType); + void SignalNetCheckThread(); /** * @Description : stop the NetCheck processing thread. * @@ -58,7 +58,6 @@ private: std::thread *pDealNetCheckThread; NetStateHandler netStateHandler; StaNetState lastNetState; - int currentIpType; /** * @Description : Detect Internet ability diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_state_machine.cpp b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_state_machine.cpp index ffc9b049c..212cc2f48 100755 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_state_machine.cpp +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_state_machine.cpp @@ -49,7 +49,9 @@ StaStateMachine::StaStateMachine() targetRoamBssid(WPA_BSSID_ANY), currentTpType(IPTYPE_IPV4), isWpsConnect(IsWpsConnected::WPS_INVALID), - pDhcpServer(nullptr), + getIpSucNum(0), + getIpFailNum(0), + pDhcpService(nullptr), pNetSpeed(nullptr), pNetcheck(nullptr), msgQueueUp(nullptr), @@ -85,9 +87,10 @@ StaStateMachine::~StaStateMachine() ParsePointer(pGetIpState); ParsePointer(pLinkedState); ParsePointer(pApRoamingState); - ParsePointer(pDhcpServer); ParsePointer(pNetSpeed); ParsePointer(pNetcheck); + ParsePointer(pDhcpResultNotify); + ParsePointer(pDhcpService); } /* ---------------------------Initialization functions------------------------------ */ @@ -107,13 +110,11 @@ ErrCode StaStateMachine::InitStaStateMachine() StartStateMachine(); InitStaSMHandleMap(); - pDhcpServer = - new (std::nothrow) StaDhcpServer(std::bind(&StaStateMachine::HandleDhcpResult, this, std::placeholders::_1)); - if (pDhcpServer == nullptr) { + pDhcpService = new (std::nothrow) DhcpService(); + if (pDhcpService == nullptr) { WIFI_LOGE("pDhcpServer is null\n"); return WIFI_OPT_FAILED; } - pDhcpServer->InitDhcpThread(); pNetcheck = new (std::nothrow) StaNetworkCheck(std::bind(&StaStateMachine::HandleNetCheckResult, this, std::placeholders::_1)); @@ -157,6 +158,8 @@ ErrCode StaStateMachine::InitStaStates() tmpErrNumber += JudgmentEmpty(pApRoamingState); pNetSpeed = new StaNetWorkSpeed(); tmpErrNumber += JudgmentEmpty(pNetSpeed); + pDhcpResultNotify = new DhcpResultNotify(this); + tmpErrNumber += JudgmentEmpty(pDhcpResultNotify); if (tmpErrNumber != 0) { WIFI_LOGE("InitStaStates some one state is null\n"); return WIFI_OPT_FAILED; @@ -450,6 +453,11 @@ bool StaStateMachine::WpaStartedState::ExecuteStateMsg(InternalMessage *msg) void StaStateMachine::StopWifiProcess() { WIFI_LOGD("Enter StaStateMachine::StopWifiProcess.\n"); + if (currentTpType == IPTYPE_IPV4) { + pDhcpService->StopDhcpClient(IF_NAME, false); + } else { + pDhcpService->StopDhcpClient(IF_NAME, true); + } if (lastNetworkId != INVALID_NETWORK_ID) { if (statusId == static_cast(WifiDeviceConfigStatus::DISABLED)) { WIFI_LOGD("The network status is DISABLED:1.\n"); @@ -464,6 +472,9 @@ void StaStateMachine::StopWifiProcess() } WIFI_LOGD("linkedInfo network = %{public}d", linkedInfo.networkId); + DhcpInfo dhcpInfo; + WifiSettings::GetInstance().SaveDhcpInfo(dhcpInfo); + /* clear connection information. */ InitWifiLinkedInfo(); WifiSettings::GetInstance().SaveLinkedInfo(linkedInfo); @@ -701,6 +712,13 @@ void StaStateMachine::DealDisconnectEvent(InternalMessage *msg) WIFI_LOGD("Enter DealDisconnectEvent.\n"); pNetcheck->StopNetCheckThread(); + if (currentTpType == IPTYPE_IPV4) { + pDhcpService->StopDhcpClient(IF_NAME, false); + } else { + pDhcpService->StopDhcpClient(IF_NAME, true); + } + getIpSucNum = 0; + getIpFailNum = 0; if (statusId == static_cast(WifiDeviceConfigStatus::DISABLED)) { WIFI_LOGD("The network status is DISABLED:1.\n"); WifiSettings::GetInstance().SetDeviceState(lastNetworkId, static_cast(WifiDeviceConfigStatus::DISABLED)); @@ -713,6 +731,9 @@ void StaStateMachine::DealDisconnectEvent(InternalMessage *msg) WifiSettings::GetInstance().SyncDeviceConfig(); statusId = static_cast(WifiDeviceConfigStatus::INVALID); + + DhcpInfo dhcpInfo; + WifiSettings::GetInstance().SaveDhcpInfo(dhcpInfo); /* Initialize connection informatoin. */ InitWifiLinkedInfo(); if (lastLinkedInfo.detailedState == DetailedState::CONNECTING) { @@ -1413,7 +1434,17 @@ void StaStateMachine::GetIpState::GoInState() } } else { pStaStateMachine->currentTpType = static_cast(WifiSettings::GetInstance().GetDhcpIpType()); - pStaStateMachine->pDhcpServer->SignalDhcpThread(pStaStateMachine->currentTpType); + if (pStaStateMachine->currentTpType == IPTYPE_IPV4) { + pStaStateMachine->pDhcpService->StartDhcpClient(IF_NAME, false); + } else { + pStaStateMachine->pDhcpService->StartDhcpClient(IF_NAME, true); + } + if (pStaStateMachine->pDhcpService->GetDhcpResult(IF_NAME, pStaStateMachine->pDhcpResultNotify, 15) != 0) { + LOGE(" Dhcp connection failed.\n"); + pStaStateMachine->NotifyResult( + WifiInternalMsgCode::STA_CONNECT_RES, static_cast(OperateResState::CONNECT_NETWORK_DISABLED)); + pStaStateMachine->DisConnectProcess(); + } } return; @@ -1439,119 +1470,47 @@ bool StaStateMachine::ConfigStaticIpAddress(StaticIpAddress &staticIpAddress) WIFI_LOGI("Enter StaStateMachine::SetDhcpResultFromStatic."); DhcpResult result; - switch (currentTpType) { case IPTYPE_IPV4: { - result[0].isOptSuc = true; - result[0].iptype = IPTYPE_IPV4; - result[0].ip = staticIpAddress.ipAddress.address.GetIpv4Address(); - result[0].gateWay = staticIpAddress.gateway.GetIpv4Address(); - result[0].subnet = staticIpAddress.GetIpv4Mask(); - result[0].dns = staticIpAddress.dnsServer1.GetIpv4Address(); - result[0].dns2 = staticIpAddress.dnsServer2.GetIpv4Address(); - result[1].isOptSuc = false; + result.strYourCli = staticIpAddress.ipAddress.address.GetIpv4Address(); + result.strRouter1 = staticIpAddress.gateway.GetIpv4Address(); + result.strSubnet = staticIpAddress.GetIpv4Mask(); + result.strDns1 = staticIpAddress.dnsServer1.GetIpv4Address(); + pDhcpResultNotify->OnSuccess(1, IF_NAME, result); + break; } case IPTYPE_IPV6: { - result[0].isOptSuc = false; - - result[1].isOptSuc = true; - result[1].iptype = IPTYPE_IPV6; - result[1].ip = staticIpAddress.ipAddress.address.GetIpv6Address(); - result[1].gateWay = staticIpAddress.gateway.GetIpv6Address(); - result[1].subnet = staticIpAddress.GetIpv6Mask(); - result[1].dns = staticIpAddress.dnsServer1.GetIpv6Address(); - result[1].dns2 = staticIpAddress.dnsServer2.GetIpv6Address(); + result.strYourCli = staticIpAddress.ipAddress.address.GetIpv6Address(); + result.strRouter1 = staticIpAddress.gateway.GetIpv6Address(); + result.strSubnet = staticIpAddress.GetIpv6Mask(); + result.strDns1 = staticIpAddress.dnsServer1.GetIpv6Address(); + pDhcpResultNotify->OnSuccess(1, IF_NAME, result); break; } case IPTYPE_MIX: { - result[0].isOptSuc = true; - result[0].iptype = IPTYPE_IPV4; - result[0].ip = staticIpAddress.ipAddress.address.GetIpv4Address(); - result[0].gateWay = staticIpAddress.gateway.GetIpv4Address(); - result[0].subnet = staticIpAddress.GetIpv4Mask(); - result[0].dns = staticIpAddress.dnsServer1.GetIpv4Address(); - result[0].dns2 = staticIpAddress.dnsServer2.GetIpv4Address(); - - result[1].isOptSuc = true; - result[1].iptype = IPTYPE_IPV6; - result[1].ip = staticIpAddress.ipAddress.address.GetIpv6Address(); - result[1].gateWay = staticIpAddress.gateway.GetIpv6Address(); - result[1].subnet = staticIpAddress.GetIpv6Mask(); - result[1].dns = staticIpAddress.dnsServer1.GetIpv6Address(); - result[1].dns2 = staticIpAddress.dnsServer2.GetIpv6Address(); + result.iptype = IPTYPE_IPV4; + result.strYourCli = staticIpAddress.ipAddress.address.GetIpv4Address(); + result.strRouter1 = staticIpAddress.gateway.GetIpv4Address(); + result.strSubnet = staticIpAddress.GetIpv4Mask(); + result.strDns1 = staticIpAddress.dnsServer1.GetIpv4Address(); + pDhcpResultNotify->OnSuccess(1, IF_NAME, result); + + result.iptype = IPTYPE_IPV6; + result.strYourCli = staticIpAddress.ipAddress.address.GetIpv6Address(); + result.strRouter1 = staticIpAddress.gateway.GetIpv6Address(); + result.strSubnet = staticIpAddress.GetIpv6Mask(); + result.strDns1 = staticIpAddress.dnsServer1.GetIpv6Address(); + pDhcpResultNotify->OnSuccess(1, IF_NAME, result); break; } default: return false; } - - HandleDhcpResult(result); return true; } -void StaStateMachine::HandleDhcpResult(const DhcpResult &dhcpResult) -{ - WIFI_LOGI("Enter HandleDhcpResult"); - bool isGetIpSuc = false; - bool isSetIpSuc = false; - - /* number 2 is the number of ip_type */ - for (int index = 0; index < 2; index++) { - WIFI_LOGI("HandleDhcpResult:isOptSuc=%{public}d, iptype=%{public}d, ip=%s, gateway=%s, " - "subnet=%s", - dhcpResult[index].isOptSuc, - dhcpResult[index].iptype, - dhcpResult[index].ip.c_str(), - dhcpResult[index].gateWay.c_str(), - dhcpResult[index].subnet.c_str()); - if (dhcpResult[index].isOptSuc) { - /* Configures network adapter. */ - if (index == 0) { - linkedInfo.ipAddress = IpTools::ConvertIpv4Address(dhcpResult[index].ip); - WifiSettings::GetInstance().SaveLinkedInfo(linkedInfo); - } - isGetIpSuc = true; - } - } - - /* Configures network adapter. */ - int ret = IfConfig::GetInstance().SetIfAddr(dhcpResult); - if (ret == 0) { - isSetIpSuc = true; - } - - if (!isGetIpSuc) { - SaveLinkstate(ConnState::CONNECTED, DetailedState::NOTWORKING); - statusId = static_cast(WifiDeviceConfigStatus::DISABLED); - NotifyResult(WifiInternalMsgCode::STA_CONNECT_RES, static_cast(OperateResState::CONNECT_OBTAINING_IP_FAIL)); - WIFI_LOGE("HandleDhcpResult get ip addr failed!"); - return; - } - - if (!isSetIpSuc) { - SaveLinkstate(ConnState::CONNECTED, DetailedState::NOTWORKING); - statusId = static_cast(WifiDeviceConfigStatus::DISABLED); - NotifyResult(WifiInternalMsgCode::STA_CONNECT_RES, static_cast(OperateResState::CONNECT_NETWORK_DISABLED)); - WIFI_LOGE("HandleDhcpResult SetIfConfig failed!"); - return; - } else { - WIFI_LOGI("HandleDhcpResult SetIfConfig succeed!"); - NotifyResult(WifiInternalMsgCode::STA_CONNECT_RES, static_cast(OperateResState::CONNECT_AP_CONNECTED)); - /* Update the uplink and downlink network rates periodically. */ - StartTimer(static_cast(CMD_GET_NETWORK_SPEED), STA_NETWORK_SPEED_DELAY); - } - - sleep(SLEEPTIME); /* Wait for the network adapter information to take effect. */ - - /* Portal hotspot checking. */ - if (PortalHttpDetection() != 0) { - pNetcheck->SignalNetCheckThread(currentTpType); - } - /* Check whether the Internet access is normal by ping command. */ -} - void StaStateMachine::HandleNetCheckResult(StaNetState netState) { WIFI_LOGI("Enter HandleNetCheckResult"); @@ -1774,6 +1733,83 @@ void StaStateMachine::SetWifiLinkedInfo(int networkId) } } + +/* ------------------ state machine dhcp callback function ----------------- */ + +StaStateMachine::DhcpResultNotify::DhcpResultNotify(StaStateMachine *staStateMachine) +{ + pStaStateMachine = staStateMachine; +} + +StaStateMachine::DhcpResultNotify::~DhcpResultNotify() +{} + +void StaStateMachine::DhcpResultNotify::OnSuccess(int status, const std::string &ifname, DhcpResult &result) +{ + WIFI_LOGI("Enter DhcpResultNotify::OnSuccess"); + if (ifname.compare("wlan0") == 0) { + WIFI_LOGD("iptype=%d, ip=%s, gateway=%s, subnet=%s, serverAddress=%s, leaseDuration=%d", + result.iptype, + result.strYourCli.c_str(), + result.strSubnet.c_str(), + result.strRouter1.c_str(), + result.strServer.c_str(), + result.uLeaseTime); + + if (result.iptype == 0) { + DhcpInfo dhcpInfo; + dhcpInfo.ipAddress = IpTools::ConvertIpv4Address(result.strYourCli); + dhcpInfo.netGate = IpTools::ConvertIpv4Address(result.strRouter1); + dhcpInfo.netMask = IpTools::ConvertIpv4Address(result.strSubnet); + dhcpInfo.dns1 = IpTools::ConvertIpv4Address(result.strDns1); + dhcpInfo.dns2 = IpTools::ConvertIpv4Address(result.strDns2); + dhcpInfo.serverAddress = IpTools::ConvertIpv4Address(result.strServer); + dhcpInfo.leaseDuration = result.uLeaseTime; + WifiSettings::GetInstance().SaveDhcpInfo(dhcpInfo); + pStaStateMachine->linkedInfo.ipAddress = IpTools::ConvertIpv4Address(result.strYourCli); + WifiSettings::GetInstance().SaveLinkedInfo(pStaStateMachine->linkedInfo); + } + + IfConfig::GetInstance().SetIfAddr(result, result.iptype); + if (pStaStateMachine->getIpSucNum == 0) { + pStaStateMachine->SaveLinkstate(ConnState::CONNECTED, DetailedState::CONNECTED); + pStaStateMachine->NotifyResult( + WifiInternalMsgCode::STA_CONNECT_RES, static_cast(OperateResState::CONNECT_AP_CONNECTED)); + /* Wait for the network adapter information to take effect. */ + sleep(SLEEPTIME); + + /* Check whether the Internet access is normal by send http. */ + pStaStateMachine->pNetcheck->SignalNetCheckThread(); + } + pStaStateMachine->getIpSucNum++; + return; + } +} + +void StaStateMachine::DhcpResultNotify::OnFailed(int status, const std::string &ifname, const std::string &reason) +{ + WIFI_LOGI("Enter DhcpResultNotify::OnFailed"); + if (ifname.compare("wlan0") == 0) { + if (pStaStateMachine->currentTpType != IPTYPE_IPV4) { + if (pStaStateMachine->getIpSucNum == 0 && pStaStateMachine->getIpFailNum == 1) { + pStaStateMachine->NotifyResult( + WifiInternalMsgCode::STA_CONNECT_RES, static_cast(OperateResState::CONNECT_OBTAINING_IP_FAIL)); + pStaStateMachine->DisConnectProcess(); + } + } else { + pStaStateMachine->NotifyResult( + WifiInternalMsgCode::STA_CONNECT_RES, static_cast(OperateResState::CONNECT_OBTAINING_IP_FAIL)); + pStaStateMachine->DisConnectProcess(); + } + pStaStateMachine->getIpFailNum++; + } +} + +void StaStateMachine::DhcpResultNotify::OnSerExitNotify(const std::string &ifname) +{ + WIFI_LOGI("Enter DhcpResultNotify::OnSerExitNotify"); +} + /* ------------------ state machine Comment function ----------------- */ void StaStateMachine::NotifyResult(int msgCode, int stateCode) { diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_state_machine.h b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_state_machine.h index be0a10817..b6cd277a0 100755 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_state_machine.h +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_state_machine.h @@ -26,9 +26,10 @@ #include "wifi_msg.h" #include "state_machine.h" #include "wifi_sta_hal_interface.h" -#include "sta_dhcp_server.h" #include "sta_network_speed.h" #include "sta_network_check.h" +#include "dhcp_service.h" +#include "i_dhcp_result_notify.h" #include "sta_define.h" namespace OHOS { @@ -253,6 +254,48 @@ public: StaStateMachine *pStaStateMachine; }; + class DhcpResultNotify : public IDhcpResultNotify { + public: + /** + * @Description : Construct a new dhcp result notify object + * + */ + explicit DhcpResultNotify(StaStateMachine *pStaStateMachine); + + /** + * @Description : Destroy the dhcp result notify object + * + */ + ~DhcpResultNotify() override; + + /** + * @Description : Get dhcp result of specified interface success notify asynchronously + * + * @param status - int + * @param ifname - interface name,eg:wlan0 + * @param result - dhcp result + */ + void OnSuccess(int status, const std::string &ifname, DhcpResult &result) override; + + /** + * @Description : Get dhcp result of specified interface failed notify asynchronously + * + * @param status - int + * @param ifname - interface name,eg:wlan0 + * @param reason - failed reason + */ + void OnFailed(int status, const std::string &ifname, const std::string &reason) override; + + /** + * @Description : Get the abnormal exit notify of dhcp server process. + * + * @param ifname - interface name,eg:wlan0 + */ + void OnSerExitNotify(const std::string& ifname) override; + private: + StaStateMachine *pStaStateMachine; + }; + public: /** * @Description Initialize StaStateMachine @@ -421,12 +464,6 @@ private: */ bool ConfigStaticIpAddress(StaticIpAddress &staticIpAddress); int PortalHttpDetection(); - /** - * @Description Processing obtaining result of ip from dhcp. - * - * @param dhcpResult - the results needed to handle from dhcp(in) - */ - void HandleDhcpResult(const DhcpResult &dhcpResult); /** * @Description the process of handling network check results. * @@ -564,9 +601,12 @@ private: std::string targetRoamBssid; int currentTpType; IsWpsConnected isWpsConnect; + int getIpSucNum; + int getIpFailNum; WifiLinkedInfo linkedInfo; WifiLinkedInfo lastLinkedInfo; - StaDhcpServer *pDhcpServer; + IDhcpService *pDhcpService; + DhcpResultNotify *pDhcpResultNotify; StaNetWorkSpeed *pNetSpeed; StaNetworkCheck *pNetcheck; WifiMessageQueue *msgQueueUp; /* Uplink message queue. */ -- Gitee From 84cdd8c06e6acccd1ba7638dbbe0eb884d7c56a6 Mon Sep 17 00:00:00 2001 From: Fagan Date: Wed, 7 Jul 2021 11:39:26 +0800 Subject: [PATCH 2/3] fix compile error. --- .../wifi_standard/wifi_framework/wifi_manage/wifi_sta/BUILD.gn | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/BUILD.gn b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/BUILD.gn index 24335352a..0ade06f43 100644 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/BUILD.gn +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/BUILD.gn @@ -57,6 +57,8 @@ ohos_shared_library("wifi_sta_service") { "//foundation/communication/wifi/services/wifi_standard/depends/include/system/core/libutils/include", "//foundation/communication/wifi/services/wifi_standard/depends/include/system/core/base/include", "//foundation/communication/wifi/services/wifi_standard/depends/include/system/libbase/include", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/include", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/interfaces", ] cflags_cc = [ -- Gitee From da8e7eb064fe5e342561c9d810553044d802344f Mon Sep 17 00:00:00 2001 From: Fagan Date: Thu, 15 Jul 2021 18:19:16 +0800 Subject: [PATCH 3/3] fixed dhcp ipv4 client issue --- .../wifi_standard/wifi_framework/BUILD.gn | 2 +- .../dhcp_client/include/dhcp_client.h | 11 +- .../dhcp_client/include/dhcp_define.h | 32 +- .../dhcp_client/include/dhcp_function.h | 2 +- .../dhcp_client/include/dhcp_ipv4.h | 6 + .../dhcp_client/include/dhcp_socket.h | 14 +- .../dhcp_manage/dhcp_client/src/dhcp_client.c | 18 +- .../dhcp_client/src/dhcp_function.c | 23 +- .../dhcp_manage/dhcp_client/src/dhcp_ipv4.c | 827 +++++++++--------- .../dhcp_manage/dhcp_client/src/dhcp_main.c | 124 +-- .../dhcp_client/src/dhcp_options.c | 7 +- .../dhcp_manage/dhcp_client/src/dhcp_socket.c | 420 +++++---- .../dhcp_manage/{ => mgr_service}/BUILD.gn | 12 +- .../include/dhcp_client_service_impl.h | 46 +- .../{ => mgr_service}/include/dhcp_define.h | 0 .../{ => mgr_service}/include/dhcp_func.h | 2 +- .../include/dhcp_server_service_impl.h | 78 +- .../{ => mgr_service}/include/dhcp_service.h | 0 .../interfaces/i_dhcp_client_service.h | 0 .../interfaces/i_dhcp_result_notify.h | 0 .../interfaces/i_dhcp_server_service.h | 0 .../interfaces/i_dhcp_service.h | 0 .../src/dhcp_client_service_impl.cpp | 0 .../{ => mgr_service}/src/dhcp_func.cpp | 13 +- .../src/dhcp_server_service_impl.cpp | 9 +- .../{ => mgr_service}/src/dhcp_service.cpp | 0 .../wifi_manage/wifi_sta/BUILD.gn | 6 +- .../wifi_sta/sta_state_machine.cpp | 1 + 28 files changed, 853 insertions(+), 800 deletions(-) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/BUILD.gn (81%) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/include/dhcp_client_service_impl.h (99%) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/include/dhcp_define.h (100%) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/include/dhcp_func.h (98%) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/include/dhcp_server_service_impl.h (100%) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/include/dhcp_service.h (100%) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/interfaces/i_dhcp_client_service.h (100%) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/interfaces/i_dhcp_result_notify.h (100%) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/interfaces/i_dhcp_server_service.h (100%) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/interfaces/i_dhcp_service.h (100%) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/src/dhcp_client_service_impl.cpp (100%) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/src/dhcp_func.cpp (97%) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/src/dhcp_server_service_impl.cpp (99%) rename services/wifi_standard/wifi_framework/dhcp_manage/{ => mgr_service}/src/dhcp_service.cpp (100%) diff --git a/services/wifi_standard/wifi_framework/BUILD.gn b/services/wifi_standard/wifi_framework/BUILD.gn index 84e80d5ea..cade18e52 100644 --- a/services/wifi_standard/wifi_framework/BUILD.gn +++ b/services/wifi_standard/wifi_framework/BUILD.gn @@ -34,7 +34,7 @@ group("wifi_manage") { group("dhcp_manage") { deps = [ - "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage:dhcp_manager_service", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service:dhcp_manager_service", "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client:dhcp_client_service" ] } \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_client.h b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_client.h index 1bb0acede..3bc347442 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_client.h +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_client.h @@ -36,11 +36,11 @@ enum DHCP_IP_TYPE { struct DhcpClientCfg { char workdir[DIR_MAX_LEN]; - char conf_file[DIR_MAX_LEN]; - char pid_file[DIR_MAX_LEN]; - char result_file[DIR_MAX_LEN]; + char confFile[DIR_MAX_LEN]; + char pidFile[DIR_MAX_LEN]; + char resultFile[DIR_MAX_LEN]; char interface[INFNAME_SIZE]; /* The name of the interface to use */ - int ifindex; /* Index number of the interface to use */ + int ifaceIndex; /* Index number of the interface to use */ unsigned int ipaddr4; /* ipv4 of the interface to use */ unsigned int iptype; unsigned char hwaddr[MAC_ADDR_LEN]; /* HWaddr of the interface to use */ @@ -49,12 +49,13 @@ struct DhcpClientCfg { unsigned char *hostname; /* Optional hostname to use */ bool timeoutExit; /* Send packet timed out */ }; -extern struct DhcpClientCfg gClientCfg; int StartProcess(void); int StopProcess(const char *pidFile); int GetProStatus(const char *pidFile); +struct DhcpClientCfg *GetDhcpClientCfg(void); + #ifdef __cplusplus } #endif diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_define.h b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_define.h index 5c67cc662..ffe9ee538 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_define.h +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_define.h @@ -35,17 +35,13 @@ extern "C" { #define T1 0.5 #define T2 0.875 #define TIME_INTERVAL_MAX 1 -#define SENDPACKET_MAXNUM 3 -#define TIMEOUT_TIMES_MAX 4 +#define TIMEOUT_TIMES_MAX 6 #define TIMEOUT_WAIT_SEC 1 -#define TIMEOUT_ONE_WAIT_SEC 1 -#define TIMEOUT_TWO_WAIT_SEC 10 -#define TIMEOUT_THREE_WAIT_SEC 30 #define TIMEOUT_MORE_WAIT_SEC 60 #define ONE_HOURS_SEC 3600 #define LEASETIME_DEFAULT 1 -#define SLEEP_TIME_200_MS 200 * 1000 -#define SLEEP_TIME_500_MS 500 * 1000 +#define SLEEP_TIME_200_MS (200 * 1000) +#define SLEEP_TIME_500_MS (500 * 1000) #define MAC_ADDR_LEN 6 #define MAC_ADDR_CHAR_NUM 3 @@ -61,16 +57,6 @@ extern "C" { #define DIR_MAX_LEN 256 #define INFNAME_SIZE 16 /* Length of interface name */ -/* dhcp4 state */ -#define INIT_SELECTING 0 -#define REQUESTING 1 -#define BOUND 2 -#define RENEWING 3 -#define REBINDING 4 -#define INIT_REBOOT 5 -#define RENEW_REQUESTED 6 -#define RELEASED 7 - /* UDP port numbers for BOOTP */ #define BOOTP_SERVER 67 #define BOOTP_CLIENT 68 @@ -90,6 +76,18 @@ extern "C" { #define DHCP_INFORM 8 #define DHCP_FORCERENEW 9 +/* dhcp state code */ +enum EnumDhcpStateCode { + DHCP_STATE_INIT = 0, + DHCP_STATE_SELECTING, + DHCP_STATE_REQUESTING, + DHCP_STATE_BOUND, + DHCP_STATE_RENEWING, + DHCP_STATE_REBINDING, + DHCP_STATE_RELEASED, + DHCP_STATE_RENEWED, +}; + /* dhcp return code */ enum EnumErrCode { /* success */ diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_function.h b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_function.h index 6f4675c89..82b2958c6 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_function.h +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_function.h @@ -32,7 +32,7 @@ int GetLocalInterface(const char *ifname, int *ifindex, unsigned char *hwaddr, u int GetLocalIp(const char *ifname, uint32_t *ifaddr4); int SetLocalInterface(const char *ifname, uint32_t ifaddr4); -int InitPidfile(const char *pidDir, const char *pidFile); +int InitPidfile(const char *pidDir, const char *pidFile, pid_t pid); pid_t GetPID(const char *pidFile); #ifdef __cplusplus diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_ipv4.h b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_ipv4.h index 826e44ff8..18ac401f5 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_ipv4.h +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_ipv4.h @@ -17,11 +17,17 @@ #include +#include "dhcp_define.h" + #ifdef __cplusplus extern "C" { #endif +int SetIpv4State(int state); int InitSignalHandle(void); + +int GetPacketHeaderInfo(struct DhcpPacket *packet, uint8_t type); +int GetPacketCommonInfo(struct DhcpPacket *packet); int DhcpDiscover(uint32_t transid, uint32_t requestip); int DhcpRequest(uint32_t transid, uint32_t reqip, uint32_t servip); int DhcpRenew(uint32_t transid, uint32_t clientip, uint32_t serverip); diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_socket.h b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_socket.h index e76dca897..453fa155d 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_socket.h +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/include/dhcp_socket.h @@ -22,11 +22,19 @@ extern "C" { #endif -int CreateRawSocket(int ifindex); -int CreateSocket(const char *ifname, uint32_t ip, int port); +int CreateRawSocket(int *rawFd); +int BindRawSocket(const int rawFd, const int ifaceIndex, const uint8_t *ifaceAddr); + +int CreateKernelSocket(int *sockFd); +int BindKernelSocket(const int sockFd, const char *ifaceName, const uint32_t sockIp, const int sockPort, bool bCast); + int SendToDhcpPacket( - const struct DhcpPacket *sendPacket, uint32_t srcIp, uint32_t destIp, const uint8_t *destHwaddr, int ifindex); + const struct DhcpPacket *sendPacket, uint32_t srcIp, uint32_t destIp, int destIndex, const uint8_t *destHwaddr); int SendDhcpPacket(struct DhcpPacket *sendPacket, uint32_t srcIp, uint32_t destIp); +int CheckReadBytes(const int count, const int totLen); +int CheckUdpPacket(struct UdpDhcpPacket *packet, const int totLen); +int CheckPacketIpSum(struct UdpDhcpPacket *udpPacket, const int bytes); +int CheckPacketUdpSum(struct UdpDhcpPacket *udpPacket, const int bytes); int GetDhcpRawPacket(struct DhcpPacket *getPacket, int fd); int GetDhcpPacket(struct DhcpPacket *getPacket, int fd); diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_client.c b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_client.c index a34d667d8..5fb048887 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_client.c +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_client.c @@ -30,31 +30,34 @@ #define LOG_TAG "WifiDhcpClient" /* Default options. */ -struct DhcpClientCfg gClientCfg = {"", "", "", "", "", 0, 0, DHCP_IP_TYPE_NONE, {'\0'}, NULL, NULL, false}; +static struct DhcpClientCfg g_clientCfg = {"", "", "", "", "", 0, 0, DHCP_IP_TYPE_NONE, {'\0'}, NULL, NULL, false}; + +struct DhcpClientCfg *GetDhcpClientCfg(void) +{ + return &g_clientCfg; +} int StartProcess(void) { + LOGI("StartProcess() begin.\n"); if (InitSignalHandle() != DHCP_OPT_SUCCESS) { - LOGE("StartProcess() failed, InitSignalHandle error!\n"); return DHCP_OPT_FAILED; } - if ((gClientCfg.iptype == DHCP_IP_TYPE_ALL) || (gClientCfg.iptype == DHCP_IP_TYPE_V6)) { + if ((g_clientCfg.iptype == DHCP_IP_TYPE_ALL) || (g_clientCfg.iptype == DHCP_IP_TYPE_V6)) { /* Handle dhcp v6. */ } - if ((gClientCfg.iptype == DHCP_IP_TYPE_ALL) || (gClientCfg.iptype == DHCP_IP_TYPE_V4)) { + if ((g_clientCfg.iptype == DHCP_IP_TYPE_ALL) || (g_clientCfg.iptype == DHCP_IP_TYPE_V4)) { /* Handle dhcp v4. */ StartIpv4(); } - return DHCP_OPT_SUCCESS; } int StopProcess(const char *pidFile) { - LOGI("StopProcess() enter, pidFile:%{public}s.\n", pidFile); - + LOGI("StopProcess() begin, pidFile:%{public}s.\n", pidFile); pid_t pid = GetPID(pidFile); if (pid <= 0) { LOGW("StopProcess() GetPID pidFile:%{public}s, pid == -1!\n", pidFile); @@ -72,7 +75,6 @@ int StopProcess(const char *pidFile) return DHCP_OPT_FAILED; } - LOGI("StopProcess() end.\n"); unlink(pidFile); return DHCP_OPT_SUCCESS; } diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_function.c b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_function.c index 5c2d5fc83..69300b47e 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_function.c +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_function.c @@ -30,7 +30,6 @@ #include #include #include -#include #include "securec.h" #include "dhcp_define.h" @@ -41,7 +40,7 @@ bool Ip4StrConToInt(const char *strIp, uint32_t *uIp, bool bHost) { - if ((strIp == NULL) || (strlen(strIp) <= 0)) { + if ((strIp == NULL) || (strlen(strIp) == 0)) { LOGE("Ip4StrConToInt failed, strIp == NULL or \"\"!\n"); return false; } @@ -89,6 +88,7 @@ char *Ip4IntConToStr(uint32_t uIp, bool bHost) } if (strncpy_s(strIp, INET_ADDRSTRLEN, bufIp4, strlen(bufIp4)) != EOK) { LOGE("Ip4IntConToStr uIp:%{public}u failed, strIp strncpy_s failed!\n", uIp); + free(strIp); return NULL; } @@ -97,7 +97,7 @@ char *Ip4IntConToStr(uint32_t uIp, bool bHost) bool Ip6StrConToChar(const char *strIp, uint8_t chIp[], size_t chlen) { - if ((strIp == NULL) || (strlen(strIp) <= 0)) { + if ((strIp == NULL) || (strlen(strIp) == 0)) { LOGE("Ip6StrConToChar failed, strIp == NULL or \"\"!\n"); return false; } @@ -156,7 +156,7 @@ const char *HwaddrNtoa(const unsigned char *hwaddr, size_t hwlen, char *buf, siz int GetLocalInterface(const char *ifname, int *ifindex, unsigned char *hwaddr, uint32_t *ifaddr4) { - if ((ifname == NULL) || (strlen(ifname) <= 0)) { + if ((ifname == NULL) || (strlen(ifname) == 0)) { LOGE("GetLocalInterface() failed, ifname == NULL or \"\"!\n"); return DHCP_OPT_FAILED; } @@ -212,12 +212,13 @@ int GetLocalInterface(const char *ifname, int *ifindex, unsigned char *hwaddr, u int GetLocalIp(const char *ifname, uint32_t *ifaddr4) { - if ((ifname == NULL) || (strlen(ifname) <= 0)) { + if ((ifname == NULL) || (strlen(ifname) == 0)) { LOGE("GetLocalIp() failed, ifname == NULL or \"\"!\n"); return DHCP_OPT_FAILED; } - struct ifaddrs *ifaddr = NULL, *ifa = NULL; + struct ifaddrs *ifaddr = NULL; + struct ifaddrs *ifa = NULL; int family, s; char strIp[NI_MAXHOST]; @@ -271,7 +272,7 @@ int GetLocalIp(const char *ifname, uint32_t *ifaddr4) int SetLocalInterface(const char *ifname, uint32_t ifaddr4) { - if ((ifname == NULL) || (strlen(ifname) <= 0)) { + if ((ifname == NULL) || (strlen(ifname) == 0)) { LOGE("SetLocalInterface() failed, ifname == NULL or \"\"!\n"); return DHCP_OPT_FAILED; } @@ -320,9 +321,9 @@ int SetLocalInterface(const char *ifname, uint32_t ifaddr4) return DHCP_OPT_SUCCESS; } -int InitPidfile(const char *pidDir, const char *pidFile) +int InitPidfile(const char *pidDir, const char *pidFile, pid_t pid) { - if ((pidDir == NULL) || (strlen(pidDir) <= 0) || (pidFile == NULL) || (strlen(pidFile) <= 0)) { + if ((pidDir == NULL) || (strlen(pidDir) == 0) || (pidFile == NULL) || (strlen(pidFile) == 0)) { LOGE("InitPidfile() failed, pidDir or pidFile == NULL or \"\"!\n"); return DHCP_OPT_FAILED; } @@ -336,8 +337,8 @@ int InitPidfile(const char *pidDir, const char *pidFile) } char buf[PID_MAX_LEN] = {0}; - if (snprintf_s(buf, PID_MAX_LEN, PID_MAX_LEN - 1, "%d", getpid()) < 0) { - LOGE("InitPidfile() pidFile:%{public}s failed, snprintf error:%{public}s!\n", pidFile, strerror(errno)); + if (snprintf_s(buf, PID_MAX_LEN, PID_MAX_LEN - 1, "%d", pid) < 0) { + LOGE("InitPidfile() pidFile:%{public}s failed, snprintf_s error:%{public}s!\n", pidFile, strerror(errno)); close(fd); return DHCP_OPT_FAILED; } diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_ipv4.c b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_ipv4.c index 3470d2212..604590a64 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_ipv4.c +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_ipv4.c @@ -39,20 +39,21 @@ #define LOG_TAG "WifiDhcpIpv4" /* static defined */ -static int g_dhcp4State = INIT_SELECTING; -static int sockFd = -1; -static int sentPacketNum = 0; -static int sigSockFds[NUMBER_TWO]; -static uint32_t timeoutTimestamp = 0; -static uint32_t renewalTimestamp = 0; -static uint32_t leaseTime = 0; -static uint32_t renewalSec = 0; -static uint32_t rebindSec = 0; -static uint32_t requestedIp4 = 0; -static uint32_t serverIp4 = 0; -static uint32_t socketMode = SOCKET_MODE_INVALID; -static uint32_t transID = 0; - +static int g_dhcp4State = DHCP_STATE_INIT; +static int g_sockFd = -1; +static int g_sigSockFds[NUMBER_TWO]; +static uint32_t g_sentPacketNum = 0; +static uint32_t g_timeoutTimestamp = 0; +static uint32_t g_renewalTimestamp = 0; +static uint32_t g_leaseTime = 0; +static uint32_t g_renewalSec = 0; +static uint32_t g_rebindSec = 0; +static uint32_t g_requestedIp4 = 0; +static uint32_t g_serverIp4 = 0; +static uint32_t g_socketMode = SOCKET_MODE_INVALID; +static uint32_t g_transID = 0; + +static struct DhcpClientCfg *g_cltCnf; /* Send signals. */ static void SignalHandler(int signum) @@ -64,7 +65,7 @@ static void SignalHandler(int signum) /* Send signal SIGUSR1. */ case SIGUSR2: /* Send signal SIGUSR2. */ - send(sigSockFds[1], &signum, sizeof(signum), MSG_DONTWAIT); + send(g_sigSockFds[1], &signum, sizeof(signum), MSG_DONTWAIT); break; default: break; @@ -74,9 +75,9 @@ static void SignalHandler(int signum) /* Set the socket mode. */ static void SetSocketMode(uint32_t mode) { - close(sockFd); - sockFd = -1; - socketMode = mode; + close(g_sockFd); + g_sockFd = -1; + g_socketMode = mode; LOGI("SetSocketMode() the socket mode %{public}s.\n", (mode == SOCKET_MODE_RAW) ? "raw" : ((mode == SOCKET_MODE_KERNEL) ? "kernel" : "not valid")); } @@ -85,16 +86,17 @@ static void SetSocketMode(uint32_t mode) static void ExecDhcpRelease(void) { /* Ensure that we've received dhcp ack packet completely. */ - if ((g_dhcp4State == BOUND) || (g_dhcp4State == RENEWING) || (g_dhcp4State == REBINDING)) { + if ((g_dhcp4State == DHCP_STATE_BOUND) || (g_dhcp4State == DHCP_STATE_RENEWING) || + (g_dhcp4State == DHCP_STATE_REBINDING)) { /* Unicast dhcp release packet. */ - DhcpRelease(requestedIp4, serverIp4); + DhcpRelease(g_requestedIp4, g_serverIp4); } - g_dhcp4State = RELEASED; + g_dhcp4State = DHCP_STATE_RELEASED; SetSocketMode(SOCKET_MODE_INVALID); /* Ensure that the function select() is always blocked and don't need to receive ip from dhcp server. */ - timeoutTimestamp = SIGNED_INTEGER_MAX; + g_timeoutTimestamp = SIGNED_INTEGER_MAX; LOGI("ExecDhcpRelease() enter released state...\n"); } @@ -104,33 +106,34 @@ static void ExecDhcpRenew(void) { /* Set socket mode and dhcp ipv4 state, make sure dhcp packets can be sent normally. */ switch (g_dhcp4State) { - case INIT_SELECTING: - LOGI("ExecDhcpRenew() dhcp ipv4 old state:INIT_SELECTING, no need change state.\n"); + case DHCP_STATE_INIT: + case DHCP_STATE_SELECTING: + LOGI("ExecDhcpRenew() dhcp ipv4 old state:%{public}d, no need change state.\n", g_dhcp4State); break; - case REQUESTING: - case RENEW_REQUESTED: - case RELEASED: - LOGI("ExecDhcpRenew() dhcp ipv4 old state:%{public}d, init state:INIT_SELECTING.\n", g_dhcp4State); + case DHCP_STATE_REQUESTING: + case DHCP_STATE_RELEASED: + case DHCP_STATE_RENEWED: + LOGI("ExecDhcpRenew() dhcp ipv4 old state:%{public}d, init state:INIT.\n", g_dhcp4State); /* Init socket mode and dhcp ipv4 state. */ - g_dhcp4State = INIT_SELECTING; + g_dhcp4State = DHCP_STATE_INIT; SetSocketMode(SOCKET_MODE_RAW); break; - case BOUND: + case DHCP_STATE_BOUND: /* Set socket mode, send unicast packet. */ SetSocketMode(SOCKET_MODE_KERNEL); - case RENEWING: - case REBINDING: - LOGI("ExecDhcpRenew() dhcp ipv4 old state:%{public}d, set state:RENEW_REQUESTED.\n", g_dhcp4State); + case DHCP_STATE_RENEWING: + case DHCP_STATE_REBINDING: + LOGI("ExecDhcpRenew() dhcp ipv4 old state:%{public}d, set state:RENEWED.\n", g_dhcp4State); /* Set dhcp ipv4 state, send request packet. */ - g_dhcp4State = RENEW_REQUESTED; + g_dhcp4State = DHCP_STATE_RENEWED; break; default: break; } /* Start record again, go back to init state. */ - sentPacketNum = 0; - timeoutTimestamp = 0; + g_sentPacketNum = 0; + g_timeoutTimestamp = 0; LOGI("ExecDhcpRenew() a dhcp renew is executed...\n"); } @@ -154,34 +157,36 @@ static void AddParamaterRequestList(struct DhcpPacket *packet) packet->options[end + DHCP_OPT_DATA_INDEX + len] = DHO_END; } -/* Init packet common info. */ -static void GetPacketCommonInfo(struct DhcpPacket *packet, uint8_t type) +/* Init the socket fd. */ +static void InitSocketFd(void) { - if (memset_s(packet, sizeof(struct DhcpPacket), 0, sizeof(struct DhcpPacket)) != EOK) { - return; - } + if (g_sockFd < 0) { + if (g_socketMode == SOCKET_MODE_INVALID) { + return; + } - switch (type) { - case DHCP_DISCOVER: - case DHCP_REQUEST: - case DHCP_RELEASE: - case DHCP_INFORM: - packet->op = BOOT_REQUEST; - break; - case DHCP_OFFER: - case DHCP_ACK: - case DHCP_NAK: - packet->op = BOOT_REPLY; - break; - default: - break; + bool bInitSuccess = true; + if (g_socketMode == SOCKET_MODE_RAW) { + if ((CreateRawSocket(&g_sockFd) != SOCKET_OPT_SUCCESS) || + (BindRawSocket(g_sockFd, g_cltCnf->ifaceIndex, NULL) != SOCKET_OPT_SUCCESS)) { + LOGE("InitSocketFd() fd:%{public}d,index:%{public}d failed!\n", g_sockFd, g_cltCnf->ifaceIndex); + bInitSuccess = false; + } + } else { + if ((CreateKernelSocket(&g_sockFd) != SOCKET_OPT_SUCCESS) || + (BindKernelSocket(g_sockFd, g_cltCnf->interface, INADDR_ANY, BOOTP_CLIENT, true) != + SOCKET_OPT_SUCCESS)) { + LOGE("InitSocketFd() fd:%{public}d,ifname:%{public}s failed!\n", g_sockFd, g_cltCnf->interface); + bInitSuccess = false; + } + } + if (!bInitSuccess || (g_sockFd < 0)) { + LOGE("InitSocketFd() %{public}d err:%{public}s, couldn't listen on socket!\n", g_sockFd, strerror(errno)); + unlink(g_cltCnf->pidFile); + unlink(g_cltCnf->resultFile); + exit(EXIT_SUCCESS); + } } - packet->htype = ETHERNET_TYPE; - packet->hlen = ETHERNET_LEN; - packet->cookie = htonl(MAGIC_COOKIE); - packet->options[0] = DHO_END; - - AddSimpleOption(packet->options, DHO_MESSAGETYPE, type); } /* Create a random xid. */ @@ -206,147 +211,113 @@ static uint32_t GetTransId(void) return random(); } -/* Init the socket fd. */ -static void InitSocketFd(void) -{ - if ((sockFd < 0) && (socketMode != SOCKET_MODE_INVALID)) { - if (socketMode == SOCKET_MODE_RAW) { - sockFd = CreateRawSocket(gClientCfg.ifindex); - } else { - sockFd = CreateSocket(gClientCfg.interface, INADDR_ANY, BOOTP_CLIENT); - } - - if (sockFd < 0) { - /* Init failed: couldn't listen on socket. */ - LOGE("InitSocketFd() sockFd:%{public}d failed, couldn't listen on socket, error:%{public}s!\n", - sockFd, strerror(errno)); - unlink(gClientCfg.pid_file); - unlink(gClientCfg.result_file); - exit(EXIT_SUCCESS); - } - } -} - static void InitSelecting(time_t timestamp) { - if (sentPacketNum >= SENDPACKET_MAXNUM * TIMEOUT_TIMES_MAX) { + if (g_sentPacketNum > TIMEOUT_TIMES_MAX) { /* Send packet timed out, now exit process. */ - LOGW("InitSelecting() send packet timed out %{public}d times, now exit process!\n", sentPacketNum); - timeoutTimestamp = timestamp + TIMEOUT_MORE_WAIT_SEC; - sentPacketNum = 0; - gClientCfg.timeoutExit = true; + LOGW("InitSelecting() send packet timed out %{public}u times, now exit process!\n", g_sentPacketNum); + g_timeoutTimestamp = timestamp + TIMEOUT_MORE_WAIT_SEC; + g_sentPacketNum = 0; + g_cltCnf->timeoutExit = true; return; } - uint32_t uTimeoutSec; - if (sentPacketNum < SENDPACKET_MAXNUM) { - if (sentPacketNum == 0) { - transID = GetTransId(); - } - uTimeoutSec = TIMEOUT_WAIT_SEC; - } else { - uTimeoutSec = - (sentPacketNum < SENDPACKET_MAXNUM * NUMBER_TWO) - ? TIMEOUT_ONE_WAIT_SEC - : ((sentPacketNum < SENDPACKET_MAXNUM * NUMBER_THREE) ? TIMEOUT_TWO_WAIT_SEC : TIMEOUT_THREE_WAIT_SEC); + if (g_sentPacketNum == 0) { + g_transID = GetTransId(); } /* Broadcast dhcp discover packet. */ - DhcpDiscover(transID, requestedIp4); + DhcpDiscover(g_transID, g_requestedIp4); + if (g_dhcp4State != DHCP_STATE_SELECTING) { + g_dhcp4State = DHCP_STATE_SELECTING; + } - timeoutTimestamp = timestamp + uTimeoutSec; - LOGI("InitSelecting() DhcpDiscover sentPacketNum:%{public}d,timeoutSec:%{public}u,timestamp:%{public}u.\n", - sentPacketNum, + uint32_t uTimeoutSec = TIMEOUT_WAIT_SEC << g_sentPacketNum; + g_timeoutTimestamp = timestamp + uTimeoutSec; + LOGI("InitSelecting() DhcpDiscover g_sentPacketNum:%{public}u,timeoutSec:%{public}u,timestamp:%{public}u.\n", + g_sentPacketNum, uTimeoutSec, - timeoutTimestamp); + g_timeoutTimestamp); - sentPacketNum++; + g_sentPacketNum++; } static void Requesting(time_t timestamp) { - if (sentPacketNum >= SENDPACKET_MAXNUM * TIMEOUT_TIMES_MAX) { + if (g_sentPacketNum > TIMEOUT_TIMES_MAX) { /* Send packet timed out, now enter init state. */ - g_dhcp4State = INIT_SELECTING; + g_dhcp4State = DHCP_STATE_INIT; SetSocketMode(SOCKET_MODE_RAW); - sentPacketNum = 0; - timeoutTimestamp = timestamp; + g_sentPacketNum = 0; + g_timeoutTimestamp = timestamp; return; } - if (g_dhcp4State == RENEW_REQUESTED) { + if (g_dhcp4State == DHCP_STATE_RENEWED) { /* Unicast dhcp request packet in the renew state. */ - DhcpRenew(transID, requestedIp4, serverIp4); + DhcpRenew(g_transID, g_requestedIp4, g_serverIp4); } else { /* Broadcast dhcp request packet in the requesting state. */ - DhcpRequest(transID, requestedIp4, serverIp4); + DhcpRequest(g_transID, g_requestedIp4, g_serverIp4); } - uint32_t uTimeoutSec; - if (sentPacketNum < SENDPACKET_MAXNUM) { - uTimeoutSec = TIMEOUT_WAIT_SEC; - } else { - uTimeoutSec = - (sentPacketNum < SENDPACKET_MAXNUM * NUMBER_TWO) - ? TIMEOUT_ONE_WAIT_SEC - : ((sentPacketNum < SENDPACKET_MAXNUM * NUMBER_THREE) ? TIMEOUT_TWO_WAIT_SEC : TIMEOUT_THREE_WAIT_SEC); - } - timeoutTimestamp = timestamp + uTimeoutSec; - LOGI("Requesting() DhcpRequest sentPacketNum:%{public}d,timeoutSec:%{public}u,timeoutTimestamp:%{public}u.\n", - sentPacketNum, + uint32_t uTimeoutSec = TIMEOUT_WAIT_SEC << g_sentPacketNum; + g_timeoutTimestamp = timestamp + uTimeoutSec; + LOGI("Requesting() DhcpRequest g_sentPacketNum:%{public}u,timeoutSec:%{public}u,g_timeoutTimestamp:%{public}u.\n", + g_sentPacketNum, uTimeoutSec, - timeoutTimestamp); + g_timeoutTimestamp); - sentPacketNum++; + g_sentPacketNum++; } static void Renewing(time_t timestamp) { - if ((renewalSec + TIME_INTERVAL_MAX) < rebindSec) { + if ((g_renewalSec + TIME_INTERVAL_MAX) < g_rebindSec) { /* Cur time is between renewal and rebind time, unicast dhcp request packet in the renew state. */ - DhcpRenew(transID, requestedIp4, serverIp4); + DhcpRenew(g_transID, g_requestedIp4, g_serverIp4); /* Set a new renewal time. */ - renewalSec += (rebindSec - renewalSec) / NUMBER_TWO; - timeoutTimestamp = renewalTimestamp + renewalSec; + g_renewalSec += (g_rebindSec - g_renewalSec) / NUMBER_TWO; + g_timeoutTimestamp = g_renewalTimestamp + g_renewalSec; LOGI("Renewing() DhcpRenew unicast renewalTime:%{public}u,renewal:%{public}u,timeoutTime:%{public}u, " "rebind:%{public}u.\n", - renewalTimestamp, - renewalSec, - timeoutTimestamp, - rebindSec); + g_renewalTimestamp, + g_renewalSec, + g_timeoutTimestamp, + g_rebindSec); } else { /* Cur time reaches rebind time, now enter rebinding state. */ - g_dhcp4State = REBINDING; + g_dhcp4State = DHCP_STATE_REBINDING; LOGI("Renewing() cur time reaches rebind time, now enter rebinding state...\n"); - timeoutTimestamp = timestamp + (rebindSec - renewalSec); + g_timeoutTimestamp = timestamp + (g_rebindSec - g_renewalSec); LOGI("Renewing() timestamp:%{public}d,rebind:%{public}u,renewal:%{public}u, timeoutTime:%{public}u.\n", - (int)timestamp, rebindSec, renewalSec, timeoutTimestamp); + (int)timestamp, g_rebindSec, g_renewalSec, g_timeoutTimestamp); } } static void Rebinding(time_t timestamp) { - if ((rebindSec + TIME_INTERVAL_MAX) < leaseTime) { + if ((g_rebindSec + TIME_INTERVAL_MAX) < g_leaseTime) { /* Cur time is between rebind and lease time, broadcast dhcp request packet in the rebind state. */ - DhcpRenew(transID, requestedIp4, 0); + DhcpRenew(g_transID, g_requestedIp4, 0); /* Set a new rebind time. */ - rebindSec += (leaseTime - rebindSec) / NUMBER_TWO; - timeoutTimestamp = renewalTimestamp + rebindSec; + g_rebindSec += (g_leaseTime - g_rebindSec) / NUMBER_TWO; + g_timeoutTimestamp = g_renewalTimestamp + g_rebindSec; LOGI("Rebinding() DhcpRenew broadcast renewalTime:%{public}u,rebind:%{public}u,timeoutTime:%{public}u, " "lease:%{public}u.\n", - renewalTimestamp, - rebindSec, - timeoutTimestamp, - leaseTime); + g_renewalTimestamp, + g_rebindSec, + g_timeoutTimestamp, + g_leaseTime); } else { /* Cur time reaches lease time, send packet timed out, now enter init state. */ LOGI("Rebinding() 555 cur time reaches lease time, now enter init state...\n"); - g_dhcp4State = INIT_SELECTING; + g_dhcp4State = DHCP_STATE_INIT; SetSocketMode(SOCKET_MODE_RAW); - sentPacketNum = 0; - timeoutTimestamp = timestamp; + g_sentPacketNum = 0; + g_timeoutTimestamp = timestamp; return; } } @@ -354,27 +325,28 @@ static void Rebinding(time_t timestamp) static void DhcpRequestHandle(time_t timestamp) { switch (g_dhcp4State) { - case INIT_SELECTING: + case DHCP_STATE_INIT: + case DHCP_STATE_SELECTING: InitSelecting(timestamp); break; - case RENEW_REQUESTED: - case REQUESTING: + case DHCP_STATE_REQUESTING: + case DHCP_STATE_RENEWED: Requesting(timestamp); break; - case BOUND: + case DHCP_STATE_BOUND: /* Now the renewal time run out, ready to enter renewing state. */ LOGI("DhcpRequestHandle() 333 the renewal time run out, ready to enter renewing state...\n"); - g_dhcp4State = RENEWING; + g_dhcp4State = DHCP_STATE_RENEWING; SetSocketMode(SOCKET_MODE_KERNEL); - case RENEWING: + case DHCP_STATE_RENEWING: Renewing(timestamp); break; - case REBINDING: + case DHCP_STATE_REBINDING: Rebinding(timestamp); break; - case RELEASED: + case DHCP_STATE_RELEASED: /* Ensure that the function select() is always blocked and don't need to receive ip from dhcp server. */ - timeoutTimestamp = SIGNED_INTEGER_MAX; + g_timeoutTimestamp = SIGNED_INTEGER_MAX; break; default: break; @@ -399,31 +371,108 @@ static void DhcpOfferPacketHandle(uint8_t type, const struct DhcpPacket *packet, return; } - transID = packet->xid; - requestedIp4 = packet->yiaddr; - serverIp4 = htonl(u32Data); + g_transID = packet->xid; + g_requestedIp4 = packet->yiaddr; + g_serverIp4 = htonl(u32Data); - char *pReqIp = Ip4IntConToStr(requestedIp4, false); + char *pReqIp = Ip4IntConToStr(g_requestedIp4, false); if (pReqIp != NULL) { LOGI( "DhcpOfferPacketHandle() receive DHCP_OFFER, xid:%{public}u, requestIp: host %{public}u->%{public}s.\n", - transID, - ntohl(requestedIp4), + g_transID, + ntohl(g_requestedIp4), pReqIp); free(pReqIp); } - char *pSerIp = Ip4IntConToStr(serverIp4, false); + char *pSerIp = Ip4IntConToStr(g_serverIp4, false); if (pSerIp != NULL) { LOGI("DhcpOfferPacketHandle() receive DHCP_OFFER, serverIp: host %{public}u->%{public}s.\n", - ntohl(serverIp4), + ntohl(g_serverIp4), pSerIp); free(pSerIp); } /* Receive dhcp offer packet finished, next send dhcp request packet. */ - g_dhcp4State = REQUESTING; - sentPacketNum = 0; - timeoutTimestamp = timestamp; + g_dhcp4State = DHCP_STATE_REQUESTING; + g_sentPacketNum = 0; + g_timeoutTimestamp = timestamp; +} + +static void ParseOtherNetworkInfo(const struct DhcpPacket *packet, struct DhcpResult *result) +{ + if ((packet == NULL) || (result == NULL)) { + LOGE("ParseOtherNetworkInfo() error, packet == NULL or result == NULL!\n"); + return; + } + + uint32_t u32Data = 0; + uint32_t u32Data2 = 0; + if (GetDhcpOptionUint32n(packet, DHO_DNSSERVER, &u32Data, &u32Data2)) { + char *pDnsIp = Ip4IntConToStr(u32Data, true); + if (pDnsIp != NULL) { + LOGI("ParseOtherNetworkInfo() recv DHCP_ACK 6, dns1: %{public}u->%{public}s.\n", u32Data, pDnsIp); + if (strncpy_s(result->strOptDns1, INET_ADDRSTRLEN, pDnsIp, INET_ADDRSTRLEN - 1) != EOK) { + free(pDnsIp); + return; + } + free(pDnsIp); + pDnsIp = NULL; + } + if ((u32Data2 > 0) && ((pDnsIp = Ip4IntConToStr(u32Data2, true)) != NULL)) { + LOGI("ParseOtherNetworkInfo() recv DHCP_ACK 6, dns2: %{public}u->%{public}s.\n", u32Data2, pDnsIp); + if (strncpy_s(result->strOptDns2, INET_ADDRSTRLEN, pDnsIp, INET_ADDRSTRLEN - 1) != EOK) { + free(pDnsIp); + return; + } + free(pDnsIp); + } + } +} + +static void ParseNetworkInfo(const struct DhcpPacket *packet, struct DhcpResult *result) +{ + if ((packet == NULL) || (result == NULL)) { + LOGE("ParseNetworkInfo() error, packet == NULL or result == NULL!\n"); + return; + } + + uint32_t u32Data = 0; + if (GetDhcpOptionUint32(packet, DHO_SUBNETMASK, &u32Data)) { + char *pSubIp = Ip4IntConToStr(u32Data, true); + if (pSubIp != NULL) { + LOGI("ParseNetworkInfo() recv DHCP_ACK 1, subnetmask: %{public}u->%{public}s.\n", u32Data, pSubIp); + if (strncpy_s(result->strOptSubnet, INET_ADDRSTRLEN, pSubIp, INET_ADDRSTRLEN - 1) != EOK) { + free(pSubIp); + return; + } + free(pSubIp); + } + } + + u32Data = 0; + uint32_t u32Data2 = 0; + if (GetDhcpOptionUint32n(packet, DHO_ROUTER, &u32Data, &u32Data2)) { + char *pRouterIp = Ip4IntConToStr(u32Data, true); + if (pRouterIp != NULL) { + LOGI("ParseNetworkInfo() recv DHCP_ACK 3, router1: %{public}u->%{public}s.\n", u32Data, pRouterIp); + if (strncpy_s(result->strOptRouter1, INET_ADDRSTRLEN, pRouterIp, INET_ADDRSTRLEN - 1) != EOK) { + free(pRouterIp); + return; + } + free(pRouterIp); + pRouterIp = NULL; + } + if ((u32Data2 > 0) && ((pRouterIp = Ip4IntConToStr(u32Data2, true)) != NULL)) { + LOGI("ParseNetworkInfo() recv DHCP_ACK 3, router2: %{public}u->%{public}s.\n", u32Data2, pRouterIp); + if (strncpy_s(result->strOptRouter2, INET_ADDRSTRLEN, pRouterIp, INET_ADDRSTRLEN - 1) != EOK) { + free(pRouterIp); + return; + } + free(pRouterIp); + } + } + + ParseOtherNetworkInfo(packet, result); } static void FormatString(struct DhcpResult *result) @@ -433,42 +482,42 @@ static void FormatString(struct DhcpResult *result) return; } - if (strlen(result->strYiaddr) <= 0) { + if (strlen(result->strYiaddr) == 0) { if (strncpy_s(result->strYiaddr, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { return; } } - if (strlen(result->strOptServerId) <= 0) { + if (strlen(result->strOptServerId) == 0) { if (strncpy_s(result->strOptServerId, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { return; } } - if (strlen(result->strOptSubnet) <= 0) { + if (strlen(result->strOptSubnet) == 0) { if (strncpy_s(result->strOptSubnet, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { return; } } - if (strlen(result->strOptDns1) <= 0) { + if (strlen(result->strOptDns1) == 0) { if (strncpy_s(result->strOptDns1, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { return; } } - if (strlen(result->strOptDns2) <= 0) { + if (strlen(result->strOptDns2) == 0) { if (strncpy_s(result->strOptDns2, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { return; } } - if (strlen(result->strOptRouter1) <= 0) { + if (strlen(result->strOptRouter1) == 0) { if (strncpy_s(result->strOptRouter1, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { return; } } - if (strlen(result->strOptRouter2) <= 0) { + if (strlen(result->strOptRouter2) == 0) { if (strncpy_s(result->strOptRouter2, INET_ADDRSTRLEN, "*", INET_ADDRSTRLEN - 1) != EOK) { return; } } - if (strlen(result->strOptVendor) <= 0) { + if (strlen(result->strOptVendor) == 0) { if (strncpy_s(result->strOptVendor, DHCP_FILE_MAX_BYTES, "*", DHCP_FILE_MAX_BYTES - 1) != EOK) { return; } @@ -494,16 +543,16 @@ static void WriteDhcpResult(struct DhcpResult *result) result->strOptSubnet, result->uOptLeasetime, curTime); - FILE *pFile = fopen(gClientCfg.result_file, "w+"); + FILE *pFile = fopen(g_cltCnf->resultFile, "w+"); if (pFile == NULL) { - LOGE("WriteDhcpResult fopen %{public}s err:%{public}s!\n", gClientCfg.result_file, strerror(errno)); + LOGE("WriteDhcpResult fopen %{public}s err:%{public}s!\n", g_cltCnf->resultFile, strerror(errno)); return; } /* Lock the writing file. */ if (flock(fileno(pFile), LOCK_EX) != 0) { LOGE("WriteDhcpResult() flock file:%{public}s LOCK_EX failed, error:%{public}s!\n", - gClientCfg.result_file, strerror(errno)); + g_cltCnf->resultFile, strerror(errno)); fclose(pFile); return; } @@ -513,102 +562,25 @@ static void WriteDhcpResult(struct DhcpResult *result) result->strYiaddr, result->strOptServerId, result->strOptSubnet, result->strOptDns1, result->strOptDns2, result->strOptRouter1, result->strOptRouter2, result->strOptVendor, result->uOptLeasetime); if (nBytes <= 0) { - LOGE("WriteDhcpResult() fprintf %{public}s error:%{public}s!\n", gClientCfg.result_file, strerror(errno)); + LOGE("WriteDhcpResult() fprintf %{public}s error:%{public}s!\n", g_cltCnf->resultFile, strerror(errno)); fclose(pFile); return; } - LOGI("WriteDhcpResult() fprintf %{public}s success, nBytes:%{public}d.\n", gClientCfg.result_file, nBytes); + LOGI("WriteDhcpResult() fprintf %{public}s success, nBytes:%{public}d.\n", g_cltCnf->resultFile, nBytes); /* Unlock the writing file. */ if (flock(fileno(pFile), LOCK_UN) != 0) { LOGE("WriteDhcpResult() flock file:%{public}s LOCK_UN failed, error:%{public}s!\n", - gClientCfg.result_file, + g_cltCnf->resultFile, strerror(errno)); fclose(pFile); return; } if (fclose(pFile) != 0) { - LOGE("WriteDhcpResult() fclose %{public}s error:%{public}s!\n", gClientCfg.result_file, strerror(errno)); - return; - } -} - -static void ParseOtherNetworkInfo(const struct DhcpPacket *packet, struct DhcpResult *result) -{ - if ((packet == NULL) || (result == NULL)) { - LOGE("ParseOtherNetworkInfo() error, packet == NULL or result == NULL!\n"); + LOGE("WriteDhcpResult() fclose %{public}s error:%{public}s!\n", g_cltCnf->resultFile, strerror(errno)); return; } - - uint32_t u32Data = 0; - uint32_t u32Data2 = 0; - if (GetDhcpOptionUint32n(packet, DHO_DNSSERVER, &u32Data, &u32Data2)) { - char *pDnsIp = Ip4IntConToStr(u32Data, true); - if (pDnsIp != NULL) { - LOGI("ParseOtherNetworkInfo() recv DHCP_ACK 6, dns1: %{public}u->%{public}s.\n", u32Data, pDnsIp); - if (strncpy_s(result->strOptDns1, INET_ADDRSTRLEN, pDnsIp, INET_ADDRSTRLEN - 1) != EOK) { - free(pDnsIp); - return; - } - free(pDnsIp); - pDnsIp = NULL; - } - if ((u32Data2 > 0) && ((pDnsIp = Ip4IntConToStr(u32Data2, true)) != NULL)) { - LOGI("ParseOtherNetworkInfo() recv DHCP_ACK 6, dns2: %{public}u->%{public}s.\n", u32Data2, pDnsIp); - if (strncpy_s(result->strOptDns2, INET_ADDRSTRLEN, pDnsIp, INET_ADDRSTRLEN - 1) != EOK) { - free(pDnsIp); - return; - } - free(pDnsIp); - } - } -} - -static void ParseNetworkInfo(const struct DhcpPacket *packet, struct DhcpResult *result) -{ - if ((packet == NULL) || (result == NULL)) { - LOGE("ParseNetworkInfo() error, packet == NULL or result == NULL!\n"); - return; - } - - uint32_t u32Data = 0; - if (GetDhcpOptionUint32(packet, DHO_SUBNETMASK, &u32Data)) { - char *pSubIp = Ip4IntConToStr(u32Data, true); - if (pSubIp != NULL) { - LOGI("ParseNetworkInfo() recv DHCP_ACK 1, subnetmask: %{public}u->%{public}s.\n", u32Data, pSubIp); - if (strncpy_s(result->strOptSubnet, INET_ADDRSTRLEN, pSubIp, INET_ADDRSTRLEN - 1) != EOK) { - free(pSubIp); - return; - } - free(pSubIp); - } - } - - u32Data = 0; - uint32_t u32Data2 = 0; - if (GetDhcpOptionUint32n(packet, DHO_ROUTER, &u32Data, &u32Data2)) { - char *pRouterIp = Ip4IntConToStr(u32Data, true); - if (pRouterIp != NULL) { - LOGI("ParseNetworkInfo() recv DHCP_ACK 3, router1: %{public}u->%{public}s.\n", u32Data, pRouterIp); - if (strncpy_s(result->strOptRouter1, INET_ADDRSTRLEN, pRouterIp, INET_ADDRSTRLEN - 1) != EOK) { - free(pRouterIp); - return; - } - free(pRouterIp); - pRouterIp = NULL; - } - if ((u32Data2 > 0) && ((pRouterIp = Ip4IntConToStr(u32Data2, true)) != NULL)) { - LOGI("ParseNetworkInfo() recv DHCP_ACK 3, router2: %{public}u->%{public}s.\n", u32Data2, pRouterIp); - if (strncpy_s(result->strOptRouter2, INET_ADDRSTRLEN, pRouterIp, INET_ADDRSTRLEN - 1) != EOK) { - free(pRouterIp); - return; - } - free(pRouterIp); - } - } - - ParseOtherNetworkInfo(packet, result); } static void SyncDhcpResult(const struct DhcpPacket *packet, struct DhcpResult *result) @@ -631,7 +603,7 @@ static void SyncDhcpResult(const struct DhcpPacket *packet, struct DhcpResult *r } /* Set the specified client process interface network info. */ - if (SetLocalInterface(gClientCfg.interface, ntohl(requestedIp4)) != DHCP_OPT_SUCCESS) { + if (SetLocalInterface(g_cltCnf->interface, ntohl(g_requestedIp4)) != DHCP_OPT_SUCCESS) { LOGE("SyncDhcpResult() error, SetLocalInterface yiaddr:%{public}s failed!\n", result->strYiaddr); return; } @@ -652,38 +624,38 @@ static void ParseDhcpAckPacket(const struct DhcpPacket *packet, time_t timestamp } /* Set default leasetime. */ - leaseTime = LEASETIME_DEFAULT * ONE_HOURS_SEC; - requestedIp4 = packet->yiaddr; + g_leaseTime = LEASETIME_DEFAULT * ONE_HOURS_SEC; + g_requestedIp4 = packet->yiaddr; uint32_t u32Data = 0; if (GetDhcpOptionUint32(packet, DHO_LEASETIME, &u32Data)) { - leaseTime = u32Data; - LOGI("ParseDhcpAckPacket() recv DHCP_ACK 51, lease:%{public}u.\n", leaseTime); + g_leaseTime = u32Data; + LOGI("ParseDhcpAckPacket() recv DHCP_ACK 51, lease:%{public}u.\n", g_leaseTime); } - renewalSec = leaseTime * T1; /* First renewal seconds. */ - rebindSec = leaseTime * T2; /* Second rebind seconds. */ - renewalTimestamp = timestamp; /* Record begin renewing or rebinding timestamp. */ - dhcpResult.uOptLeasetime = leaseTime; + g_renewalSec = g_leaseTime * T1; /* First renewal seconds. */ + g_rebindSec = g_leaseTime * T2; /* Second rebind seconds. */ + g_renewalTimestamp = timestamp; /* Record begin renewing or rebinding timestamp. */ + dhcpResult.uOptLeasetime = g_leaseTime; u32Data = 0; if (!GetDhcpOptionUint32(packet, DHO_SERVERID, &u32Data)) { LOGW("ParseDhcpAckPacket() GetDhcpOptionUint32 DHO_SERVERID failed!\n"); } else { - serverIp4 = htonl(u32Data); + g_serverIp4 = htonl(u32Data); } - LOGI("recv DHCP_ACK 51, lease:%{public}u,new:%{public}u,bind:%{public}u.\n", leaseTime, renewalSec, rebindSec); - char *pReqIp = Ip4IntConToStr(requestedIp4, false); + LOGI("recv ACK 51 lease:%{public}u,new:%{public}u,bind:%{public}u.\n", g_leaseTime, g_renewalSec, g_rebindSec); + char *pReqIp = Ip4IntConToStr(g_requestedIp4, false); if (pReqIp != NULL) { - LOGI("ParseDhcpAckPacket() recv DHCP_ACK yiaddr: %{public}u->%{public}s.\n", ntohl(requestedIp4), pReqIp); + LOGI("ParseDhcpAckPacket() recv DHCP_ACK yiaddr: %{public}u->%{public}s.\n", ntohl(g_requestedIp4), pReqIp); if (strncpy_s(dhcpResult.strYiaddr, INET_ADDRSTRLEN, pReqIp, INET_ADDRSTRLEN - 1) != EOK) { free(pReqIp); return; } free(pReqIp); } - char *pSerIp = Ip4IntConToStr(serverIp4, false); + char *pSerIp = Ip4IntConToStr(g_serverIp4, false); if (pSerIp != NULL) { - LOGI("ParseDhcpAckPacket() recv DHCP_ACK 54, serid: %{public}u->%{public}s.\n", ntohl(serverIp4), pSerIp); + LOGI("ParseDhcpAckPacket() recv DHCP_ACK 54, serid: %{public}u->%{public}s.\n", ntohl(g_serverIp4), pSerIp); if (strncpy_s(dhcpResult.strOptServerId, INET_ADDRSTRLEN, pSerIp, INET_ADDRSTRLEN - 1) != EOK) { free(pSerIp); return; @@ -697,10 +669,10 @@ static void ParseDhcpAckPacket(const struct DhcpPacket *packet, time_t timestamp /* Sync the specified client process interface network info to the file. */ SyncDhcpResult(packet, &dhcpResult); - /* Receive dhcp ack packet finished, leaseTime * T1 later enter renewing state. */ - g_dhcp4State = BOUND; + /* Receive dhcp ack packet finished, g_leaseTime * T1 later enter renewing state. */ + g_dhcp4State = DHCP_STATE_BOUND; SetSocketMode(SOCKET_MODE_INVALID); - timeoutTimestamp = timestamp + renewalSec; + g_timeoutTimestamp = timestamp + g_renewalSec; } static void DhcpAckOrNakPacketHandle(uint8_t type, struct DhcpPacket *packet, time_t timestamp) @@ -718,11 +690,11 @@ static void DhcpAckOrNakPacketHandle(uint8_t type, struct DhcpPacket *packet, ti if (type == DHCP_NAK) { /* If receive dhcp nak packet, init g_dhcp4State, resend dhcp discover packet. */ LOGI("DhcpAckOrNakPacketHandle() receive DHCP_NAK 53, init g_dhcp4State, resend dhcp discover packet!\n"); - g_dhcp4State = INIT_SELECTING; + g_dhcp4State = DHCP_STATE_INIT; SetSocketMode(SOCKET_MODE_RAW); - requestedIp4 = 0; - sentPacketNum = 0; - timeoutTimestamp = timestamp; + g_requestedIp4 = 0; + g_sentPacketNum = 0; + g_timeoutTimestamp = timestamp; /* Avoid excessive network traffic. */ LOGI("DhcpAckOrNakPacketHandle() receive DHCP_NAK 53, avoid excessive network traffic, need sleep!\n"); @@ -742,17 +714,17 @@ static void DhcpResponseHandle(time_t timestamp) int getLen; uint8_t u8Message = 0; - if (socketMode == SOCKET_MODE_RAW) { - getLen = GetDhcpRawPacket(&packet, sockFd); + if (g_socketMode == SOCKET_MODE_RAW) { + getLen = GetDhcpRawPacket(&packet, g_sockFd); } else { - getLen = GetDhcpPacket(&packet, sockFd); + getLen = GetDhcpPacket(&packet, g_sockFd); } if (getLen < 0) { if ((getLen == SOCKET_OPT_ERROR) && (errno != EINTR)) { LOGE("DhcpResponseHandle() get packet read error, reopening socket!\n"); - /* Reopen sockFd. */ - SetSocketMode(socketMode); + /* Reopen g_sockFd. */ + SetSocketMode(g_socketMode); } LOGE("DhcpResponseHandle() get packet failed, error:%{public}s!\n", strerror(errno)); return; @@ -760,8 +732,8 @@ static void DhcpResponseHandle(time_t timestamp) LOGI("DhcpResponseHandle() get packet success, getLen:%{public}d.\n", getLen); /* Check packet data. */ - if (packet.xid != transID) { - LOGW("DhcpResponseHandle() get xid:%{public}u and transID:%{public}u not same!\n", packet.xid, transID); + if (packet.xid != g_transID) { + LOGW("DhcpResponseHandle() get xid:%{public}u and g_transID:%{public}u not same!\n", packet.xid, g_transID); return; } if (!GetDhcpOptionUint8(&packet, DHO_MESSAGETYPE, &u8Message)) { @@ -770,17 +742,17 @@ static void DhcpResponseHandle(time_t timestamp) } switch (g_dhcp4State) { - case INIT_SELECTING: + case DHCP_STATE_SELECTING: DhcpOfferPacketHandle(u8Message, &packet, timestamp); break; - case RENEW_REQUESTED: - case REQUESTING: - case RENEWING: - case REBINDING: + case DHCP_STATE_REQUESTING: + case DHCP_STATE_RENEWING: + case DHCP_STATE_REBINDING: + case DHCP_STATE_RENEWED: DhcpAckOrNakPacketHandle(u8Message, &packet, timestamp); break; - case BOUND: - case RELEASED: + case DHCP_STATE_BOUND: + case DHCP_STATE_RELEASED: LOGW("DhcpResponseHandle() g_dhcp4State is BOUND or RELEASED, ignore all packets!\n"); break; default: @@ -792,9 +764,9 @@ static void DhcpResponseHandle(time_t timestamp) static void SignalReceiver(void) { int signum; - if (read(sigSockFds[0], &signum, sizeof(signum)) < 0) { - LOGE("SignalReceiver() failed, sigSockFds[0]:%{public}d read error:%{public}s!\n", - sigSockFds[0], strerror(errno)); + if (read(g_sigSockFds[0], &signum, sizeof(signum)) < 0) { + LOGE("SignalReceiver() failed, g_sigSockFds[0]:%{public}d read error:%{public}s!\n", + g_sigSockFds[0], strerror(errno)); return; } @@ -802,8 +774,8 @@ static void SignalReceiver(void) case SIGTERM: LOGW("SignalReceiver() SIGTERM!\n"); SetSocketMode(SOCKET_MODE_INVALID); - unlink(gClientCfg.pid_file); - unlink(gClientCfg.result_file); + unlink(g_cltCnf->pidFile); + unlink(g_cltCnf->resultFile); exit(EXIT_SUCCESS); break; case SIGUSR1: @@ -820,11 +792,23 @@ static void SignalReceiver(void) } +/* Set dhcp ipv4 state. */ +int SetIpv4State(int state) +{ + if (state < 0) { + LOGE("SetIpv4State() failed, state:%{public}d!\n", state); + return DHCP_OPT_FAILED; + } + + g_dhcp4State = state; + return DHCP_OPT_SUCCESS; +} + /* Init signal handle function. */ int InitSignalHandle(void) { /* Create signal socket fd. */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, sigSockFds) != 0) { + if (socketpair(AF_UNIX, SOCK_STREAM, 0, g_sigSockFds) != 0) { LOGE("InitSignalHandle() failed, socketpair error str:%{public}s!\n", strerror(errno)); return DHCP_OPT_FAILED; } @@ -848,21 +832,51 @@ int InitSignalHandle(void) return DHCP_OPT_SUCCESS; } -/* Broadcast dhcp discover packet, discover dhcp servers that can provide ip address. */ -int DhcpDiscover(uint32_t transid, uint32_t requestip) +int GetPacketHeaderInfo(struct DhcpPacket *packet, uint8_t type) { - LOGI("DhcpDiscover() enter, transid:%{public}u,requestip:%{public}u.\n", transid, requestip); - struct DhcpPacket packet; + if (packet == NULL) { + LOGE("GetPacketHeaderInfo() failed, packet == NULL!\n"); + return DHCP_OPT_FAILED; + } + + switch (type) { + case DHCP_DISCOVER: + case DHCP_REQUEST: + case DHCP_RELEASE: + case DHCP_INFORM: + packet->op = BOOT_REQUEST; + break; + case DHCP_OFFER: + case DHCP_ACK: + case DHCP_NAK: + packet->op = BOOT_REPLY; + break; + default: + break; + } + packet->htype = ETHERNET_TYPE; + packet->hlen = ETHERNET_LEN; + packet->cookie = htonl(MAGIC_COOKIE); + packet->options[0] = DHO_END; + AddSimpleOption(packet->options, DHO_MESSAGETYPE, type); - /* Init packet common info. */ - GetPacketCommonInfo(&packet, DHCP_DISCOVER); + return DHCP_OPT_SUCCESS; +} + +int GetPacketCommonInfo(struct DhcpPacket *packet) +{ + if (packet == NULL) { + LOGE("GetPacketCommonInfo() failed, packet == NULL!\n"); + return DHCP_OPT_FAILED; + } /* Add packet client_cfg info. */ - if (memcpy_s(packet.chaddr, sizeof(packet.chaddr), gClientCfg.hwaddr, MAC_ADDR_LEN) != EOK) { - return -1; + if (memcpy_s(packet->chaddr, sizeof(packet->chaddr), g_cltCnf->hwaddr, MAC_ADDR_LEN) != EOK) { + LOGE("GetPacketCommonInfo() failed, memcpy_s error!\n"); + return DHCP_OPT_FAILED; } - int nClientIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + gClientCfg.clientid[DHCP_OPT_LEN_INDEX]; - AddOptionString(packet.options, gClientCfg.clientid, nClientIdLen); + int nClientIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + g_cltCnf->clientid[DHCP_OPT_LEN_INDEX]; + AddOptionString(packet->options, g_cltCnf->clientid, nClientIdLen); /* Add packet vendor info, vendor format: pro-version. */ char buf[VENDOR_MAX_LEN - DHCP_OPT_CODE_BYTES - DHCP_OPT_LEN_BYTES] = {0}; @@ -875,76 +889,72 @@ int DhcpDiscover(uint32_t transid, uint32_t requestip) DHCPC_NAME, DHCPC_VERSION); if (nRes < 0) { - return -1; + LOGE("GetPacketCommonInfo() failed, snprintf_s res:%{public}d error!\n", nRes); + return DHCP_OPT_FAILED; } pVendorId[DHCP_OPT_CODE_INDEX] = DHO_VENDOR; pVendorId[DHCP_OPT_LEN_INDEX] = strlen(buf); if (strncpy_s((char *)pVendorId + DHCP_OPT_DATA_INDEX, VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, buf, strlen(buf)) != EOK) { - return -1; + LOGE("GetPacketCommonInfo() failed, strncpy_s error!\n"); + return DHCP_OPT_FAILED; } if (strlen((char *)vendorId) > 0) { int nVendorIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + pVendorId[DHCP_OPT_LEN_INDEX]; - AddOptionString(packet.options, vendorId, nVendorIdLen); + AddOptionString(packet->options, vendorId, nVendorIdLen); + } + + return DHCP_OPT_SUCCESS; +} + +/* Broadcast dhcp discover packet, discover dhcp servers that can provide ip address. */ +int DhcpDiscover(uint32_t transid, uint32_t requestip) +{ + LOGI("DhcpDiscover() enter, transid:%{public}u,requestip:%{public}u.\n", transid, requestip); + + struct DhcpPacket packet; + if (memset_s(&packet, sizeof(struct DhcpPacket), 0, sizeof(struct DhcpPacket)) != EOK) { + return -1; + } + + /* Get packet header and common info. */ + if ((GetPacketHeaderInfo(&packet, DHCP_DISCOVER) != DHCP_OPT_SUCCESS) || + (GetPacketCommonInfo(&packet) != DHCP_OPT_SUCCESS)) { + return -1; } - /* Init packet non-default info. */ + /* Get packet not common info. */ packet.xid = transid; if (requestip > 0) { AddSimpleOption(packet.options, DHO_IPADDRESS, requestip); } - AddParamaterRequestList(&packet); /* Begin broadcast dhcp discover packet. */ LOGI("DhcpDiscover() discover, begin broadcast discover packet...\n"); - return SendToDhcpPacket(&packet, INADDR_ANY, INADDR_BROADCAST, (uint8_t *)MAC_BCAST_ADDR, gClientCfg.ifindex); + return SendToDhcpPacket(&packet, INADDR_ANY, INADDR_BROADCAST, g_cltCnf->ifaceIndex, (uint8_t *)MAC_BCAST_ADDR); } /* Broadcast dhcp request packet, tell dhcp servers that which ip address to choose. */ int DhcpRequest(uint32_t transid, uint32_t reqip, uint32_t servip) { - /* Init packet common info. */ - struct DhcpPacket packet; - GetPacketCommonInfo(&packet, DHCP_REQUEST); + LOGI("DhcpRequest() enter, transid:%{public}u,reqip:%{public}u.\n", transid, reqip); - /* Add packet client_cfg info. */ - if (memcpy_s(packet.chaddr, sizeof(packet.chaddr), gClientCfg.hwaddr, MAC_ADDR_LEN) != EOK) { + struct DhcpPacket packet; + if (memset_s(&packet, sizeof(struct DhcpPacket), 0, sizeof(struct DhcpPacket)) != EOK) { return -1; } - int nClientIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + gClientCfg.clientid[DHCP_OPT_LEN_INDEX]; - AddOptionString(packet.options, gClientCfg.clientid, nClientIdLen); - /* Add packet vendor info, vendor format: pro-version. */ - char buf[VENDOR_MAX_LEN - DHCP_OPT_CODE_BYTES - DHCP_OPT_LEN_BYTES] = {0}; - unsigned char vendorId[VENDOR_MAX_LEN] = {0}; - unsigned char *pVendorId = vendorId; - - int nRes = snprintf_s(buf, - VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, - VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX - 1, - "%s-%s", - DHCPC_NAME, - DHCPC_VERSION); - if (nRes < 0) { - return -1; - } - pVendorId[DHCP_OPT_CODE_INDEX] = DHO_VENDOR; - pVendorId[DHCP_OPT_LEN_INDEX] = strlen(buf); - if (strncpy_s((char *)pVendorId + DHCP_OPT_DATA_INDEX, VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, buf, strlen(buf)) != - EOK) { + /* Get packet header and common info. */ + if ((GetPacketHeaderInfo(&packet, DHCP_REQUEST) != DHCP_OPT_SUCCESS) || + (GetPacketCommonInfo(&packet) != DHCP_OPT_SUCCESS)) { return -1; } - if (strlen((char *)vendorId) > 0) { - int nVendorIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + pVendorId[DHCP_OPT_LEN_INDEX]; - AddOptionString(packet.options, vendorId, nVendorIdLen); - } - /* Init packet non-default info. */ + /* Get packet not common info. */ packet.xid = transid; AddSimpleOption(packet.options, DHO_IPADDRESS, reqip); AddSimpleOption(packet.options, DHO_SERVERID, servip); - AddParamaterRequestList(&packet); /* Begin broadcast dhcp request packet. */ @@ -955,68 +965,40 @@ int DhcpRequest(uint32_t transid, uint32_t reqip, uint32_t servip) } char *pSerIp = Ip4IntConToStr(servip, false); if (pSerIp != NULL) { - LOGI("DhcpRequest() broadcast reqt packet, servIp: host %{public}u->%{public}s.\n", ntohl(servip), pSerIp); + LOGI("DhcpRequest() broadcast req packet, servIp: host %{public}u->%{public}s.\n", ntohl(servip), pSerIp); free(pSerIp); } - - return SendToDhcpPacket(&packet, INADDR_ANY, INADDR_BROADCAST, (uint8_t *)MAC_BCAST_ADDR, gClientCfg.ifindex); + return SendToDhcpPacket(&packet, INADDR_ANY, INADDR_BROADCAST, g_cltCnf->ifaceIndex, (uint8_t *)MAC_BCAST_ADDR); } /* Unicast or broadcast dhcp request packet, request to extend the lease from the dhcp server. */ int DhcpRenew(uint32_t transid, uint32_t clientip, uint32_t serverip) { - struct DhcpPacket packet; - struct in_addr serverAddr; - - /* Init packet common info. */ - GetPacketCommonInfo(&packet, DHCP_REQUEST); + LOGI("DhcpRenew() enter, transid:%{public}u,clientip:%{public}u.\n", transid, clientip); - /* Add packet client_cfg info. */ - if (memcpy_s(packet.chaddr, sizeof(packet.chaddr), gClientCfg.hwaddr, MAC_ADDR_LEN) != EOK) { + struct DhcpPacket packet; + if (memset_s(&packet, sizeof(struct DhcpPacket), 0, sizeof(struct DhcpPacket)) != EOK) { return -1; } - int nClientIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + gClientCfg.clientid[DHCP_OPT_LEN_INDEX]; - AddOptionString(packet.options, gClientCfg.clientid, nClientIdLen); - - /* Add packet vendor info, vendor format: pro-version. */ - char buf[VENDOR_MAX_LEN - DHCP_OPT_CODE_BYTES - DHCP_OPT_LEN_BYTES] = {0}; - unsigned char vendorId[VENDOR_MAX_LEN] = {0}; - unsigned char *pVendorId = vendorId; - int nRes = snprintf_s(buf, - VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, - VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX - 1, - "%s-%s", - DHCPC_NAME, - DHCPC_VERSION); - if (nRes < 0) { + /* Get packet header and common info. */ + if ((GetPacketHeaderInfo(&packet, DHCP_REQUEST) != DHCP_OPT_SUCCESS) || + (GetPacketCommonInfo(&packet) != DHCP_OPT_SUCCESS)) { return -1; } - pVendorId[DHCP_OPT_CODE_INDEX] = DHO_VENDOR; - pVendorId[DHCP_OPT_LEN_INDEX] = strlen(buf); - if (strncpy_s((char *)pVendorId + DHCP_OPT_DATA_INDEX, VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, buf, strlen(buf)) != - EOK) { - return -1; - } - if (strlen((char *)vendorId) > 0) { - int nVendorIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + pVendorId[DHCP_OPT_LEN_INDEX]; - AddOptionString(packet.options, vendorId, nVendorIdLen); - } - /* Init packet non-default info. */ + /* Get packet not common info. */ packet.xid = transid; packet.ciaddr = clientip; - AddParamaterRequestList(&packet); + /* Begin broadcast or unicast dhcp request packet. */ + struct in_addr serverAddr; serverAddr.s_addr = serverip; if (serverip == 0) { - /* Begin broadcast dhcp request packet. */ LOGI("DhcpRenew() rebind, begin broadcast req packet, serverip:%{public}s...\n", inet_ntoa(serverAddr)); - return SendToDhcpPacket(&packet, INADDR_ANY, INADDR_BROADCAST, (uint8_t *)MAC_BCAST_ADDR, gClientCfg.ifindex); + return SendToDhcpPacket(&packet, INADDR_ANY, INADDR_BROADCAST, g_cltCnf->ifaceIndex, (uint8_t *)MAC_BCAST_ADDR); } - - /* Begin unicast dhcp request packet. */ LOGI("DhcpRenew() renew, begin unicast request packet, serverip:%{public}s...\n", inet_ntoa(serverAddr)); return SendDhcpPacket(&packet, clientip, serverip); } @@ -1024,53 +1006,28 @@ int DhcpRenew(uint32_t transid, uint32_t clientip, uint32_t serverip) /* Unicast dhcp release packet, releasing an ip address in Use from the dhcp server. */ int DhcpRelease(uint32_t clientip, uint32_t serverip) { - struct DhcpPacket packet; - struct in_addr requestAddr, serverAddr; + LOGI("DhcpRelease() enter, clientip:%{public}u.\n", clientip); - /* Init packet common info. */ - GetPacketCommonInfo(&packet, DHCP_RELEASE); - - /* Add packet client_cfg info. */ - if (memcpy_s(packet.chaddr, sizeof(packet.chaddr), gClientCfg.hwaddr, MAC_ADDR_LEN) != EOK) { + struct DhcpPacket packet; + if (memset_s(&packet, sizeof(struct DhcpPacket), 0, sizeof(struct DhcpPacket)) != EOK) { return -1; } - int nClientIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + gClientCfg.clientid[DHCP_OPT_LEN_INDEX]; - AddOptionString(packet.options, gClientCfg.clientid, nClientIdLen); - - /* Add packet vendor info, vendor format: pro-version. */ - char buf[VENDOR_MAX_LEN - DHCP_OPT_CODE_BYTES - DHCP_OPT_LEN_BYTES] = {0}; - unsigned char vendorId[VENDOR_MAX_LEN] = {0}; - unsigned char *pVendorId = vendorId; - int nRes = snprintf_s(buf, - VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, - VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX - 1, - "%s-%s", - DHCPC_NAME, - DHCPC_VERSION); - if (nRes < 0) { - return -1; - } - pVendorId[DHCP_OPT_CODE_INDEX] = DHO_VENDOR; - pVendorId[DHCP_OPT_LEN_INDEX] = strlen(buf); - if (strncpy_s((char *)pVendorId + DHCP_OPT_DATA_INDEX, VENDOR_MAX_LEN - DHCP_OPT_DATA_INDEX, buf, strlen(buf)) != - EOK) { + /* Get packet header and common info. */ + if ((GetPacketHeaderInfo(&packet, DHCP_RELEASE) != DHCP_OPT_SUCCESS) || + (GetPacketCommonInfo(&packet) != DHCP_OPT_SUCCESS)) { return -1; } - if (strlen((char *)vendorId) > 0) { - int nVendorIdLen = DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + pVendorId[DHCP_OPT_LEN_INDEX]; - AddOptionString(packet.options, vendorId, nVendorIdLen); - } - /* Init packet non-default info. */ + /* Get packet not common info. */ packet.xid = GetTransId(); AddSimpleOption(packet.options, DHO_IPADDRESS, clientip); AddSimpleOption(packet.options, DHO_SERVERID, serverip); + /* Begin unicast dhcp release packet. */ + struct in_addr requestAddr, serverAddr; requestAddr.s_addr = clientip; serverAddr.s_addr = serverip; - - /* Begin unicast dhcp release packet. */ LOGI("DhcpRelease() release, begin unicast release packet, clientip:%{public}s,", inet_ntoa(requestAddr)); LOGI("serverip:%{public}s...\n", inet_ntoa(serverAddr)); return SendDhcpPacket(&packet, clientip, serverip); @@ -1083,35 +1040,35 @@ int StartIpv4(void) struct timeval timeout; time_t curTimestamp; + g_cltCnf = GetDhcpClientCfg(); + /* Init dhcp ipv4 state. */ - g_dhcp4State = INIT_SELECTING; + g_dhcp4State = DHCP_STATE_INIT; SetSocketMode(SOCKET_MODE_RAW); for (; ;) { - LOGI("StartIpv4() for enter...\n"); - - if (gClientCfg.timeoutExit) { + if (g_cltCnf->timeoutExit) { LOGW("StartIpv4() send packet timed out, now break!\n"); break; } FD_ZERO(&exceptfds); - timeout.tv_sec = timeoutTimestamp - time(NULL); + timeout.tv_sec = g_timeoutTimestamp - time(NULL); timeout.tv_usec = 0; InitSocketFd(); - if (sockFd >= 0) { - FD_SET(sockFd, &exceptfds); + if (g_sockFd >= 0) { + FD_SET(g_sockFd, &exceptfds); } - FD_SET(sigSockFds[0], &exceptfds); + FD_SET(g_sigSockFds[0], &exceptfds); if (timeout.tv_sec <= 0) { LOGI("StartIpv4() already timed out, need send or resend packet...\n"); nRet = 0; } else { LOGI("StartIpv4() waiting on select...\n"); - nMaxFds = (sigSockFds[0] > sockFd) ? sigSockFds[0] : sockFd; + nMaxFds = (g_sigSockFds[0] > g_sockFd) ? g_sigSockFds[0] : g_sockFd; nRet = select(nMaxFds + 1, &exceptfds, NULL, NULL, &timeout); } if (nRet < 0) { @@ -1126,13 +1083,13 @@ int StartIpv4(void) curTimestamp = time(NULL); if (nRet == 0) { DhcpRequestHandle(curTimestamp); - } else if ((socketMode != SOCKET_MODE_INVALID) && FD_ISSET(sockFd, &exceptfds)) { + } else if ((g_socketMode != SOCKET_MODE_INVALID) && FD_ISSET(g_sockFd, &exceptfds)) { DhcpResponseHandle(curTimestamp); - } else if (FD_ISSET(sigSockFds[0], &exceptfds)) { + } else if (FD_ISSET(g_sigSockFds[0], &exceptfds)) { SignalReceiver(); } else { - LOGW("StartIpv4() nRet:%{public}d, socketMode:%{public}d, continue select...\n", nRet, socketMode); + LOGW("StartIpv4() nRet:%{public}d, g_socketMode:%{public}d, continue select...\n", nRet, g_socketMode); } } - return gClientCfg.timeoutExit ? StopProcess(gClientCfg.pid_file) : DHCP_OPT_SUCCESS; + return g_cltCnf->timeoutExit ? StopProcess(g_cltCnf->pidFile) : DHCP_OPT_SUCCESS; } \ No newline at end of file diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_main.c b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_main.c index ab4df293e..ecc3b6e85 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_main.c +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_main.c @@ -15,13 +15,12 @@ #include #include #include -#include #include -#include #include #include #include #include +#include #include "securec.h" #include "dhcp_client.h" @@ -40,6 +39,8 @@ static int InitSpecifiedClientCfg(int argc, char *argv[]); static int ExecClientProAction(const char *action); static int GetClientNetworkInfo(void); +static struct DhcpClientCfg *g_cltCfg; + /* Static defined. */ static int Usage(void) { @@ -69,7 +70,10 @@ static int RunChildProcess(void) return DHCP_OPT_FAILED; } - signal(SIGHUP, SIG_IGN); + if (signal(SIGHUP, SIG_IGN) == SIG_ERR) { + LOGE("RunChildProcess() signal SIGHUP SIG_ERR, return!\n"); + return DHCP_OPT_FAILED; + } /* Ensure we can never get a controlling terminal. */ pid_t childPid; @@ -94,9 +98,18 @@ static int CreateDaemon(void) LOGI("CreateDaemon() enter, pid:%{public}d, ppid:%{public}d.\n", getpid(), getppid()); /* A daemon process need close all open files. */ - fclose(stdin); - fclose(stdout); - fclose(stderr); + if (fclose(stdin) != 0) { + LOGE("CreateDaemon() fclose stdin error:%{public}s!\n", strerror(errno)); + return DHCP_OPT_FAILED; + } + if (fclose(stdout) != 0) { + LOGE("CreateDaemon() fclose stdout error:%{public}s!\n", strerror(errno)); + return DHCP_OPT_FAILED; + } + if (fclose(stderr) != 0) { + LOGE("CreateDaemon() fclose stderr error:%{public}s!\n", strerror(errno)); + return DHCP_OPT_FAILED; + } /* Ensure that the process is not a fork subprocess, init process id is 1. */ if (getppid() == 1) { @@ -148,8 +161,8 @@ static int CheckClientProParam(int argc, char *argv[]) return 1; } else { /* Check client process param ACTION "start","stop","status". */ - if ((strncasecmp(cmdParam, "start", NUMBER_FIVE) != 0) && (strncasecmp(cmdParam, "stop", NUMBER_FOUR) != 0) - && (strncasecmp(cmdParam, "status", NUMBER_FIVE) != 0)) { + if ((strncasecmp(cmdParam, "start", NUMBER_FIVE) != 0) && (strncasecmp(cmdParam, "stop", NUMBER_FOUR) != 0) && + (strncasecmp(cmdParam, "status", NUMBER_FIVE) != 0)) { printf("CheckClientProParam() argv[1]:%s error, please input valid ACTION!\n", cmdParam); Usage(); return -1; @@ -170,20 +183,20 @@ static int GetClientOption(int argc, char *argv[]) while ((ch = getopt(argc - NUMBER_TWO, argv + NUMBER_TWO, "w:a46")) != -1) { switch (ch) { case 'w': /* Specify the client's working directory. */ - LOGI("GetClientOption() cur workdir:%{public}s, optarg:%{public}s\n", gClientCfg.workdir, optarg); - if (strncpy_s(gClientCfg.workdir, sizeof(gClientCfg.workdir), optarg, DIR_MAX_LEN - 1) != EOK) { + LOGI("GetClientOption() cur workdir:%{public}s, optarg:%{public}s\n", g_cltCfg->workdir, optarg); + if (strncpy_s(g_cltCfg->workdir, sizeof(g_cltCfg->workdir), optarg, DIR_MAX_LEN - 1) != EOK) { return -1; } break; case 'a': /* Handle dhcp v4 and v6. */ - gClientCfg.iptype = DHCP_IP_TYPE_ALL; + g_cltCfg->iptype = DHCP_IP_TYPE_ALL; break; case '4': /* Only handle dhcp v4. */ - LOGI("GetClientOption() cur iptype:%{public}u, optarg:%{public}s\n", gClientCfg.iptype, optarg); - gClientCfg.iptype = DHCP_IP_TYPE_V4; + LOGI("GetClientOption() cur iptype:%{public}u, optarg:%{public}s\n", g_cltCfg->iptype, optarg); + g_cltCfg->iptype = DHCP_IP_TYPE_V4; break; case '6': /* Only handle dhcp v6. */ - gClientCfg.iptype = DHCP_IP_TYPE_V6; + g_cltCfg->iptype = DHCP_IP_TYPE_V6; break; default: printf("GetClientOption() please input valid OPTION!\n"); @@ -196,40 +209,41 @@ static int GetClientOption(int argc, char *argv[]) static int InitSpecifiedClientCfg(int argc, char *argv[]) { - if ((strncpy_s(gClientCfg.workdir, sizeof(gClientCfg.workdir), WORKDIR, DIR_MAX_LEN - 1) != EOK) || - (strncpy_s(gClientCfg.interface, sizeof(gClientCfg.interface), argv[NUMBER_TWO], INFNAME_SIZE - 1) != EOK)) { + g_cltCfg = GetDhcpClientCfg(); + if ((strncpy_s(g_cltCfg->workdir, sizeof(g_cltCfg->workdir), WORKDIR, DIR_MAX_LEN - 1) != EOK) || + (strncpy_s(g_cltCfg->interface, sizeof(g_cltCfg->interface), argv[NUMBER_TWO], INFNAME_SIZE - 1) != EOK)) { return -1; } - gClientCfg.iptype = DHCP_IP_TYPE_ALL; + g_cltCfg->iptype = DHCP_IP_TYPE_ALL; if ((argc > NUMBER_THREE) && (GetClientOption(argc, argv) != 0)) { return -1; } - if (strlen(gClientCfg.workdir) > 0) { - int n = snprintf_s(gClientCfg.conf_file, - DIR_MAX_LEN, DIR_MAX_LEN - 1, "%s%s", gClientCfg.workdir, DHCPC_CONF); + if (strlen(g_cltCfg->workdir) > 0) { + int n = snprintf_s(g_cltCfg->confFile, + DIR_MAX_LEN, DIR_MAX_LEN - 1, "%s%s", g_cltCfg->workdir, DHCPC_CONF); if (n < 0) { return -1; } - n = snprintf_s(gClientCfg.pid_file, - DIR_MAX_LEN, DIR_MAX_LEN - 1, "%s%s.pid", gClientCfg.workdir, gClientCfg.interface); + n = snprintf_s(g_cltCfg->pidFile, + DIR_MAX_LEN, DIR_MAX_LEN - 1, "%s%s.pid", g_cltCfg->workdir, g_cltCfg->interface); if (n < 0) { return -1; } - n = snprintf_s(gClientCfg.result_file, - DIR_MAX_LEN, DIR_MAX_LEN - 1, "%s%s.result", gClientCfg.workdir, gClientCfg.interface); + n = snprintf_s(g_cltCfg->resultFile, + DIR_MAX_LEN, DIR_MAX_LEN - 1, "%s%s.result", g_cltCfg->workdir, g_cltCfg->interface); if (n < 0) { return -1; } } LOGI("InitSpecifiedClientCfg() " - "gClientCfg.workdir:%{public}s,conf_file:%{public}s,pid_file:%{public}s,result_file:%{public}s, " + "g_cltCfg->workdir:%{public}s,confFile:%{public}s,pidFile:%{public}s,resultFile:%{public}s, " "iptype:%{public}d\n", - gClientCfg.workdir, - gClientCfg.conf_file, - gClientCfg.pid_file, - gClientCfg.result_file, - gClientCfg.iptype); + g_cltCfg->workdir, + g_cltCfg->confFile, + g_cltCfg->pidFile, + g_cltCfg->resultFile, + g_cltCfg->iptype); return 0; } @@ -237,16 +251,16 @@ static int ExecClientProAction(const char *action) { /* Stop the specified network interface service. */ if (strncasecmp(action, "stop", NUMBER_FOUR) == 0) { - if (StopProcess(gClientCfg.pid_file) != DHCP_OPT_SUCCESS) { - LOGI("ExecClientProAction() StopProcess pid_file:%{public}s not success.\n", gClientCfg.pid_file); + if (StopProcess(g_cltCfg->pidFile) != DHCP_OPT_SUCCESS) { + LOGI("ExecClientProAction() StopProcess pidFile:%{public}s not success.\n", g_cltCfg->pidFile); } else { - LOGI("ExecClientProAction() StopProcess pid_file:%{public}s success.\n", gClientCfg.pid_file); + LOGI("ExecClientProAction() StopProcess pidFile:%{public}s success.\n", g_cltCfg->pidFile); } return 1; } /* Get the specified client process running status. */ - int proStatus = GetProStatus(gClientCfg.pid_file); + int proStatus = GetProStatus(g_cltCfg->pidFile); if (strncasecmp(action, "status", NUMBER_FIVE) == 0) { LOGI("ExecClientProAction() action:%{public}s GetProStatus proStatus:%{public}d.\n", action, proStatus); return 1; @@ -270,8 +284,8 @@ static int ExecClientProAction(const char *action) } /* Init the specified client process id info. */ - if (InitPidfile(gClientCfg.workdir, gClientCfg.pid_file) != DHCP_OPT_SUCCESS) { - LOGE("ExecClientProAction() InitPidfile failed, interface:%{public}s.\n", gClientCfg.interface); + if (InitPidfile(g_cltCfg->workdir, g_cltCfg->pidFile, getpid()) != DHCP_OPT_SUCCESS) { + LOGE("ExecClientProAction() InitPidfile failed, interface:%{public}s.\n", g_cltCfg->interface); return -1; } @@ -280,45 +294,45 @@ static int ExecClientProAction(const char *action) static int GetClientNetworkInfo(void) { - if (GetLocalInterface(gClientCfg.interface, &gClientCfg.ifindex, gClientCfg.hwaddr, NULL) != DHCP_OPT_SUCCESS) { - LOGE("GetClientNetworkInfo() GetLocalInterface failed, interface:%{public}s.\n", gClientCfg.interface); + if (GetLocalInterface(g_cltCfg->interface, &g_cltCfg->ifaceIndex, g_cltCfg->hwaddr, NULL) != DHCP_OPT_SUCCESS) { + LOGE("GetClientNetworkInfo() GetLocalInterface failed, interface:%{public}s.\n", g_cltCfg->interface); return -1; } char macAddr[MAC_ADDR_LEN * MAC_ADDR_CHAR_NUM]; if (memset_s(macAddr, sizeof(macAddr), 0, sizeof(macAddr)) != EOK) { return -1; } - HwaddrNtoa(gClientCfg.hwaddr, MAC_ADDR_LEN, macAddr, sizeof(macAddr)); - LOGI("GetClientNetworkInfo() gClientCfg.interface:%{public}s -> ifindex:%{private}d,hwaddr:%{private}s.\n", - gClientCfg.interface, gClientCfg.ifindex, macAddr); + HwaddrNtoa(g_cltCfg->hwaddr, MAC_ADDR_LEN, macAddr, sizeof(macAddr)); + LOGI("GetClientNetworkInfo() g_cltCfg->interface:%{public}s -> ifaceIndex:%{private}d,hwaddr:%{private}s.\n", + g_cltCfg->interface, g_cltCfg->ifaceIndex, macAddr); - if (GetLocalIp(gClientCfg.interface, &gClientCfg.ipaddr4) != DHCP_OPT_SUCCESS) { - LOGE("GetClientNetworkInfo() failed, gClientCfg.interface:%{public}s.\n", gClientCfg.interface); + if (GetLocalIp(g_cltCfg->interface, &g_cltCfg->ipaddr4) != DHCP_OPT_SUCCESS) { + LOGE("GetClientNetworkInfo() failed, g_cltCfg->interface:%{public}s.\n", g_cltCfg->interface); return -1; } - char *cIp = Ip4IntConToStr(gClientCfg.ipaddr4, true); + char *cIp = Ip4IntConToStr(g_cltCfg->ipaddr4, true); if (cIp == NULL) { - LOGE("GetClientNetworkInfo() Ip4IntConToStr gClientCfg.ipaddr4 failed!\n"); + LOGE("GetClientNetworkInfo() Ip4IntConToStr g_cltCfg->ipaddr4 failed!\n"); return -1; } LOGI("GetClientNetworkInfo() GetLocalIp interface:%{public}s -> ipaddr4:%{private}u - %{private}s.\n", - gClientCfg.interface, gClientCfg.ipaddr4, cIp); + g_cltCfg->interface, g_cltCfg->ipaddr4, cIp); free(cIp); /* Generate clientid for the specified client process interface. */ - if (gClientCfg.clientid == NULL) { - gClientCfg.clientid = malloc(DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + MAC_ADDR_LEN + 1); - if (gClientCfg.clientid == NULL) { - LOGE("GetClientNetworkInfo() gClientCfg.clientid malloc failed!\n"); + if (g_cltCfg->clientid == NULL) { + g_cltCfg->clientid = malloc(DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + MAC_ADDR_LEN + 1); + if (g_cltCfg->clientid == NULL) { + LOGE("GetClientNetworkInfo() g_cltCfg->clientid malloc failed!\n"); return -1; } - gClientCfg.clientid[DHCP_OPT_CODE_INDEX] = DHO_CLIENTID; - gClientCfg.clientid[DHCP_OPT_LEN_INDEX] = MAC_ADDR_LEN + 1; + g_cltCfg->clientid[DHCP_OPT_CODE_INDEX] = DHO_CLIENTID; + g_cltCfg->clientid[DHCP_OPT_LEN_INDEX] = MAC_ADDR_LEN + 1; /* Generate format: 1 + hwaddr. */ - gClientCfg.clientid[DHCP_OPT_DATA_INDEX] = NUMBER_ONE; - if (memcpy_s(gClientCfg.clientid + DHCP_OPT_DATA_INDEX + 1, + g_cltCfg->clientid[DHCP_OPT_DATA_INDEX] = NUMBER_ONE; + if (memcpy_s(g_cltCfg->clientid + DHCP_OPT_DATA_INDEX + 1, MAC_ADDR_LEN, - gClientCfg.hwaddr, + g_cltCfg->hwaddr, MAC_ADDR_LEN) != EOK) { return -1; } diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_options.c b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_options.c index e16feef50..f95a06095 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_options.c +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_options.c @@ -154,9 +154,9 @@ const uint8_t *GetDhcpOption(const struct DhcpPacket *packet, int code, size_t * } const uint8_t *pOption = packet->options; - int i = 0, maxLen = DHCP_OPT_MAX_BYTES, over = 0, done = 0, curr = OPTION_FIELD, getRet; + int i = 0, maxLen = DHCP_OPT_MAX_BYTES, over = 0, done = 0, curr = OPTION_FIELD; while (done == 0) { - getRet = GetDhcpOptionData(packet, code, i, maxLen); + int getRet = GetDhcpOptionData(packet, code, i, maxLen); if (getRet == DHCP_OPT_SUCCESS) { *length = pOption[i + DHCP_OPT_LEN_INDEX]; return pOption + i + DHCP_OPT_DATA_INDEX; @@ -289,6 +289,7 @@ char *GetDhcpOptionString(const struct DhcpPacket *packet, int code) char *s = (char *)malloc(sizeof(char) * (len + 1)); if (s) { if (memcpy_s(s, len + 1, p, len) != EOK) { + free(s); return NULL; } s[len] = '\0'; @@ -338,7 +339,7 @@ int AddOptionString(uint8_t *optionptr, uint8_t *optionstr, int optionstrLen) /* add a one to four byte option to a packet */ int AddSimpleOption(uint8_t *optionptr, uint8_t code, uint32_t data) { - uint8_t length = 0; + uint8_t length; uint8_t option[DHCP_OPT_CODE_BYTES + DHCP_OPT_LEN_BYTES + DHCP_UINT32_BYTES]; uint8_t *u8; uint16_t *u16; diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_socket.c b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_socket.c index 6c863d95c..2b9143d33 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_socket.c +++ b/services/wifi_standard/wifi_framework/dhcp_manage/dhcp_client/src/dhcp_socket.c @@ -46,191 +46,226 @@ static uint16_t CheckSum(u_int16_t *addr, int count) /* Add left-over byte, if any */ if (count > 0) { - /* Make sure that the left-over byte is added correctly both - * with little and big endian hosts */ + /* Make sure that the left-over byte is added correctly both with little and big endian hosts */ u_int16_t tmp; *(unsigned char *)(&tmp) = *(unsigned char *)source; sum += tmp; } + /* Fold 32-bit sum to 16 bits */ - while (sum >> DHCP_UINT16_BITS) + while (sum >> DHCP_UINT16_BITS) { sum = (sum & 0xffff) + (sum >> DHCP_UINT16_BITS); + } return ~sum; } -/* raw socket can receive data frames or data packets from the local network interface */ -int CreateRawSocket(int ifindex) +/* Raw socket can receive data frames or data packets from the local network interface. */ +int CreateRawSocket(int *rawFd) { - LOGI("CreateRawSocket() ifindex:%{public}d.\n", ifindex); - - int fd; - struct sockaddr_ll sock; + int sockFd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); + if (sockFd == -1) { + LOGE("CreateRawSocket() failed, socket error:%{public}s.\n", strerror(errno)); + return SOCKET_OPT_FAILED; + } + *rawFd = sockFd; + return SOCKET_OPT_SUCCESS; +} - if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) { - LOGE("CreateRawSocket() ifindex:%{public}d failed, socket error:%{public}s.\n", ifindex, strerror(errno)); - return -1; +int BindRawSocket(const int rawFd, const int ifaceIndex, const uint8_t *ifaceAddr) +{ + if (rawFd < 0) { + LOGE("BindRawSocket() failed, rawFd:%{public}d error!\n", rawFd); + return SOCKET_OPT_FAILED; } - sock.sll_family = AF_PACKET; - sock.sll_protocol = htons(ETH_P_IP); - sock.sll_ifindex = ifindex; - if (bind(fd, (struct sockaddr *)&sock, sizeof(sock)) < 0) { - LOGE("CreateRawSocket() ifindex:%{public}d failed, bind error:%{public}s.\n", ifindex, strerror(errno)); - close(fd); - return -1; + struct sockaddr_ll rawAddr; + if (memset_s(&rawAddr, sizeof(rawAddr), 0, sizeof(rawAddr)) != EOK) { + LOGE("BindRawSocket() failed, memset_s rawAddr error!\n"); + close(rawFd); + return SOCKET_OPT_FAILED; + } + rawAddr.sll_ifindex = ifaceIndex; + rawAddr.sll_protocol = htons(ETH_P_IP); + rawAddr.sll_family = AF_PACKET; + if (ifaceAddr != NULL) { + rawAddr.sll_halen = MAC_ADDR_LEN; + if (memcpy_s(rawAddr.sll_addr, sizeof(rawAddr.sll_addr), ifaceAddr, MAC_ADDR_LEN) != EOK) { + LOGE("BindRawSocket() failed, memcpy_s rawAddr.sll_addr error!\n"); + close(rawFd); + return SOCKET_OPT_FAILED; + } + } + int nRet = bind(rawFd, (struct sockaddr *)&rawAddr, sizeof(rawAddr)); + if (nRet == -1) { + LOGE("BindRawSocket() index:%{public}d failed, bind error:%{public}s.\n", ifaceIndex, strerror(errno)); + close(rawFd); + return SOCKET_OPT_FAILED; } - return fd; + return SOCKET_OPT_SUCCESS; } -/* kernel socket can receive data frames or data packets from the local network interface, ip and port */ -int CreateSocket(const char *ifname, uint32_t ip, int port) +/* Kernel socket can receive data frames or data packets from the local network interface, ip and port. */ +int CreateKernelSocket(int *sockFd) { - LOGI("CreateSocket() ifname:%{public}s, ip:0x%{public}08x, port:%{public}d.\n", ifname, ip, port); - - struct ifreq interface; - int fd; - struct sockaddr_in addr; - int n = 1; - - if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - LOGE("CreateSocket() ifname:%{public}s failed, socket error:%{public}s.\n", ifname, strerror(errno)); - return -1; + int nFd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (nFd == -1) { + LOGE("CreateKernelSocket() failed, socket error:%{public}s.\n", strerror(errno)); + return SOCKET_OPT_FAILED; } + *sockFd = nFd; + return SOCKET_OPT_SUCCESS; +} - if (memset_s(&addr, sizeof(addr), 0, sizeof(addr)) != EOK) { - return -1; +int BindKernelSocket(const int sockFd, const char *ifaceName, const uint32_t sockIp, const int sockPort, bool bCast) +{ + if (sockFd < 0) { + LOGE("BindKernelSocket() failed, sockFd:%{public}d error!\n", sockFd); + return SOCKET_OPT_FAILED; } - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = ip; - addr.sin_port = htons(port); - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&n, sizeof(n)) == -1) { - close(fd); - return -1; - } - if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *)&n, sizeof(n)) == -1) { - close(fd); - return -1; + /* Bind the specified interface. */ + if (ifaceName != NULL) { + struct ifreq ifaceReq; + if (strncpy_s(ifaceReq.ifr_name, sizeof(ifaceReq.ifr_name), ifaceName, IFNAMSIZ) != EOK) { + close(sockFd); + return SOCKET_OPT_FAILED; + } + if (setsockopt(sockFd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&ifaceReq, sizeof(ifaceReq)) == -1) { + LOGE("BindKernelSocket() %{public}s SO_BINDTODEVICE error:%{public}s.\n", ifaceName, strerror(errno)); + close(sockFd); + return SOCKET_OPT_FAILED; + } + } + + /* Set the broadcast feature of the data sent by the socket. */ + if (bCast) { + if (setsockopt(sockFd, SOL_SOCKET, SO_BROADCAST, (const char *)&bCast, sizeof(bool)) == -1) { + LOGE("BindKernelSocket() sockFd:%{public}d SO_BROADCAST error:%{public}s.\n", sockFd, strerror(errno)); + close(sockFd); + return SOCKET_OPT_FAILED; + } + } + + /* Allow multiple sockets to use the same port number. */ + bool bReuseaddr = true; + if (setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, (const char *)&bReuseaddr, sizeof(bool)) == -1) { + LOGE("BindKernelSocket() sockFd:%{public}d SO_REUSEADDR error:%{public}s.\n", sockFd, strerror(errno)); + close(sockFd); + return SOCKET_OPT_FAILED; } - if (strncpy_s(interface.ifr_ifrn.ifrn_name, sizeof(interface.ifr_ifrn.ifrn_name), ifname, IFNAMSIZ) != EOK) { - return -1; - } - if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0) { - close(fd); - return -1; + struct sockaddr_in kernelAddr; + if (memset_s(&kernelAddr, sizeof(kernelAddr), 0, sizeof(kernelAddr)) != EOK) { + close(sockFd); + return SOCKET_OPT_FAILED; } - - if (bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) { - close(fd); - return -1; + kernelAddr.sin_addr.s_addr = sockIp; + kernelAddr.sin_port = htons(sockPort); + kernelAddr.sin_family = AF_INET; + int nRet = bind(sockFd, (struct sockaddr *)&kernelAddr, sizeof(kernelAddr)); + if (nRet == -1) { + LOGE("BindKernelSocket() sockFd:%{public}d failed, bind error:%{public}s.\n", sockFd, strerror(errno)); + close(sockFd); + return SOCKET_OPT_FAILED; } - return fd; + return SOCKET_OPT_SUCCESS; } -/* Constuct a ip/udp header for a packet, and specify the source and dest hardware address */ int SendToDhcpPacket( - const struct DhcpPacket *sendPacket, uint32_t srcIp, uint32_t destIp, const uint8_t *destHwaddr, int ifindex) + const struct DhcpPacket *sendPacket, uint32_t srcIp, uint32_t destIp, int destIndex, const uint8_t *destHwaddr) { - int fd; - int result; - struct sockaddr_ll dest; - struct UdpDhcpPacket packet; - - if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) { - LOGE("socket call failed: %{public}s!\n", strerror(errno)); - return -1; - } - - if ((memset_s(&dest, sizeof(dest), 0, sizeof(dest)) != EOK) - || (memset_s(&packet, sizeof(packet), 0, sizeof(packet)) != EOK)) { - return -1; + int nFd = -1; + if (CreateRawSocket(&nFd) != SOCKET_OPT_SUCCESS) { + return SOCKET_OPT_FAILED; } - dest.sll_family = AF_PACKET; - dest.sll_protocol = htons(ETH_P_IP); - dest.sll_ifindex = ifindex; - dest.sll_halen = MAC_ADDR_LEN; - if (memcpy_s(dest.sll_addr, sizeof(dest.sll_addr), destHwaddr, MAC_ADDR_LEN) != EOK) { - return -1; + struct sockaddr_ll rawAddr; + rawAddr.sll_ifindex = destIndex; + rawAddr.sll_protocol = htons(ETH_P_IP); + rawAddr.sll_family = AF_PACKET; + rawAddr.sll_halen = MAC_ADDR_LEN; + if (memcpy_s(rawAddr.sll_addr, sizeof(rawAddr.sll_addr), destHwaddr, MAC_ADDR_LEN) != EOK) { + close(nFd); + return SOCKET_OPT_FAILED; } - if (bind(fd, (struct sockaddr *)&dest, sizeof(struct sockaddr_ll)) < 0) { - LOGE("bind call failed: %{public}s!\n", strerror(errno)); - close(fd); - return -1; + if (bind(nFd, (struct sockaddr *)&rawAddr, sizeof(rawAddr)) == -1) { + LOGE("SendToDhcpPacket() index:%{public}d failed, bind error:%{public}s.\n", destIndex, strerror(errno)); + close(nFd); + return SOCKET_OPT_FAILED; } - packet.ip.protocol = IPPROTO_UDP; - packet.ip.saddr = srcIp; - packet.ip.daddr = destIp; - packet.udp.source = htons(BOOTP_CLIENT); - packet.udp.dest = htons(BOOTP_SERVER); - packet.udp.len = htons(sizeof(packet.udp) + sizeof(struct DhcpPacket)); /* cheat on the psuedo-header */ - packet.ip.tot_len = packet.udp.len; - if (memcpy_s(&(packet.data), sizeof(struct DhcpPacket), sendPacket, sizeof(struct DhcpPacket)) != EOK) { - return -1; + /* Filling the structure information. */ + struct UdpDhcpPacket udpPackets; + if (memset_s(&udpPackets, sizeof(udpPackets), 0, sizeof(udpPackets)) != EOK) { + close(nFd); + return SOCKET_OPT_FAILED; } - packet.udp.check = CheckSum((u_int16_t *)&packet, sizeof(struct UdpDhcpPacket)); - - packet.ip.tot_len = htons(sizeof(struct UdpDhcpPacket)); - packet.ip.ihl = sizeof(packet.ip) >> DHCP_UINT16_BYTES; - packet.ip.version = IPVERSION; - packet.ip.ttl = IPDEFTTL; - packet.ip.check = CheckSum((u_int16_t *)&(packet.ip), sizeof(packet.ip)); - - result = sendto(fd, &packet, sizeof(struct UdpDhcpPacket), 0, (struct sockaddr *)&dest, sizeof(dest)); - if (result <= 0) { - LOGE("write on socket failed: %{public}s!\n", strerror(errno)); + udpPackets.udp.source = htons(BOOTP_CLIENT); + udpPackets.udp.dest = htons(BOOTP_SERVER); + udpPackets.udp.len = htons(sizeof(udpPackets.udp) + sizeof(struct DhcpPacket)); + udpPackets.ip.tot_len = udpPackets.udp.len; + udpPackets.ip.protocol = IPPROTO_UDP; + udpPackets.ip.saddr = srcIp; + udpPackets.ip.daddr = destIp; + if (memcpy_s(&(udpPackets.data), sizeof(struct DhcpPacket), sendPacket, sizeof(struct DhcpPacket)) != EOK) { + close(nFd); + return SOCKET_OPT_FAILED; } - close(fd); - return result; + udpPackets.udp.check = CheckSum((u_int16_t *)&udpPackets, sizeof(struct UdpDhcpPacket)); + udpPackets.ip.ihl = sizeof(udpPackets.ip) >> DHCP_UINT16_BYTES; + udpPackets.ip.version = IPVERSION; + udpPackets.ip.tot_len = htons(sizeof(struct UdpDhcpPacket)); + udpPackets.ip.ttl = IPDEFTTL; + udpPackets.ip.check = CheckSum((u_int16_t *)&(udpPackets.ip), sizeof(udpPackets.ip)); + + ssize_t nBytes = sendto(nFd, &udpPackets, sizeof(udpPackets), 0, (struct sockaddr *)&rawAddr, sizeof(rawAddr)); + if (nBytes <= 0) { + LOGE("SendToDhcpPacket() fd:%{public}d failed, sendto error:%{public}s.\n", nFd, strerror(errno)); + } else { + LOGI("SendToDhcpPacket() fd:%{public}d, index:%{public}d, bytes:%{public}d.\n", nFd, destIndex, (int)nBytes); + } + close(nFd); + return (nBytes <= 0) ? SOCKET_OPT_FAILED : SOCKET_OPT_SUCCESS; } -/* Let the kernel do all the work for packet generation */ int SendDhcpPacket(struct DhcpPacket *sendPacket, uint32_t srcIp, uint32_t destIp) { - int fd; - int n = 1; - int result; - struct sockaddr_in src; - struct sockaddr_in dest; - - if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - return -1; - } - - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&n, sizeof(n)) == -1) { - return -1; + int nFd = -1; + if ((CreateKernelSocket(&nFd) != SOCKET_OPT_SUCCESS) || + (BindKernelSocket(nFd, NULL, srcIp, BOOTP_CLIENT, false) != SOCKET_OPT_SUCCESS)) { + LOGE("SendDhcpPacket() fd:%{public}d,srcIp:%{public}u failed!\n", nFd, srcIp); + return SOCKET_OPT_FAILED; } - if ((memset_s(&src, sizeof(src), 0, sizeof(src)) != EOK) - || (memset_s(&dest, sizeof(dest), 0, sizeof(dest)) != EOK)) { - return -1; + struct sockaddr_in kernelAddr; + if (memset_s(&kernelAddr, sizeof(kernelAddr), 0, sizeof(kernelAddr)) != EOK) { + close(nFd); + return SOCKET_OPT_FAILED; } - - src.sin_family = AF_INET; - src.sin_port = htons(BOOTP_CLIENT); - src.sin_addr.s_addr = srcIp; - if (bind(fd, (struct sockaddr *)&src, sizeof(struct sockaddr)) == -1) { - return -1; + kernelAddr.sin_addr.s_addr = destIp; + kernelAddr.sin_port = htons(BOOTP_SERVER); + kernelAddr.sin_family = AF_INET; + int nRet = connect(nFd, (struct sockaddr *)&kernelAddr, sizeof(kernelAddr)); + if (nRet == -1) { + LOGE("SendDhcpPacket() nFd:%{public}d failed, connect error:%{public}s.\n", nFd, strerror(errno)); + close(nFd); + return SOCKET_OPT_FAILED; } - dest.sin_family = AF_INET; - dest.sin_port = htons(BOOTP_SERVER); - dest.sin_addr.s_addr = destIp; - if (connect(fd, (struct sockaddr *)&dest, sizeof(struct sockaddr)) == -1) { - return -1; + ssize_t nBytes = write(nFd, sendPacket, sizeof(struct DhcpPacket)); + if (nBytes <= 0) { + LOGE("SendDhcpPacket() fd:%{public}d failed, write error:%{public}s.\n", nFd, strerror(errno)); + } else { + LOGI("SendDhcpPacket() fd:%{public}d, srcIp:%{public}u, bytes:%{public}d.\n", nFd, srcIp, (int)nBytes); } - - result = write(fd, sendPacket, sizeof(struct DhcpPacket)); - close(fd); - return result; + close(nFd); + return (nBytes <= 0) ? SOCKET_OPT_FAILED : SOCKET_OPT_SUCCESS; } -static int CheckReadBytes(const int count, const int totLen) +int CheckReadBytes(const int count, const int totLen) { if (count < 0) { LOGE("CheckReadBytes() couldn't read on raw listening socket, count:%{public}d, error:%{public}s!\n", @@ -251,20 +286,19 @@ static int CheckReadBytes(const int count, const int totLen) return SOCKET_OPT_FAILED; } - LOGI("CheckReadBytes() success, count:%{public}d, totLen:%{public}d.\n", count, totLen); + LOGI("CheckReadBytes() count:%{public}d, tot:%{public}d, common:%{public}d.\n", count, totLen, nCommonSize); return SOCKET_OPT_SUCCESS; } -static int CheckUdpPacket(struct UdpDhcpPacket *packet, const int totLen) +int CheckUdpPacket(struct UdpDhcpPacket *packet, const int totLen) { if (packet == NULL) { LOGE("CheckUdpPacket() failed, packet == NULL!\n"); return SOCKET_OPT_FAILED; } - int nSize = (int)sizeof(struct UdpDhcpPacket); - if (totLen > nSize) { - LOGE("CheckUdpPacket() failed, totLen:%{public}d error, nSize:%{public}d!\n", totLen, nSize); + if (totLen > (int)sizeof(struct UdpDhcpPacket)) { + LOGE("CheckUdpPacket() totLen:%{public}d more than %{public}d!\n", totLen, (int)sizeof(struct UdpDhcpPacket)); return SOCKET_OPT_FAILED; } @@ -291,62 +325,88 @@ static int CheckUdpPacket(struct UdpDhcpPacket *packet, const int totLen) LOGE("CheckUdpPacket() failed, packet->udp.len:%{public}d error, uLen:%{public}d!\n", packet->udp.len, uLen); return SOCKET_OPT_FAILED; } - LOGI("CheckUdpPacket() success, totLen:%{public}d.\n", totLen); return SOCKET_OPT_SUCCESS; } -int GetDhcpRawPacket(struct DhcpPacket *getPacket, int fd) +int CheckPacketIpSum(struct UdpDhcpPacket *udpPacket, const int bytes) { - struct UdpDhcpPacket packet; - int bytes, nRet; - u_int16_t check; - u_int32_t source, dest; - - if (memset_s(&packet, sizeof(struct UdpDhcpPacket), 0, sizeof(struct UdpDhcpPacket)) != EOK) { + if (udpPacket == NULL) { return SOCKET_OPT_FAILED; } - /* Check and get udp dhcp packet bytes. */ - bytes = read(fd, &packet, sizeof(struct UdpDhcpPacket)); - if ((nRet = CheckReadBytes(bytes, (int)ntohs(packet.ip.tot_len))) != SOCKET_OPT_SUCCESS) { - usleep(SLEEP_TIME_200_MS); - return nRet; - } - - /* Check udp packet. */ - bytes = (int)ntohs(packet.ip.tot_len); - if ((nRet = CheckUdpPacket(&packet, bytes)) != SOCKET_OPT_SUCCESS) { + if (CheckUdpPacket(udpPacket, bytes) != SOCKET_OPT_SUCCESS) { usleep(SLEEP_TIME_500_MS); - return nRet; + return SOCKET_OPT_FAILED; } /* Check packet ip sum. */ - check = packet.ip.check; - packet.ip.check = 0; - if (check != CheckSum((u_int16_t *)&(packet.ip), sizeof(packet.ip))) { - LOGE("GetDhcpRawPacket() CheckSum packet.ip.check failed!\n"); + u_int16_t check = udpPacket->ip.check; + udpPacket->ip.check = 0; + uint16_t uCheckSum = CheckSum((u_int16_t *)&(udpPacket->ip), sizeof(udpPacket->ip)); + if (check != uCheckSum) { + LOGE("CheckPacketIpSum() failed, ip.check:%{public}d, uCheckSum:%{public}d!\n", check, uCheckSum); return SOCKET_OPT_ERROR; } + LOGI("CheckPacketIpSum() success, bytes:%{public}d.\n", bytes); + return SOCKET_OPT_SUCCESS; +} + +int CheckPacketUdpSum(struct UdpDhcpPacket *udpPacket, const int bytes) +{ + if (udpPacket == NULL) { + LOGE("CheckPacketUdpSum() failed, udpPacket == NULL!\n"); + return SOCKET_OPT_FAILED; + } /* Check packet udp sum. */ - check = packet.udp.check; - packet.udp.check = 0; - source = packet.ip.saddr; - dest = packet.ip.daddr; - if (memset_s(&packet.ip, sizeof(packet.ip), 0, sizeof(packet.ip)) != EOK) { + u_int16_t check = udpPacket->udp.check; + udpPacket->udp.check = 0; + u_int32_t source = udpPacket->ip.saddr; + u_int32_t dest = udpPacket->ip.daddr; + if (memset_s(&udpPacket->ip, sizeof(udpPacket->ip), 0, sizeof(udpPacket->ip)) != EOK) { + LOGE("CheckPacketUdpSum() failed, memset_s ERROR!\n"); return SOCKET_OPT_FAILED; } - packet.ip.protocol = IPPROTO_UDP; - packet.ip.saddr = source; - packet.ip.daddr = dest; - packet.ip.tot_len = packet.udp.len; - if (check && (check != CheckSum((u_int16_t *)&packet, bytes))) { - LOGE("GetDhcpRawPacket() CheckSum packet.udp.check failed!\n"); + udpPacket->ip.protocol = IPPROTO_UDP; + udpPacket->ip.saddr = source; + udpPacket->ip.daddr = dest; + udpPacket->ip.tot_len = udpPacket->udp.len; + uint16_t uCheckSum = CheckSum((u_int16_t *)udpPacket, bytes); + if (check && (check != uCheckSum)) { + LOGE("CheckPacketUdpSum() failed, udp.check:%{public}d, uCheckSum:%{public}d!\n", check, uCheckSum); return SOCKET_OPT_FAILED; } + LOGI("CheckPacketUdpSum() success, bytes:%{public}d.\n", bytes); + return SOCKET_OPT_SUCCESS; +} - int nDhcpPacket = bytes - (int)(sizeof(packet.ip) + sizeof(packet.udp)); +int GetDhcpRawPacket(struct DhcpPacket *getPacket, int fd) +{ + if (getPacket == NULL) { + return SOCKET_OPT_FAILED; + } + + /* Get and check udp dhcp packet bytes. */ + struct UdpDhcpPacket packet; + if (memset_s(&packet, sizeof(struct UdpDhcpPacket), 0, sizeof(struct UdpDhcpPacket)) != EOK) { + return SOCKET_OPT_FAILED; + } + int nBytes = read(fd, &packet, sizeof(struct UdpDhcpPacket)); + int nRet = CheckReadBytes(nBytes, (int)ntohs(packet.ip.tot_len)); + if (nRet != SOCKET_OPT_SUCCESS) { + usleep(SLEEP_TIME_200_MS); + return nRet; + } + + /* Check udp dhcp packet sum. */ + nBytes = (int)ntohs(packet.ip.tot_len); + if (((nRet = CheckPacketIpSum(&packet, nBytes)) != SOCKET_OPT_SUCCESS) || + ((nRet = CheckPacketUdpSum(&packet, nBytes)) != SOCKET_OPT_SUCCESS)) { + return nRet; + } + + int nDhcpPacket = nBytes - (int)(sizeof(packet.ip) + sizeof(packet.udp)); if (memcpy_s(getPacket, sizeof(struct DhcpPacket), &(packet.data), nDhcpPacket) != EOK) { LOGE("GetDhcpRawPacket() memcpy_s packet.data failed!\n"); return SOCKET_OPT_FAILED; @@ -360,22 +420,22 @@ int GetDhcpRawPacket(struct DhcpPacket *getPacket, int fd) int GetDhcpPacket(struct DhcpPacket *getPacket, int fd) { - int bytes; + if (getPacket == NULL) { + return SOCKET_OPT_FAILED; + } + int bytes; if (memset_s(getPacket, sizeof(struct DhcpPacket), 0, sizeof(struct DhcpPacket)) != EOK) { return SOCKET_OPT_FAILED; } - bytes = read(fd, getPacket, sizeof(struct DhcpPacket)); - if (bytes < 0) { + if ((bytes = read(fd, getPacket, sizeof(struct DhcpPacket))) < 0) { LOGE("GetDhcpPacket() couldn't read on kernel listening socket, error:%{public}s!\n", strerror(errno)); return SOCKET_OPT_ERROR; } if (ntohl(getPacket->cookie) != MAGIC_COOKIE) { - LOGE("GetDhcpPacket() received bogus message (bad magic)!\n"); + LOGE("GetDhcpPacket() cook:%{public}x error, COOK:%{public}x!\n", ntohl(getPacket->cookie), MAGIC_COOKIE); return SOCKET_OPT_FAILED; } - - LOGI("GetDhcpPacket() received a packet, bytes:%{public}d.\n", bytes); return bytes; } diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/BUILD.gn b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/BUILD.gn similarity index 81% rename from services/wifi_standard/wifi_framework/dhcp_manage/BUILD.gn rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/BUILD.gn index 8448953ba..82cb36785 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/BUILD.gn +++ b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/BUILD.gn @@ -16,16 +16,16 @@ import("//build/ohos.gni") ohos_shared_library("dhcp_manager_service") { install_enable = true sources = [ - "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_service.cpp", - "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_client_service_impl.cpp", - "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_server_service_impl.cpp", - "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_func.cpp" + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_service.cpp", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_client_service_impl.cpp", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_server_service_impl.cpp", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_func.cpp" ] include_dirs = [ "//foundation/communication/wifi/services/wifi_standard/wifi_framework/common/log", - "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/include", - "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/interfaces", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/interfaces", "//utils/native/base/include" ] diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_client_service_impl.h b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include/dhcp_client_service_impl.h similarity index 99% rename from services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_client_service_impl.h rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include/dhcp_client_service_impl.h index 2ff862cd4..c33262e71 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_client_service_impl.h +++ b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include/dhcp_client_service_impl.h @@ -114,6 +114,30 @@ public: */ int ReleaseDhcpClient(const std::string& ifname) override; + /** + * @Description : Handle dhcp packet info. + * + * @param ifname - interface name, eg:wlan0 [in] + * @param packetResult - dhcp packet result [in] + * @param success - get success is true, get failed is false [in] + */ + void DhcpPacketInfoHandle(const std::string& ifname, struct DhcpPacketResult &packetResult, bool success = true); + + /** + * @Description : Handle dhcp result. + * + * @param second - sleep second number [out] + */ + void DhcpResultHandle(uint32_t &second); + + /** + * @Description : Get the dhcp client process pid of specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] + * @Return : The dhcp client process pid. + */ + pid_t GetDhcpClientProPid(const std::string& ifname); + private: /** * @Description : Start dhcp result handle threads. @@ -131,12 +155,6 @@ private: * */ void CheckTimeout(); - /** - * @Description : Handle dhcp result. - * - * @param second - sleep second number [out] - */ - void DhcpResultHandle(uint32_t &second); /** * @Description : Dhcp result handle threads execution function. * @@ -148,14 +166,6 @@ private: * @param ifname - interface name, eg:wlan0 [in] */ void RunDhcpRecvMsgThreadFunc(const std::string& ifname); - /** - * @Description : Handle dhcp packet info. - * - * @param ifname - interface name, eg:wlan0 [in] - * @param packetResult - dhcp packet result [in] - * @param success - get success is true, get failed is false [in] - */ - void DhcpPacketInfoHandle(const std::string& ifname, struct DhcpPacketResult &packetResult, bool success = true); /** * @Description : Fork child process function for start or stop dhcp process. * @@ -173,14 +183,6 @@ private: */ int ForkExecParentProcess(const std::string& ifname, bool bIpv6, bool bStart = false, pid_t pid = 0); - /** - * @Description : Get the dhcp client process pid of specified interface. - * - * @param ifname - interface name, eg:wlan0 [in] - * @Return : The dhcp client process pid. - */ - pid_t GetDhcpClientProPid(const std::string& ifname); - private: std::mutex mResultNotifyMutex; std::mutex mRecvMsgThreadMutex; diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_define.h b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include/dhcp_define.h similarity index 100% rename from services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_define.h rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include/dhcp_define.h diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_func.h b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include/dhcp_func.h similarity index 98% rename from services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_func.h rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include/dhcp_func.h index 99f1cca26..0b7924742 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_func.h +++ b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include/dhcp_func.h @@ -38,7 +38,7 @@ public: static unsigned int IPtoInt(const std::string& strIp); static bool Ip4StrConToInt(const std::string& strIp, uint32_t& uIp); static std::string Ip4IntConToStr(uint32_t uIp); - static bool Ip6StrConToChar(const std::string& strIp, uint8_t chIp[]); + static bool Ip6StrConToChar(const std::string& strIp, uint8_t chIp[], size_t uSize); static std::string Ip6CharConToStr(uint8_t chIp[], int size); static bool CheckIpStr(const std::string& strIp); static int GetLocalIp(const std::string ethInf, std::string& localIp); diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_server_service_impl.h b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include/dhcp_server_service_impl.h similarity index 100% rename from services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_server_service_impl.h rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include/dhcp_server_service_impl.h index dc256ccd7..d73aa0c78 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_server_service_impl.h +++ b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include/dhcp_server_service_impl.h @@ -135,62 +135,78 @@ public: */ int ReConf(void) override; -private: /** - * @Description : Fork parent process function. + * @Description : Check and update dhcp server config of specified interface. * + * @param ifname - interface name, eg:wlan0 [in] * @Return : success - DHCP_OPT_SUCCESS, failed - others. */ - int ForkParentProcess(); + int CheckAndUpdateConf(const std::string& ifname); /** - * @Description : Fork child process function for start dhcp server process. + * @Description : Delete dhcp server config of specified interface and reload all config. * - * @param ifname - interface name, eg:wlan0 [in] + * @param if_filename - interface file name, eg:wlan0.conf [in] * @Return : success - DHCP_OPT_SUCCESS, failed - others. */ - int ForkExecProcess(const std::string& ifname = "reload cfg"); + int DeleteInfConf(const std::string& if_filename); /** - * @Description : Stop dhcp server process. + * @Description : Check invalid or already exist in dhcp range. * - * @param server_pid - process id [in] + * @param range - ip address range [in] + * @Return : true - yes, false - no. + */ + bool CheckIpAddrRange(const DhcpRange& range); + + /** + * @Description : Check ip address range is or not conflict. + * + * @param srcRange - already exist in ip address range [in] + * @param addRange - need add ip address range [in] + * @Return : true - yes, false - no. + */ + bool CheckDhcpRangeConflict(const DhcpRange& srcRange, const DhcpRange& addRange); + + /** + * @Description : Add the specified interface. + * + * @param ifname - interface name, eg:wlan0 [in] * @Return : success - DHCP_OPT_SUCCESS, failed - others. */ - int StopServer(const pid_t& server_pid); + int AddSpecifiedInterface(const std::string& ifname); /** - * @Description : Check and update dhcp server config of specified interface. + * @Description : Delete the specified interface. * * @param ifname - interface name, eg:wlan0 [in] * @Return : success - DHCP_OPT_SUCCESS, failed - others. */ - int CheckAndUpdateConf(const std::string& ifname); + int DelSpecifiedInterface(const std::string& ifname); +private: /** - * @Description : Delete dhcp server config of specified interface and reload all config. + * @Description : Fork parent process function. * - * @param if_filename - interface file name, eg:wlan0.conf [in] * @Return : success - DHCP_OPT_SUCCESS, failed - others. */ - int DeleteInfConf(const std::string& if_filename); + int ForkParentProcess(); /** - * @Description : Check invalid or already exist in dhcp range. + * @Description : Fork child process function for start dhcp server process. * - * @param range - ip address range [in] - * @Return : true - yes, false - no. + * @param ifname - interface name, eg:wlan0 [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. */ - bool CheckIpAddrRange(const DhcpRange& range); + int ForkExecProcess(const std::string& ifname = "reload cfg"); /** - * @Description : Check ip address range is or not conflict. + * @Description : Stop dhcp server process. * - * @param srcRange - already exist in ip address range [in] - * @param addRange - need add ip address range [in] - * @Return : true - yes, false - no. + * @param server_pid - process id [in] + * @Return : success - DHCP_OPT_SUCCESS, failed - others. */ - bool CheckDhcpRangeConflict(const DhcpRange& srcRange, const DhcpRange& addRange); + int StopServer(const pid_t& server_pid); /** * @Description : Check ip address range list is or not same. @@ -225,22 +241,6 @@ private: */ void UnregisterSignal() const; - /** - * @Description : Add the specified interface. - * - * @param ifname - interface name, eg:wlan0 [in] - * @Return : success - DHCP_OPT_SUCCESS, failed - others. - */ - int AddSpecifiedInterface(const std::string& ifname); - - /** - * @Description : Delete the specified interface. - * - * @param ifname - interface name, eg:wlan0 [in] - * @Return : success - DHCP_OPT_SUCCESS, failed - others. - */ - int DelSpecifiedInterface(const std::string& ifname); - /** * @Description : Receives the SIGCHLD signal of the dhcp server process. * diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_service.h b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include/dhcp_service.h similarity index 100% rename from services/wifi_standard/wifi_framework/dhcp_manage/include/dhcp_service.h rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include/dhcp_service.h diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_client_service.h b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/interfaces/i_dhcp_client_service.h similarity index 100% rename from services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_client_service.h rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/interfaces/i_dhcp_client_service.h diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_result_notify.h b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/interfaces/i_dhcp_result_notify.h similarity index 100% rename from services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_result_notify.h rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/interfaces/i_dhcp_result_notify.h diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_server_service.h b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/interfaces/i_dhcp_server_service.h similarity index 100% rename from services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_server_service.h rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/interfaces/i_dhcp_server_service.h diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_service.h b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/interfaces/i_dhcp_service.h similarity index 100% rename from services/wifi_standard/wifi_framework/dhcp_manage/interfaces/i_dhcp_service.h rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/interfaces/i_dhcp_service.h diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_client_service_impl.cpp b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_client_service_impl.cpp similarity index 100% rename from services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_client_service_impl.cpp rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_client_service_impl.cpp diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_func.cpp b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_func.cpp similarity index 97% rename from services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_func.cpp rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_func.cpp index 33eab64f5..aee26e321 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_func.cpp +++ b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_func.cpp @@ -75,7 +75,7 @@ std::string DhcpFunc::Ip4IntConToStr(uint32_t uIp) { if (uIp == 0) { WIFI_LOGE("Ip4IntConToStr uIp is 0!\n"); - return NULL; + return ""; } std::string strIp = ""; @@ -92,7 +92,7 @@ std::string DhcpFunc::Ip4IntConToStr(uint32_t uIp) return strIp; } -bool DhcpFunc::Ip6StrConToChar(const std::string& strIp, uint8_t chIp[]) +bool DhcpFunc::Ip6StrConToChar(const std::string& strIp, uint8_t chIp[], size_t uSize) { if (strIp.empty()) { WIFI_LOGE("Ip6StrConToChar param error, strIp is empty()!\n"); @@ -114,7 +114,7 @@ bool DhcpFunc::Ip6StrConToChar(const std::string& strIp, uint8_t chIp[]) return false; } - for (size_t i = 0; i < sizeof(struct in6_addr); i++) { + for (size_t i = 0; i < uSize; i++) { chIp[i] = addr6.s6_addr[i]; } @@ -174,7 +174,7 @@ bool DhcpFunc::CheckIpStr(const std::string& strIp) } } else { uint8_t addr6[sizeof(struct in6_addr)] = {0}; - if (!Ip6StrConToChar(strIp, addr6)) { + if (!Ip6StrConToChar(strIp, addr6, sizeof(struct in6_addr))) { WIFI_LOGE("CheckIpStr Ip6StrConToChar failed, strIp:%{public}s.\n", strIp.c_str()); return false; } @@ -446,6 +446,7 @@ int DhcpFunc::GetDhcpPacketResult(const std::string& filename, struct DhcpPacket char strIpFlag[DHCP_NUMBER_EIGHT]; if (memset_s(strIpFlag, sizeof(strIpFlag), 0, sizeof(strIpFlag)) != EOK) { + fclose(pFile); return DHCP_OPT_FAILED; } /* Format: IpFlag AddTime cliIp servIp subnet dns1 dns2 router1 router2 vendor lease */ @@ -498,8 +499,8 @@ int DhcpFunc::InitPidfile(const std::string& piddir, const std::string& pidfile) } char buf[PID_MAX_LEN] = {0}; - if (snprintf(buf, PID_MAX_LEN, "%d", getpid()) < 0) { - WIFI_LOGE("InitPidfile() %{public}s failed, snprintf error:%{public}s!\n", pidfile.c_str(), strerror(errno)); + if (snprintf_s(buf, PID_MAX_LEN, PID_MAX_LEN - 1, "%d", getpid()) < 0) { + WIFI_LOGE("InitPidfile() %{public}s failed, snprintf_s error:%{public}s!\n", pidfile.c_str(), strerror(errno)); close(fd); return DHCP_OPT_FAILED; } diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_server_service_impl.cpp b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_server_service_impl.cpp similarity index 99% rename from services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_server_service_impl.cpp rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_server_service_impl.cpp index edd37a0cc..24dc2fd2c 100644 --- a/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_server_service_impl.cpp +++ b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_server_service_impl.cpp @@ -646,11 +646,11 @@ bool DhcpServerServiceImpl::CheckIpAddrRange(const DhcpRange &range) } } else { uint8_t uStartIp6[sizeof(struct in6_addr)] = {0}; - if (!DhcpFunc::Ip6StrConToChar(range.strStartip, uStartIp6)) { + if (!DhcpFunc::Ip6StrConToChar(range.strStartip, uStartIp6, sizeof(struct in6_addr))) { return false; } uint8_t uEndIp6[sizeof(struct in6_addr)] = {0}; - if (!DhcpFunc::Ip6StrConToChar(range.strEndip, uEndIp6)) { + if (!DhcpFunc::Ip6StrConToChar(range.strEndip, uEndIp6, sizeof(struct in6_addr))) { return false; } /* check ip6 start and end ip */ @@ -866,8 +866,9 @@ int DhcpServerServiceImpl::DelSpecifiedInterface(const std::string& ifname) return DHCP_OPT_FAILED; } - if (m_setInterfaces.find(ifname) != m_setInterfaces.end()) { - m_setInterfaces.erase(ifname); + auto iterInterfaces = m_setInterfaces.find(ifname); + if (iterInterfaces != m_setInterfaces.end()) { + m_setInterfaces.erase(iterInterfaces); WIFI_LOGI("DelSpecifiedInterface() m_setInterfaces del ifname:%{public}s success.\n", ifname.c_str()); } else { WIFI_LOGI("DelSpecifiedInterface() m_setInterfaces not exists ifname:%{public}s.\n", ifname.c_str()); diff --git a/services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_service.cpp b/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_service.cpp similarity index 100% rename from services/wifi_standard/wifi_framework/dhcp_manage/src/dhcp_service.cpp rename to services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/src/dhcp_service.cpp diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/BUILD.gn b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/BUILD.gn index 0ade06f43..92050b4e4 100644 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/BUILD.gn +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/BUILD.gn @@ -57,8 +57,8 @@ ohos_shared_library("wifi_sta_service") { "//foundation/communication/wifi/services/wifi_standard/depends/include/system/core/libutils/include", "//foundation/communication/wifi/services/wifi_standard/depends/include/system/core/base/include", "//foundation/communication/wifi/services/wifi_standard/depends/include/system/libbase/include", - "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/include", - "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/interfaces", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/include", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service/interfaces", ] cflags_cc = [ @@ -74,7 +74,7 @@ ohos_shared_library("wifi_sta_service") { deps = [ "//foundation/communication/wifi/services/wifi_standard/wifi_framework/wifi_manage:wifi_manager_service", "//foundation/communication/wifi/services/wifi_standard/wifi_framework/wifi_manage/idl_client:wifi_idl_client", - "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage:dhcp_manager_service", + "//foundation/communication/wifi/services/wifi_standard/wifi_framework/dhcp_manage/mgr_service:dhcp_manager_service", "//utils/native/base:utils", ] diff --git a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_state_machine.cpp b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_state_machine.cpp index 212cc2f48..0514e6d34 100755 --- a/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_state_machine.cpp +++ b/services/wifi_standard/wifi_framework/wifi_manage/wifi_sta/sta_state_machine.cpp @@ -52,6 +52,7 @@ StaStateMachine::StaStateMachine() getIpSucNum(0), getIpFailNum(0), pDhcpService(nullptr), + pDhcpResultNotify(nullptr), pNetSpeed(nullptr), pNetcheck(nullptr), msgQueueUp(nullptr), -- Gitee