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;
ObjectID(PPPDevice * p)33 static string ObjectID(PPPDevice* p) { return p->link_name(); }
34 }
35
PPPDevice(ControlInterface * control,EventDispatcher * dispatcher,Metrics * metrics,Manager * manager,const string & link_name,int interface_index)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
~PPPDevice()45 PPPDevice::~PPPDevice() {}
46
UpdateIPConfigFromPPP(const map<string,string> & configuration,bool blackhole_ipv6)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
UpdateIPConfigFromPPPWithMTU(const map<string,string> & configuration,bool blackhole_ipv6,int32_t mtu)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
AcquireIPv6Config()69 bool PPPDevice::AcquireIPv6Config() {
70 return AcquireIPv6ConfigWithLeaseName(string());
71 }
72 #endif
73
74 // static
GetInterfaceName(const map<string,string> & configuration)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
ParseIPConfiguration(const string & link_name,const map<string,string> & configuration)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