network_util.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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.
4
5#include "chromeos/network/network_util.h"
6
7#include "base/strings/string_tokenizer.h"
8#include "base/strings/string_util.h"
9#include "base/strings/stringprintf.h"
10#include "chromeos/network/favorite_state.h"
11#include "chromeos/network/network_state.h"
12#include "chromeos/network/network_state_handler.h"
13#include "chromeos/network/onc/onc_signature.h"
14#include "chromeos/network/onc/onc_translator.h"
15#include "third_party/cros_system_api/dbus/service_constants.h"
16
17namespace chromeos {
18
19WifiAccessPoint::WifiAccessPoint()
20    : signal_strength(0),
21      signal_to_noise(0),
22      channel(0) {
23}
24
25WifiAccessPoint::~WifiAccessPoint() {
26}
27
28CellularScanResult::CellularScanResult() {
29}
30
31CellularScanResult::~CellularScanResult() {
32}
33
34namespace network_util {
35
36std::string PrefixLengthToNetmask(int32 prefix_length) {
37  std::string netmask;
38  // Return the empty string for invalid inputs.
39  if (prefix_length < 0 || prefix_length > 32)
40    return netmask;
41  for (int i = 0; i < 4; i++) {
42    int remainder = 8;
43    if (prefix_length >= 8) {
44      prefix_length -= 8;
45    } else {
46      remainder = prefix_length;
47      prefix_length = 0;
48    }
49    if (i > 0)
50      netmask += ".";
51    int value = remainder == 0 ? 0 :
52        ((2L << (remainder - 1)) - 1) << (8 - remainder);
53    netmask += base::StringPrintf("%d", value);
54  }
55  return netmask;
56}
57
58int32 NetmaskToPrefixLength(const std::string& netmask) {
59  int count = 0;
60  int prefix_length = 0;
61  base::StringTokenizer t(netmask, ".");
62  while (t.GetNext()) {
63    // If there are more than 4 numbers, then it's invalid.
64    if (count == 4)
65      return -1;
66
67    std::string token = t.token();
68    // If we already found the last mask and the current one is not
69    // "0" then the netmask is invalid. For example, 255.224.255.0
70    if (prefix_length / 8 != count) {
71      if (token != "0")
72        return -1;
73    } else if (token == "255") {
74      prefix_length += 8;
75    } else if (token == "254") {
76      prefix_length += 7;
77    } else if (token == "252") {
78      prefix_length += 6;
79    } else if (token == "248") {
80      prefix_length += 5;
81    } else if (token == "240") {
82      prefix_length += 4;
83    } else if (token == "224") {
84      prefix_length += 3;
85    } else if (token == "192") {
86      prefix_length += 2;
87    } else if (token == "128") {
88      prefix_length += 1;
89    } else if (token == "0") {
90      prefix_length += 0;
91    } else {
92      // mask is not a valid number.
93      return -1;
94    }
95    count++;
96  }
97  if (count < 4)
98    return -1;
99  return prefix_length;
100}
101
102std::string FormattedMacAddress(const std::string& shill_mac_address) {
103  if (shill_mac_address.size() % 2 != 0)
104    return shill_mac_address;
105  std::string result;
106  for (size_t i = 0; i < shill_mac_address.size(); ++i) {
107    if ((i != 0) && (i % 2 == 0))
108      result.push_back(':');
109    result.push_back(base::ToUpperASCII(shill_mac_address[i]));
110  }
111  return result;
112}
113
114bool ParseCellularScanResults(const base::ListValue& list,
115                              std::vector<CellularScanResult>* scan_results) {
116  scan_results->clear();
117  scan_results->reserve(list.GetSize());
118  for (base::ListValue::const_iterator it = list.begin();
119       it != list.end(); ++it) {
120    if (!(*it)->IsType(base::Value::TYPE_DICTIONARY))
121      return false;
122    CellularScanResult scan_result;
123    const base::DictionaryValue* dict =
124        static_cast<const base::DictionaryValue*>(*it);
125    // If the network id property is not present then this network cannot be
126    // connected to so don't include it in the results.
127    if (!dict->GetStringWithoutPathExpansion(shill::kNetworkIdProperty,
128                                             &scan_result.network_id))
129      continue;
130    dict->GetStringWithoutPathExpansion(shill::kStatusProperty,
131                                        &scan_result.status);
132    dict->GetStringWithoutPathExpansion(shill::kLongNameProperty,
133                                        &scan_result.long_name);
134    dict->GetStringWithoutPathExpansion(shill::kShortNameProperty,
135                                        &scan_result.short_name);
136    dict->GetStringWithoutPathExpansion(shill::kTechnologyProperty,
137                                        &scan_result.technology);
138    scan_results->push_back(scan_result);
139  }
140  return true;
141}
142
143scoped_ptr<base::DictionaryValue> TranslateFavoriteStateToONC(
144    const FavoriteState* favorite) {
145  // Get the properties from the FavoriteState.
146  base::DictionaryValue shill_dictionary;
147  favorite->GetStateProperties(&shill_dictionary);
148
149  // If a corresponding NetworkState exists, merge its State properties.
150  const NetworkState* network_state =
151      NetworkHandler::Get()->network_state_handler()->GetNetworkState(
152          favorite->path());
153  if (network_state) {
154    base::DictionaryValue shill_network_dictionary;
155    network_state->GetStateProperties(&shill_network_dictionary);
156    shill_dictionary.MergeDictionary(&shill_network_dictionary);
157  }
158
159  scoped_ptr<base::DictionaryValue> onc_dictionary =
160      TranslateShillServiceToONCPart(
161          shill_dictionary, &onc::kNetworkWithStateSignature);
162  return onc_dictionary.Pass();
163}
164
165scoped_ptr<base::ListValue> TranslateNetworkListToONC(
166    NetworkTypePattern pattern,
167    bool configured_only,
168    bool visible_only,
169    int limit,
170    bool debugging_properties) {
171  NetworkStateHandler::FavoriteStateList favorite_states;
172  NetworkHandler::Get()->network_state_handler()->GetFavoriteListByType(
173      pattern, configured_only, visible_only, limit, &favorite_states);
174
175  scoped_ptr<base::ListValue> network_properties_list(new base::ListValue);
176  for (NetworkStateHandler::FavoriteStateList::iterator it =
177           favorite_states.begin();
178       it != favorite_states.end();
179       ++it) {
180    scoped_ptr<base::DictionaryValue> onc_dictionary =
181        TranslateFavoriteStateToONC(*it);
182
183    if (debugging_properties) {
184      onc_dictionary->SetString("profile_path", (*it)->profile_path());
185      std::string onc_source = (*it)->ui_data().GetONCSourceAsString();
186      if (!onc_source.empty())
187        onc_dictionary->SetString("onc_source", onc_source);
188    }
189
190    network_properties_list->Append(onc_dictionary.release());
191  }
192  return network_properties_list.Pass();
193}
194
195}  // namespace network_util
196}  // namespace chromeos
197