SCNetworkReachabilityFlags flags = kSCNetworkReachabilityFlagsReachable;
CFStringRef vpn_server_address = NULL;
+ assert(candidate != NULL);
+ assert(services_info != NULL);
+
VPNAttributesGet(candidate->serviceID,
services_info,
&flags,
Boolean primary_is_null = FALSE;
RouteListRef routes = NULL;
+ assert(services_info != NULL);
+
if (results != NULL) {
CandidateRef deferred[results->count];
int deferred_count;
/* grab a snapshot of everything we need */
services_info = services_info_copy(session, service_changes);
+ assert(services_info != NULL);
+
+ /* grab the service order */
service_order = service_order_get(services_info);
if (service_order != NULL) {
if ((S_IPMonitor_debug & kDebugFlag1) != 0) {
*/
static IONotificationPortRef S_notify = NULL;
+/*
+ * S_preconfigured
+ * An array of CFData(WatchedInfo) objects representing those
+ * pre-configured interfaces that have been connected to the
+ * system.
+ */
+static CFMutableArrayRef S_preconfigured = NULL;
+
/* S_prev_active_list
* An array of CFDictionary's representing the previously
* named interfaces.
return active;
}
+static void
+updateInterfaces(void);
+
static void
updateStore(void)
{
return n;
}
+
+#pragma mark -
+#pragma mark Interface monitoring (e.g. watch for "detach")
+
+
+typedef struct WatchedInfo *WatchedInfoRef;
+
+typedef void (*InterfaceUpdateCallBack) (
+ CFDataRef watched,
+ natural_t messageType,
+ void *messageArgument
+);
+
+typedef struct {
+ SCNetworkInterfaceRef interface;
+ io_service_t interface_node;
+ io_object_t notification;
+ InterfaceUpdateCallBack callback;
+} WatchedInfo;
+
+static void
+watcherRelease(CFDataRef watched);
+
+static void
+updateWatchedInterface(void *refCon, io_service_t service, natural_t messageType, void *messageArgument)
+{
+#pragma unused(service)
+#pragma unused(messageArgument)
+ switch (messageType) {
+ case kIOMessageServiceIsTerminated : { // if [locked] interface yanked
+ CFDataRef watched = (CFDataRef)refCon;
+ WatchedInfo *watchedInfo = (WatchedInfo *)(void *)CFDataGetBytePtr(watched);
+
+ CFRetain(watched);
+ watchedInfo->callback(watched, messageType, messageArgument);
+ watcherRelease(watched);
+ CFRelease(watched);
+ break;
+ }
+
+ default :
+ return;
+ }
+
+ return;
+}
+
+static CFDataRef
+watcherCreate(SCNetworkInterfaceRef interface, InterfaceUpdateCallBack callback)
+{
+ uint64_t entryID;
+ io_service_t interface_node;
+ kern_return_t kr;
+ CFDictionaryRef matching;
+ CFMutableDataRef watched;
+ WatchedInfo *watchedInfo;
+
+ // get the IORegistry node
+ entryID = _SCNetworkInterfaceGetIORegistryEntryID(interface);
+ matching = IORegistryEntryIDMatching(entryID);
+ interface_node = IOServiceGetMatchingService(kIOMasterPortDefault, matching);
+ if (interface_node == MACH_PORT_NULL) {
+ // interface no longer present
+ return NULL;
+ }
+
+ // create [locked] interface watcher
+ watched = CFDataCreateMutable(NULL, sizeof(WatchedInfo));
+ CFDataSetLength(watched, sizeof(WatchedInfo));
+ watchedInfo = (WatchedInfo *)(void *)CFDataGetBytePtr(watched);
+ bzero(watchedInfo, sizeof(*watchedInfo));
+
+ // retain interface
+ watchedInfo->interface = CFRetain(interface);
+
+ // ... and the interface node
+ watchedInfo->interface_node = interface_node;
+
+ // ... and set the callback
+ watchedInfo->callback = callback;
+
+ kr = IOServiceAddInterestNotification(S_notify, // IONotificationPortRef
+ watchedInfo->interface_node, // io_service_t
+ kIOGeneralInterest, // interestType
+ updateWatchedInterface, // IOServiceInterestCallback
+ (void *)watched, // refCon
+ &watchedInfo->notification); // notification
+ if (kr != KERN_SUCCESS) {
+ SC_log(LOG_ERR,
+ "IOServiceAddInterestNotification() failed, kr = 0x%x",
+ kr);
+ watcherRelease(watched);
+ CFRelease(watched);
+ return NULL;
+ }
+
+ return watched;
+}
+
+static void
+watcherRelease(CFDataRef watched)
+{
+ WatchedInfo *watchedInfo = (WatchedInfo *)(void *)CFDataGetBytePtr(watched);
+
+ // release watcher
+ if (watchedInfo->notification != IO_OBJECT_NULL) {
+ IOObjectRelease(watchedInfo->notification);
+ watchedInfo->notification = IO_OBJECT_NULL;
+ }
+
+ // release interface node
+ if (watchedInfo->interface_node != IO_OBJECT_NULL) {
+ IOObjectRelease(watchedInfo->interface_node);
+ watchedInfo->interface_node = IO_OBJECT_NULL;
+ }
+
+ // release interface
+ if (watchedInfo->interface != NULL) {
+ CFRelease(watchedInfo->interface);
+ watchedInfo->interface = NULL;
+ }
+
+ return;
+}
+
+
+#pragma mark -
+#pragma mark Locked device support [macOS]
+
+
#if !TARGET_OS_IPHONE
static boolean_t
blockNewInterfaces()
}
#endif // !TARGET_OS_IPHONE
+
+#pragma mark -
+#pragma mark Interface naming
+
+
static __inline__ boolean_t
isQuiet(void)
{
#endif // !TARGET_OS_IPHONE
static void
-updatePreConfigured(CFArrayRef interfaces)
+sharePreconfigured()
{
- CFIndex i;
- CFIndex n;
- CFMutableArrayRef new_list = NULL;
- Boolean updated = FALSE;
+ CFIndex n;
- n = (interfaces != NULL) ? CFArrayGetCount(interfaces) : 0;
- for (i = 0; i < n; i++) {
- SCNetworkInterfaceRef interface;
+ n = (S_preconfigured != NULL) ? CFArrayGetCount(S_preconfigured) : 0;
+ if (n > 0) {
+ CFMutableArrayRef preconfigured;
- interface = CFArrayGetValueAtIndex(interfaces, i);
- if (_SCNetworkInterfaceIsApplePreconfigured(interface)) {
+ preconfigured = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+ for (CFIndex i = 0; i < n; i++) {
CFStringRef bsdName;
+ CFDataRef watched = CFArrayGetValueAtIndex(S_preconfigured, i);
+ WatchedInfo *watchedInfo = (WatchedInfo *)(void *)CFDataGetBytePtr(watched);
- bsdName = SCNetworkInterfaceGetBSDName(interface);
- if (bsdName == NULL) {
- continue;
- }
+ bsdName = SCNetworkInterfaceGetBSDName(watchedInfo->interface);
+ CFArrayAppendValue(preconfigured, bsdName);
+ }
- // add pre-configured interface
- if (new_list == NULL) {
- CFArrayRef cur_list;
+ CFDictionarySetValue(S_state, kInterfaceNamerKey_PreConfiguredInterfaces, preconfigured);
+ CFRelease(preconfigured);
+ } else {
+ CFDictionaryRemoveValue(S_state, kInterfaceNamerKey_PreConfiguredInterfaces);
+ }
- cur_list = CFDictionaryGetValue(S_state, kInterfaceNamerKey_PreConfiguredInterfaces);
- if (cur_list != NULL) {
- new_list = CFArrayCreateMutableCopy(NULL, 0, cur_list);
- } else {
- new_list = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ updateStore();
+
+ return;
+}
+
+static void
+preconfiguredInterfaceUpdated(CFDataRef watched, natural_t messageType, void *messageArgument)
+{
+ Boolean updated = FALSE;
+ WatchedInfo *watchedInfo = (WatchedInfo *)(void *)CFDataGetBytePtr(watched);
+
+#pragma unused(messageArgument)
+ switch (messageType) {
+ case kIOMessageServiceIsTerminated : { // if [locked] interface yanked
+ SC_log(LOG_INFO, "[pre-configured] interface removed: %@",
+ SCNetworkInterfaceGetBSDName(watchedInfo->interface));
+
+ if (S_preconfigured != NULL) {
+ CFIndex i;
+ CFIndex n = CFArrayGetCount(S_preconfigured);
+
+ i = CFArrayGetFirstIndexOfValue(S_preconfigured, CFRangeMake(0, n), watched);
+ if (i != kCFNotFound) {
+ CFArrayRemoveValueAtIndex(S_preconfigured, i);
+ if (CFArrayGetCount(S_preconfigured) == 0) {
+ CFRelease(S_preconfigured);
+ S_preconfigured = NULL;
+ }
+ updated = TRUE;
}
}
- if (!CFArrayContainsValue(new_list, CFRangeMake(0, CFArrayGetCount(new_list)), bsdName)) {
- CFArrayAppendValue(new_list, bsdName);
- updated = TRUE;
- }
+ break;
}
+
+ default :
+ return;
}
- if (new_list != NULL) {
- if (updated) {
- CFDictionarySetValue(S_state, kInterfaceNamerKey_PreConfiguredInterfaces, new_list);
- updateStore();
+ if (updated) {
+ sharePreconfigured();
+ }
+
+ return;
+}
+
+static void
+updatePreConfiguredInterfaces(CFArrayRef interfaces)
+{
+ CFIndex n;
+ Boolean updated = FALSE;
+
+ n = (interfaces != NULL) ? CFArrayGetCount(interfaces) : 0;
+ for (CFIndex i = 0; i < n; i++) {
+ SCNetworkInterfaceRef interface;
+
+ interface = CFArrayGetValueAtIndex(interfaces, i);
+ if (_SCNetworkInterfaceIsApplePreconfigured(interface)) {
+ CFDataRef watched;
+
+ watched = watcherCreate(interface, preconfiguredInterfaceUpdated);
+ if (watched != NULL) {
+ SC_log(LOG_INFO, "watching [pre-configured] interface: %@",
+ SCNetworkInterfaceGetBSDName(interface));
+
+ if (S_preconfigured == NULL) {
+ S_preconfigured = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ }
+ CFArrayAppendValue(S_preconfigured, watched);
+ updated = TRUE;
+ }
}
+ }
- CFRelease(new_list);
+ if (updated) {
+ sharePreconfigured();
}
return;
/*
* Update the list of [Apple] pre-configured interfaces
*/
- updatePreConfigured(S_iflist);
+ updatePreConfiguredInterfaces(S_iflist);
if (isQuiet()) {
/*
return s;
}
-static int
-ifflags_set(int s, char * name, short flags)
-{
- struct ifreq ifr;
- int ret;
-
- bzero(&ifr, sizeof(ifr));
- strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
- ret = ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr);
- if (ret == -1) {
- return (ret);
- }
- ifr.ifr_flags |= flags;
- return (ioctl(s, SIOCSIFFLAGS, &ifr));
-}
-
-static int
-ifflags_clear(int s, char * name, short flags)
-{
- struct ifreq ifr;
- int ret;
-
- bzero(&ifr, sizeof(ifr));
- strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
- ret = ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr);
- if (ret == -1) {
- return (ret);
- }
- ifr.ifr_flags &= ~flags;
- return (ioctl(s, SIOCSIFFLAGS, &ifr));
-}
-
-static void
-mark_if_up(char * name)
-{
- int s = dgram_socket(AF_INET);
- if (s == -1)
- return;
- ifflags_set(s, name, IFF_UP);
- close(s);
-}
-
-static void
-mark_if_down(char * name)
-{
- int s = dgram_socket(AF_INET);
- if (s == -1)
- return;
- ifflags_clear(s, name, IFF_UP);
- close(s);
-}
-
static void
post_network_changed(void)
{
(char *)ifr_name,
protoEvent->proto_family,
protoEvent->proto_remaining_count);
- if (protoEvent->proto_remaining_count == 0) {
- mark_if_down(ifr_name);
- } else {
- mark_if_up(ifr_name);
- }
break;
}
dict = SCDynamicStoreCopyValue(store, namerKey);
if (dict != NULL) {
if (isA_CFDictionary(dict)) {
- CFIndex n;
CFArrayRef preconfigured;
if (CFDictionaryContainsKey(dict, kInterfaceNamerKey_Quiet)) {
preconfigured = CFDictionaryGetValue(dict, kInterfaceNamerKey_PreConfiguredInterfaces);
preconfigured = isA_CFArray(preconfigured);
+ if (!_SC_CFEqual(preconfigured, preconfigured_names)) {
+ CFIndex n;
+ CFIndex nx = 0;
- n = (preconfigured != NULL) ? CFArrayGetCount(preconfigured) : 0;
- for (CFIndex i = 0; i < n; i++) {
- CFStringRef bsdName = CFArrayGetValueAtIndex(preconfigured, i);
- SCNetworkInterfaceRef interface;
- CFRange range;
-
- range.location = 0;
- range.length = (preconfigured_names != NULL) ? CFArrayGetCount(preconfigured_names) : 0;
- if ((range.length > 0) &&
- CFArrayContainsValue(preconfigured_names, range, bsdName)) {
- // if we already know about this interface
- continue;
+ // start clean
+ if (preconfigured_names != NULL) {
+ nx = CFArrayGetCount(preconfigured_names);
+ CFRelease(preconfigured_names);
+ preconfigured_names = NULL;
+ }
+ if (preconfigured_interfaces != NULL) {
+ CFRelease(preconfigured_interfaces);
+ preconfigured_interfaces = NULL;
}
- for (int retry = 0; retry < 10; retry++) {
- if (retry != 0) {
- // add short delay (before retry)
- usleep(20 * 1000); // 20ms
+ // add pre-configured interfaces
+ n = (preconfigured != NULL) ? CFArrayGetCount(preconfigured) : 0;
+ for (CFIndex i = 0; i < n; i++) {
+ CFStringRef bsdName = CFArrayGetValueAtIndex(preconfigured, i);
+ SCNetworkInterfaceRef interface;
+
+ for (int retry = 0; retry < 10; retry++) {
+ if (retry != 0) {
+ // add short delay (before retry)
+ usleep(20 * 1000); // 20ms
+ }
+
+ interface = _SCNetworkInterfaceCreateWithBSDName(NULL, bsdName, kIncludeNoVirtualInterfaces);
+ if (interface == NULL) {
+ SC_log(LOG_ERR, "could not create network interface for %@", bsdName);
+ } else if (_SCNetworkInterfaceGetIOPath(interface) == NULL) {
+ SC_log(LOG_ERR, "could not get IOPath for %@", bsdName);
+ CFRelease(interface);
+ interface = NULL;
+ }
+
+ if (interface != NULL) {
+ // if we have an interface
+ break;
+ }
}
- interface = _SCNetworkInterfaceCreateWithBSDName(NULL, bsdName, kIncludeNoVirtualInterfaces);
if (interface == NULL) {
- SC_log(LOG_ERR, "could not create network interface for %@", bsdName);
- } else if (_SCNetworkInterfaceGetIOPath(interface) == NULL) {
- SC_log(LOG_ERR, "could not get IOPath for %@", bsdName);
- CFRelease(interface);
- interface = NULL;
+ // if SCNetworkInterface not [currently] available
+ continue;
}
- if (interface != NULL) {
- // if we have an interface
- break;
+ // keep track of the interface name (quicker than having to iterate the list
+ // of SCNetworkInterfaces, extract the name, and compare).
+ if (preconfigured_names == NULL) {
+ preconfigured_names = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
}
- }
+ CFArrayAppendValue(preconfigured_names, bsdName);
- if (interface == NULL) {
- // if SCNetworkInterface not [currently] available
- continue;
- }
+ if (preconfigured_interfaces == NULL) {
+ preconfigured_interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ }
+ CFArrayAppendValue(preconfigured_interfaces, interface);
+ CFRelease(interface);
- // keep track of the interface name (quicker than having to iterate the list
- // of SCNetworkInterfaces, extract the name, and compare).
- if (preconfigured_names == NULL) {
- preconfigured_names = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ updated = TRUE;
}
- CFArrayAppendValue(preconfigured_names, bsdName);
- if (preconfigured_interfaces == NULL) {
- preconfigured_interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ // check if all pre-configured interfaces were detached
+ n = (preconfigured_names != NULL) ? CFArrayGetCount(preconfigured_names) : 0;
+ if ((nx > 0) && (n == 0)) {
+ updated = TRUE;
}
- CFArrayAppendValue(preconfigured_interfaces, interface);
- CFRelease(interface);
- updated = TRUE;
- }
-
- if (updated) {
- CFStringRef interfaces = CFSTR("<empty>");
+ if (updated) {
+ CFStringRef interfaces = CFSTR("<empty>");
- // report [new] pre-configured interfaces
- if (preconfigured_names != NULL) {
- interfaces = CFStringCreateByCombiningStrings(NULL, preconfigured_names, CFSTR(","));
- } else {
- CFRetain(interfaces);
+ // report [updated] pre-configured interfaces
+ if (preconfigured_names != NULL) {
+ interfaces = CFStringCreateByCombiningStrings(NULL, preconfigured_names, CFSTR(","));
+ } else {
+ CFRetain(interfaces);
+ }
+ SC_log(LOG_INFO, "pre-configured interface list changed: %@", interfaces);
+ CFRelease(interfaces);
}
- SC_log(LOG_INFO, "pre-configured interface list changed: %@", interfaces);
- CFRelease(interfaces);
}
}
}
-static CF_RETURNS_RETAINED SCNetworkServiceRef
-copyInterfaceService(SCNetworkSetRef set, CFStringRef matchName)
-{
- CFIndex i;
- CFIndex n;
- SCNetworkServiceRef service = NULL;
- CFArrayRef services;
-
- services = SCNetworkSetCopyServices(set);
- assert(services != NULL);
-
- n = CFArrayGetCount(services);
- for (i = 0; i < n; i++) {
- SCNetworkInterfaceRef interface;
-
- service = CFArrayGetValueAtIndex(services, i);
- interface = SCNetworkServiceGetInterface(service);
- if (interface != NULL) {
- CFStringRef bsdName;
-
- bsdName = SCNetworkInterfaceGetBSDName(interface);
- if (_SC_CFEqual(bsdName, matchName)) {
- // if match
- CFRetain(service);
- break;
- }
- }
-
- service = NULL;
- }
-
- CFRelease(services);
- return service;
-}
-
-
static CF_RETURNS_RETAINED CFStringRef
copyInterfaceUUID(CFStringRef bsdName)
{
{
Boolean ok;
CFRange range;
+ CFArrayRef services;
SCNetworkSetRef set;
Boolean updated = FALSE;
- range.length = (preconfigured_names != NULL) ? CFArrayGetCount(preconfigured_names) : 0;
+ range = CFRangeMake(0,
+ (preconfigured_names != NULL) ? CFArrayGetCount(preconfigured_names) : 0);
if (range.length == 0) {
- // if no [preconfigured] interfaces
+ // if no [pre-configured] interfaces
return;
}
- range.location = 0;
set = SCNetworkSetCopyCurrent(prefs);
- if (set != NULL) {
- CFArrayRef services;
-
- /*
- * Check for (and remove) any network services associated with
- * a pre-configured interface from the prefs.
- */
- services = SCNetworkServiceCopyAll(prefs);
- if (services != NULL) {
- CFIndex n;
-
- n = CFArrayGetCount(services);
- for (CFIndex i = 0; i < n; i++) {
- CFStringRef bsdName;
- SCNetworkInterfaceRef interface;
- SCNetworkServiceRef service;
-
- service = CFArrayGetValueAtIndex(services, i);
-
- interface = SCNetworkServiceGetInterface(service);
- if (interface == NULL) {
- // if no interface
- continue;
- }
+ if (set == NULL) {
+ // if no current set
+ return;
+ }
- bsdName = SCNetworkInterfaceGetBSDName(interface);
- if (bsdName == NULL) {
- // if no interface name
- continue;
- }
+ /*
+ * Check for (and remove) any network services associated with
+ * a pre-configured interface from the prefs.
+ */
+ services = SCNetworkServiceCopyAll(prefs);
+ if (services != NULL) {
+ CFIndex n;
- if (!CFArrayContainsValue(preconfigured_names, range, bsdName)) {
- // if not preconfigured
- continue;
- }
+ n = CFArrayGetCount(services);
+ for (CFIndex i = 0; i < n; i++) {
+ CFStringRef bsdName;
+ SCNetworkInterfaceRef interface;
+ SCNetworkServiceRef service;
- // remove [preconfigured] network service from the prefs
- SC_log(LOG_NOTICE, "removing network service for %@", bsdName);
- ok = SCNetworkServiceRemove(service);
- if (!ok) {
- SC_log(LOG_ERR, "SCNetworkServiceRemove() failed: %s",
- SCErrorString(SCError()));
- }
- updated = TRUE;
+ service = CFArrayGetValueAtIndex(services, i);
+
+ interface = SCNetworkServiceGetInterface(service);
+ if (interface == NULL) {
+ // if no interface
+ continue;
}
- CFRelease(services);
- }
+ bsdName = SCNetworkInterfaceGetBSDName(interface);
+ if (bsdName == NULL) {
+ // if no interface name
+ continue;
+ }
- if (updated) {
- // commit the updated prefs ... but don't apply
- ok = SCPreferencesCommitChanges(prefs);
+ if (!CFArrayContainsValue(preconfigured_names, range, bsdName)) {
+ // if not preconfigured
+ continue;
+ }
+
+ // remove [preconfigured] network service from the prefs
+ SC_log(LOG_NOTICE, "removing network service for %@", bsdName);
+ ok = SCNetworkServiceRemove(service);
if (!ok) {
- if (SCError() != EROFS) {
- SC_log(LOG_ERR, "SCPreferencesCommitChanges() failed: %s",
- SCErrorString(SCError()));
- }
+ SC_log(LOG_ERR, "SCNetworkServiceRemove() failed: %s",
+ SCErrorString(SCError()));
}
+ updated = TRUE;
}
- /*
- * Now, add a new network service for each pre-configured interface
- */
- range.length = (preconfigured_interfaces != NULL) ? CFArrayGetCount(preconfigured_interfaces) : 0;
- for (CFIndex i = 0; i < range.length; i++) {
- CFStringRef bsdName;
- SCNetworkInterfaceRef interface = CFArrayGetValueAtIndex(preconfigured_interfaces, i);
- SCNetworkServiceRef service;
+ CFRelease(services);
+ }
- bsdName = SCNetworkInterfaceGetBSDName(interface);
- ok = SCNetworkSetEstablishDefaultInterfaceConfiguration(set, interface);
- if (!ok) {
- SC_log(LOG_ERR, "could not establish network service for %@: %s",
- bsdName,
+ if (updated) {
+ // commit the updated prefs ... but don't apply
+ ok = SCPreferencesCommitChanges(prefs);
+ if (!ok) {
+ if (SCError() != EROFS) {
+ SC_log(LOG_ERR, "SCPreferencesCommitChanges() failed: %s",
SCErrorString(SCError()));
- continue;
}
+ }
+ }
- service = copyInterfaceService(set, bsdName);
- if (service != NULL) {
- CFStringRef serviceID;
-
- serviceID = copyInterfaceUUID(bsdName);
- if (serviceID != NULL) {
- ok = _SCNetworkServiceSetServiceID(service, serviceID);
- CFRelease(serviceID);
- if (!ok) {
- SC_log(LOG_ERR, "_SCNetworkServiceSetServiceID() failed: %s",
- SCErrorString(SCError()));
- // ... and keep whatever random UUID was created for the service
- }
- } else {
- SC_log(LOG_ERR, "could not create serviceID for %@", bsdName);
- // ... and we'll use whatever random UUID was created for the service
- }
-
- SC_log(LOG_INFO, "network service %@ added for %@",
- SCNetworkServiceGetServiceID(service),
- bsdName);
+ /*
+ * Now, add a new network service for each pre-configured interface
+ */
+ for (CFIndex i = 0; i < range.length; i++) {
+ CFStringRef bsdName;
+ SCNetworkInterfaceRef interface = CFArrayGetValueAtIndex(preconfigured_interfaces, i);
+ SCNetworkServiceRef service;
+ CFStringRef serviceID;
+
+ bsdName = SCNetworkInterfaceGetBSDName(interface);
+
+ // create network service
+ service = SCNetworkServiceCreate(prefs, interface);
+ if (service == NULL) {
+ SC_log(LOG_ERR, "could not create network service for \"%@\": %s",
+ bsdName,
+ SCErrorString(SCError()));
+ continue;
+ }
- CFRelease(service);
- } else {
- SC_log(LOG_ERR, "could not find network service for %@", bsdName);
+ // update network service to use a consistent serviceID
+ serviceID = copyInterfaceUUID(bsdName);
+ if (serviceID != NULL) {
+ ok = _SCNetworkServiceSetServiceID(service, serviceID);
+ CFRelease(serviceID);
+ if (!ok) {
+ SC_log(LOG_ERR, "_SCNetworkServiceSetServiceID() failed: %s",
+ SCErrorString(SCError()));
+ // ... and keep whatever random UUID was created for the service
}
+ } else {
+ SC_log(LOG_ERR, "could not create serviceID for \"%@\"", bsdName);
+ // ... and we'll use whatever random UUID was created for the service
+ }
+
+ // establish [template] configuration
+ ok = SCNetworkServiceEstablishDefaultConfiguration(service);
+ if (!ok) {
+ SC_log(LOG_ERR, "could not establish network service for \"%@\": %s",
+ bsdName,
+ SCErrorString(SCError()));
+ SCNetworkServiceRemove(service);
+ CFRelease(service);
+ continue;
}
- CFRelease(set);
+ // add network service to the current set
+ ok = SCNetworkSetAddService(set, service);
+ if (!ok) {
+ SC_log(LOG_ERR, "could not add service for \"%@\": %s",
+ bsdName,
+ SCErrorString(SCError()));
+ SCNetworkServiceRemove(service);
+ CFRelease(service);
+ continue;
+ }
+
+ SC_log(LOG_INFO, "network service %@ added for \"%@\"",
+ SCNetworkServiceGetServiceID(service),
+ bsdName);
+
+ CFRelease(service);
}
+ CFRelease(set);
return;
}
#pragma mark Serialization
+static kern_return_t
+__CFDataCopyVMData(CFDataRef data, void **dataRef, CFIndex *dataLen)
+{
+ kern_return_t kr;
+
+ vm_address_t vm_address;
+ vm_size_t vm_size;
+
+ vm_address = (vm_address_t)CFDataGetBytePtr(data);
+ vm_size = (vm_size_t)CFDataGetLength(data);
+ kr = vm_allocate(mach_task_self(), &vm_address, vm_size, VM_FLAGS_ANYWHERE);
+ if (kr != KERN_SUCCESS) {
+ *dataRef = NULL;
+ *dataLen = 0;
+ return kr;
+ }
+
+ bcopy((char *)CFDataGetBytePtr(data), (void *)vm_address, vm_size);
+ *dataRef = (void *)vm_address;
+ *dataLen = vm_size;
+
+ return kr;
+}
+
+
Boolean
_SCSerialize(CFPropertyListRef obj, CFDataRef *xml, void **dataRef, CFIndex *dataLen)
{
*dataLen = CFDataGetLength(myXml);
}
} else {
- mach_msg_type_number_t len;
- kern_return_t status;
-
- status = vm_read(mach_task_self(),
- (vm_address_t)CFDataGetBytePtr(myXml), // address
- (vm_size_t) CFDataGetLength(myXml), // size
- (void *)dataRef,
- &len);
- if (status != KERN_SUCCESS) {
- SC_log(LOG_NOTICE, "vm_read() failed: %s", mach_error_string(status));
- CFRelease(myXml);
- *dataRef = NULL;
- *dataLen = 0;
- return FALSE;
- }
+ kern_return_t kr;
- *dataLen = len;
+ kr = __CFDataCopyVMData(myXml, dataRef, dataLen);
CFRelease(myXml);
+ if (kr != KERN_SUCCESS) {
+ SC_log(LOG_NOTICE, "__CFDataCreateVMData() failed: %s", mach_error_string(kr));
+ return FALSE;
+ }
}
return TRUE;
if (*obj == NULL) {
if (error != NULL) {
- SC_log(LOG_NOTICE, "CFPropertyListCreateWithData() faled: %@", error);
+ SC_log(LOG_NOTICE, "CFPropertyListCreateWithData() failed: %@", error);
CFRelease(error);
}
_SCErrorSet(kSCStatusFailed);
*dataLen = CFDataGetLength(myData);
}
} else {
- mach_msg_type_number_t len;
- kern_return_t status;
-
- *dataLen = CFDataGetLength(myData);
- status = vm_read(mach_task_self(),
- (vm_address_t)CFDataGetBytePtr(myData), // address
- *dataLen, // size
- (void *)dataRef,
- &len);
- if (status != KERN_SUCCESS) {
- SC_log(LOG_NOTICE, "vm_read() failed: %s", mach_error_string(status));
- CFRelease(myData);
- *dataRef = NULL;
- *dataLen = 0;
- return FALSE;
- }
+ kern_return_t kr;
- *dataLen = len;
+ kr = __CFDataCopyVMData(myData, dataRef, dataLen);
CFRelease(myData);
+ if (kr != KERN_SUCCESS) {
+ SC_log(LOG_NOTICE, "__CFDataCreateVMData() failed: %s", mach_error_string(kr));
+ return FALSE;
+ }
}
return TRUE;
Boolean
_SCSerializeData(CFDataRef data, void **dataRef, CFIndex *dataLen)
{
- mach_msg_type_number_t len;
- kern_return_t status;
+ kern_return_t kr;
if (!isA_CFData(data)) {
/* if not a CFData */
return FALSE;
}
- *dataLen = CFDataGetLength(data);
- status = vm_read(mach_task_self(),
- (vm_address_t)CFDataGetBytePtr(data), // address
- *dataLen, // size
- (void *)dataRef,
- &len);
- if (status != KERN_SUCCESS) {
- SC_log(LOG_NOTICE, "vm_read() failed: %s", mach_error_string(status));
- *dataRef = NULL;
- *dataLen = 0;
+ kr = __CFDataCopyVMData(data, dataRef, dataLen);
+ if (kr != KERN_SUCCESS) {
+ SC_log(LOG_NOTICE, "__CFDataCreateVMData() failed: %s", mach_error_string(kr));
return FALSE;
}
- *dataLen = len;
-
return TRUE;
}
if (state_data_size > MAX_STATEDUMP_SIZE) {
SC_log(LOG_ERR, "DNS configuration: state data too large (%zd > %zd)",
state_data_size,
- MAX_STATEDUMP_SIZE);
+ (size_t)MAX_STATEDUMP_SIZE);
return NULL;
}
fi
echo "#" > skywalk.txt
- echo "# skywalkctl list-providers -D" >> skywalk.txt
+ echo "# skywalkctl show" >> skywalk.txt
echo "#" >> skywalk.txt
- /usr/sbin/skywalkctl list-providers -D >> skywalk.txt 2>&1
+ /usr/sbin/skywalkctl show >> skywalk.txt 2>&1
echo "#" >> skywalk.txt
- echo "# skywalkctl channel-stats" >> skywalk.txt
+ echo "# skywalkctl flow -n" >> skywalk.txt
echo "#" >> skywalk.txt
- /usr/sbin/skywalkctl channel-stats >> skywalk.txt 2>&1
+ /usr/sbin/skywalkctl flow -n >> skywalk.txt 2>&1
echo "#" >> skywalk.txt
- echo "# skywalkctl netstat -a -n" >> skywalk.txt
+ echo "# skywalkctl flow-route -n" >> skywalk.txt
echo "#" >> skywalk.txt
- /usr/sbin/skywalkctl netstat -a -n >> skywalk.txt 2>&1
+ /usr/sbin/skywalkctl flow-route -n >> skywalk.txt 2>&1
+
+ echo "#" >> skywalk.txt
+ echo "# skywalkctl flow-switch" >> skywalk.txt
+ echo "#" >> skywalk.txt
+ /usr/sbin/skywalkctl flow-switch >> skywalk.txt 2>&1
+
+ echo "#" >> skywalk.txt
+ echo "# skywalkctl flow-owner" >> skywalk.txt
+ echo "#" >> skywalk.txt
+ /usr/sbin/skywalkctl flow-owner >> skywalk.txt 2>&1
+
+ echo "#" >> skywalk.txt
+ echo "# skywalkctl flow-adv" >> skywalk.txt
+ echo "#" >> skywalk.txt
+ /usr/sbin/skywalkctl flow-adv >> skywalk.txt 2>&1
echo "#" >> skywalk.txt
echo "# skywalkctl netstat -s" >> skywalk.txt
/usr/sbin/skywalkctl netstat -s --global >> skywalk.txt 2>&1
echo "#" >> skywalk.txt
- echo "# skywalkctl netstat --netif" >> skywalk.txt
- echo "#" >> skywalk.txt
- /usr/sbin/skywalkctl netstat --netif >> skywalk.txt 2>&1
-
- echo "#" >> skywalk.txt
- echo "# skywalkctl netstat --flowswitch" >> skywalk.txt
+ echo "# skywalkctl interface" >> skywalk.txt
echo "#" >> skywalk.txt
- /usr/sbin/skywalkctl netstat --flowswitch >> skywalk.txt 2>&1
+ /usr/sbin/skywalkctl interface >> skywalk.txt 2>&1
echo "#" >> skywalk.txt
- echo "# skywalkctl netstat --flow-adv" >> skywalk.txt
+ echo "# skywalkctl channel" >> skywalk.txt
echo "#" >> skywalk.txt
- /usr/sbin/skywalkctl netstat --flow-adv >> skywalk.txt 2>&1
+ /usr/sbin/skywalkctl channel >> skywalk.txt 2>&1
echo "#" >> skywalk.txt
- echo "# skywalkctl netstat --flow-owner" >> skywalk.txt
+ echo "# skywalkctl provider -D" >> skywalk.txt
echo "#" >> skywalk.txt
- /usr/sbin/skywalkctl netstat --flow-owner >> skywalk.txt 2>&1
+ /usr/sbin/skywalkctl provider -D >> skywalk.txt 2>&1
echo "#" >> skywalk.txt
echo "# skywalkctl netns -a" >> skywalk.txt
echo "# neutil agent dump" >> network-agents.txt
echo "#" >> network-agents.txt
/usr/local/bin/neutil agent dump >> network-agents.txt 2>&1
+
+ # Generates a default-level log message containing the current file handles that UserEventAgent has
+ /usr/local/bin/neutil session log-file-handles
+ sleep 1 &
) &
}
if (state_data_size > MAX_STATEDUMP_SIZE) {
SC_log(LOG_ERR, "Network information : state data too large (%zd > %zd)",
state_data_size,
- MAX_STATEDUMP_SIZE);
+ (size_t)MAX_STATEDUMP_SIZE);
return NULL;
}