1 //
2 // Copyright (C) 2012 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/ipconfig.h"
18
19 #include <sys/time.h>
20
21 #include <limits>
22
23 #if defined(__ANDROID__)
24 #include <dbus/service_constants.h>
25 #else
26 #include <chromeos/dbus/service_constants.h>
27 #endif // __ANDROID__
28
29 #include "shill/adaptor_interfaces.h"
30 #include "shill/control_interface.h"
31 #include "shill/error.h"
32 #include "shill/logging.h"
33 #include "shill/net/shill_time.h"
34 #include "shill/static_ip_parameters.h"
35
36 using base::Callback;
37 using std::string;
38
39 namespace shill {
40
41 namespace Logging {
42 static auto kModuleLogScope = ScopeLogger::kInet;
ObjectID(IPConfig * i)43 static string ObjectID(IPConfig* i) { return i->GetRpcIdentifier(); }
44 }
45
46 namespace {
47
48 const time_t kDefaultLeaseExpirationTime = std::numeric_limits<long>::max();
49
50 } // namespace
51
52 // static
53 const int IPConfig::kDefaultMTU = 1500;
54 const int IPConfig::kMinIPv4MTU = 576;
55 const int IPConfig::kMinIPv6MTU = 1280;
56 const int IPConfig::kUndefinedMTU = 0;
57 const char IPConfig::kType[] = "ip";
58
59 // static
60 uint IPConfig::global_serial_ = 0;
61
IPConfig(ControlInterface * control_interface,const std::string & device_name)62 IPConfig::IPConfig(ControlInterface* control_interface,
63 const std::string& device_name)
64 : device_name_(device_name),
65 type_(kType),
66 serial_(global_serial_++),
67 adaptor_(control_interface->CreateIPConfigAdaptor(this)) {
68 Init();
69 }
70
IPConfig(ControlInterface * control_interface,const std::string & device_name,const std::string & type)71 IPConfig::IPConfig(ControlInterface* control_interface,
72 const std::string& device_name,
73 const std::string& type)
74 : device_name_(device_name),
75 type_(type),
76 serial_(global_serial_++),
77 adaptor_(control_interface->CreateIPConfigAdaptor(this)) {
78 Init();
79 }
80
Init()81 void IPConfig::Init() {
82 store_.RegisterConstString(kAddressProperty, &properties_.address);
83 store_.RegisterConstString(kBroadcastProperty,
84 &properties_.broadcast_address);
85 store_.RegisterConstString(kDomainNameProperty, &properties_.domain_name);
86 store_.RegisterConstString(kAcceptedHostnameProperty,
87 &properties_.accepted_hostname);
88 store_.RegisterConstString(kGatewayProperty, &properties_.gateway);
89 store_.RegisterConstString(kMethodProperty, &properties_.method);
90 store_.RegisterConstInt32(kMtuProperty, &properties_.mtu);
91 store_.RegisterConstStrings(kNameServersProperty, &properties_.dns_servers);
92 store_.RegisterConstString(kPeerAddressProperty, &properties_.peer_address);
93 store_.RegisterConstInt32(kPrefixlenProperty, &properties_.subnet_prefix);
94 store_.RegisterConstStrings(kSearchDomainsProperty,
95 &properties_.domain_search);
96 store_.RegisterConstByteArray(kVendorEncapsulatedOptionsProperty,
97 &properties_.vendor_encapsulated_options);
98 store_.RegisterConstString(kWebProxyAutoDiscoveryUrlProperty,
99 &properties_.web_proxy_auto_discovery);
100 store_.RegisterConstString(kDelegatedPrefixProperty,
101 &properties_.delegated_prefix);
102 store_.RegisterConstInt32(kDelegatedPrefixLengthProperty,
103 &properties_.delegated_prefix_length);
104 store_.RegisterConstUint32(kLeaseDurationSecondsProperty,
105 &properties_.lease_duration_seconds);
106 time_ = Time::GetInstance();
107 current_lease_expiration_time_ = {kDefaultLeaseExpirationTime, 0};
108 SLOG(this, 2) << __func__ << " device: " << device_name();
109 }
110
~IPConfig()111 IPConfig::~IPConfig() {
112 SLOG(this, 2) << __func__ << " device: " << device_name();
113 }
114
GetRpcIdentifier()115 string IPConfig::GetRpcIdentifier() {
116 return adaptor_->GetRpcIdentifier();
117 }
118
RequestIP()119 bool IPConfig::RequestIP() {
120 return false;
121 }
122
RenewIP()123 bool IPConfig::RenewIP() {
124 return false;
125 }
126
ReleaseIP(ReleaseReason reason)127 bool IPConfig::ReleaseIP(ReleaseReason reason) {
128 return false;
129 }
130
Refresh(Error *)131 void IPConfig::Refresh(Error* /*error*/) {
132 if (!refresh_callback_.is_null()) {
133 refresh_callback_.Run(this);
134 }
135 RenewIP();
136 }
137
ApplyStaticIPParameters(StaticIPParameters * static_ip_parameters)138 void IPConfig::ApplyStaticIPParameters(
139 StaticIPParameters* static_ip_parameters) {
140 static_ip_parameters->ApplyTo(&properties_);
141 EmitChanges();
142 }
143
RestoreSavedIPParameters(StaticIPParameters * static_ip_parameters)144 void IPConfig::RestoreSavedIPParameters(
145 StaticIPParameters* static_ip_parameters) {
146 static_ip_parameters->RestoreTo(&properties_);
147 EmitChanges();
148 }
149
UpdateLeaseExpirationTime(uint32_t new_lease_duration)150 void IPConfig::UpdateLeaseExpirationTime(uint32_t new_lease_duration) {
151 struct timeval new_expiration_time;
152 time_->GetTimeBoottime(&new_expiration_time);
153 new_expiration_time.tv_sec += new_lease_duration;
154 current_lease_expiration_time_ = new_expiration_time;
155 }
156
ResetLeaseExpirationTime()157 void IPConfig::ResetLeaseExpirationTime() {
158 current_lease_expiration_time_ = {kDefaultLeaseExpirationTime, 0};
159 }
160
TimeToLeaseExpiry(uint32_t * time_left)161 bool IPConfig::TimeToLeaseExpiry(uint32_t* time_left) {
162 if (current_lease_expiration_time_.tv_sec == kDefaultLeaseExpirationTime) {
163 SLOG(this, 2) << __func__ << ": No current DHCP lease";
164 return false;
165 }
166 struct timeval now;
167 time_->GetTimeBoottime(&now);
168 if (now.tv_sec > current_lease_expiration_time_.tv_sec) {
169 SLOG(this, 2) << __func__ << ": Current DHCP lease has already expired";
170 return false;
171 }
172 *time_left = current_lease_expiration_time_.tv_sec - now.tv_sec;
173 return true;
174 }
175
UpdateProperties(const Properties & properties,bool new_lease_acquired)176 void IPConfig::UpdateProperties(const Properties& properties,
177 bool new_lease_acquired) {
178 // Take a reference of this instance to make sure we don't get destroyed in
179 // the middle of this call. (The |update_callback_| may cause a reference
180 // to be dropped. See, e.g., EthernetService::Disconnect and
181 // Ethernet::DropConnection.)
182 IPConfigRefPtr me = this;
183
184 properties_ = properties;
185
186 if (!update_callback_.is_null()) {
187 update_callback_.Run(this, new_lease_acquired);
188 }
189 EmitChanges();
190 }
191
UpdateDNSServers(const std::vector<std::string> & dns_servers)192 void IPConfig::UpdateDNSServers(const std::vector<std::string>& dns_servers) {
193 properties_.dns_servers = dns_servers;
194 EmitChanges();
195 }
196
NotifyFailure()197 void IPConfig::NotifyFailure() {
198 // Take a reference of this instance to make sure we don't get destroyed in
199 // the middle of this call. (The |update_callback_| may cause a reference
200 // to be dropped. See, e.g., EthernetService::Disconnect and
201 // Ethernet::DropConnection.)
202 IPConfigRefPtr me = this;
203
204 if (!failure_callback_.is_null()) {
205 failure_callback_.Run(this);
206 }
207 }
208
NotifyExpiry()209 void IPConfig::NotifyExpiry() {
210 if (!expire_callback_.is_null()) {
211 expire_callback_.Run(this);
212 }
213 }
214
RegisterUpdateCallback(const UpdateCallback & callback)215 void IPConfig::RegisterUpdateCallback(const UpdateCallback& callback) {
216 update_callback_ = callback;
217 }
218
RegisterFailureCallback(const Callback & callback)219 void IPConfig::RegisterFailureCallback(const Callback& callback) {
220 failure_callback_ = callback;
221 }
222
RegisterRefreshCallback(const Callback & callback)223 void IPConfig::RegisterRefreshCallback(const Callback& callback) {
224 refresh_callback_ = callback;
225 }
226
RegisterExpireCallback(const Callback & callback)227 void IPConfig::RegisterExpireCallback(const Callback& callback) {
228 expire_callback_ = callback;
229 }
230
ResetProperties()231 void IPConfig::ResetProperties() {
232 properties_ = Properties();
233 EmitChanges();
234 }
235
EmitChanges()236 void IPConfig::EmitChanges() {
237 adaptor_->EmitStringChanged(kAddressProperty, properties_.address);
238 adaptor_->EmitStringsChanged(kNameServersProperty, properties_.dns_servers);
239 }
240
241 } // namespace shill
242