]> git.saurik.com Git - apple/configd.git/blobdiff - SystemConfiguration.fproj/SCNetworkProtocol.c
configd-1061.40.2.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCNetworkProtocol.c
index 1c6c73a4cd4a8f225e35970e978eac2d2c43efc7..d0cd41ea214e662dac5fb60e54c5c5025f80d169 100644 (file)
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004-2008, 2016-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreFoundation/CFRuntime.h>
-#include <SystemConfiguration/SystemConfiguration.h>
-#include <SystemConfiguration/SCNetworkConfigurationInternal.h>
-#include <SystemConfiguration/SCValidation.h>
-#include <SystemConfiguration/SCPrivate.h>
-
-#include "SCNetworkConfiguration.h"
 #include "SCNetworkConfigurationInternal.h"
 
 #include <pthread.h>
 static CFStringRef     __SCNetworkProtocolCopyDescription      (CFTypeRef cf);
 static void            __SCNetworkProtocolDeallocate           (CFTypeRef cf);
 static Boolean         __SCNetworkProtocolEqual                (CFTypeRef cf1, CFTypeRef cf2);
+static CFHashCode      __SCNetworkProtocolHash                 (CFTypeRef cf);
 
 
-const CFStringRef kSCNetworkProtocolTypeAppleTalk       = CFSTR("AppleTalk");
 const CFStringRef kSCNetworkProtocolTypeDNS            = CFSTR("DNS");
 const CFStringRef kSCNetworkProtocolTypeIPv4           = CFSTR("IPv4");
 const CFStringRef kSCNetworkProtocolTypeIPv6           = CFSTR("IPv6");
 const CFStringRef kSCNetworkProtocolTypeProxies                = CFSTR("Proxies");
+#if    !TARGET_OS_IPHONE
+const CFStringRef kSCNetworkProtocolTypeSMB            = CFSTR("SMB");
+#endif // !TARGET_OS_IPHONE
 
 
 static CFTypeID __kSCNetworkProtocolTypeID     = _kCFRuntimeNotATypeID;
@@ -64,7 +61,7 @@ static const CFRuntimeClass __SCNetworkProtocolClass = {
        NULL,                                   // copy
        __SCNetworkProtocolDeallocate,          // dealloc
        __SCNetworkProtocolEqual,               // equal
-       NULL,                                   // hash
+       __SCNetworkProtocolHash,                // hash
        NULL,                                   // copyFormattingDesc
        __SCNetworkProtocolCopyDescription      // copyDebugDesc
 };
@@ -73,13 +70,6 @@ static const CFRuntimeClass __SCNetworkProtocolClass = {
 static pthread_once_t          initialized     = PTHREAD_ONCE_INIT;
 
 
-static __inline__ CFTypeRef
-isA_SCNetworkProtocol(CFTypeRef obj)
-{
-       return (isA_CFType(obj, SCNetworkProtocolGetTypeID()));
-}
-
-
 static CFStringRef
 __SCNetworkProtocolCopyDescription(CFTypeRef cf)
 {
@@ -88,10 +78,13 @@ __SCNetworkProtocolCopyDescription(CFTypeRef cf)
        SCNetworkProtocolPrivateRef     protocolPrivate = (SCNetworkProtocolPrivateRef)cf;
 
        result = CFStringCreateMutable(allocator, 0);
-       CFStringAppendFormat(result, NULL, CFSTR("<SCNetworkProtocol %p [%p]> { "), cf, allocator);
-       CFStringAppendFormat(result, NULL, CFSTR("id=%@"), protocolPrivate->entityID);
-       CFStringAppendFormat(result, NULL, CFSTR(", service=%@"), protocolPrivate->service);
-       CFStringAppendFormat(result, NULL, CFSTR(" }"));
+       CFStringAppendFormat(result, NULL, CFSTR("<SCNetworkProtocol %p [%p]> {"), cf, allocator);
+       CFStringAppendFormat(result, NULL, CFSTR("id = %@"), protocolPrivate->entityID);
+       CFStringAppendFormat(result, NULL, CFSTR(", service = %p"), protocolPrivate->service);
+       CFStringAppendFormat(result, NULL,
+                            CFSTR(", prefs = %p"),
+                            ((SCNetworkServicePrivateRef)protocolPrivate->service)->prefs);
+       CFStringAppendFormat(result, NULL, CFSTR("}"));
 
        return result;
 }
@@ -104,6 +97,7 @@ __SCNetworkProtocolDeallocate(CFTypeRef cf)
 
        /* release resources */
        CFRelease(protocolPrivate->entityID);
+       CFRelease(protocolPrivate->service);
 
        return;
 }
@@ -122,15 +116,24 @@ __SCNetworkProtocolEqual(CFTypeRef cf1, CFTypeRef cf2)
                return FALSE;   // if not the same protocol type
 
        if (p1->service == p2->service)
