1 // Copyright (c) 2012 The Chromium 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.
5 #include "chromeos/network/onc/onc_translation_tables.h"
9 #include "base/logging.h"
10 #include "components/onc/onc_constants.h"
11 #include "third_party/cros_system_api/dbus/service_constants.h"
16 // CertificatePattern is converted with function CreateUIData(...) to UIData
21 const FieldTranslationEntry eap_fields
[] = {
22 {::onc::eap::kAnonymousIdentity
, shill::kEapAnonymousIdentityProperty
},
23 {::onc::eap::kIdentity
, shill::kEapIdentityProperty
},
24 // This field is converted during translation, see onc_translator_*.
25 // { ::onc::eap::kInner, shill::kEapPhase2AuthProperty },
27 // This field is converted during translation, see onc_translator_*.
28 // { ::onc::eap::kOuter, shill::kEapMethodProperty },
29 {::onc::eap::kPassword
, shill::kEapPasswordProperty
},
30 {::onc::eap::kSaveCredentials
, shill::kSaveCredentialsProperty
},
31 {::onc::eap::kServerCAPEMs
, shill::kEapCaCertPemProperty
},
32 {::onc::eap::kUseSystemCAs
, shill::kEapUseSystemCasProperty
},
33 {::onc::eap::kUseProactiveKeyCaching
,
34 shill::kEapUseProactiveKeyCachingProperty
},
37 const FieldTranslationEntry ipsec_fields
[] = {
38 // This field is converted during translation, see onc_translator_*.
39 // { ::onc::ipsec::kAuthenticationType, shill::kL2tpIpsecAuthenticationType
41 {::onc::ipsec::kGroup
, shill::kL2tpIpsecTunnelGroupProperty
},
42 // Ignored by Shill, not necessary to synchronize.
43 // { ::onc::ipsec::kIKEVersion, shill::kL2tpIpsecIkeVersion },
44 {::onc::ipsec::kPSK
, shill::kL2tpIpsecPskProperty
},
45 // This field is converted during translation, see onc_translator_*.
46 // { ::onc::vpn::kSaveCredentials, shill::kSaveCredentialsProperty},
47 {::onc::ipsec::kServerCAPEMs
, shill::kL2tpIpsecCaCertPemProperty
},
50 const FieldTranslationEntry xauth_fields
[] = {
51 {::onc::vpn::kPassword
, shill::kL2tpIpsecXauthPasswordProperty
},
52 {::onc::vpn::kUsername
, shill::kL2tpIpsecXauthUserProperty
},
55 const FieldTranslationEntry l2tp_fields
[] = {
56 {::onc::l2tp::kPassword
, shill::kL2tpIpsecPasswordProperty
},
57 // We don't synchronize l2tp's SaveCredentials field for now, as Shill
58 // doesn't support separate settings for ipsec and l2tp.
59 // { ::onc::l2tp::kSaveCredentials, &kBoolSignature },
60 {::onc::l2tp::kUsername
, shill::kL2tpIpsecUserProperty
},
61 {::onc::l2tp::kLcpEchoDisabled
, shill::kL2tpIpsecLcpEchoDisabledProperty
},
64 const FieldTranslationEntry openvpn_fields
[] = {
65 {::onc::openvpn::kAuth
, shill::kOpenVPNAuthProperty
},
66 {::onc::openvpn::kAuthNoCache
, shill::kOpenVPNAuthNoCacheProperty
},
67 {::onc::openvpn::kAuthRetry
, shill::kOpenVPNAuthRetryProperty
},
68 {::onc::openvpn::kCipher
, shill::kOpenVPNCipherProperty
},
69 {::onc::openvpn::kCompLZO
, shill::kOpenVPNCompLZOProperty
},
70 {::onc::openvpn::kCompNoAdapt
, shill::kOpenVPNCompNoAdaptProperty
},
71 {::onc::openvpn::kIgnoreDefaultRoute
,
72 shill::kOpenVPNIgnoreDefaultRouteProperty
},
73 {::onc::openvpn::kKeyDirection
, shill::kOpenVPNKeyDirectionProperty
},
74 {::onc::openvpn::kNsCertType
, shill::kOpenVPNNsCertTypeProperty
},
75 // This field is converted during translation, see onc_translator_*.
76 // { ::onc::vpn::kOTP, shill::kOpenVPNTokenProperty or kOpenVPNOTPProperty},
77 // This field is converted during translation, see onc_translator_*.
78 // { ::onc::vpn::kPassword, shill::kOpenVPNPasswordProperty},
79 {::onc::openvpn::kPort
, shill::kOpenVPNPortProperty
},
80 {::onc::openvpn::kProto
, shill::kOpenVPNProtoProperty
},
81 {::onc::openvpn::kPushPeerInfo
, shill::kOpenVPNPushPeerInfoProperty
},
82 {::onc::openvpn::kRemoteCertEKU
, shill::kOpenVPNRemoteCertEKUProperty
},
83 // This field is converted during translation, see onc_translator_*.
84 // { ::onc::openvpn::kRemoteCertKU, shill::kOpenVPNRemoteCertKUProperty },
85 {::onc::openvpn::kRemoteCertTLS
, shill::kOpenVPNRemoteCertTLSProperty
},
86 {::onc::openvpn::kRenegSec
, shill::kOpenVPNRenegSecProperty
},
87 // This field is converted during translation, see onc_translator_*.
88 // { ::onc::vpn::kSaveCredentials, shill::kSaveCredentialsProperty},
89 {::onc::openvpn::kServerCAPEMs
, shill::kOpenVPNCaCertPemProperty
},
90 {::onc::openvpn::kServerPollTimeout
,
91 shill::kOpenVPNServerPollTimeoutProperty
},
92 {::onc::openvpn::kShaper
, shill::kOpenVPNShaperProperty
},
93 {::onc::openvpn::kStaticChallenge
, shill::kOpenVPNStaticChallengeProperty
},
94 {::onc::openvpn::kTLSAuthContents
, shill::kOpenVPNTLSAuthContentsProperty
},
95 {::onc::openvpn::kTLSRemote
, shill::kOpenVPNTLSRemoteProperty
},
96 {::onc::vpn::kUsername
, shill::kOpenVPNUserProperty
},
97 {::onc::openvpn::kVerifyHash
, shill::kOpenVPNVerifyHashProperty
},
100 const FieldTranslationEntry verify_x509_fields
[] = {
101 {::onc::verify_x509::kName
, shill::kOpenVPNVerifyX509NameProperty
},
102 {::onc::verify_x509::kType
, shill::kOpenVPNVerifyX509TypeProperty
},
105 const FieldTranslationEntry vpn_fields
[] = {
106 {::onc::vpn::kAutoConnect
, shill::kAutoConnectProperty
},
107 // These fields are converted during translation, see onc_translator_*.
108 // { ::onc::vpn::kHost, shill::kProviderHostProperty},
109 // { ::onc::vpn::kType, shill::kProviderTypeProperty },
112 const FieldTranslationEntry wifi_fields
[] = {
113 {::onc::wifi::kAutoConnect
, shill::kAutoConnectProperty
},
114 {::onc::wifi::kBSSID
, shill::kWifiBSsid
},
115 // This dictionary is converted during translation, see onc_translator_*.
116 // { ::onc::wifi::kEAP, shill::kEap*},
117 {::onc::wifi::kFrequency
, shill::kWifiFrequency
},
118 {::onc::wifi::kFrequencyList
, shill::kWifiFrequencyListProperty
},
119 {::onc::wifi::kHexSSID
, shill::kWifiHexSsid
},
120 {::onc::wifi::kHiddenSSID
, shill::kWifiHiddenSsid
},
121 {::onc::wifi::kPassphrase
, shill::kPassphraseProperty
},
122 {::onc::wifi::kRoamThreshold
, shill::kWifiRoamThresholdProperty
},
123 // This field is converted during translation, see onc_translator_*.
124 // { ::onc::wifi::kSecurity, shill::kSecurityClassProperty },
125 {::onc::wifi::kSignalStrength
, shill::kSignalStrengthProperty
},
128 const FieldTranslationEntry wimax_fields
[] = {
129 {::onc::wimax::kAutoConnect
, shill::kAutoConnectProperty
},
130 // This dictionary is converted during translation, see onc_translator_*.
131 // { ::onc::wimax::kEAP, shill::kEap*},
132 {::onc::wimax::kSignalStrength
, shill::kSignalStrengthProperty
},
135 const FieldTranslationEntry cellular_apn_fields
[] = {
136 {::onc::cellular_apn::kAccessPointName
, shill::kApnProperty
},
137 {::onc::cellular_apn::kName
, shill::kApnNameProperty
},
138 {::onc::cellular_apn::kUsername
, shill::kApnUsernameProperty
},
139 {::onc::cellular_apn::kPassword
, shill::kApnPasswordProperty
},
140 {::onc::cellular_apn::kLocalizedName
, shill::kApnLocalizedNameProperty
},
141 {::onc::cellular_apn::kLanguage
, shill::kApnLanguageProperty
},
144 const FieldTranslationEntry cellular_found_network_fields
[] = {
145 {::onc::cellular_found_network::kNetworkId
, shill::kNetworkIdProperty
},
146 {::onc::cellular_found_network::kStatus
, shill::kStatusProperty
},
147 {::onc::cellular_found_network::kTechnology
, shill::kTechnologyProperty
},
148 {::onc::cellular_found_network::kShortName
, shill::kShortNameProperty
},
149 {::onc::cellular_found_network::kLongName
, shill::kLongNameProperty
},
152 const FieldTranslationEntry cellular_payment_portal_fields
[] = {
153 {::onc::cellular_payment_portal::kMethod
, shill::kPaymentPortalMethod
},
154 {::onc::cellular_payment_portal::kPostData
, shill::kPaymentPortalPostData
},
155 {::onc::cellular_payment_portal::kUrl
, shill::kPaymentPortalURL
},
158 const FieldTranslationEntry cellular_provider_fields
[] = {
159 {::onc::cellular_provider::kCode
, shill::kOperatorCodeKey
},
160 {::onc::cellular_provider::kCountry
, shill::kOperatorCountryKey
},
161 {::onc::cellular_provider::kName
, shill::kOperatorNameKey
},
164 const FieldTranslationEntry sim_lock_status_fields
[] = {
165 {::onc::sim_lock_status::kLockEnabled
, shill::kSIMLockEnabledProperty
},
166 {::onc::sim_lock_status::kLockType
, shill::kSIMLockTypeProperty
},
167 {::onc::sim_lock_status::kRetriesLeft
, shill::kSIMLockRetriesLeftProperty
},
170 // This must only contain Service properties and not Device properties.
171 // For Device properties see kCellularDeviceTable.
172 const FieldTranslationEntry cellular_fields
[] = {
173 {::onc::cellular::kActivationType
, shill::kActivationTypeProperty
},
174 // This field is converted during translation, see onc_translator_*.
175 // { ::onc::cellular::kActivationState, shill::kActivationStateProperty},
176 {::onc::cellular::kAutoConnect
, shill::kAutoConnectProperty
},
177 // This field is converted during translation, see onc_translator_*.
178 // { ::onc::cellular::kNetworkTechnology,
179 // shill::kNetworkTechnologyProperty},
180 // This field is converted during translation, see onc_translator_*.
181 // { ::onc::cellular::kPaymentPortal, shill::kPaymentPortal},
182 // This field is converted during translation, see onc_translator_*.
183 // { ::onc::cellular::kRoamingState, shill::kRoamingStateProperty},
184 {::onc::cellular::kSignalStrength
, shill::kSignalStrengthProperty
},
187 const FieldTranslationEntry network_fields
[] = {
188 {::onc::network_config::kGUID
, shill::kGuidProperty
},
189 {::onc::network_config::kConnectable
, shill::kConnectableProperty
},
190 {::onc::network_config::kPriority
, shill::kPriorityProperty
},
192 // Shill doesn't allow setting the name for non-VPN networks.
193 // Name is conditionally translated, see onc_translator_*.
194 // {::onc::network_config::kName, shill::kNameProperty },
196 // Type is converted during translation, see onc_translator_*.
197 // {::onc::network_config::kType, shill::kTypeProperty },
198 // {::onc::network_config::kProxySettings, shill::ProxyConfig},
200 // These fields are converted during translation, see
201 // onc_translator_shill_to_onc.cc. They are only converted when going from
202 // Shill->ONC, and ignored otherwise.
203 // {::onc::network_config::kConnectionState, shill::kStateProperty },
204 // {::onc::network_config::kErrorState, shill::kErrorProperty},
205 // {::onc::network_config::kRestrictedConnectivity, shill::kStateProperty },
206 // {::onc::network_config::kSource, shill::kProfileProperty },
207 // {::onc::network_config::kMacAddress, shill::kAddressProperty },
210 const FieldTranslationEntry ipconfig_fields
[] = {
211 {::onc::ipconfig::kIPAddress
, shill::kAddressProperty
},
212 {::onc::ipconfig::kGateway
, shill::kGatewayProperty
},
213 {::onc::ipconfig::kRoutingPrefix
, shill::kPrefixlenProperty
},
214 {::onc::ipconfig::kNameServers
, shill::kNameServersProperty
},
215 // This field is converted during translation, see ShillToONCTranslator::
216 // TranslateIPConfig. It is only converted from Shill->ONC.
217 // { ::onc::ipconfig::kType, shill::kMethodProperty},
218 {::onc::ipconfig::kWebProxyAutoDiscoveryUrl
,
219 shill::kWebProxyAutoDiscoveryUrlProperty
},
222 const FieldTranslationEntry static_or_saved_ipconfig_fields
[] = {
223 {::onc::ipconfig::kIPAddress
, shill::kAddressProperty
},
224 {::onc::ipconfig::kGateway
, shill::kGatewayProperty
},
225 {::onc::ipconfig::kRoutingPrefix
, shill::kPrefixlenProperty
},
226 {::onc::ipconfig::kNameServers
, shill::kNameServersProperty
},
229 struct OncValueTranslationEntry
{
230 const OncValueSignature
* onc_signature
;
231 const FieldTranslationEntry
* field_translation_table
;
234 const OncValueTranslationEntry onc_value_translation_table
[] = {
235 {&kEAPSignature
, eap_fields
},
236 {&kIPsecSignature
, ipsec_fields
},
237 {&kL2TPSignature
, l2tp_fields
},
238 {&kXAUTHSignature
, xauth_fields
},
239 {&kOpenVPNSignature
, openvpn_fields
},
240 {&kVerifyX509Signature
, verify_x509_fields
},
241 {&kVPNSignature
, vpn_fields
},
242 {&kWiFiSignature
, wifi_fields
},
243 {&kWiFiWithStateSignature
, wifi_fields
},
244 {&kWiMAXSignature
, wimax_fields
},
245 {&kWiMAXWithStateSignature
, wimax_fields
},
246 {&kCellularApnSignature
, cellular_apn_fields
},
247 {&kCellularFoundNetworkSignature
, cellular_found_network_fields
},
248 {&kCellularPaymentPortalSignature
, cellular_payment_portal_fields
},
249 {&kCellularProviderSignature
, cellular_provider_fields
},
250 {&kSIMLockStatusSignature
, sim_lock_status_fields
},
251 {&kCellularSignature
, cellular_fields
},
252 {&kCellularWithStateSignature
, cellular_fields
},
253 {&kNetworkWithStateSignature
, network_fields
},
254 {&kNetworkConfigurationSignature
, network_fields
},
255 {&kIPConfigSignature
, ipconfig_fields
},
256 {&kSavedIPConfigSignature
, static_or_saved_ipconfig_fields
},
257 {&kStaticIPConfigSignature
, static_or_saved_ipconfig_fields
},
260 struct NestedShillDictionaryEntry
{
261 const OncValueSignature
* onc_signature
;
262 // NULL terminated list of Shill property keys.
263 const char* const* shill_property_path
;
266 const char* cellular_apn_path_entries
[] = {shill::kCellularApnProperty
, NULL
};
268 const char* static_ip_config_path_entries
[] = {shill::kStaticIPConfigProperty
,
271 const NestedShillDictionaryEntry nested_shill_dictionaries
[] = {
272 {&kCellularApnSignature
, cellular_apn_path_entries
},
273 {&kStaticIPConfigSignature
, static_ip_config_path_entries
},
278 const StringTranslationEntry kNetworkTypeTable
[] = {
279 // This mapping is ensured in the translation code.
280 // { network_type::kEthernet, shill::kTypeEthernet },
281 // { network_type::kEthernet, shill::kTypeEthernetEap },
282 {::onc::network_type::kWiFi
, shill::kTypeWifi
},
283 {::onc::network_type::kWimax
, shill::kTypeWimax
},
284 {::onc::network_type::kCellular
, shill::kTypeCellular
},
285 {::onc::network_type::kVPN
, shill::kTypeVPN
},
288 const StringTranslationEntry kVPNTypeTable
[] = {
289 {::onc::vpn::kTypeL2TP_IPsec
, shill::kProviderL2tpIpsec
},
290 {::onc::vpn::kOpenVPN
, shill::kProviderOpenVpn
},
291 {::onc::vpn::kThirdPartyVpn
, shill::kProviderThirdPartyVpn
},
294 const StringTranslationEntry kWiFiSecurityTable
[] = {
295 {::onc::wifi::kSecurityNone
, shill::kSecurityNone
},
296 {::onc::wifi::kWEP_PSK
, shill::kSecurityWep
},
297 {::onc::wifi::kWPA_PSK
, shill::kSecurityPsk
},
298 {::onc::wifi::kWPA_EAP
, shill::kSecurity8021x
},
301 const StringTranslationEntry kEAPOuterTable
[] = {
302 {::onc::eap::kPEAP
, shill::kEapMethodPEAP
},
303 {::onc::eap::kEAP_TLS
, shill::kEapMethodTLS
},
304 {::onc::eap::kEAP_TTLS
, shill::kEapMethodTTLS
},
305 {::onc::eap::kLEAP
, shill::kEapMethodLEAP
},
308 // Translation of the EAP.Inner field in case of EAP.Outer == PEAP
309 const StringTranslationEntry kEAP_PEAP_InnerTable
[] = {
310 {::onc::eap::kMD5
, shill::kEapPhase2AuthPEAPMD5
},
311 {::onc::eap::kMSCHAPv2
, shill::kEapPhase2AuthPEAPMSCHAPV2
},
312 {::onc::eap::kGTC
, shill::kEapPhase2AuthPEAPGTC
},
315 // Translation of the EAP.Inner field in case of EAP.Outer == TTLS
316 const StringTranslationEntry kEAP_TTLS_InnerTable
[] = {
317 {::onc::eap::kMD5
, shill::kEapPhase2AuthTTLSMD5
},
318 {::onc::eap::kMSCHAPv2
, shill::kEapPhase2AuthTTLSMSCHAPV2
},
319 {::onc::eap::kPAP
, shill::kEapPhase2AuthTTLSPAP
},
320 {::onc::eap::kGTC
, shill::kEapPhase2AuthTTLSGTC
},
323 const StringTranslationEntry kActivationStateTable
[] = {
324 {::onc::cellular::kActivated
, shill::kActivationStateActivated
},
325 {::onc::cellular::kActivating
, shill::kActivationStateActivating
},
326 {::onc::cellular::kNotActivated
, shill::kActivationStateNotActivated
},
327 {::onc::cellular::kPartiallyActivated
,
328 shill::kActivationStatePartiallyActivated
},
331 const StringTranslationEntry kNetworkTechnologyTable
[] = {
332 {::onc::cellular::kTechnologyCdma1Xrtt
, shill::kNetworkTechnology1Xrtt
},
333 {::onc::cellular::kTechnologyGsm
, shill::kNetworkTechnologyGsm
},
334 {::onc::cellular::kTechnologyEdge
, shill::kNetworkTechnologyEdge
},
335 {::onc::cellular::kTechnologyEvdo
, shill::kNetworkTechnologyEvdo
},
336 {::onc::cellular::kTechnologyGprs
, shill::kNetworkTechnologyGprs
},
337 {::onc::cellular::kTechnologyHspa
, shill::kNetworkTechnologyHspa
},
338 {::onc::cellular::kTechnologyHspaPlus
, shill::kNetworkTechnologyHspaPlus
},
339 {::onc::cellular::kTechnologyLte
, shill::kNetworkTechnologyLte
},
340 {::onc::cellular::kTechnologyLteAdvanced
,
341 shill::kNetworkTechnologyLteAdvanced
},
342 {::onc::cellular::kTechnologyUmts
, shill::kNetworkTechnologyUmts
},
345 const StringTranslationEntry kRoamingStateTable
[] = {
346 {::onc::cellular::kRoamingHome
, shill::kRoamingStateHome
},
347 {::onc::cellular::kRoamingRoaming
, shill::kRoamingStateRoaming
},
350 // This must contain only Shill Device properties and no Service properties.
351 // For Service properties see cellular_fields.
352 const FieldTranslationEntry kCellularDeviceTable
[] = {
353 // This field is converted during translation, see onc_translator_*.
354 // { ::onc::cellular::kAPNList, shill::kCellularApnListProperty},
355 {::onc::cellular::kAllowRoaming
, shill::kCellularAllowRoamingProperty
},
356 {::onc::cellular::kCarrier
, shill::kCarrierProperty
},
357 {::onc::cellular::kESN
, shill::kEsnProperty
},
358 {::onc::cellular::kFamily
, shill::kTechnologyFamilyProperty
},
359 {::onc::cellular::kFirmwareRevision
, shill::kFirmwareRevisionProperty
},
360 // This field is converted during translation, see onc_translator_*.
361 // { ::onc::cellular::kFoundNetworks, shill::kFoundNetworksProperty},
362 {::onc::cellular::kHardwareRevision
, shill::kHardwareRevisionProperty
},
363 // This field is converted during translation, see onc_translator_*.
364 // { ::onc::cellular::kHomeProvider, shill::kHomeProviderProperty},
365 {::onc::cellular::kICCID
, shill::kIccidProperty
},
366 {::onc::cellular::kIMEI
, shill::kImeiProperty
},
367 {::onc::cellular::kIMSI
, shill::kImsiProperty
},
368 {::onc::cellular::kManufacturer
, shill::kManufacturerProperty
},
369 {::onc::cellular::kMDN
, shill::kMdnProperty
},
370 {::onc::cellular::kMEID
, shill::kMeidProperty
},
371 {::onc::cellular::kMIN
, shill::kMinProperty
},
372 {::onc::cellular::kModelID
, shill::kModelIDProperty
},
373 {::onc::cellular::kPRLVersion
, shill::kPRLVersionProperty
},
374 // This field is converted during translation, see onc_translator_*.
375 // { ::onc::cellular::kSIMLockStatus, shill::kSIMLockStatusProperty},
376 {::onc::cellular::kSIMPresent
, shill::kSIMPresentProperty
},
377 {::onc::cellular::kSupportedCarriers
, shill::kSupportedCarriersProperty
},
378 {::onc::cellular::kSupportNetworkScan
, shill::kSupportNetworkScanProperty
},
381 const FieldTranslationEntry
* GetFieldTranslationTable(
382 const OncValueSignature
& onc_signature
) {
383 for (const OncValueTranslationEntry
* it
= onc_value_translation_table
;
384 it
->onc_signature
!= NULL
; ++it
) {
385 if (it
->onc_signature
== &onc_signature
)
386 return it
->field_translation_table
;
391 std::vector
<std::string
> GetPathToNestedShillDictionary(
392 const OncValueSignature
& onc_signature
) {
393 std::vector
<std::string
> shill_property_path
;
394 for (const NestedShillDictionaryEntry
* it
= nested_shill_dictionaries
;
395 it
->onc_signature
!= NULL
; ++it
) {
396 if (it
->onc_signature
== &onc_signature
) {
397 for (const char* const* key
= it
->shill_property_path
; *key
!= NULL
;
399 shill_property_path
.push_back(std::string(*key
));
404 return shill_property_path
;
407 bool GetShillPropertyName(const std::string
& onc_field_name
,
408 const FieldTranslationEntry table
[],
409 std::string
* shill_property_name
) {
410 for (const FieldTranslationEntry
* it
= table
; it
->onc_field_name
!= NULL
;
412 if (it
->onc_field_name
!= onc_field_name
)
414 *shill_property_name
= it
->shill_property_name
;
420 bool TranslateStringToShill(const StringTranslationEntry table
[],
421 const std::string
& onc_value
,
422 std::string
* shill_value
) {
423 for (int i
= 0; table
[i
].onc_value
!= NULL
; ++i
) {
424 if (onc_value
!= table
[i
].onc_value
)
426 *shill_value
= table
[i
].shill_value
;
429 LOG(ERROR
) << "Value '" << onc_value
<< "' cannot be translated to Shill";
433 bool TranslateStringToONC(const StringTranslationEntry table
[],
434 const std::string
& shill_value
,
435 std::string
* onc_value
) {
436 for (int i
= 0; table
[i
].shill_value
!= NULL
; ++i
) {
437 if (shill_value
!= table
[i
].shill_value
)
439 *onc_value
= table
[i
].onc_value
;
442 LOG(ERROR
) << "Value '" << shill_value
<< "' cannot be translated to ONC";
447 } // namespace chromeos