blob: 7842d85a1a7d9becac8a56b068f336c919a7ffda [file] [log] [blame]
Paul Stewart1062d9d2012-04-27 10:42:27 -07001// Copyright (c) 2012 The Chromium OS 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 "shill/static_ip_parameters.h"
6
mukesh agrawalcc0fded2012-05-09 13:40:58 -07007#include <string.h>
8
Paul Stewart1062d9d2012-04-27 10:42:27 -07009#include <base/string_split.h>
Paul Stewartdef189e2012-08-02 20:12:09 -070010#include <base/string_util.h>
Paul Stewart1062d9d2012-04-27 10:42:27 -070011#include <chromeos/dbus/service_constants.h>
12
13#include "shill/error.h"
14#include "shill/ip_address.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070015#include "shill/logging.h"
Paul Stewart1062d9d2012-04-27 10:42:27 -070016#include "shill/property_accessor.h"
17#include "shill/property_store.h"
18#include "shill/store_interface.h"
19
20using std::string;
21using std::vector;
22
23namespace shill {
24
25// static
26const char StaticIPParameters::kConfigKeyPrefix[] = "StaticIP.";
27// static
Paul Stewartdef189e2012-08-02 20:12:09 -070028const char StaticIPParameters::kSavedConfigKeyPrefix[] = "SavedIP.";
29// static
Paul Stewart1062d9d2012-04-27 10:42:27 -070030const StaticIPParameters::Property StaticIPParameters::kProperties[] = {
31 { flimflam::kAddressProperty, Property::kTypeString },
32 { flimflam::kGatewayProperty, Property::kTypeString },
33 { flimflam::kMtuProperty, Property::kTypeInt32 },
34 { flimflam::kNameServersProperty, Property::kTypeStrings },
35 { flimflam::kPeerAddressProperty, Property::kTypeString },
36 { flimflam::kPrefixlenProperty, Property::kTypeInt32 }
37};
38
39StaticIPParameters::StaticIPParameters() {}
40
41StaticIPParameters::~StaticIPParameters() {}
42
43void StaticIPParameters::PlumbPropertyStore(PropertyStore *store) {
44 for (size_t i = 0; i < arraysize(kProperties); ++i) {
45 const Property &property = kProperties[i];
46 const string name(string(kConfigKeyPrefix) + property.name);
Paul Stewartdef189e2012-08-02 20:12:09 -070047 const string saved_name(string(kSavedConfigKeyPrefix) + property.name);
Paul Stewart1062d9d2012-04-27 10:42:27 -070048 switch (property.type) {
49 case Property::kTypeInt32:
50 store->RegisterDerivedInt32(
51 name,
52 Int32Accessor(
53 new CustomMappedAccessor<StaticIPParameters, int32, size_t>(
54 this,
55 &StaticIPParameters::ClearMappedProperty,
56 &StaticIPParameters::GetMappedInt32Property,
57 &StaticIPParameters::SetMappedInt32Property,
58 i)));
Paul Stewartdef189e2012-08-02 20:12:09 -070059 store->RegisterDerivedInt32(
60 saved_name,
61 Int32Accessor(
62 new CustomMappedAccessor<StaticIPParameters, int32, size_t>(
63 this,
64 &StaticIPParameters::ClearMappedSavedProperty,
65 &StaticIPParameters::GetMappedSavedInt32Property,
66 &StaticIPParameters::SetMappedSavedInt32Property,
67 i)));
Paul Stewart1062d9d2012-04-27 10:42:27 -070068 break;
69 case Property::kTypeString:
70 case Property::kTypeStrings:
71 store->RegisterDerivedString(
72 name,
73 StringAccessor(
74 new CustomMappedAccessor<StaticIPParameters, string, size_t>(
75 this,
76 &StaticIPParameters::ClearMappedProperty,
77 &StaticIPParameters::GetMappedStringProperty,
78 &StaticIPParameters::SetMappedStringProperty,
79 i)));
Paul Stewartdef189e2012-08-02 20:12:09 -070080 store->RegisterDerivedString(
81 saved_name,
82 StringAccessor(
83 new CustomMappedAccessor<StaticIPParameters, string, size_t>(
84 this,
85 &StaticIPParameters::ClearMappedSavedProperty,
86 &StaticIPParameters::GetMappedSavedStringProperty,
87 &StaticIPParameters::SetMappedSavedStringProperty,
88 i)));
Paul Stewart1062d9d2012-04-27 10:42:27 -070089 break;
90 default:
91 NOTIMPLEMENTED();
92 break;
93 }
94 }
95}
96
97void StaticIPParameters::Load(
98 StoreInterface *storage, const string &storage_id) {
99 for (size_t i = 0; i < arraysize(kProperties); ++i) {
100 const Property &property = kProperties[i];
101 const string name(string(kConfigKeyPrefix) + property.name);
102 switch (property.type) {
103 case Property::kTypeInt32:
104 {
105 int32 value;
106 if (storage->GetInt(storage_id, name, &value)) {
107 args_.SetInt(property.name, value);
108 } else {
109 args_.RemoveInt(property.name);
110 }
111 }
112 break;
113 case Property::kTypeString:
114 case Property::kTypeStrings:
115 {
116 string value;
117 if (storage->GetString(storage_id, name, &value)) {
118 args_.SetString(property.name, value);
119 } else {
120 args_.RemoveString(property.name);
121 }
122 }
123 break;
124 default:
125 NOTIMPLEMENTED();
126 break;
127 }
128 }
129}
130
131void StaticIPParameters::Save(
132 StoreInterface *storage, const string &storage_id) {
133 for (size_t i = 0; i < arraysize(kProperties); ++i) {
134 const Property &property = kProperties[i];
135 const string name(string(kConfigKeyPrefix) + property.name);
136 bool property_exists = false;
137 switch (property.type) {
138 case Property::kTypeInt32:
139 if (args_.ContainsInt(property.name)) {
140 property_exists = true;
141 storage->SetInt(storage_id, name, args_.GetInt(property.name));
142 }
143 break;
144 case Property::kTypeString:
145 case Property::kTypeStrings:
146 if (args_.ContainsString(property.name)) {
147 property_exists = true;
148 storage->SetString(storage_id, name, args_.GetString(property.name));
149 }
150 break;
151 default:
152 NOTIMPLEMENTED();
153 break;
154 }
155 if (!property_exists) {
156 storage->DeleteKey(storage_id, name);
157 }
158 }
159}
160
161void StaticIPParameters::ApplyInt(
Paul Stewartdef189e2012-08-02 20:12:09 -0700162 const string &property, int32 *value_out) {
163 saved_args_.SetInt(property, *value_out);
Paul Stewart1062d9d2012-04-27 10:42:27 -0700164 if (args_.ContainsInt(property)) {
165 *value_out = args_.GetInt(property);
166 }
167}
168
169void StaticIPParameters::ApplyString(
Paul Stewartdef189e2012-08-02 20:12:09 -0700170 const string &property, string *value_out) {
171 saved_args_.SetString(property, *value_out);
Paul Stewart1062d9d2012-04-27 10:42:27 -0700172 if (args_.ContainsString(property)) {
173 *value_out = args_.GetString(property);
174 }
175}
176
177void StaticIPParameters::ApplyStrings(
Paul Stewartdef189e2012-08-02 20:12:09 -0700178 const string &property, vector<string> *value_out) {
179 saved_args_.SetString(property, JoinString(*value_out, ','));
Paul Stewart1062d9d2012-04-27 10:42:27 -0700180 if (args_.ContainsString(property)) {
181 vector<string> values;
182 string value(args_.GetString(property));
183 if (!value.empty()) {
184 base::SplitString(value, ',', &values);
185 }
186 *value_out = values;
187 }
188}
189
190
Paul Stewartdef189e2012-08-02 20:12:09 -0700191void StaticIPParameters::ApplyTo(IPConfig::Properties *props) {
Paul Stewart1062d9d2012-04-27 10:42:27 -0700192 if (props->address_family == IPAddress::kFamilyUnknown) {
193 // In situations where no address is supplied (bad or missing DHCP config)
194 // supply an address family ourselves.
195 // TODO(pstew): Guess from the address values.
196 props->address_family = IPAddress::kFamilyIPv4;
197 }
Paul Stewartdef189e2012-08-02 20:12:09 -0700198 ClearSavedParameters();
Paul Stewart1062d9d2012-04-27 10:42:27 -0700199 ApplyString(flimflam::kAddressProperty, &props->address);
200 ApplyString(flimflam::kGatewayProperty, &props->gateway);
201 ApplyInt(flimflam::kMtuProperty, &props->mtu);
202 ApplyStrings(flimflam::kNameServersProperty, &props->dns_servers);
203 ApplyString(flimflam::kPeerAddressProperty, &props->peer_address);
204 ApplyInt(flimflam::kPrefixlenProperty, &props->subnet_prefix);
205}
206
Paul Stewartdef189e2012-08-02 20:12:09 -0700207void StaticIPParameters::ClearSavedParameters() {
208 saved_args_.Clear();
209}
210
Paul Stewart1062d9d2012-04-27 10:42:27 -0700211bool StaticIPParameters::ContainsAddress() const {
212 return args_.ContainsString(flimflam::kAddressProperty) &&
213 args_.ContainsInt(flimflam::kPrefixlenProperty);
214}
215
216void StaticIPParameters::ClearMappedProperty(
217 const size_t &index, Error *error) {
218 CHECK(index < arraysize(kProperties));
219
220 const Property &property = kProperties[index];
221 switch (property.type) {
222 case Property::kTypeInt32:
223 if (args_.ContainsInt(property.name)) {
224 args_.RemoveInt(property.name);
225 } else {
226 error->Populate(Error::kNotFound, "Property is not set");
227 }
228 break;
229 case Property::kTypeString:
230 case Property::kTypeStrings:
231 if (args_.ContainsString(property.name)) {
232 args_.RemoveString(property.name);
233 } else {
234 error->Populate(Error::kNotFound, "Property is not set");
235 }
236 break;
237 default:
238 NOTIMPLEMENTED();
239 break;
240 }
241}
242
Paul Stewartdef189e2012-08-02 20:12:09 -0700243void StaticIPParameters::ClearMappedSavedProperty(
244 const size_t &index, Error *error) {
245 error->Populate(Error::kInvalidArguments, "Property is read-only");
246}
247
Paul Stewart1062d9d2012-04-27 10:42:27 -0700248int32 StaticIPParameters::GetMappedInt32Property(
249 const size_t &index, Error *error) {
250 CHECK(index < arraysize(kProperties));
251
252 const string &key = kProperties[index].name;
253 if (!args_.ContainsInt(key)) {
254 error->Populate(Error::kNotFound, "Property is not set");
255 return 0;
256 }
257 return args_.GetInt(key);
258}
259
Paul Stewartdef189e2012-08-02 20:12:09 -0700260int32 StaticIPParameters::GetMappedSavedInt32Property(
261 const size_t &index, Error *error) {
262 CHECK(index < arraysize(kProperties));
263
264 const string &key = kProperties[index].name;
265 if (!saved_args_.ContainsInt(key)) {
266 error->Populate(Error::kNotFound, "Property is not set");
267 return 0;
268 }
269 return saved_args_.GetInt(key);
270}
271
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700272string StaticIPParameters::GetMappedStringProperty(
273 const size_t &index, Error *error) {
Paul Stewart1062d9d2012-04-27 10:42:27 -0700274 CHECK(index < arraysize(kProperties));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700275
276 const string &key = kProperties[index].name;
277 if (!args_.ContainsString(key)) {
278 error->Populate(Error::kNotFound, "Property is not set");
279 return string();
280 }
281 return args_.GetString(key);
Paul Stewart1062d9d2012-04-27 10:42:27 -0700282}
283
Paul Stewartdef189e2012-08-02 20:12:09 -0700284string StaticIPParameters::GetMappedSavedStringProperty(
285 const size_t &index, Error *error) {
286 CHECK(index < arraysize(kProperties));
287
288 const string &key = kProperties[index].name;
289 if (!saved_args_.ContainsString(key)) {
290 error->Populate(Error::kNotFound, "Property is not set");
291 return string();
292 }
293 return saved_args_.GetString(key);
294}
295
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700296bool StaticIPParameters::SetMappedInt32Property(
Paul Stewart1062d9d2012-04-27 10:42:27 -0700297 const size_t &index, const int32 &value, Error *error) {
298 CHECK(index < arraysize(kProperties));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700299 if (args_.ContainsInt(kProperties[index].name) &&
300 args_.GetInt(kProperties[index].name) == value) {
301 return false;
302 }
Paul Stewart1062d9d2012-04-27 10:42:27 -0700303 args_.SetInt(kProperties[index].name, value);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700304 return true;
Paul Stewart1062d9d2012-04-27 10:42:27 -0700305}
306
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700307bool StaticIPParameters::SetMappedSavedInt32Property(
Paul Stewartdef189e2012-08-02 20:12:09 -0700308 const size_t &index, const int32 &value, Error *error) {
309 error->Populate(Error::kInvalidArguments, "Property is read-only");
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700310 return false;
Paul Stewartdef189e2012-08-02 20:12:09 -0700311}
312
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700313bool StaticIPParameters::SetMappedStringProperty(
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700314 const size_t &index, const string &value, Error *error) {
315 CHECK(index < arraysize(kProperties));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700316 if (args_.ContainsString(kProperties[index].name) &&
317 args_.GetString(kProperties[index].name) == value) {
318 return false;
319 }
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700320 args_.SetString(kProperties[index].name, value);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700321 return true;
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700322}
323
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700324bool StaticIPParameters::SetMappedSavedStringProperty(
Paul Stewartdef189e2012-08-02 20:12:09 -0700325 const size_t &index, const string &value, Error *error) {
326 error->Populate(Error::kInvalidArguments, "Property is read-only");
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700327 return false;
Paul Stewartdef189e2012-08-02 20:12:09 -0700328}
329
Paul Stewart1062d9d2012-04-27 10:42:27 -0700330} // namespace shill