-               return TRUE;    // if both point to the same service
+               return TRUE;    // if both point to the same service
 
        if ((p1->service != NULL) && (p2->service != NULL) && CFEqual(p1->service, p2->service))
-               return TRUE;    // if both effectively point to the same service
+               return TRUE;    // if both effectively point to the same service
 
        return FALSE;
 }
 
 
+static CFHashCode
+__SCNetworkProtocolHash(CFTypeRef cf)
+{
+       SCNetworkProtocolPrivateRef     protocolPrivate = (SCNetworkProtocolPrivateRef)cf;
+
+       return CFHash(protocolPrivate->entityID);
+}
+
+
 static void
 __SCNetworkProtocolInitialize(void)
 {
@@ -151,17 +154,18 @@ __SCNetworkProtocolCreatePrivate(CFAllocatorRef           allocator,
        pthread_once(&initialized, __SCNetworkProtocolInitialize);
 
        /* allocate target */
-       size           = sizeof(SCNetworkProtocolPrivate) - sizeof(CFRuntimeBase);
+       size            = sizeof(SCNetworkProtocolPrivate) - sizeof(CFRuntimeBase);
        protocolPrivate = (SCNetworkProtocolPrivateRef)_CFRuntimeCreateInstance(allocator,
-                                                                             __kSCNetworkProtocolTypeID,
-                                                                             size,
-                                                                             NULL);
+                                                                               __kSCNetworkProtocolTypeID,
+                                                                               size,
+                                                                               NULL);
        if (protocolPrivate == NULL) {
                return NULL;
        }
 
-       protocolPrivate->entityID       = CFStringCreateCopy(NULL, entityID);
-       protocolPrivate->service        = service;
+       /* initialize non-zero/NULL members */
+       protocolPrivate->entityID       = CFStringCreateCopy(NULL, entityID);
+       protocolPrivate->service        = CFRetain(service);
 
        return protocolPrivate;
 }
