1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/network/network_util.h"
7 #include "base/strings/string_tokenizer.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/stringprintf.h"
10 #include "chromeos/login/login_state.h"
11 #include "chromeos/network/device_state.h"
12 #include "chromeos/network/managed_network_configuration_handler.h"
13 #include "chromeos/network/network_state.h"
14 #include "chromeos/network/network_state_handler.h"
15 #include "chromeos/network/network_ui_data.h"
16 #include "chromeos/network/onc/onc_signature.h"
17 #include "chromeos/network/onc/onc_translation_tables.h"
18 #include "chromeos/network/onc/onc_translator.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
23 WifiAccessPoint::WifiAccessPoint()
29 WifiAccessPoint::~WifiAccessPoint() {
32 CellularScanResult::CellularScanResult() {
35 CellularScanResult::~CellularScanResult() {
38 namespace network_util
{
40 std::string
PrefixLengthToNetmask(int32 prefix_length
) {
42 // Return the empty string for invalid inputs.
43 if (prefix_length
< 0 || prefix_length
> 32)
45 for (int i
= 0; i
< 4; i
++) {
47 if (prefix_length
>= 8) {
50 remainder
= prefix_length
;
55 int value
= remainder
== 0 ? 0 :
56 ((2L << (remainder
- 1)) - 1) << (8 - remainder
);
57 netmask
+= base::StringPrintf("%d", value
);
62 int32
NetmaskToPrefixLength(const std::string
& netmask
) {
64 int prefix_length
= 0;
65 base::StringTokenizer
t(netmask
, ".");
67 // If there are more than 4 numbers, then it's invalid.
71 std::string token
= t
.token();
72 // If we already found the last mask and the current one is not
73 // "0" then the netmask is invalid. For example, 255.224.255.0
74 if (prefix_length
/ 8 != count
) {
77 } else if (token
== "255") {
79 } else if (token
== "254") {
81 } else if (token
== "252") {
83 } else if (token
== "248") {
85 } else if (token
== "240") {
87 } else if (token
== "224") {
89 } else if (token
== "192") {
91 } else if (token
== "128") {
93 } else if (token
== "0") {
96 // mask is not a valid number.
103 return prefix_length
;
106 std::string
FormattedMacAddress(const std::string
& shill_mac_address
) {
107 if (shill_mac_address
.size() % 2 != 0)
108 return shill_mac_address
;
110 for (size_t i
= 0; i
< shill_mac_address
.size(); ++i
) {
111 if ((i
!= 0) && (i
% 2 == 0))
112 result
.push_back(':');
113 result
.push_back(base::ToUpperASCII(shill_mac_address
[i
]));
118 bool ParseCellularScanResults(const base::ListValue
& list
,
119 std::vector
<CellularScanResult
>* scan_results
) {
120 scan_results
->clear();
121 scan_results
->reserve(list
.GetSize());
122 for (base::ListValue::const_iterator it
= list
.begin();
123 it
!= list
.end(); ++it
) {
124 if (!(*it
)->IsType(base::Value::TYPE_DICTIONARY
))
126 CellularScanResult scan_result
;
127 const base::DictionaryValue
* dict
=
128 static_cast<const base::DictionaryValue
*>(*it
);
129 // If the network id property is not present then this network cannot be
130 // connected to so don't include it in the results.
131 if (!dict
->GetStringWithoutPathExpansion(shill::kNetworkIdProperty
,
132 &scan_result
.network_id
))
134 dict
->GetStringWithoutPathExpansion(shill::kStatusProperty
,
135 &scan_result
.status
);
136 dict
->GetStringWithoutPathExpansion(shill::kLongNameProperty
,
137 &scan_result
.long_name
);
138 dict
->GetStringWithoutPathExpansion(shill::kShortNameProperty
,
139 &scan_result
.short_name
);
140 dict
->GetStringWithoutPathExpansion(shill::kTechnologyProperty
,
141 &scan_result
.technology
);
142 scan_results
->push_back(scan_result
);
147 scoped_ptr
<base::DictionaryValue
> TranslateNetworkStateToONC(
148 const NetworkState
* network
) {
149 // Get the properties from the NetworkState.
150 scoped_ptr
<base::DictionaryValue
> shill_dictionary(new base::DictionaryValue
);
151 network
->GetStateProperties(shill_dictionary
.get());
153 // Get any Device properties required to translate state.
154 if (NetworkTypePattern::Cellular().MatchesType(network
->type())) {
155 // We need to set Device[Cellular.ProviderRequiresRoaming] so that
156 // Cellular[RoamingState] can be set correctly for badging network icons.
157 const DeviceState
* device
=
158 NetworkHandler::Get()->network_state_handler()->GetDeviceState(
159 network
->device_path());
161 scoped_ptr
<base::DictionaryValue
> device_dict(new base::DictionaryValue
);
162 device_dict
->SetBooleanWithoutPathExpansion(
163 shill::kProviderRequiresRoamingProperty
,
164 device
->provider_requires_roaming());
165 shill_dictionary
->SetWithoutPathExpansion(shill::kDeviceProperty
,
166 device_dict
.release());
170 // NetworkState is always associated with the primary user profile, regardless
171 // of what profile is associated with the page that calls this method. We do
172 // not expose any sensitive properties in the resulting dictionary, it is
173 // only used to show connection state and icons.
174 std::string user_id_hash
= chromeos::LoginState::Get()->primary_user_hash();
175 ::onc::ONCSource onc_source
= ::onc::ONC_SOURCE_NONE
;
176 NetworkHandler::Get()
177 ->managed_network_configuration_handler()
178 ->FindPolicyByGUID(user_id_hash
, network
->guid(), &onc_source
);
180 scoped_ptr
<base::DictionaryValue
> onc_dictionary
=
181 TranslateShillServiceToONCPart(*shill_dictionary
, onc_source
,
182 &onc::kNetworkWithStateSignature
, network
);
183 return onc_dictionary
.Pass();
186 scoped_ptr
<base::ListValue
> TranslateNetworkListToONC(
187 NetworkTypePattern pattern
,
188 bool configured_only
,
191 bool debugging_properties
) {
192 NetworkStateHandler::NetworkStateList network_states
;
193 NetworkHandler::Get()->network_state_handler()->GetNetworkListByType(
194 pattern
, configured_only
, visible_only
, limit
, &network_states
);
196 scoped_ptr
<base::ListValue
> network_properties_list(new base::ListValue
);
197 for (const NetworkState
* state
: network_states
) {
198 scoped_ptr
<base::DictionaryValue
> onc_dictionary
=
199 TranslateNetworkStateToONC(state
);
201 if (debugging_properties
) {
202 onc_dictionary
->SetBoolean("connectable", state
->connectable());
203 onc_dictionary
->SetBoolean("visible", state
->visible());
204 onc_dictionary
->SetString("profile_path", state
->profile_path());
205 onc_dictionary
->SetString("service_path", state
->path());
208 network_properties_list
->Append(onc_dictionary
.release());
210 return network_properties_list
.Pass();
213 std::string
TranslateONCTypeToShill(const std::string
& onc_type
) {
214 if (onc_type
== ::onc::network_type::kEthernet
)
215 return shill::kTypeEthernet
;
216 std::string shill_type
;
217 onc::TranslateStringToShill(onc::kNetworkTypeTable
, onc_type
, &shill_type
);
221 std::string
TranslateShillTypeToONC(const std::string
& shill_type
) {
222 if (shill_type
== shill::kTypeEthernet
)
223 return ::onc::network_type::kEthernet
;
224 std::string onc_type
;
225 onc::TranslateStringToONC(onc::kNetworkTypeTable
, shill_type
, &onc_type
);
229 } // namespace network_util
230 } // namespace chromeos