123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/system/diagnostics/networking_log.h"
- #include <sstream>
- #include <utility>
- #include "base/check.h"
- #include "base/containers/contains.h"
- #include "base/i18n/time_formatting.h"
- #include "base/notreached.h"
- #include "base/strings/string_number_conversions.h"
- #include "base/strings/string_util.h"
- #include "base/strings/stringprintf.h"
- #include "base/strings/utf_string_conversions.h"
- #include "base/time/time.h"
- namespace ash {
- namespace diagnostics {
- namespace {
- const char kNewline[] = "\n";
- // NetworkingInfo constants:
- const char kNetworkingInfoSectionName[] = "--- Network Info ---";
- const char kNetworkEventsSectionName[] = "--- Network Events ---";
- const char kNetworkNameTitle[] = "Name: ";
- const char kNetworkTypeTitle[] = "Type: ";
- const char kNetworkStateTitle[] = "State: ";
- const char kActiveTitle[] = "Active: ";
- const char kMacAddressTitle[] = "MAC Address: ";
- // CellularStateProperties constants:
- const char kCellularIccidTitle[] = "ICCID: ";
- const char kCellularEidTitle[] = "EID: ";
- const char kCellularNetworkTechnologyTitle[] = "Technology: ";
- const char kCellularRoamingTitle[] = "Roaming: ";
- const char kCellularRoamingStateTitle[] = "Roaming State: ";
- const char kCellularSignalStrengthTitle[] = "Signal Strength: ";
- const char kCellularSimLockedTitle[] = "SIM Locked: ";
- const char kCellularLockTypeTitle[] = "SIM Lock Type: ";
- // EthernetStateProperties constants:
- const char kEthernetAuthenticationTitle[] = "Authentication: ";
- // WiFiStateProperties constants:
- const char kWifiSignalStrengthTitle[] = "Signal Strength: ";
- const char kWifiFrequencyTitle[] = "Frequency: ";
- const char kWifiSsidTitle[] = "SSID: ";
- const char kWifiBssidTitle[] = "BSSID: ";
- const char kSecurityTitle[] = "Security: ";
- // IpConfigProperties constants:
- const char kNameServersTitle[] = "Name Servers: ";
- const char kGatewayTitle[] = "Gateway: ";
- const char kIPAddressTitle[] = "IP Address: ";
- const char kSubnetMaskTitle[] = "Subnet Mask: ";
- // Event log entries
- const char kEventLogFilename[] = "network_events.log";
- const char kNetworkAddedEventTemplate[] =
- "%s network [%s] started in state %s\n";
- const char kNetworkRemovedEventTemplate[] = "%s network [%s] removed\n";
- const char kNetworkStateChangedEventTemplate[] =
- "%s network [%s] changed state from %s to %s\n";
- const char kJoinedWiFiEventTemplate[] =
- "%s network [%s] joined SSID '%s' on access point [%s]\n";
- const char kLeftWiFiEventTemplate[] = "%s network [%s] left SSID '%s'\n";
- const char kAccessPointRoamingEventTemplate[] =
- "%s network [%s] on SSID '%s' roamed from access point [%s] to [%s]\n";
- std::string GetSubnetMask(int prefix) {
- uint32_t mask = (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF;
- std::vector<uint32_t> pieces = {mask >> 24, (mask >> 16) & 0xFF,
- (mask >> 8) & 0xFF, mask & 0xFF};
- std::vector<std::string> vec;
- for (const auto& piece : pieces) {
- vec.push_back(base::NumberToString(piece));
- }
- return base::JoinString(vec, ".");
- }
- std::string GetSecurityType(mojom::SecurityType type) {
- switch (type) {
- case mojom::SecurityType::kNone:
- return "None";
- case mojom::SecurityType::kWep8021x:
- case mojom::SecurityType::kWpaEap:
- return "EAP";
- case mojom::SecurityType::kWepPsk:
- return "WEP";
- case mojom::SecurityType::kWpaPsk:
- return "PSK (WPA or RSN)";
- }
- }
- std::string GetSsid(const mojom::NetworkPtr& network) {
- DCHECK(network->type == mojom::NetworkType::kWiFi);
- return network->type_properties ? network->type_properties->get_wifi()->ssid
- : "";
- }
- std::string GetBssid(const mojom::NetworkPtr& network) {
- DCHECK(network->type == mojom::NetworkType::kWiFi);
- return network->type_properties ? network->type_properties->get_wifi()->bssid
- : "";
- }
- bool HasJoinedWiFiNetwork(const mojom::NetworkPtr& old_state,
- const mojom::NetworkPtr& new_state) {
- const std::string old_ssid = GetSsid(old_state);
- return old_ssid.empty() && (old_ssid != GetSsid(new_state));
- }
- bool HasLeftWiFiNetwork(const mojom::NetworkPtr& old_state,
- const mojom::NetworkPtr& new_state) {
- const std::string new_ssid = GetSsid(new_state);
- return new_ssid.empty() && (new_ssid != GetSsid(old_state));
- }
- bool HasRoamedAccessPoint(const mojom::NetworkPtr& old_state,
- const mojom::NetworkPtr& new_state) {
- const std::string new_ssid = GetSsid(new_state);
- return !new_ssid.empty() && (new_ssid == GetSsid(old_state)) &&
- (GetBssid(old_state) != GetBssid(new_state));
- }
- void AddWifiInfoToLog(const mojom::NetworkTypeProperties& type_props,
- std::stringstream& output) {
- output << kWifiSignalStrengthTitle << type_props.get_wifi()->signal_strength
- << kNewline << kWifiFrequencyTitle << type_props.get_wifi()->frequency
- << kNewline << kWifiSsidTitle << type_props.get_wifi()->ssid
- << kNewline << kWifiBssidTitle << type_props.get_wifi()->bssid
- << kNewline << kSecurityTitle
- << GetSecurityType(type_props.get_wifi()->security) << kNewline;
- }
- std::string GetBoolAsString(bool value) {
- return value ? "True" : "False";
- }
- std::string GetCellularRoamingState(mojom::RoamingState state) {
- switch (state) {
- case mojom::RoamingState::kNone:
- return "None";
- case mojom::RoamingState::kHome:
- return "Home";
- case mojom::RoamingState::kRoaming:
- return "Roaming";
- }
- }
- std::string GetCellularLockType(mojom::LockType lock_type) {
- switch (lock_type) {
- case mojom::LockType::kNone:
- return "None";
- case mojom::LockType::kSimPin:
- return "sim-pin";
- case mojom::LockType::kSimPuk:
- return "sim-puk";
- }
- }
- void AddCellularInfoToLog(const mojom::NetworkTypeProperties& type_props,
- std::stringstream& output) {
- output << kCellularIccidTitle << type_props.get_cellular()->iccid << kNewline
- << kCellularEidTitle << type_props.get_cellular()->eid << kNewline
- << kCellularNetworkTechnologyTitle
- << type_props.get_cellular()->network_technology << kNewline
- << kCellularRoamingTitle
- << GetBoolAsString(type_props.get_cellular()->roaming) << kNewline
- << kCellularRoamingStateTitle
- << GetCellularRoamingState(type_props.get_cellular()->roaming_state)
- << kNewline << kCellularSignalStrengthTitle
- << type_props.get_cellular()->signal_strength << kNewline
- << kCellularSimLockedTitle
- << GetBoolAsString(type_props.get_cellular()->sim_locked) << kNewline
- << kCellularLockTypeTitle
- << GetCellularLockType(type_props.get_cellular()->lock_type)
- << kNewline;
- }
- std::string GetEthernetAuthenticationType(mojom::AuthenticationType type) {
- switch (type) {
- case mojom::AuthenticationType::kNone:
- return "None";
- case mojom::AuthenticationType::k8021x:
- return "EAP";
- }
- }
- void AddEthernetInfoToLog(const mojom::NetworkTypeProperties& type_props,
- std::stringstream& output) {
- output << kEthernetAuthenticationTitle
- << GetEthernetAuthenticationType(
- type_props.get_ethernet()->authentication)
- << kNewline;
- }
- void AddTypePropertiesToLog(const mojom::NetworkTypeProperties& type_props,
- mojom::NetworkType type,
- std::stringstream& output) {
- switch (type) {
- case mojom::NetworkType::kWiFi:
- AddWifiInfoToLog(type_props, output);
- break;
- case mojom::NetworkType::kCellular:
- AddCellularInfoToLog(type_props, output);
- break;
- case mojom::NetworkType::kEthernet:
- AddEthernetInfoToLog(type_props, output);
- break;
- case mojom::NetworkType::kUnsupported:
- NOTREACHED();
- break;
- }
- }
- void AddIPConfigPropertiesToLog(const mojom::IPConfigProperties& ip_config,
- std::stringstream& output) {
- output << kGatewayTitle << ip_config.gateway.value_or("") << kNewline;
- output << kIPAddressTitle << ip_config.ip_address.value_or("") << kNewline;
- auto name_servers = base::JoinString(
- ip_config.name_servers.value_or(std::vector<std::string>()), ", ");
- output << kNameServersTitle << name_servers << kNewline;
- // A routing prefix can not be 0, 0 indicates an unset value.
- auto subnet_mask = ip_config.routing_prefix != 0
- ? GetSubnetMask(ip_config.routing_prefix)
- : "";
- output << kSubnetMaskTitle << subnet_mask << kNewline;
- }
- std::string GetNetworkStateString(mojom::NetworkState state) {
- switch (state) {
- case mojom::NetworkState::kOnline:
- return "Online";
- case mojom::NetworkState::kConnected:
- return "Connected";
- case mojom::NetworkState::kConnecting:
- return "Connecting";
- case mojom::NetworkState::kNotConnected:
- return "Not Connected";
- case mojom::NetworkState::kDisabled:
- return "Disabled";
- case mojom::NetworkState::kPortal:
- return "Portal";
- }
- }
- std::string GetNetworkType(mojom::NetworkType type) {
- switch (type) {
- case mojom::NetworkType::kWiFi:
- return "WiFi";
- case mojom::NetworkType::kCellular:
- return "Cellular";
- case mojom::NetworkType::kEthernet:
- return "Ethernet";
- case mojom::NetworkType::kUnsupported:
- NOTREACHED();
- return "";
- }
- }
- } // namespace
- NetworkingLog::NetworkingLog(const base::FilePath& log_base_path)
- : event_log_(log_base_path.Append(kEventLogFilename)) {}
- NetworkingLog::~NetworkingLog() = default;
- std::string NetworkingLog::GetNetworkInfo() const {
- std::stringstream output;
- output << kNetworkingInfoSectionName << kNewline;
- for (const auto& pair : latest_network_states_) {
- const mojom::NetworkPtr& network = pair.second;
- output << kNewline << kNetworkNameTitle << network->name << kNewline
- << kNetworkTypeTitle << GetNetworkType(network->type) << kNewline
- << kNetworkStateTitle << GetNetworkStateString(network->state)
- << kNewline << kActiveTitle
- << (network->observer_guid == active_guid_ ? "True" : "False")
- << kNewline << kMacAddressTitle << network->mac_address.value_or("")
- << kNewline;
- if (network->type_properties) {
- AddTypePropertiesToLog(*network->type_properties, network->type, output);
- }
- if (network->ip_config) {
- AddIPConfigPropertiesToLog(*network->ip_config, output);
- }
- }
- return output.str();
- }
- std::string NetworkingLog::GetNetworkEvents() const {
- return std::string(kNetworkEventsSectionName) + kNewline + kNewline +
- event_log_.GetContents();
- }
- void NetworkingLog::UpdateNetworkList(
- const std::vector<std::string>& observer_guids,
- std::string active_guid) {
- // If a network is no longer valid, remove it from the map.
- for (auto iter = latest_network_states_.begin();
- iter != latest_network_states_.end();) {
- if (!base::Contains(observer_guids, iter->first)) {
- LogNetworkRemoved(iter->second);
- iter = latest_network_states_.erase(iter);
- continue;
- }
- ++iter;
- }
- active_guid_ = active_guid;
- }
- void NetworkingLog::UpdateNetworkState(mojom::NetworkPtr network) {
- if (network.is_null()) {
- LOG(ERROR) << "Network to log update is null";
- return;
- }
- if (!base::Contains(latest_network_states_, network->observer_guid)) {
- LogNetworkAdded(network);
- latest_network_states_.emplace(network->observer_guid, std::move(network));
- return;
- }
- LogNetworkChanges(network);
- latest_network_states_[network->observer_guid] = std::move(network);
- }
- void NetworkingLog::LogEvent(const std::string& event_string) {
- const std::string datetime =
- base::UTF16ToUTF8(base::TimeFormatShortDateAndTime(base::Time::Now()));
- event_log_.Append(datetime + " - " + event_string);
- }
- void NetworkingLog::LogNetworkAdded(const mojom::NetworkPtr& network) {
- const std::string line = base::StringPrintf(
- kNetworkAddedEventTemplate, GetNetworkType(network->type).c_str(),
- network->mac_address.value_or("").c_str(),
- GetNetworkStateString(network->state).c_str());
- LogEvent(line);
- }
- void NetworkingLog::LogNetworkRemoved(const mojom::NetworkPtr& network) {
- if (network.is_null()) {
- LOG(ERROR) << "Network to log removal is null";
- return;
- }
- const std::string line = base::StringPrintf(
- kNetworkRemovedEventTemplate, GetNetworkType(network->type).c_str(),
- network->mac_address.value_or("").c_str());
- LogEvent(line);
- }
- void NetworkingLog::LogNetworkChanges(const mojom::NetworkPtr& new_state) {
- DCHECK(base::Contains(latest_network_states_, new_state->observer_guid));
- const mojom::NetworkPtr& old_state =
- latest_network_states_.at(new_state->observer_guid);
- if (new_state->type == mojom::NetworkType::kWiFi) {
- if (HasJoinedWiFiNetwork(old_state, new_state)) {
- LogJoinedWiFiNetwork(new_state);
- } else if (HasLeftWiFiNetwork(old_state, new_state)) {
- LogLeftWiFiNetwork(new_state, GetSsid(old_state));
- } else if (HasRoamedAccessPoint(old_state, new_state)) {
- LogWiFiRoamedAccessPoint(new_state, GetBssid(old_state));
- }
- }
- if (old_state->state != new_state->state) {
- LogNetworkStateChanged(old_state, new_state);
- }
- }
- void NetworkingLog::LogNetworkStateChanged(const mojom::NetworkPtr& old_state,
- const mojom::NetworkPtr& new_state) {
- const std::string line =
- base::StringPrintf(kNetworkStateChangedEventTemplate,
- GetNetworkType(new_state->type).c_str(),
- new_state->mac_address.value_or("").c_str(),
- GetNetworkStateString(old_state->state).c_str(),
- GetNetworkStateString(new_state->state).c_str());
- LogEvent(line);
- }
- void NetworkingLog::LogJoinedWiFiNetwork(const mojom::NetworkPtr& network) {
- const std::string line = base::StringPrintf(
- kJoinedWiFiEventTemplate, GetNetworkType(network->type).c_str(),
- network->mac_address.value_or("").c_str(), GetSsid(network).c_str(),
- GetBssid(network).c_str());
- LogEvent(line);
- }
- void NetworkingLog::LogLeftWiFiNetwork(const mojom::NetworkPtr& network,
- const std::string& old_ssid) {
- const std::string line = base::StringPrintf(
- kLeftWiFiEventTemplate, GetNetworkType(network->type).c_str(),
- network->mac_address.value_or("").c_str(), old_ssid.c_str());
- LogEvent(line);
- }
- void NetworkingLog::LogWiFiRoamedAccessPoint(const mojom::NetworkPtr& network,
- const std::string& old_bssid) {
- const std::string line = base::StringPrintf(
- kAccessPointRoamingEventTemplate, GetNetworkType(network->type).c_str(),
- network->mac_address.value_or("").c_str(), GetSsid(network).c_str(),
- old_bssid.c_str(), GetBssid(network).c_str());
- LogEvent(line);
- }
- } // namespace diagnostics
- } // namespace ash
|