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