@@ -170,16 +174,17 @@ __SCNetworkProtocolCreatePrivate(CFAllocatorRef           allocator,
 __private_extern__ Boolean
 __SCNetworkProtocolIsValidType(CFStringRef protocolType)
 {
-       int                             i;
-       static const CFStringRef        *valid_types[]   = {
-               &kSCNetworkProtocolTypeAppleTalk,
+       static const CFStringRef        *valid_types[]  = {
                &kSCNetworkProtocolTypeDNS,
                &kSCNetworkProtocolTypeIPv4,
                &kSCNetworkProtocolTypeIPv6,
-               &kSCNetworkProtocolTypeProxies
+               &kSCNetworkProtocolTypeProxies,
+#if    !TARGET_OS_IPHONE
+               &kSCNetworkProtocolTypeSMB,
+#endif // !TARGET_OS_IPHONE
        };
 
-       for (i = 0; i < sizeof(valid_types)/sizeof(valid_types[0]); i++) {
+       for (size_t i = 0; i < sizeof(valid_types)/sizeof(valid_types[0]); i++) {
                if (CFEqual(protocolType, *valid_types[i])) {
                        // if known/valid protocol type
                        return TRUE;
@@ -203,17 +208,34 @@ static CFStringRef
 copyProtocolConfigurationPath(SCNetworkProtocolPrivateRef protocolPrivate)
 {
        CFStringRef                     path;
-       SCNetworkServicePrivateRef      servicePrivate;
+       SCNetworkServicePrivateRef      servicePrivate;
 
        servicePrivate = (SCNetworkServicePrivateRef)protocolPrivate->service;
        path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,                             // allocator
                                                              servicePrivate->serviceID,        // service
-                                                             protocolPrivate->entityID);       // entity
+                                                             protocolPrivate->entityID);       // entity
        return path;
 }
 
 
-/* ---------- SCNetworkProtocol APIs ---------- */
+#pragma mark -
+#pragma mark SCNetworkProtocol APIs
+
+
+CFComparisonResult
+_SCNetworkProtocolCompare(const void *val1, const void *val2, void *context)
+{
+#pragma unused(context)
+       SCNetworkProtocolRef    p1      = (SCNetworkProtocolRef)val1;
+       SCNetworkProtocolRef    p2      = (SCNetworkProtocolRef)val2;
+       CFStringRef             type1;
+       CFStringRef             type2;
+
+       type1 = SCNetworkProtocolGetProtocolType(p1);
+       type2 = SCNetworkProtocolGetProtocolType(p2);
+
+       return CFStringCompare(type1, type2, 0);
+}
 
 
 CFTypeID
@@ -230,8 +252,14 @@ SCNetworkProtocolGetConfiguration(SCNetworkProtocolRef protocol)
        CFDictionaryRef                 config;
        CFStringRef                     path;
        SCNetworkProtocolPrivateRef     protocolPrivate = (SCNetworkProtocolPrivateRef)protocol;
-       SCNetworkServicePrivateRef      servicePrivate  = (SCNetworkServicePrivateRef)protocolPrivate->service;
+       SCNetworkServicePrivateRef      servicePrivate;
+
+       if (!isA_SCNetworkProtocol(protocol)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
 
+       servicePrivate = (SCNetworkServicePrivateRef)protocolPrivate->service;
        path = copyProtocolConfigurationPath(protocolPrivate);
        config = __getPrefsConfiguration(servicePrivate->prefs, path);
        CFRelease(path);
@@ -246,8 +274,14 @@ SCNetworkProtocolGetEnabled(SCNetworkProtocolRef protocol)
        Boolean                         enabled;
        CFStringRef                     path;
        SCNetworkProtocolPrivateRef     protocolPrivate = (SCNetworkProtocolPrivateRef)protocol;
-       SCNetworkServicePrivateRef      servicePrivate  = (SCNetworkServicePrivateRef)protocolPrivate->service;
+       SCNetworkServicePrivateRef      servicePrivate;
 
+       if (!isA_SCNetworkProtocol(protocol)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       servicePrivate = (SCNetworkServicePrivateRef)protocolPrivate->service;
        path = copyProtocolConfigurationPath(protocolPrivate);
        enabled = __getPrefsEnabled(servicePrivate->prefs, path);
        CFRelease(path);
@@ -261,6 +295,11 @@ SCNetworkProtocolGetProtocolType(SCNetworkProtocolRef protocol)
 {
        SCNetworkProtocolPrivateRef     protocolPrivate = (SCNetworkProtocolPrivateRef)protocol;
 
+       if (!isA_SCNetworkProtocol(protocol)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return NULL;
+       }
+
        return protocolPrivate->entityID;
 }
 
@@ -271,12 +310,35 @@ SCNetworkProtocolSetConfiguration(SCNetworkProtocolRef protocol, CFDictionaryRef
        Boolean                         ok;
        CFStringRef                     path;
        SCNetworkProtocolPrivateRef     protocolPrivate = (SCNetworkProtocolPrivateRef)protocol;
-       SCNetworkServicePrivateRef      servicePrivate  = (SCNetworkServicePrivateRef)protocolPrivate->service;
+       SCNetworkServiceRef             service;
+       SCNetworkServicePrivateRef      servicePrivate;
+
+       if (!isA_SCNetworkProtocol(protocol)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       service = protocolPrivate->service;
+       servicePrivate = (SCNetworkServicePrivateRef)service;
+       if (!__SCNetworkServiceExists(service)) {
+               SC_log(LOG_ERR, "SCNetworkProtocolSetConfiguration() w/removed service\n  protocol = %@\n  service = %@",
+                      protocolPrivate->entityID,
+                      servicePrivate);
+               _SC_crash_once("SCNetworkProtocolSetConfiguration() w/removed service", NULL, NULL);
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
 
        path = copyProtocolConfigurationPath(protocolPrivate);
        ok = __setPrefsConfiguration(servicePrivate->prefs, path, config, TRUE);
        CFRelease(path);
 
+       if (ok) {
+               SC_log(LOG_DEBUG, "SCNetworkProtocolSetConfiguration(): %@ --> %@",
+                      protocol,
+                      config != NULL ? config : (CFDictionaryRef)CFSTR("NULL"));
+       }
+
        return ok;
 }
 
@@ -287,11 +349,34 @@ SCNetworkProtocolSetEnabled(SCNetworkProtocolRef protocol, Boolean enabled)
        Boolean                         ok;
        CFStringRef                     path;
        SCNetworkProtocolPrivateRef     protocolPrivate = (SCNetworkProtocolPrivateRef)protocol;
-       SCNetworkServicePrivateRef      servicePrivate  = (SCNetworkServicePrivateRef)protocolPrivate->service;
+       SCNetworkServiceRef             service;
+       SCNetworkServicePrivateRef      servicePrivate;
+
+       if (!isA_SCNetworkProtocol(protocol)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       service = protocolPrivate->service;
+       servicePrivate = (SCNetworkServicePrivateRef)service;
+       if (!__SCNetworkServiceExists(service)) {
+               SC_log(LOG_ERR, "SCNetworkProtocolSetEnabled() w/removed service\n  protocol = %@\n  service = %@",
+                      protocolPrivate->entityID,
+                      servicePrivate);
+               _SC_crash_once("SCNetworkProtocolSetEnabled() w/removed service", NULL, NULL);
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
 
        path = copyProtocolConfigurationPath(protocolPrivate);
        ok = __setPrefsEnabled(servicePrivate->prefs, path, enabled);
        CFRelease(path);
 
+       if (ok) {
+               SC_log(LOG_DEBUG, "SCNetworkProtocolSetEnabled(): %@ -> %s",
+                      protocol,
+                      enabled ? "Enabled" : "Disabled");
+       }
+
        return ok;
 }