1 // 2 // Copyright (C) 2013 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "shill/ppp_device.h" 18 19 #include <base/stl_util.h> 20 #include <base/strings/string_number_conversions.h> 21 22 #include "shill/logging.h" 23 #include "shill/metrics.h" 24 #include "shill/technology.h" 25 26 using std::map; 27 using std::string; 28 29 namespace shill { 30 31 namespace Logging { 32 static auto kModuleLogScope = ScopeLogger::kPPP; 33 static string ObjectID(PPPDevice* p) { return p->link_name(); } 34 } 35 36 PPPDevice::PPPDevice(ControlInterface* control, 37 EventDispatcher* dispatcher, 38 Metrics* metrics, 39 Manager* manager, 40 const string& link_name, 41 int interface_index) 42 : VirtualDevice(control, dispatcher, metrics, manager, link_name, 43 interface_index, Technology::kPPP) {} 44 45 PPPDevice::~PPPDevice() {} 46 47 void PPPDevice::UpdateIPConfigFromPPP(const map<string, string>& configuration, 48 bool blackhole_ipv6) { 49 SLOG(this, 2) << __func__ << " on " << link_name(); 50 IPConfig::Properties properties = 51 ParseIPConfiguration(link_name(), configuration); 52 properties.blackhole_ipv6 = blackhole_ipv6; 53 UpdateIPConfig(properties); 54 } 55 56 void PPPDevice::UpdateIPConfigFromPPPWithMTU( 57 const map<string, string>& configuration, 58 bool blackhole_ipv6, 59 int32_t mtu) { 60 SLOG(this, 2) << __func__ << " on " << link_name(); 61 IPConfig::Properties properties = 62 ParseIPConfiguration(link_name(), configuration); 63 properties.blackhole_ipv6 = blackhole_ipv6; 64 properties.mtu = mtu; 65 UpdateIPConfig(properties); 66 } 67 68 #ifndef DISABLE_DHCPV6 69 bool PPPDevice::AcquireIPv6Config() { 70 return AcquireIPv6ConfigWithLeaseName(string()); 71 } 72 #endif 73 74 // static 75 string PPPDevice::GetInterfaceName(const map<string, string>& configuration) { 76 if (ContainsKey(configuration, kPPPInterfaceName)) { 77 return configuration.find(kPPPInterfaceName)->second; 78 } 79 return string(); 80 } 81 82 IPConfig::Properties PPPDevice::ParseIPConfiguration( 83 const string& link_name, const map<string, string>& configuration) { 84 SLOG(PPP, nullptr, 2) << __func__ << " on " << link_name; 85 IPConfig::Properties properties; 86 properties.address_family = IPAddress::kFamilyIPv4; 87 properties.subnet_prefix = IPAddress::GetMaxPrefixLength( 88 properties.address_family); 89 for (const auto& it : configuration) { 90 const string& key = it.first; 91 const string& value = it.second; 92 SLOG(PPP, nullptr, 2) << "Processing: " << key << " -> " << value; 93 if (key == kPPPInternalIP4Address) { 94 properties.address = value; 95 } else if (key == kPPPExternalIP4Address) { 96 properties.peer_address = value; 97 } else if (key == kPPPGatewayAddress) { 98 properties.gateway = value; 99 } else if (key == kPPPDNS1) { 100 properties.dns_servers.insert(properties.dns_servers.begin(), value); 101 } else if (key == kPPPDNS2) { 102 properties.dns_servers.push_back(value); 103 } else if (key == kPPPLNSAddress) { 104 // This is really a L2TPIPSec property. But it's sent to us by 105 // our PPP plugin. 106 size_t prefix = IPAddress::GetMaxPrefixLength(properties.address_family); 107 properties.exclusion_list.push_back(value + "/" + 108 base::SizeTToString(prefix)); 109 } else if (key == kPPPMRU) { 110 int mru; 111 if (!base::StringToInt(value, &mru)) { 112 LOG(WARNING) << "Failed to parse MRU: " << value; 113 continue; 114 } 115 properties.mtu = mru; 116 metrics()->SendSparseToUMA(Metrics::kMetricPPPMTUValue, mru); 117 } else { 118 SLOG(PPP, nullptr, 2) << "Key ignored."; 119 } 120 } 121 if (properties.gateway.empty()) { 122 // The gateway may be unspecified, since this is a point-to-point 123 // link. Set to the peer's address, so that Connection can set the 124 // routing table. 125 properties.gateway = properties.peer_address; 126 } 127 return properties; 128 } 129 130 } // namespace shill 131