2 * Copyright (c) 2004-2014 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * Modification History
27 * May 13, 2004 Allan Nathanson <ajn@apple.com>
32 #include <CoreFoundation/CoreFoundation.h>
33 #include <CoreFoundation/CFRuntime.h>
34 #include <SystemConfiguration/SystemConfiguration.h>
35 #include "SCNetworkConfigurationInternal.h"
36 #include <SystemConfiguration/SCValidation.h>
37 #include <SystemConfiguration/SCPrivate.h>
38 #include "SCPreferencesInternal.h"
42 #define EXTERNAL_ID_DOMAIN_PREFIX "_"
44 static CFStringRef
__SCNetworkServiceCopyDescription (CFTypeRef cf
);
45 static void __SCNetworkServiceDeallocate (CFTypeRef cf
);
46 static Boolean
__SCNetworkServiceEqual (CFTypeRef cf1
, CFTypeRef cf2
);
47 static CFHashCode
__SCNetworkServiceHash (CFTypeRef cf
);
50 static CFTypeID __kSCNetworkServiceTypeID
= _kCFRuntimeNotATypeID
;
53 static const CFRuntimeClass __SCNetworkServiceClass
= {
55 "SCNetworkService", // className
58 __SCNetworkServiceDeallocate
, // dealloc
59 __SCNetworkServiceEqual
, // equal
60 __SCNetworkServiceHash
, // hash
61 NULL
, // copyFormattingDesc
62 __SCNetworkServiceCopyDescription
// copyDebugDesc
66 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
70 __SCNetworkServiceCopyDescription(CFTypeRef cf
)
72 CFAllocatorRef allocator
= CFGetAllocator(cf
);
73 CFMutableStringRef result
;
74 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)cf
;
76 result
= CFStringCreateMutable(allocator
, 0);
77 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkService %p [%p]> {"), cf
, allocator
);
78 CFStringAppendFormat(result
, NULL
, CFSTR("id = %@"), servicePrivate
->serviceID
);
79 if (servicePrivate
->prefs
!= NULL
) {
80 CFStringAppendFormat(result
, NULL
, CFSTR(", prefs = %p"), servicePrivate
->prefs
);
81 } else if (servicePrivate
->store
!= NULL
) {
82 CFStringAppendFormat(result
, NULL
, CFSTR(", store = %p"), servicePrivate
->store
);
84 if (servicePrivate
->name
!= NULL
) {
85 CFStringAppendFormat(result
, NULL
, CFSTR(", name = %@"), servicePrivate
->name
);
87 CFStringAppendFormat(result
, NULL
, CFSTR("}"));
94 __SCNetworkServiceDeallocate(CFTypeRef cf
)
96 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)cf
;
98 /* release resources */
100 CFRelease(servicePrivate
->serviceID
);
101 if (servicePrivate
->interface
!= NULL
) CFRelease(servicePrivate
->interface
);
102 if (servicePrivate
->prefs
!= NULL
) CFRelease(servicePrivate
->prefs
);
103 if (servicePrivate
->store
!= NULL
) CFRelease(servicePrivate
->store
);
104 if (servicePrivate
->name
!= NULL
) CFRelease(servicePrivate
->name
);
105 if (servicePrivate
->externalIDs
!= NULL
) CFRelease(servicePrivate
->externalIDs
);
112 __SCNetworkServiceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
114 SCNetworkServicePrivateRef s1
= (SCNetworkServicePrivateRef
)cf1
;
115 SCNetworkServicePrivateRef s2
= (SCNetworkServicePrivateRef
)cf2
;
120 if (s1
->prefs
!= s2
->prefs
)
121 return FALSE
; // if not the same prefs
123 if (!CFEqual(s1
->serviceID
, s2
->serviceID
))
124 return FALSE
; // if not the same service identifier
131 __SCNetworkServiceHash(CFTypeRef cf
)
133 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)cf
;
135 return CFHash(servicePrivate
->serviceID
);
140 __SCNetworkServiceInitialize(void)
142 __kSCNetworkServiceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkServiceClass
);
147 __private_extern__ SCNetworkServicePrivateRef
148 __SCNetworkServiceCreatePrivate(CFAllocatorRef allocator
,
149 SCPreferencesRef prefs
,
150 CFStringRef serviceID
,
151 SCNetworkInterfaceRef interface
)
153 SCNetworkServicePrivateRef servicePrivate
;
156 /* initialize runtime */
157 pthread_once(&initialized
, __SCNetworkServiceInitialize
);
159 /* allocate target */
160 size
= sizeof(SCNetworkServicePrivate
) - sizeof(CFRuntimeBase
);
161 servicePrivate
= (SCNetworkServicePrivateRef
)_CFRuntimeCreateInstance(allocator
,
162 __kSCNetworkServiceTypeID
,
165 if (servicePrivate
== NULL
) {
169 servicePrivate
->prefs
= (prefs
!= NULL
) ? CFRetain(prefs
): NULL
;
170 servicePrivate
->serviceID
= CFStringCreateCopy(NULL
, serviceID
);
171 servicePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
172 servicePrivate
->name
= NULL
;
174 return servicePrivate
;
179 #pragma mark Service ordering
183 _SCNetworkServiceCompare(const void *val1
, const void *val2
, void *context
)
187 CFArrayRef order
= (CFArrayRef
)context
;
188 SCNetworkServiceRef s1
= (SCNetworkServiceRef
)val1
;
189 SCNetworkServiceRef s2
= (SCNetworkServiceRef
)val2
;
191 id1
= SCNetworkServiceGetServiceID(s1
);
192 id2
= SCNetworkServiceGetServiceID(s2
);
199 range
= CFRangeMake(0, CFArrayGetCount(order
));
200 o1
= CFArrayGetFirstIndexOfValue(order
, range
, id1
);
201 o2
= CFArrayGetFirstIndexOfValue(order
, range
, id2
);
204 return (o2
!= kCFNotFound
) ? kCFCompareGreaterThan
: kCFCompareLessThan
;
205 } else if (o1
< o2
) {
206 return (o1
!= kCFNotFound
) ? kCFCompareLessThan
: kCFCompareGreaterThan
;
210 return CFStringCompare(id1
, id2
, 0);
215 #pragma mark SCNetworkService APIs
221 __private_extern__ CFArrayRef
/* of SCNetworkServiceRef's */
222 __SCNetworkServiceCopyAllEnabled(SCPreferencesRef prefs
)
224 CFMutableArrayRef array
= NULL
;
229 sets
= SCNetworkSetCopyAll(prefs
);
234 n_sets
= CFArrayGetCount(sets
);
235 for (i_sets
= 0; i_sets
< n_sets
; i_sets
++) {
241 set
= CFArrayGetValueAtIndex(sets
, i_sets
);
242 services
= SCNetworkSetCopyServices(set
);
243 if (services
== NULL
) {
247 n_services
= CFArrayGetCount(services
);
248 for (i_services
= 0; i_services
< n_services
; i_services
++) {
249 SCNetworkServiceRef service
;
251 service
= CFArrayGetValueAtIndex(services
, i_services
);
252 if (!SCNetworkServiceGetEnabled(service
)) {
257 if ((array
== NULL
) ||
258 !CFArrayContainsValue(array
,
259 CFRangeMake(0, CFArrayGetCount(array
)),
262 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
264 CFArrayAppendValue(array
, service
);
275 __private_extern__ Boolean
276 __SCNetworkServiceExistsForInterface(CFArrayRef services
, SCNetworkInterfaceRef interface
)
281 n
= isA_CFArray(services
) ? CFArrayGetCount(services
) : 0;
282 for (i
= 0; i
< n
; i
++) {
283 SCNetworkServiceRef service
;
284 SCNetworkInterfaceRef service_interface
;
286 service
= CFArrayGetValueAtIndex(services
, i
);
288 service_interface
= SCNetworkServiceGetInterface(service
);
289 while (service_interface
!= NULL
) {
290 if (CFEqual(interface
, service_interface
)) {
294 service_interface
= SCNetworkInterfaceGetInterface(service_interface
);
303 mergeDict(const void *key
, const void *value
, void *context
)
305 CFMutableDictionaryRef newDict
= (CFMutableDictionaryRef
)context
;
307 CFDictionarySetValue(newDict
, key
, value
);
312 static CF_RETURNS_RETAINED CFDictionaryRef
313 _protocolTemplate(SCNetworkServiceRef service
, CFStringRef protocolType
)
315 SCNetworkInterfaceRef interface
;
316 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
317 CFDictionaryRef
template = NULL
;
319 interface
= servicePrivate
->interface
;
320 if (interface
!= NULL
) {
321 SCNetworkInterfaceRef childInterface
;
322 CFStringRef childInterfaceType
= NULL
;
323 CFStringRef interfaceType
;
326 interfaceType
= SCNetworkInterfaceGetInterfaceType(servicePrivate
->interface
);
327 childInterface
= SCNetworkInterfaceGetInterface(servicePrivate
->interface
);
328 if (childInterface
!= NULL
) {
329 childInterfaceType
= SCNetworkInterfaceGetInterfaceType(childInterface
);
332 template = __copyProtocolTemplate(interfaceType
, childInterfaceType
, protocolType
);
333 if (template != NULL
) {
334 CFDictionaryRef overrides
;
336 // move to the interface at the lowest layer
337 while (childInterface
!= NULL
) {
338 interface
= childInterface
;
339 childInterface
= SCNetworkInterfaceGetInterface(interface
);
342 overrides
= __SCNetworkInterfaceGetTemplateOverrides(interface
, protocolType
);
343 if (overrides
!= NULL
) {
344 CFMutableDictionaryRef newTemplate
;
346 newTemplate
= CFDictionaryCreateMutableCopy(NULL
, 0, template);
347 CFDictionaryApplyFunction(overrides
, mergeDict
, newTemplate
);
349 template = newTemplate
;
354 if (template == NULL
) {
355 template = CFDictionaryCreate(NULL
,
359 &kCFTypeDictionaryKeyCallBacks
,
360 &kCFTypeDictionaryValueCallBacks
);
368 SCNetworkServiceAddProtocolType(SCNetworkServiceRef service
, CFStringRef protocolType
)
370 CFDictionaryRef entity
;
371 CFDictionaryRef newEntity
= NULL
;
374 SCNetworkProtocolRef protocol
;
375 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
377 if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs
== NULL
)) {
378 _SCErrorSet(kSCStatusInvalidArgument
);
382 if (!__SCNetworkProtocolIsValidType(protocolType
)) {
383 _SCErrorSet(kSCStatusInvalidArgument
);
387 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
388 servicePrivate
->serviceID
, // service
389 protocolType
); // entity
391 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
392 if (entity
!= NULL
) {
393 // if "protocol" already exists
394 _SCErrorSet(kSCStatusKeyExists
);
398 newEntity
= CFDictionaryCreate(NULL
,
402 &kCFTypeDictionaryKeyCallBacks
,
403 &kCFTypeDictionaryValueCallBacks
);
404 ok
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
);
405 CFRelease(newEntity
);
410 protocol
= SCNetworkServiceCopyProtocol(service
, protocolType
);
411 assert(protocol
!= NULL
);
413 newEntity
= _protocolTemplate(service
, protocolType
);
414 ok
= SCNetworkProtocolSetConfiguration(protocol
, newEntity
);
415 CFRelease(newEntity
);
425 CFArrayRef
/* of SCNetworkServiceRef's */
426 SCNetworkServiceCopyAll(SCPreferencesRef prefs
)
428 CFMutableArrayRef array
;
431 CFDictionaryRef services
;
433 path
= SCPreferencesPathKeyCreateNetworkServices(NULL
);
434 services
= SCPreferencesPathGetValue(prefs
, path
);
437 if ((services
!= NULL
) && !isA_CFDictionary(services
)) {
441 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
443 n
= (services
!= NULL
) ? CFDictionaryGetCount(services
) : 0;
446 const void * keys_q
[N_QUICK
];
447 const void ** keys
= keys_q
;
448 const void * vals_q
[N_QUICK
];
449 const void ** vals
= vals_q
;
451 if (n
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
452 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
453 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFPropertyListRef
), 0);
455 CFDictionaryGetKeysAndValues(services
, keys
, vals
);
456 for (i
= 0; i
< n
; i
++) {
457 CFDictionaryRef entity
;
458 SCNetworkServicePrivateRef servicePrivate
;
460 if (!isA_CFDictionary(vals
[i
])) {
463 CFSTR("SCNetworkServiceCopyAll(): error w/service \"%@\"\n"),
468 entity
= CFDictionaryGetValue(vals
[i
], kSCEntNetInterface
);
469 if (!isA_CFDictionary(entity
)) {
473 CFSTR("SCNetworkServiceCopyAll(): no \"%@\" entity for service \"%@\"\n"),
479 servicePrivate
= __SCNetworkServiceCreatePrivate(NULL
, prefs
, keys
[i
], NULL
);
480 assert(servicePrivate
!= NULL
);
481 CFArrayAppendValue(array
, (SCNetworkServiceRef
)servicePrivate
);
482 CFRelease(servicePrivate
);
484 if (keys
!= keys_q
) {
485 CFAllocatorDeallocate(NULL
, keys
);
486 CFAllocatorDeallocate(NULL
, vals
);
495 CFArrayRef
/* of SCNetworkInterfaceRef's */
496 __SCNetworkServiceCopyAllInterfaces(SCPreferencesRef prefs
)
498 CFMutableArrayRef interfaces
= NULL
;
499 CFArrayRef services
= NULL
;
500 CFIndex servicesCount
= 0;
501 SCNetworkServiceRef service
= NULL
;
502 SCNetworkInterfaceRef interface
= NULL
;
504 services
= SCNetworkServiceCopyAll(prefs
);
505 if (services
== NULL
) {
509 servicesCount
= CFArrayGetCount(services
);
510 if (servicesCount
== 0) {
514 interfaces
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
516 for (CFIndex idx
= 0; idx
< servicesCount
; idx
++) {
517 service
= CFArrayGetValueAtIndex(services
, idx
);
518 interface
= SCNetworkServiceGetInterface(service
);
520 if (isA_SCNetworkInterface(interface
) == NULL
) {
523 CFArrayAppendValue(interfaces
, interface
);
526 if (CFArrayGetCount(interfaces
) == 0) {
527 // Do not return an empty array
528 CFRelease(interfaces
);
534 if (services
!= NULL
) {
542 * build a list of all of a services entity types that are associated
543 * with the services interface. The list will include :
545 * - entity types associated with the interface type (Ethernet, FireWire, PPP, ...)
546 * - entity types associated with the interface sub-type (PPPSerial, PPPoE, L2TP, PPTP, ...)
547 * - entity types associated with the hardware device (Ethernet, AirPort, FireWire, Modem, ...)
550 _copyInterfaceEntityTypes(CFDictionaryRef protocols
)
552 CFDictionaryRef interface
;
553 CFMutableSetRef interface_entity_types
;
555 interface_entity_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
557 interface
= CFDictionaryGetValue(protocols
, kSCEntNetInterface
);
558 if (isA_CFDictionary(interface
)) {
559 CFStringRef entities
[] = { kSCPropNetInterfaceType
,
560 kSCPropNetInterfaceSubType
,
561 kSCPropNetInterfaceHardware
};
564 // include the "Interface" entity itself
565 CFSetAddValue(interface_entity_types
, kSCEntNetInterface
);
567 // include the entities associated with the interface
568 for (i
= 0; i
< sizeof(entities
)/sizeof(entities
[0]); i
++) {
571 entity
= CFDictionaryGetValue(interface
, entities
[i
]);
572 if (isA_CFString(entity
)) {
573 CFSetAddValue(interface_entity_types
, entity
);
578 * and, because we've found some misguided network preference code
579 * developers leaving [PPP] entity dictionaries around even though
580 * they are unused and/or unneeded...
582 CFSetAddValue(interface_entity_types
, kSCEntNetPPP
);
585 return interface_entity_types
;
590 SCNetworkServiceCopy(SCPreferencesRef prefs
, CFStringRef serviceID
)
592 CFDictionaryRef entity
;
594 SCNetworkServicePrivateRef servicePrivate
;
596 if (!isA_CFString(serviceID
)) {
597 _SCErrorSet(kSCStatusInvalidArgument
);
601 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
602 serviceID
, // service
603 kSCEntNetInterface
); // entity
604 entity
= SCPreferencesPathGetValue(prefs
, path
);
607 if (!isA_CFDictionary(entity
)) {
608 // a "service" must have an "interface"
609 _SCErrorSet(kSCStatusNoKey
);
613 servicePrivate
= __SCNetworkServiceCreatePrivate(NULL
, prefs
, serviceID
, NULL
);
614 return (SCNetworkServiceRef
)servicePrivate
;
619 _SCNetworkServiceCopyActive(SCDynamicStoreRef store
, CFStringRef serviceID
)
621 SCNetworkServicePrivateRef servicePrivate
;
623 if (!isA_CFString(serviceID
)) {
624 _SCErrorSet(kSCStatusInvalidArgument
);
628 servicePrivate
= __SCNetworkServiceCreatePrivate(NULL
, NULL
, serviceID
, NULL
);
629 assert(servicePrivate
!= NULL
);
631 servicePrivate
->store
= CFRetain(store
);
633 return (SCNetworkServiceRef
)servicePrivate
;
638 SCNetworkServiceCopyProtocol(SCNetworkServiceRef service
, CFStringRef protocolType
)
640 CFSetRef non_protocol_entities
;
642 CFDictionaryRef protocols
;
643 SCNetworkProtocolPrivateRef protocolPrivate
= NULL
;
644 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
646 if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs
== NULL
)) {
647 _SCErrorSet(kSCStatusInvalidArgument
);
651 if (!isA_CFString(protocolType
)) {
652 _SCErrorSet(kSCStatusInvalidArgument
);
656 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
657 servicePrivate
->serviceID
, // service
659 protocols
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
662 if (!isA_CFDictionary(protocols
)) {
664 _SCErrorSet(kSCStatusFailed
);
668 non_protocol_entities
= _copyInterfaceEntityTypes(protocols
);
669 if (CFSetContainsValue(non_protocol_entities
, protocolType
)) {
670 // if the "protocolType" matches an interface entity type
671 _SCErrorSet(kSCStatusInvalidArgument
);
675 if (!CFDictionaryContainsKey(protocols
, protocolType
)) {
676 // if the "protocolType" entity does not exist
677 _SCErrorSet(kSCStatusNoKey
);
681 protocolPrivate
= __SCNetworkProtocolCreatePrivate(NULL
, protocolType
, service
);
685 CFRelease(non_protocol_entities
);
687 return (SCNetworkProtocolRef
)protocolPrivate
;
691 CFArrayRef
/* of SCNetworkProtocolRef's */
692 SCNetworkServiceCopyProtocols(SCNetworkServiceRef service
)
694 CFMutableArrayRef array
;
696 CFSetRef non_protocol_entities
;
698 CFDictionaryRef protocols
;
699 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
701 if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs
== NULL
)) {
702 _SCErrorSet(kSCStatusInvalidArgument
);
706 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
707 servicePrivate
->serviceID
, // service
709 protocols
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
712 if (!isA_CFDictionary(protocols
)) {
714 _SCErrorSet(kSCStatusFailed
);
718 non_protocol_entities
= _copyInterfaceEntityTypes(protocols
);
720 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
722 n
= CFDictionaryGetCount(protocols
);
725 const void * keys_q
[N_QUICK
];
726 const void ** keys
= keys_q
;
727 const void * vals_q
[N_QUICK
];
728 const void ** vals
= vals_q
;
730 if (n
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
731 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
732 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFPropertyListRef
), 0);
734 CFDictionaryGetKeysAndValues(protocols
, keys
, vals
);
735 for (i
= 0; i
< n
; i
++) {
736 SCNetworkProtocolPrivateRef protocolPrivate
;
738 if (!isA_CFDictionary(vals
[i
])) {
739 // if it's not a dictionary then it can't be a protocol entity
743 if (CFSetContainsValue(non_protocol_entities
, keys
[i
])) {
744 // skip any non-protocol (interface) entities
748 protocolPrivate
= __SCNetworkProtocolCreatePrivate(NULL
, keys
[i
], service
);
749 CFArrayAppendValue(array
, (SCNetworkProtocolRef
)protocolPrivate
);
751 CFRelease(protocolPrivate
);
753 if (keys
!= keys_q
) {
754 CFAllocatorDeallocate(NULL
, keys
);
755 CFAllocatorDeallocate(NULL
, vals
);
759 CFRelease(non_protocol_entities
);
766 __SCNetworkServiceSetInterfaceEntity(SCNetworkServiceRef service
,
767 SCNetworkInterfaceRef interface
)
769 CFDictionaryRef entity
;
772 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
774 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
775 servicePrivate
->serviceID
, // service
776 kSCEntNetInterface
); // entity
777 entity
= __SCNetworkInterfaceCopyInterfaceEntity(interface
);
778 ok
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, entity
);
787 SCNetworkServiceCreate(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
789 CFArrayRef components
;
790 CFArrayRef interface_config
;
791 CFStringRef interface_name
;
792 SCNetworkInterfaceRef newInterface
;
795 CFStringRef serviceID
;
796 SCNetworkServicePrivateRef servicePrivate
;
797 CFArrayRef supported_protocols
;
799 if (!isA_SCNetworkInterface(interface
)) {
800 _SCErrorSet(kSCStatusInvalidArgument
);
804 // only allow network interfaces which support one or more protocols
805 // to be added to a service. The one exception is that we allow
806 // third-party interface types to be configured.
807 supported_protocols
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
);
808 if (supported_protocols
== NULL
) {
809 CFStringRef interface_type
;
811 interface_type
= SCNetworkInterfaceGetInterfaceType(interface
);
812 if (CFStringFind(interface_type
, CFSTR("."), 0).location
== kCFNotFound
) {
813 _SCErrorSet(kSCStatusInvalidArgument
);
818 // do not allow creation of a network service if the interface is a
819 // member of a bond or bridge
820 if (__SCNetworkInterfaceIsMember(prefs
, interface
)) {
821 _SCErrorSet(kSCStatusKeyExists
);
825 // establish the service
826 prefix
= SCPreferencesPathKeyCreateNetworkServices(NULL
);
827 path
= __SCPreferencesPathCreateUniqueChild_WithMoreSCFCompatibility(prefs
, prefix
);
828 if (path
== NULL
) path
= SCPreferencesPathCreateUniqueChild(prefs
, prefix
);
834 components
= CFStringCreateArrayBySeparatingStrings(NULL
, path
, CFSTR("/"));
837 serviceID
= CFArrayGetValueAtIndex(components
, 2);
838 servicePrivate
= __SCNetworkServiceCreatePrivate(NULL
, prefs
, serviceID
, NULL
);
839 CFRelease(components
);
841 // duplicate the interface and associate the copy with the new service
842 newInterface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
,
846 servicePrivate
->interface
= newInterface
;
848 // establish "default" configuration(s) for the interface
849 for (interface
= newInterface
;
851 interface
= SCNetworkInterfaceGetInterface(interface
)) {
852 SCNetworkInterfaceRef childInterface
;
853 CFStringRef childInterfaceType
= NULL
;
854 CFDictionaryRef config
;
855 CFStringRef interfaceType
;
857 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
858 childInterface
= SCNetworkInterfaceGetInterface(interface
);
859 if (childInterface
!= NULL
) {
860 childInterfaceType
= SCNetworkInterfaceGetInterfaceType(childInterface
);
863 config
= __copyInterfaceTemplate(interfaceType
, childInterfaceType
);
864 if (config
!= NULL
) {
865 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeBluetooth
) ||
866 CFEqual(interfaceType
, kSCNetworkInterfaceTypeIrDA
) ||
867 CFEqual(interfaceType
, kSCNetworkInterfaceTypeModem
) ||
868 CFEqual(interfaceType
, kSCNetworkInterfaceTypeSerial
) ||
869 CFEqual(interfaceType
, kSCNetworkInterfaceTypeWWAN
)) {
870 CFDictionaryRef overrides
;
872 overrides
= __SCNetworkInterfaceGetTemplateOverrides(interface
, kSCNetworkInterfaceTypeModem
);
874 // a ConnectionScript (and related keys) from the interface
875 // should trump the settings from the configuration template.
876 if (overrides
!= NULL
) {
877 CFMutableDictionaryRef newConfig
;
879 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
880 if (CFDictionaryContainsKey(overrides
, kSCPropNetModemConnectionScript
)) {
881 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemConnectionPersonality
);
882 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemConnectionScript
);
883 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemDeviceVendor
);
884 CFDictionaryRemoveValue(newConfig
, kSCPropNetModemDeviceModel
);
886 CFDictionaryApplyFunction(overrides
, mergeDict
, newConfig
);
890 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
) ||
891 CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
892 CFDictionaryRef overrides
;
894 overrides
= __SCNetworkInterfaceGetTemplateOverrides(interface
, kSCNetworkInterfaceTypePPP
);
895 if (overrides
!= NULL
) {
896 CFMutableDictionaryRef newConfig
;
898 newConfig
= CFDictionaryCreateMutableCopy(NULL
, 0, config
);
899 CFDictionaryApplyFunction(overrides
, mergeDict
, newConfig
);
905 if (!__SCNetworkInterfaceSetConfiguration(interface
, NULL
, config
, TRUE
)) {
906 SCLog(TRUE
, LOG_DEBUG
,
907 CFSTR("SCNetworkService __SCNetworkInterfaceSetConfiguration failed(), interface=%@, type=NULL"),
914 // add the interface [entity] to the service
915 (void) __SCNetworkServiceSetInterfaceEntity((SCNetworkServiceRef
)servicePrivate
,
916 servicePrivate
->interface
);
918 // push the [deep] interface configuration into the service.
919 interface_config
= __SCNetworkInterfaceCopyDeepConfiguration(NULL
, servicePrivate
->interface
);
920 __SCNetworkInterfaceSetDeepConfiguration(NULL
, servicePrivate
->interface
, interface_config
);
921 if (interface_config
!= NULL
) CFRelease(interface_config
);
923 // set the service name to match that of the associated interface
925 // Note: It might seem a bit odd to call SCNetworkServiceGetName
926 // followed by an immediate call to SCNetworkServiceSetName. The
927 // trick here is that if no name has previously been set, the
928 // "get" function will return the name of the associated interface.
930 // ... and we "set" a name to ensure that applications that do
931 // not use the APIs will still find a UserDefinedName property
932 // in the SCDynamicStore.
934 interface_name
= SCNetworkServiceGetName((SCNetworkServiceRef
)servicePrivate
);
935 if (interface_name
!= NULL
) {
936 (void) SCNetworkServiceSetName((SCNetworkServiceRef
)servicePrivate
,
940 return (SCNetworkServiceRef
)servicePrivate
;
945 SCNetworkServiceEstablishDefaultConfiguration(SCNetworkServiceRef service
)
948 SCNetworkInterfaceRef interface
;
950 CFArrayRef protocolTypes
;
951 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
953 if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs
== NULL
)) {
954 _SCErrorSet(kSCStatusInvalidArgument
);
958 interface
= SCNetworkServiceGetInterface(service
);
959 if (interface
== NULL
) {
963 protocolTypes
= SCNetworkInterfaceGetSupportedProtocolTypes(interface
);
964 n
= (protocolTypes
!= NULL
) ? CFArrayGetCount(protocolTypes
) : 0;
965 for (i
= 0; i
< n
; i
++) {
967 CFDictionaryRef newEntity
= NULL
;
969 SCNetworkProtocolRef protocol
= NULL
;
970 CFStringRef protocolType
;
972 protocolType
= CFArrayGetValueAtIndex(protocolTypes
, i
);
973 ok
= SCNetworkServiceAddProtocolType(service
, protocolType
);
974 if (!ok
&& (SCError() != kSCStatusKeyExists
)) {
975 // could not add protocol
979 protocol
= SCNetworkServiceCopyProtocol(service
, protocolType
);
980 if (protocol
== NULL
) {
981 // oops, somethings wrong (should never happen)
985 newEntity
= _protocolTemplate(service
, protocolType
);
986 ok
= SCNetworkProtocolSetConfiguration(protocol
, newEntity
);
988 // could not set default configuration
992 enabled
= !CFDictionaryContainsKey(newEntity
, kSCResvInactive
);
993 ok
= SCNetworkProtocolSetEnabled(protocol
, enabled
);
995 // could not enable/disable protocol
1001 if (newEntity
!= NULL
) CFRelease(newEntity
);
1002 if (protocol
!= NULL
) CFRelease(protocol
);
1010 SCNetworkServiceGetEnabled(SCNetworkServiceRef service
)
1014 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
1016 if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs
== NULL
)) {
1017 _SCErrorSet(kSCStatusInvalidArgument
);
1021 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
1022 servicePrivate
->serviceID
, // service
1024 enabled
= __getPrefsEnabled(servicePrivate
->prefs
, path
);
1031 SCNetworkInterfaceRef
1032 SCNetworkServiceGetInterface(SCNetworkServiceRef service
)
1034 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
1036 if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs
== NULL
)) {
1037 _SCErrorSet(kSCStatusInvalidArgument
);
1041 if (servicePrivate
->interface
== NULL
) {
1042 CFDictionaryRef entity
;
1045 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
1046 servicePrivate
->serviceID
, // service
1047 kSCEntNetInterface
); // entity
1048 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
1051 if (isA_CFDictionary(entity
)) {
1052 servicePrivate
->interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, entity
, service
);
1056 return servicePrivate
->interface
;
1061 SCNetworkServiceGetName(SCNetworkServiceRef service
)
1063 CFDictionaryRef entity
;
1064 SCNetworkInterfaceRef interface
;
1065 CFStringRef name
= NULL
;
1067 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
1068 Boolean useSystemInterfaces
= TRUE
;
1070 if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs
== NULL
)) {
1071 _SCErrorSet(kSCStatusInvalidArgument
);
1075 if (servicePrivate
->name
!= NULL
) {
1076 return servicePrivate
->name
;
1079 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
1080 servicePrivate
->serviceID
, // service
1082 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
1085 useSystemInterfaces
= ((__SCPreferencesUsingDefaultPrefs(servicePrivate
->prefs
)) &&
1086 (__SCPreferencesGetLimitSCNetworkConfiguration(servicePrivate
->prefs
) == FALSE
));
1088 if (isA_CFDictionary(entity
)) {
1089 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
1090 if (isA_CFString(name
)) {
1091 servicePrivate
->name
= CFRetain(name
);
1092 if (useSystemInterfaces
== FALSE
) {
1093 return servicePrivate
->name
;
1098 interface
= SCNetworkServiceGetInterface(service
);
1099 while (interface
!= NULL
) {
1100 SCNetworkInterfaceRef childInterface
;
1101 CFStringRef interfaceType
;
1103 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1104 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
1108 childInterface
= SCNetworkInterfaceGetInterface(interface
);
1109 if ((childInterface
== NULL
) ||
1110 CFEqual(childInterface
, kSCNetworkInterfaceIPv4
)) {
1114 interface
= childInterface
;
1117 if (interface
!= NULL
) {
1119 CFStringRef interface_name
= NULL
;
1120 CFStringRef suffix
= NULL
;
1123 // check if the [stored] service name matches the non-localized interface
1124 // name. If so, return the localized name.
1126 // Also, the older "Built-in XXX" interface names are too long for the
1127 // current UI. If we find that the [stored] service name matches the older
1128 // name, return the newer (and shorter) localized name.
1130 // Note: the user/admin will no longer be able to set the service name
1131 // to "Built-in Ethernet".
1133 for (i
= 0; i
< 3; i
++) {
1134 if (servicePrivate
->name
== NULL
) {
1135 // if no [stored] service name to compare
1141 // compare the non-localized interface name
1142 interface_name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
1143 if (interface_name
!= NULL
) {
1144 CFRetain(interface_name
);
1147 #if !TARGET_OS_IPHONE
1149 // compare the older "Built-in XXX" localized name
1150 interface_name
= __SCNetworkInterfaceCopyXLocalizedDisplayName(interface
);
1153 // compare the older "Built-in XXX" non-localized name
1154 interface_name
= __SCNetworkInterfaceCopyXNonLocalizedDisplayName(interface
);
1156 #endif // !TARGET_OS_IPHONE
1161 if (interface_name
!= NULL
) {
1162 Boolean match
= FALSE
;
1164 if (CFEqual(name
, interface_name
)) {
1165 // if service name matches the OLD localized
1168 } else if (CFStringHasPrefix(name
, interface_name
)) {
1169 CFIndex prefixLen
= CFStringGetLength(interface_name
);
1170 CFIndex suffixLen
= CFStringGetLength(name
);
1172 suffix
= CFStringCreateWithSubstring(NULL
,
1174 CFRangeMake(prefixLen
, suffixLen
- prefixLen
));
1177 CFRelease(interface_name
);
1180 CFRelease(servicePrivate
->name
);
1181 servicePrivate
->name
= NULL
;
1188 // if the service name has not been set, use the localized interface name
1190 if (servicePrivate
->name
== NULL
) {
1191 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
1192 if (interface_name
!= NULL
) {
1193 if (suffix
!= NULL
) {
1194 servicePrivate
->name
= CFStringCreateWithFormat(NULL
,
1200 servicePrivate
->name
= CFRetain(interface_name
);
1204 if (suffix
!= NULL
) CFRelease(suffix
);
1207 return servicePrivate
->name
;
1212 SCNetworkServiceGetServiceID(SCNetworkServiceRef service
)
1214 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
1216 if (!isA_SCNetworkService(service
)) {
1217 _SCErrorSet(kSCStatusInvalidArgument
);
1221 return servicePrivate
->serviceID
;
1226 SCNetworkServiceGetTypeID(void)
1228 pthread_once(&initialized
, __SCNetworkServiceInitialize
); /* initialize runtime */
1229 return __kSCNetworkServiceTypeID
;
1234 SCNetworkServiceRemove(SCNetworkServiceRef service
)
1238 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
1241 if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs
== NULL
)) {
1242 _SCErrorSet(kSCStatusInvalidArgument
);
1246 // remove service from all sets
1248 sets
= SCNetworkSetCopyAll(servicePrivate
->prefs
);
1253 n
= CFArrayGetCount(sets
);
1254 for (i
= 0; i
< n
; i
++) {
1255 SCNetworkSetRef set
;
1257 set
= CFArrayGetValueAtIndex(sets
, i
);
1258 ok
= SCNetworkSetRemoveService(set
, service
);
1259 if (!ok
&& (SCError() != kSCStatusNoKey
)) {
1269 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
1270 servicePrivate
->serviceID
, // service
1272 ok
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
);
1280 SCNetworkServiceRemoveProtocolType(SCNetworkServiceRef service
, CFStringRef protocolType
)
1282 CFDictionaryRef entity
;
1285 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
1287 if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs
== NULL
)) {
1288 _SCErrorSet(kSCStatusInvalidArgument
);
1292 if (!__SCNetworkProtocolIsValidType(protocolType
)) {
1293 _SCErrorSet(kSCStatusInvalidArgument
);
1297 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
1298 servicePrivate
->serviceID
, // service
1299 protocolType
); // entity
1301 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
1302 if (entity
== NULL
) {
1303 // if "protocol" does not exist
1304 _SCErrorSet(kSCStatusNoKey
);
1308 ok
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
);
1318 SCNetworkServiceSetEnabled(SCNetworkServiceRef service
, Boolean enabled
)
1322 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
1324 if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs
== NULL
)) {
1325 _SCErrorSet(kSCStatusInvalidArgument
);
1329 // make sure that we do not enable a network service if the
1330 // associated interface is a member of a bond or bridge.
1332 SCNetworkInterfaceRef interface
;
1334 interface
= SCNetworkServiceGetInterface(service
);
1335 if ((interface
!= NULL
) &&
1336 __SCNetworkInterfaceIsMember(servicePrivate
->prefs
, interface
)) {
1337 _SCErrorSet(kSCStatusKeyExists
);
1342 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
1343 servicePrivate
->serviceID
, // service
1345 ok
= __setPrefsEnabled(servicePrivate
->prefs
, path
, enabled
);
1353 SCNetworkServiceSetName(SCNetworkServiceRef service
, CFStringRef name
)
1355 CFDictionaryRef entity
;
1358 CFStringRef saveName
= NULL
;
1359 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
1361 if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs
== NULL
)) {
1362 _SCErrorSet(kSCStatusInvalidArgument
);
1367 if (!isA_CFString(name
)) {
1368 _SCErrorSet(kSCStatusInvalidArgument
);
1371 saveName
= CFRetain(name
);
1375 SCNetworkInterfaceRef interface
;
1377 interface
= SCNetworkServiceGetInterface(service
);
1378 while (interface
!= NULL
) {
1379 SCNetworkInterfaceRef childInterface
;
1381 childInterface
= SCNetworkInterfaceGetInterface(interface
);
1382 if (childInterface
== NULL
) {
1386 interface
= childInterface
;
1389 if (interface
!= NULL
) {
1390 CFStringRef interface_name
;
1392 interface_name
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
1393 if (interface_name
!= NULL
) {
1394 if (CFEqual(name
, interface_name
)) {
1395 // if service name matches the localized interface name
1396 // then store the non-localized name.
1397 interface_name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
1398 if (interface_name
!= NULL
) {
1399 CFRelease(saveName
);
1400 saveName
= CFRetain(interface_name
);
1402 } else if (CFStringHasPrefix(name
, interface_name
)) {
1403 CFIndex prefixLen
= CFStringGetLength(interface_name
);
1405 CFIndex suffixLen
= CFStringGetLength(name
);
1407 // if service name matches the localized interface name plus
1408 // a few extra characters) then store the non-localized name with
1410 suffix
= CFStringCreateWithSubstring(NULL
,
1412 CFRangeMake(prefixLen
, suffixLen
- prefixLen
));
1413 interface_name
= __SCNetworkInterfaceGetNonLocalizedDisplayName(interface
);
1414 if (interface_name
!= NULL
) {
1415 CFRelease(saveName
);
1416 saveName
= CFStringCreateWithFormat(NULL
,
1428 #define PREVENT_DUPLICATE_SERVICE_NAMES
1429 #ifdef PREVENT_DUPLICATE_SERVICE_NAMES
1433 // ensure that each service is uniquely named within its sets
1435 sets
= SCNetworkSetCopyAll(servicePrivate
->prefs
);
1440 set_count
= CFArrayGetCount(sets
);
1441 for (set_index
= 0; set_index
< set_count
; set_index
++) {
1442 CFIndex service_index
;
1443 Boolean isDup
= FALSE
;
1444 Boolean isMember
= FALSE
;
1445 CFIndex service_count
;
1446 CFArrayRef services
;
1447 SCNetworkSetRef set
= CFArrayGetValueAtIndex(sets
, set_index
);
1449 services
= SCNetworkSetCopyServices(set
);
1451 service_count
= CFArrayGetCount(services
);
1452 for (service_index
= 0; service_index
< service_count
; service_index
++) {
1453 CFStringRef otherID
;
1454 CFStringRef otherName
;
1455 SCNetworkServiceRef otherService
;
1457 otherService
= CFArrayGetValueAtIndex(services
, service_index
);
1459 otherID
= SCNetworkServiceGetServiceID(otherService
);
1460 if (CFEqual(servicePrivate
->serviceID
, otherID
)) {
1461 // if the service is a member of this set
1466 otherName
= SCNetworkServiceGetName(otherService
);
1467 if ((otherName
!= NULL
) && CFEqual(name
, otherName
)) {
1473 CFRelease(services
);
1475 if (isMember
&& isDup
) {
1477 * if this service is a member of the set and
1478 * the "name" is not unique.
1481 if (saveName
!= NULL
) CFRelease(saveName
);
1482 _SCErrorSet(kSCStatusKeyExists
);
1490 #endif /* PREVENT_DUPLICATE_SERVICE_NAMES */
1492 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
1493 servicePrivate
->serviceID
, // service
1495 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
1496 if (isA_CFDictionary(entity
) ||
1497 ((entity
== NULL
) && (name
!= NULL
))) {
1498 CFMutableDictionaryRef newEntity
;
1500 if (entity
!= NULL
) {
1501 newEntity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1503 newEntity
= CFDictionaryCreateMutable(NULL
,
1505 &kCFTypeDictionaryKeyCallBacks
,
1506 &kCFTypeDictionaryValueCallBacks
);
1508 if (saveName
!= NULL
) {
1509 CFDictionarySetValue(newEntity
, kSCPropUserDefinedName
, saveName
);
1511 CFDictionaryRemoveValue(newEntity
, kSCPropUserDefinedName
);
1513 ok
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
);
1514 CFRelease(newEntity
);
1517 if (saveName
!= NULL
) CFRelease(saveName
);
1519 if (servicePrivate
->name
!= NULL
) CFRelease(servicePrivate
->name
);
1520 if (name
!= NULL
) CFRetain(name
);
1521 servicePrivate
->name
= name
;
1528 #pragma mark SCNetworkService SPIs
1531 SCNetworkServicePrimaryRank
1532 SCNetworkServiceGetPrimaryRank(SCNetworkServiceRef service
)
1534 CFDictionaryRef entity
;
1537 SCNetworkServicePrimaryRank rank
= kSCNetworkServicePrimaryRankDefault
;
1538 CFStringRef rankStr
= NULL
;
1539 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
1541 if (!isA_SCNetworkService(service
)) {
1542 _SCErrorSet(kSCStatusInvalidArgument
);
1546 if (servicePrivate
->prefs
!= NULL
) {
1547 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
1548 servicePrivate
->serviceID
,
1550 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
1552 if (isA_CFDictionary(entity
)) {
1553 rankStr
= CFDictionaryGetValue(entity
, kSCPropNetServicePrimaryRank
);
1554 ok
= __str_to_rank(rankStr
, &rank
);
1556 } else if (servicePrivate
->store
!= NULL
) {
1557 path
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
,
1558 kSCDynamicStoreDomainState
,
1559 servicePrivate
->serviceID
,
1561 entity
= SCDynamicStoreCopyValue(servicePrivate
->store
, path
);
1563 if (entity
!= NULL
) {
1564 if (isA_CFDictionary(entity
)) {
1565 rankStr
= CFDictionaryGetValue(entity
, kSCPropNetServicePrimaryRank
);
1566 ok
= __str_to_rank(rankStr
, &rank
);
1571 _SCErrorSet(kSCStatusInvalidArgument
);
1576 rank
= kSCNetworkServicePrimaryRankDefault
;
1577 _SCErrorSet(kSCStatusInvalidArgument
);
1578 } else if (rank
== kSCNetworkServicePrimaryRankDefault
) {
1579 _SCErrorSet(kSCStatusOK
);
1587 SCNetworkServiceSetPrimaryRank(SCNetworkServiceRef service
,
1588 SCNetworkServicePrimaryRank newRank
)
1591 CFDictionaryRef entity
;
1592 CFMutableDictionaryRef newEntity
;
1593 CFStringRef path
= NULL
;
1594 CFStringRef rankStr
= NULL
;
1595 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
1597 if (!isA_SCNetworkService(service
)) {
1598 _SCErrorSet(kSCStatusInvalidArgument
);
1602 ok
= __rank_to_str(newRank
, &rankStr
);
1604 _SCErrorSet(kSCStatusInvalidArgument
);
1608 if (servicePrivate
->prefs
!= NULL
) {
1610 case kSCNetworkServicePrimaryRankDefault
:
1611 case kSCNetworkServicePrimaryRankNever
:
1612 case kSCNetworkServicePrimaryRankScoped
:
1613 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
1614 servicePrivate
->serviceID
,
1616 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
1617 if (entity
!= NULL
) {
1618 if (!isA_CFDictionary(entity
)) {
1620 _SCErrorSet(kSCStatusFailed
);
1623 newEntity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1625 newEntity
= CFDictionaryCreateMutable(NULL
,
1627 &kCFTypeDictionaryKeyCallBacks
,
1628 &kCFTypeDictionaryValueCallBacks
);
1630 if (rankStr
!= NULL
) {
1631 CFDictionarySetValue(newEntity
, kSCPropNetServicePrimaryRank
, rankStr
);
1633 CFDictionaryRemoveValue(newEntity
, kSCPropNetServicePrimaryRank
);
1635 if (CFDictionaryGetCount(newEntity
) > 0) {
1636 ok
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
);
1638 ok
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
);
1640 CFRelease(newEntity
);
1646 _SCErrorSet(kSCStatusInvalidArgument
);
1649 } else if (servicePrivate
->store
!= NULL
) {
1650 path
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
,
1651 kSCDynamicStoreDomainState
,
1652 servicePrivate
->serviceID
,
1654 entity
= SCDynamicStoreCopyValue(servicePrivate
->store
, path
);
1655 if (entity
!= NULL
) {
1656 if (!isA_CFDictionary(entity
)) {
1659 _SCErrorSet(kSCStatusFailed
);
1662 newEntity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
1665 newEntity
= CFDictionaryCreateMutable(NULL
,
1667 &kCFTypeDictionaryKeyCallBacks
,
1668 &kCFTypeDictionaryValueCallBacks
);
1670 if (rankStr
!= NULL
) {
1671 CFDictionarySetValue(newEntity
, kSCPropNetServicePrimaryRank
, rankStr
);
1673 CFDictionaryRemoveValue(newEntity
, kSCPropNetServicePrimaryRank
);
1675 if (CFDictionaryGetCount(newEntity
) > 0) {
1676 ok
= SCDynamicStoreSetValue(servicePrivate
->store
, path
, newEntity
);
1678 ok
= SCDynamicStoreRemoveValue(servicePrivate
->store
, path
);
1680 CFRelease(newEntity
);
1685 _SCErrorSet(kSCStatusInvalidArgument
);
1691 if (path
!= NULL
) CFRelease(path
);
1697 _SCNetworkServiceIsVPN(SCNetworkServiceRef service
)
1699 SCNetworkInterfaceRef interface
;
1700 CFStringRef interfaceType
;
1702 interface
= SCNetworkServiceGetInterface(service
);
1703 if (interface
== NULL
) {
1707 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1708 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
1709 interface
= SCNetworkInterfaceGetInterface(interface
);
1710 if (interface
== NULL
) {
1714 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
1715 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
1718 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPTP
)) {
1721 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeVPN
)) {
1723 } else if (CFEqual(interfaceType
, kSCNetworkInterfaceTypeIPSec
)) {
1732 SCNetworkServiceSetExternalID(SCNetworkServiceRef service
, CFStringRef identifierDomain
, CFStringRef identifier
)
1734 CFStringRef prefs_path
;
1735 CFDictionaryRef service_dictionary
;
1736 SCNetworkServicePrivateRef service_private
= (SCNetworkServicePrivateRef
)service
;
1737 Boolean success
= FALSE
;
1738 CFStringRef prefixed_domain
;
1740 if (!isA_SCNetworkService(service
) || (service_private
->prefs
== NULL
) || !isA_CFString(identifierDomain
)) {
1741 _SCErrorSet(kSCStatusInvalidArgument
);
1745 if (identifier
!= NULL
&& !isA_CFString(identifier
)) {
1746 _SCErrorSet(kSCStatusInvalidArgument
);
1750 prefixed_domain
= CFStringCreateWithFormat(NULL
, 0, CFSTR("%s%@"), EXTERNAL_ID_DOMAIN_PREFIX
, identifierDomain
);
1752 prefs_path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
1753 service_private
->serviceID
,
1756 service_dictionary
= SCPreferencesPathGetValue(service_private
->prefs
, prefs_path
);
1757 if (isA_CFDictionary(service_dictionary
) || ((service_dictionary
== NULL
) && (identifier
!= NULL
))) {
1758 CFMutableDictionaryRef new_service_dictionary
;
1760 if (service_dictionary
!= NULL
) {
1761 new_service_dictionary
= CFDictionaryCreateMutableCopy(NULL
, 0, service_dictionary
);
1763 new_service_dictionary
= CFDictionaryCreateMutable(NULL
,
1765 &kCFTypeDictionaryKeyCallBacks
,
1766 &kCFTypeDictionaryValueCallBacks
);
1769 if (identifier
!= NULL
) {
1770 CFDictionarySetValue(new_service_dictionary
, prefixed_domain
, identifier
);
1772 CFDictionaryRemoveValue(new_service_dictionary
, prefixed_domain
);
1774 success
= SCPreferencesPathSetValue(service_private
->prefs
, prefs_path
, new_service_dictionary
);
1775 CFRelease(new_service_dictionary
);
1777 CFRelease(prefs_path
);
1779 if (identifier
!= NULL
) {
1780 if (service_private
->externalIDs
== NULL
) {
1781 service_private
->externalIDs
= CFDictionaryCreateMutable(NULL
,
1783 &kCFTypeDictionaryKeyCallBacks
,
1784 &kCFTypeDictionaryValueCallBacks
);
1786 CFDictionarySetValue(service_private
->externalIDs
, prefixed_domain
, identifier
);
1788 if (service_private
->externalIDs
!= NULL
) {
1789 CFDictionaryRemoveValue(service_private
->externalIDs
, prefixed_domain
);
1793 CFRelease(prefixed_domain
);
1796 _SCErrorSet(kSCStatusFailed
);
1804 SCNetworkServiceCopyExternalID(SCNetworkServiceRef service
, CFStringRef identifierDomain
)
1806 SCNetworkServicePrivateRef service_private
= (SCNetworkServicePrivateRef
)service
;
1807 CFStringRef identifier
= NULL
;
1808 CFStringRef prefixed_domain
;
1810 if (!isA_SCNetworkService(service
) || (service_private
->prefs
== NULL
) || !isA_CFString(identifierDomain
)) {
1811 _SCErrorSet(kSCStatusInvalidArgument
);
1815 prefixed_domain
= CFStringCreateWithFormat(NULL
, 0, CFSTR("%s%@"), EXTERNAL_ID_DOMAIN_PREFIX
, identifierDomain
);
1817 if (service_private
->externalIDs
!= NULL
) {
1818 identifier
= CFDictionaryGetValue(service_private
->externalIDs
, prefixed_domain
);
1819 if (identifier
!= NULL
) {
1820 CFRetain(identifier
);
1824 if (identifier
== NULL
) {
1825 CFStringRef prefs_path
;
1826 CFDictionaryRef service_dictionary
;
1828 prefs_path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
,
1829 service_private
->serviceID
,
1832 service_dictionary
= SCPreferencesPathGetValue(service_private
->prefs
, prefs_path
);
1833 if (isA_CFDictionary(service_dictionary
)) {
1834 identifier
= CFDictionaryGetValue(service_dictionary
, prefixed_domain
);
1835 if (identifier
!= NULL
) {
1836 CFRetain(identifier
);
1837 if (service_private
->externalIDs
== NULL
) {
1838 service_private
->externalIDs
= CFDictionaryCreateMutable(NULL
,
1840 &kCFTypeDictionaryKeyCallBacks
,
1841 &kCFTypeDictionaryValueCallBacks
);
1843 CFDictionarySetValue(service_private
->externalIDs
, prefixed_domain
, identifier
);
1846 CFRelease(prefs_path
);
1849 CFRelease(prefixed_domain
);
1851 if (identifier
== NULL
) {
1852 _SCErrorSet(kSCStatusNoKey
);
1860 CFStringRef oldServiceID
;
1861 CFStringRef newServiceID
;
1862 } serviceContext
, *serviceContextRef
;
1866 replaceServiceID(const void *value
, void *context
)
1868 CFStringRef link
= NULL
;
1869 CFStringRef oldLink
;
1870 CFMutableArrayRef newServiceOrder
;
1872 serviceContextRef service_context
= (serviceContextRef
)context
;
1873 CFArrayRef serviceOrder
= NULL
;
1874 SCNetworkSetRef set
= (SCNetworkSetRef
)value
;
1875 SCNetworkSetPrivateRef setPrivate
= (SCNetworkSetPrivateRef
)set
;
1877 // update service order
1878 serviceOrder
= SCNetworkSetGetServiceOrder(set
);
1879 if ((isA_CFArray(serviceOrder
) != NULL
) &&
1880 (CFArrayContainsValue(serviceOrder
,
1881 CFRangeMake(0, CFArrayGetCount(serviceOrder
)),
1882 service_context
->oldServiceID
) == TRUE
)) {
1884 CFIndex serviceOrderIndex
;
1886 // replacing all instances of old service ID with new one
1887 newServiceOrder
= CFArrayCreateMutableCopy(NULL
, 0, serviceOrder
);
1888 count
= CFArrayGetCount(newServiceOrder
);
1889 for (serviceOrderIndex
= 0; serviceOrderIndex
< count
; serviceOrderIndex
++) {
1890 CFStringRef serviceID
;
1892 serviceID
= CFArrayGetValueAtIndex(newServiceOrder
, serviceOrderIndex
);
1893 if (CFEqual(serviceID
, service_context
->oldServiceID
)) {
1894 CFArraySetValueAtIndex(newServiceOrder
, serviceOrderIndex
, service_context
->newServiceID
);
1897 SCNetworkSetSetServiceOrder(set
, newServiceOrder
);
1898 CFRelease(newServiceOrder
);
1901 // check if service with old serviceID is part of the set
1902 path
= SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL
, // allocator
1903 setPrivate
->setID
, // set
1904 service_context
->oldServiceID
, // service
1906 oldLink
= SCPreferencesPathGetLink(setPrivate
->prefs
, path
);
1907 if (oldLink
== NULL
) {
1908 // don't make any changes if service with old serviceID is not found
1912 // remove link between "set" and old "service"
1913 SCPreferencesPathRemoveValue(setPrivate
->prefs
, path
);
1916 // create the link between "set" and the "service"
1917 path
= SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL
, // allocator
1918 setPrivate
->setID
, // set
1919 service_context
->newServiceID
, // service
1921 link
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
1922 service_context
->newServiceID
, // service
1924 SCPreferencesPathSetLink(setPrivate
->prefs
, path
, link
);
1940 _SCNetworkServiceSetServiceID(SCNetworkServiceRef service
, CFStringRef newServiceID
)
1942 CFArrayRef allSets
= NULL
;
1943 CFDictionaryRef entity
;
1944 CFStringRef newPath
;
1946 CFStringRef oldPath
= NULL
;
1947 serviceContext service_context
;
1948 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
1950 if (!isA_SCNetworkService(service
) || (servicePrivate
->prefs
== NULL
)) {
1951 _SCErrorSet(kSCStatusInvalidArgument
);
1955 if (!isA_CFString(newServiceID
)) {
1956 _SCErrorSet(kSCStatusInvalidArgument
);
1960 if (CFEqual(newServiceID
, servicePrivate
->serviceID
)) {
1961 // no work needs to be done if new service ID is equal to current service ID
1965 newPath
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
1966 newServiceID
, // service
1968 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, newPath
);
1969 if (isA_CFDictionary(entity
)) {
1970 // if the new service already exists
1971 _SCErrorSet(kSCStatusKeyExists
);
1975 oldPath
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
1976 servicePrivate
->serviceID
, // service
1978 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, oldPath
);
1979 if (!isA_CFDictionary(entity
)) {
1980 // if the service has already been removed
1981 _SCErrorSet(kSCStatusNoKey
);
1985 ok
= SCPreferencesPathSetValue(servicePrivate
->prefs
, newPath
, entity
);
1988 ok
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, oldPath
);
1991 allSets
= SCNetworkSetCopyAll(servicePrivate
->prefs
);
1993 service_context
.newServiceID
= newServiceID
;
1994 service_context
.oldServiceID
= servicePrivate
->serviceID
;
1996 // find all sets w/oldServiceID and update
1997 // ... and update the serviceOrder
1998 CFArrayApplyFunction(allSets
,
1999 CFRangeMake(0, CFArrayGetCount(allSets
)),
2003 if (servicePrivate
->interface
!= NULL
) {
2004 SCNetworkInterfaceRef newInterface
;
2006 // duplicate the interface and associate the copy with the new service ID
2007 newInterface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
,
2008 servicePrivate
->interface
,
2009 servicePrivate
->prefs
,
2011 CFRelease(servicePrivate
->interface
);
2012 servicePrivate
->interface
= newInterface
;
2015 // replace serviceID with new one
2016 CFRetain(newServiceID
);
2017 CFRelease(servicePrivate
->serviceID
);
2018 servicePrivate
->serviceID
= newServiceID
;
2022 if (oldPath
!= NULL
) {
2025 if (newPath
!= NULL
) {
2028 if (allSets
!= NULL
) {
2034 #define kVPNProtocolPayloadInfo CFSTR("com.apple.payload")
2035 #define kSCEntNetLoginWindowEAPOL CFSTR("EAPOL.LoginWindow")
2038 copyInterfaceConfiguration(SCNetworkServiceRef oldService
, SCNetworkServiceRef newService
)
2040 SCNetworkInterfaceRef oldInterface
;
2041 SCNetworkInterfaceRef newInterface
;
2043 oldInterface
= SCNetworkServiceGetInterface(oldService
);
2044 newInterface
= SCNetworkServiceGetInterface(newService
);
2046 while (oldInterface
!= NULL
) {
2047 CFDictionaryRef configuration
;
2048 CFStringRef interfaceType
;
2050 if (newInterface
== NULL
) {
2051 // oops ... interface layering does not match
2055 // copy interface configuration
2056 configuration
= SCNetworkInterfaceGetConfiguration(oldInterface
);
2058 if ((configuration
!= NULL
) ||
2059 (SCError() == kSCStatusOK
)) {
2060 if (SCNetworkInterfaceSetConfiguration(newInterface
, configuration
) == FALSE
) {
2061 SCLog(_sc_debug
, LOG_DEBUG
, CFSTR("problem setting interface configuration"));
2066 // special case: PPP/L2TP + IPSec
2067 interfaceType
= SCNetworkInterfaceGetInterfaceType(oldInterface
);
2068 if (CFEqual(interfaceType
, kSCNetworkInterfaceTypePPP
)) {
2069 SCNetworkInterfaceRef childInterface
;
2071 childInterface
= SCNetworkInterfaceGetInterface(oldInterface
);
2072 if (childInterface
!= NULL
) {
2073 CFStringRef childInterfaceType
;
2075 childInterfaceType
= SCNetworkInterfaceGetInterfaceType(childInterface
);
2077 if (CFEqual(childInterfaceType
, kSCNetworkInterfaceTypeL2TP
)) {
2078 configuration
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCEntNetIPSec
);
2079 if ((configuration
!= NULL
) ||
2080 (SCError() == kSCStatusOK
)) {
2081 if (SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCEntNetIPSec
, configuration
) == FALSE
) {
2082 SCLog(_sc_debug
, LOG_DEBUG
, CFSTR("problem setting child interface configuration"));
2089 // special case: 802.1x
2090 configuration
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCEntNetEAPOL
);
2091 if ((configuration
!= NULL
) ||
2092 (SCError() == kSCStatusOK
)) {
2093 (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCEntNetEAPOL
, configuration
);
2096 // special case: Managed Client
2097 configuration
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kVPNProtocolPayloadInfo
);
2098 if ((configuration
!= NULL
) ||
2099 (SCError() == kSCStatusOK
)) {
2100 (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kVPNProtocolPayloadInfo
, configuration
);
2103 // special case: Network Pref
2104 configuration
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCValNetPPPAuthProtocolEAP
);
2105 if ((configuration
!= NULL
) ||
2106 (SCError() == kSCStatusOK
)) {
2107 (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCValNetPPPAuthProtocolEAP
, configuration
);
2110 // special case: Remote Pref
2111 configuration
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCEntNetLoginWindowEAPOL
);
2112 if ((configuration
!= NULL
) ||
2113 (SCError() == kSCStatusOK
)) {
2114 (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCEntNetLoginWindowEAPOL
, configuration
);
2117 // special case: Network Extension
2118 configuration
= SCNetworkInterfaceGetExtendedConfiguration(oldInterface
, kSCNetworkInterfaceTypeIPSec
);
2119 if ((configuration
!= NULL
) ||
2120 (SCError() == kSCStatusOK
)) {
2121 (void) SCNetworkInterfaceSetExtendedConfiguration(newInterface
, kSCNetworkInterfaceTypeIPSec
, configuration
);
2124 oldInterface
= SCNetworkInterfaceGetInterface(oldInterface
);
2125 newInterface
= SCNetworkInterfaceGetInterface(newInterface
);
2132 addProtocolToService(SCNetworkServiceRef service
, CFStringRef protocolType
, CFDictionaryRef configuration
, Boolean enabled
)
2135 SCNetworkProtocolRef protocol
;
2137 protocol
= SCNetworkServiceCopyProtocol(service
, protocolType
);
2139 if ((protocol
== NULL
) &&
2140 (SCError() == kSCStatusNoKey
)) {
2141 ok
= SCNetworkServiceAddProtocolType(service
, protocolType
);
2143 protocol
= SCNetworkServiceCopyProtocol(service
, protocolType
);
2146 if (protocol
!= NULL
) {
2147 SCNetworkProtocolSetConfiguration(protocol
, configuration
);
2148 SCNetworkProtocolSetEnabled(protocol
, enabled
);
2149 CFRelease(protocol
);
2158 __SCNetworkServiceMigrateNew(SCPreferencesRef prefs
,
2159 SCNetworkServiceRef service
,
2160 CFDictionaryRef bsdMapping
,
2161 CFDictionaryRef setMapping
,
2162 CFDictionaryRef serviceSetMapping
)
2164 CFStringRef deviceName
= NULL
;
2166 SCNetworkInterfaceRef interface
= NULL
;
2167 CFDictionaryRef interfaceEntity
= NULL
;
2168 CFMutableDictionaryRef interfaceEntityMutable
= NULL
;
2169 SCNetworkSetRef newSet
= NULL
;
2170 SCPreferencesRef ni_prefs
= NULL
;
2171 SCNetworkInterfaceRef ni_interface
= NULL
;
2172 SCNetworkInterfaceRef oldInterface
= NULL
;
2173 SCNetworkSetRef oldSet
= NULL
;
2174 SCNetworkServiceRef newService
= NULL
;
2175 CFStringRef serviceID
= NULL
;
2176 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
) service
;
2177 CFMutableDictionaryRef servicesMutable
= NULL
;
2178 CFArrayRef setList
= NULL
;
2179 Boolean success
= FALSE
;
2180 CFStringRef targetDeviceName
= NULL
;
2181 CFStringRef userDefinedName
= NULL
;
2182 CFStringRef userDefinedNameInterface
= NULL
;
2183 CFArrayRef protocols
= NULL
;
2184 CFStringRef subType
;
2186 if ((isA_SCNetworkService(service
) == NULL
) ||
2187 (isA_SCNetworkInterface(servicePrivate
->interface
) == NULL
) ||
2188 (servicePrivate
->prefs
== NULL
)) {
2191 serviceID
= servicePrivate
->serviceID
;
2193 newService
= SCNetworkServiceCopy(prefs
, serviceID
);
2194 if (newService
!= NULL
) {
2195 // Cannot add service if it already exists
2196 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkServiceMigrateNew: Cannot add service if it already exists."));
2200 oldInterface
= SCNetworkServiceGetInterface(service
);
2201 interfaceEntity
= __SCNetworkInterfaceCopyInterfaceEntity(oldInterface
);
2202 if (interfaceEntity
== NULL
) {
2203 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkServiceMigrateNew: interfaceEntity does not exist"));
2206 interfaceEntityMutable
= CFDictionaryCreateMutableCopy(NULL
, 0, interfaceEntity
);
2207 CFRelease(interfaceEntity
);
2209 if (isA_CFDictionary(bsdMapping
) != NULL
) {
2210 deviceName
= CFDictionaryGetValue(interfaceEntityMutable
, kSCPropNetInterfaceDeviceName
);
2211 if (isA_CFString(deviceName
) != NULL
) {
2212 targetDeviceName
= CFDictionaryGetValue(bsdMapping
, deviceName
);
2213 if (targetDeviceName
!= NULL
) {
2215 CFDictionarySetValue(interfaceEntityMutable
, kSCPropNetInterfaceDeviceName
, targetDeviceName
);
2216 ni_prefs
= __SCPreferencesCreateNIPrefsFromPrefs(prefs
);
2217 ni_interface
= __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL
, ni_prefs
, targetDeviceName
);
2218 if (ni_interface
!= NULL
) {
2219 userDefinedNameInterface
= __SCNetworkInterfaceGetUserDefinedName(ni_interface
);
2223 if (userDefinedNameInterface
== NULL
) {
2224 userDefinedNameInterface
= CFDictionaryGetValue(interfaceEntityMutable
, kSCPropUserDefinedName
);
2227 subType
= CFDictionaryGetValue(interfaceEntityMutable
, kSCPropNetInterfaceSubType
);
2228 interface
= _SCNetworkInterfaceCreateWithEntity(NULL
, interfaceEntityMutable
, NULL
);
2229 if (userDefinedNameInterface
!= NULL
) {
2230 __SCNetworkInterfaceSetUserDefinedName(interface
, userDefinedNameInterface
);
2232 // Supporting PPPoE subtype
2233 if (subType
!= NULL
&&
2234 CFEqual(subType
, kSCValNetInterfaceSubTypePPPoE
)) {
2235 SCNetworkInterfaceRef childInterface
= SCNetworkInterfaceGetInterface(interface
);
2236 if (childInterface
!= NULL
) {
2237 __SCNetworkInterfaceSetUserDefinedName(childInterface
, userDefinedNameInterface
);
2240 newService
= SCNetworkServiceCreate(prefs
, interface
);
2242 if (newService
== NULL
) {
2243 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkServiceMigrateNew: Could not create new service"));
2247 enabled
= SCNetworkServiceGetEnabled(service
);
2248 SCNetworkServiceSetEnabled(newService
, enabled
);
2250 if (SCNetworkServiceEstablishDefaultConfiguration(newService
) == FALSE
) {
2251 SCNetworkServiceRemove(newService
);
2252 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkServiceMigrateNew: SCNetworkServiceEstablishDefaultConfiguration failed"));
2257 _SCNetworkServiceSetServiceID(newService
, serviceID
);
2259 userDefinedName
= SCNetworkServiceGetName(service
);
2260 if (userDefinedName
!= NULL
&&
2261 SCNetworkServiceSetName(newService
, userDefinedName
) == FALSE
) {
2262 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkServiceMigrateNew: Could not set service name to %@"), userDefinedName
);
2265 // Determine which sets to add service
2266 if (setMapping
!= NULL
&&
2267 serviceSetMapping
!= NULL
) {
2268 setList
= CFDictionaryGetValue(serviceSetMapping
, service
);
2269 if (setList
!= NULL
) {
2270 for (CFIndex idx
= 0; idx
< CFArrayGetCount(setList
); idx
++) {
2271 oldSet
= CFArrayGetValueAtIndex(setList
, idx
);
2272 newSet
= CFDictionaryGetValue(setMapping
, oldSet
);
2274 if (newSet
== NULL
) {
2277 if (SCNetworkSetAddService(newSet
, newService
) == FALSE
) {
2278 SCLog(_sc_debug
, LOG_DEBUG
, CFSTR("__SCNetworkServiceMigrateNew: Could not add service to set: %@"), newSet
);
2285 protocols
= SCNetworkServiceCopyProtocols(service
);
2286 if (protocols
!= NULL
) {
2288 for (CFIndex idx
= 0; idx
< CFArrayGetCount(protocols
); idx
++) {
2289 SCNetworkProtocolRef protocol
= CFArrayGetValueAtIndex(protocols
, idx
);
2290 CFDictionaryRef configuration
= SCNetworkProtocolGetConfiguration(protocol
);
2291 CFStringRef protocolType
= SCNetworkProtocolGetProtocolType(protocol
);
2292 enabled
= SCNetworkProtocolGetEnabled(protocol
);
2293 addProtocolToService(newService
, protocolType
, configuration
, enabled
);
2295 CFRelease(protocols
);
2298 copyInterfaceConfiguration(service
, newService
);
2302 if (interface
!= NULL
) {
2303 CFRelease(interface
);
2305 if (interfaceEntityMutable
!= NULL
) {
2306 CFRelease(interfaceEntityMutable
);
2308 if (newService
!= NULL
) {
2309 CFRelease(newService
);
2311 if (servicesMutable
!= NULL
) {
2312 CFRelease(servicesMutable
);
2314 if (ni_prefs
!= NULL
) {
2315 CFRelease(ni_prefs
);
2317 if (ni_interface
!= NULL
) {
2318 CFRelease(ni_interface
);
2326 __SCNetworkServiceCreate(SCPreferencesRef prefs
,
2327 SCNetworkInterfaceRef interface
,
2328 CFStringRef userDefinedName
)
2330 SCNetworkSetRef currentSet
= NULL
;
2332 SCNetworkServiceRef service
= NULL
;
2334 if (interface
== NULL
) {
2338 if (userDefinedName
== NULL
) {
2339 userDefinedName
= __SCNetworkInterfaceGetUserDefinedName(interface
);
2340 if (userDefinedName
== NULL
) {
2341 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkServiceCreate: userDefinedName is NULL"));
2345 service
= SCNetworkServiceCreate(prefs
, interface
);
2346 if (service
== NULL
) {
2347 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkServiceCreate: Failed to create service: %s"), SCErrorString(SCError()));
2349 ok
= SCNetworkServiceSetName(service
, userDefinedName
);
2351 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkServiceCreate: Failed to set name: %s"), SCErrorString(SCError()));
2352 SCNetworkServiceRemove(service
);
2356 ok
= SCNetworkServiceEstablishDefaultConfiguration(service
);
2358 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkServiceCreate: Failed to establish default configuration: %s"), SCErrorString(SCError()));
2359 SCNetworkServiceRemove(service
);
2363 currentSet
= SCNetworkSetCopyCurrent(prefs
);
2364 if (currentSet
== NULL
) {
2365 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkServiceCreate: Could not copy current set"));
2366 if (service
!= NULL
) {
2367 SCNetworkServiceRemove(service
);
2371 if (service
!= NULL
) {
2372 ok
= SCNetworkSetAddService(currentSet
, service
);
2374 SCLog(TRUE
, LOG_DEBUG
, CFSTR("__SCNetworkServiceCreate: Could not add service to the current set"));
2375 SCNetworkServiceRemove(service
);
2381 if (service
!= NULL
) {
2384 if (currentSet
!= NULL
) {
2385 CFRelease(currentSet
);