blob: afe343b5fe0f59097d276dac2c14f322eba3d00b [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/logging.h>
10#include <base/string_split.h>
11#include <chromeos/dbus/service_constants.h>
12
13#include "shill/error.h"
14#include "shill/ip_address.h"
15#include "shill/property_accessor.h"
16#include "shill/property_store.h"
17#include "shill/store_interface.h"
18
19using std::string;
20using std::vector;
21
22namespace shill {
23
24// static
25const char StaticIPParameters::kConfigKeyPrefix[] = "StaticIP.";
26// static
27const StaticIPParameters::Property StaticIPParameters::kProperties[] = {
28 { flimflam::kAddressProperty, Property::kTypeString },
29 { flimflam::kGatewayProperty, Property::kTypeString },
30 { flimflam::kMtuProperty, Property::kTypeInt32 },
31 { flimflam::kNameServersProperty, Property::kTypeStrings },
32 { flimflam::kPeerAddressProperty, Property::kTypeString },
33 { flimflam::kPrefixlenProperty, Property::kTypeInt32 }
34};
35
36StaticIPParameters::StaticIPParameters() {}
37
38StaticIPParameters::~StaticIPParameters() {}
39
40void StaticIPParameters::PlumbPropertyStore(PropertyStore *store) {
41 for (size_t i = 0; i < arraysize(kProperties); ++i) {
42 const Property &property = kProperties[i];
43 const string name(string(kConfigKeyPrefix) + property.name);
44 switch (property.type) {
45 case Property::kTypeInt32:
46 store->RegisterDerivedInt32(
47 name,
48 Int32Accessor(
49 new CustomMappedAccessor<StaticIPParameters, int32, size_t>(
50 this,
51 &StaticIPParameters::ClearMappedProperty,
52 &StaticIPParameters::GetMappedInt32Property,
53 &StaticIPParameters::SetMappedInt32Property,
54 i)));
55 break;
56 case Property::kTypeString:
57 case Property::kTypeStrings:
58 store->RegisterDerivedString(
59 name,
60 StringAccessor(
61 new CustomMappedAccessor<StaticIPParameters, string, size_t>(
62 this,
63 &StaticIPParameters::ClearMappedProperty,
64 &StaticIPParameters::GetMappedStringProperty,
65 &StaticIPParameters::SetMappedStringProperty,
66 i)));
67 break;
68 default:
69 NOTIMPLEMENTED();
70 break;
71 }
72 }
73}
74
75void StaticIPParameters::Load(
76 StoreInterface *storage, const string &storage_id) {
77 for (size_t i = 0; i < arraysize(kProperties); ++i) {
78 const Property &property = kProperties[i];
79 const string name(string(kConfigKeyPrefix) + property.name);
80 switch (property.type) {
81 case Property::kTypeInt32:
82 {
83 int32 value;
84 if (storage->GetInt(storage_id, name, &value)) {
85 args_.SetInt(property.name, value);
86 } else {
87 args_.RemoveInt(property.name);
88 }
89 }
90 break;
91 case Property::kTypeString:
92 case Property::kTypeStrings:
93 {
94 string value;
95 if (storage->GetString(storage_id, name, &value)) {
96 args_.SetString(property.name, value);
97 } else {
98 args_.RemoveString(property.name);
99 }
100 }
101 break;
102 default:
103 NOTIMPLEMENTED();
104 break;
105 }
106 }
107}
108
109void StaticIPParameters::Save(
110 StoreInterface *storage, const string &storage_id) {
111 for (size_t i = 0; i < arraysize(kProperties); ++i) {
112 const Property &property = kProperties[i];
113 const string name(string(kConfigKeyPrefix) + property.name);
114 bool property_exists = false;
115 switch (property.type) {
116 case Property::kTypeInt32:
117 if (args_.ContainsInt(property.name)) {
118 property_exists = true;
119 storage->SetInt(storage_id, name, args_.GetInt(property.name));
120 }
121 break;
122 case Property::kTypeString:
123 case Property::kTypeStrings:
124 if (args_.ContainsString(property.name)) {
125 property_exists = true;
126 storage->SetString(storage_id, name, args_.GetString(property.name));
127 }
128 break;
129 default:
130 NOTIMPLEMENTED();
131 break;
132 }
133 if (!property_exists) {
134 storage->DeleteKey(storage_id, name);
135 }
136 }
137}
138
139void StaticIPParameters::ApplyInt(
140 const string &property, int32 *value_out) const {
141 if (args_.ContainsInt(property)) {
142 *value_out = args_.GetInt(property);
143 }
144}
145
146void StaticIPParameters::ApplyString(
147 const string &property, string *value_out) const {
148 if (args_.ContainsString(property)) {
149 *value_out = args_.GetString(property);
150 }
151}
152
153void StaticIPParameters::ApplyStrings(
154 const string &property, vector<string> *value_out) const {
155 if (args_.ContainsString(property)) {
156 vector<string> values;
157 string value(args_.GetString(property));
158 if (!value.empty()) {
159 base::SplitString(value, ',', &values);
160 }
161 *value_out = values;
162 }
163}
164
165
166void StaticIPParameters::ApplyTo(IPConfig::Properties *props) const {
167 if (props->address_family == IPAddress::kFamilyUnknown) {
168 // In situations where no address is supplied (bad or missing DHCP config)
169 // supply an address family ourselves.
170 // TODO(pstew): Guess from the address values.
171 props->address_family = IPAddress::kFamilyIPv4;
172 }
173 ApplyString(flimflam::kAddressProperty, &props->address);
174 ApplyString(flimflam::kGatewayProperty, &props->gateway);
175 ApplyInt(flimflam::kMtuProperty, &props->mtu);
176 ApplyStrings(flimflam::kNameServersProperty, &props->dns_servers);
177 ApplyString(flimflam::kPeerAddressProperty, &props->peer_address);
178 ApplyInt(flimflam::kPrefixlenProperty, &props->subnet_prefix);
179}
180
181bool StaticIPParameters::ContainsAddress() const {
182 return args_.ContainsString(flimflam::kAddressProperty) &&
183 args_.ContainsInt(flimflam::kPrefixlenProperty);
184}
185
186void StaticIPParameters::ClearMappedProperty(
187 const size_t &index, Error *error) {
188 CHECK(index < arraysize(kProperties));
189
190 const Property &property = kProperties[index];
191 switch (property.type) {
192 case Property::kTypeInt32:
193 if (args_.ContainsInt(property.name)) {
194 args_.RemoveInt(property.name);
195 } else {
196 error->Populate(Error::kNotFound, "Property is not set");
197 }
198 break;
199 case Property::kTypeString:
200 case Property::kTypeStrings:
201 if (args_.ContainsString(property.name)) {
202 args_.RemoveString(property.name);
203 } else {
204 error->Populate(Error::kNotFound, "Property is not set");
205 }
206 break;
207 default:
208 NOTIMPLEMENTED();
209 break;
210 }
211}
212
Paul Stewart1062d9d2012-04-27 10:42:27 -0700213int32 StaticIPParameters::GetMappedInt32Property(
214 const size_t &index, Error *error) {
215 CHECK(index < arraysize(kProperties));
216
217 const string &key = kProperties[index].name;
218 if (!args_.ContainsInt(key)) {
219 error->Populate(Error::kNotFound, "Property is not set");
220 return 0;
221 }
222 return args_.GetInt(key);
223}
224
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700225string StaticIPParameters::GetMappedStringProperty(
226 const size_t &index, Error *error) {
Paul Stewart1062d9d2012-04-27 10:42:27 -0700227 CHECK(index < arraysize(kProperties));
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700228
229 const string &key = kProperties[index].name;
230 if (!args_.ContainsString(key)) {
231 error->Populate(Error::kNotFound, "Property is not set");
232 return string();
233 }
234 return args_.GetString(key);
Paul Stewart1062d9d2012-04-27 10:42:27 -0700235}
236
237void StaticIPParameters::SetMappedInt32Property(
238 const size_t &index, const int32 &value, Error *error) {
239 CHECK(index < arraysize(kProperties));
240 args_.SetInt(kProperties[index].name, value);
241}
242
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700243void StaticIPParameters::SetMappedStringProperty(
244 const size_t &index, const string &value, Error *error) {
245 CHECK(index < arraysize(kProperties));
246 args_.SetString(kProperties[index].name, value);
247}
248
Paul Stewart1062d9d2012-04-27 10:42:27 -0700249} // namespace shill