System Configuration

RSS for tag

System Configuration allows applications to access a device’s network configuration settings and determine the reachability of the device.

Posts under System Configuration tag

20 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Ios18 bug on “Help apple improve search”
hey guyss…. Im currently using ios18 developer beta 2 on my iphoen 12…Idk if u guys noticed it or not.. but when i turn off the toggle for “Help improve apple search” (settings->search->help improve apple search) it again turns on without my knowledge seconds aftr i close the page. Ive tried restarting my iphone & many more.. nothing seems to work.. im kindoff a more private guy i usually turn off apple analytics.. usage diagnostics and i always make sure data is stored only on my local storage.. and this bug kinda piss me off 😕. i’ve given u the link below to check it out. Peace. https://youtube.com/shorts/YfVDCA-Dfrs?si=qLcl0mWL-Jm9iJFz
1
1
185
2w
How to Restrict App from Moving to Background and Prompt User for Exit Confirmation?
Hello Apple Developer Forum, I'm working on an iOS app and need to implement a feature where the app asks the user for confirmation before moving to the background. Specifically, when the user tries to send the app to the background, I want to display an alert asking "Are you sure you want to exit?" and based on their response, either allow the app to move to the background or prevent it from doing so. Could anyone provide a solution or guidance on how to achieve this? Thanks.
2
0
198
2w
How to detect that WiFi has no internet connection?
In some cases the user connects to a WiFi network that doesn't have internet access. The OS itself is able to display a warning in System Settings: However, in my app NWPathMonitor reports that the WiFi path is satisfied. How could I detect that the internet access is not working while WiFi is connected? I could try to connect to my own servers and report failures to the user, but that takes a long time to receive the timeout error. I cannot reduce the timeout, because maybe the user is on a very slow network and long loading time might be expected. But iOS can detect that there is not internet within a few seconds and display a warning, so I wonder how does Apple implement it in System Settings and if there is something I can implement in my app.
2
0
202
2w
iOS18 Contacts bug report
Dear developers, I am experiencing a bug with Contacts on my iPhone13 since downloading the beta. Some names in the listing of contacts do not correspond with their card once opened in the Contacts app. The option to share contacts in 3rd party apps has disappeared. Noticed specifically in WhatsApp where my contacts are no longer synced and no longer show against numbers. Best regards
1
0
186
2w
NEHotspotConfigurationManager removeConfiguration not working consistent
Hey, I'm currently developing an app that uses NEHotspotConfigurationManager to connect to and disconnect from a WiFi network based on user actions. I'm using the following code to connect and disconnect: Connect let configuration = NEHotspotConfiguration(ssid: ssid, passphrase: password, isWEP: false) configuration.joinOnce = true NEHotspotConfigurationManager.shared.apply(configuration) { (error) in if let error = error { print("Error connecting to WiFi network: \(error.localizedDescription)") } else { self.lastSSID = ssid } } Disconnect NEHotspotConfigurationManager.shared.removeConfiguration(forSSID: self.lastSSID) The issue I'm encountering is that the app successfully connects to the WiFi network and disconnects properly the first time. However, after connecting again, the second disconnect attempt fails to disconnect from the WiFi network. I found a similar bug report from 2020 that mentioned this issue. The suggested workaround involved setting joinOnce = false, which is not suitable for my app's requirements.
2
0
241
Jun ’24
Wi-Fi SSID information missing from System Configuration Framework since macOS 14.4
I have a small application (already published to the Mac App Store) to monitor, and notify the user of some important state changes about thier computer. To display Wi-Fi informations, I listening on the "State:/Network/Interface/.*/AirPort" events of the System Configuration framework. Before 14.4, the returned dictionary had an "SSID_STR" property which was contained the connected network name, but from 14.4, if "SSID_STR" are presents, it's will be always an empty string (""). My first idea was to put "NSLocationUsageDescription" into the Info.plist (and enable Location under App Sandbox in the Signing & Capabilities section) and try to request permission with the Core Locations requestWhenInUseAuthorization call, but even if i had the correct permission (.authorizedAlways), this will did not came to success. There are any workaround or entitlement available to get back the access to this information?
2
0
348
Jun ’24
How to disable/disconnect ethernet adapter USB type using Network Framework API for Mac
I have tried networksetup -setnetworkserviceenabled "USB 10/100/1000 LAN" on networksetup -setnetworkserviceenabled "USB 10/100/1000 LAN" off and same with ifconfig cmd sudo ifconfig down sudo ifconfig up I am able to bounces the interfaces with these commands but the network connectivity is not restored properly for USB 10/100/1000 LAN interface May I know is there any other way we can achieve this programmatically using network framework API available for Mac
4
0
288
May ’24
API to parse DHCP option 121 returned from DHCPInfoGetOptionData
I am trying to fetch static routes added on my mac machine by DHCP server. I am able to get DHCP info using SCDynamicStoreCopyDHCPInfo and then get DHCP options using DHCPInfoGetOptionData. However, I could not find any API that can help me parse the raw data returned by DHCPInfoGetOptionData. Since macOS is parsing and adding these static routes and also displaying them in AdditionalRoutes of service, is there any API available to developers to parse this raw data into destination, mask and gateway?
1
0
494
Apr ’24
Network Name (local domain Name) of a Mac (Mac-OS)
I want to get the network-name (domain-name) on my Mac-Machine. Where iin the Settings does this domain name gets configured. I refer to this page which talks about computer name and host name, I could find where my hostname is present (Settings->General->Sharing->local host name) but not anything related to the network-name (local -domain) . Even try to fetch this info using the linux api to getdomainname, api call succeeded but it returns Nothing. #include <iostream> #include <unistd.h> #include <limits.h> #include <cstring> int main() { char domainname[255]; // Get the domain name if (getdomainname(domainname, 255) != 0) { std::cout << "Error getting domain name" << std::endl; return 1; } std::cout << "Domain name: " << domainname << std::endl; return 0; } Output Domain name: I even came across Search-Domains, Does it have anything to do with the network-name (domain name of the machine)?
5
0
595
Apr ’24
Challenges Detecting Active Interfaces and IPv4 Changes on macOS with SystemConfiguration Framework
I am encountering an issue while using the SystemConfiguration framework to detect IPv4 address changes and active interfaces on macOS. Specifically, I'm facing difficulties when the interface switches from one network to another. When connected to a network with a Captive Portal enabled, I'm unable to retrieve the active interface using the stored key State:/Network/Global/IPv4. The output I receive is: No such key However, when I attempt to retrieve interface information using scutil --nwi, the output is as follows: IPv4 network interface information No IPv4 states found REACH : flags 0x00000000 (Not Reachable) IPv6 network interface information No IPv6 states found REACH : flags 0x00000000 (Not Reachable) Network interfaces: en0 Despite this output, the interface en0 is active and has a valid IPv4 address: when checking through ifconfig: en0:flags=8b63<UP,BROADCAST,SMART,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500 options=6460<TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM> ether bc:d0:74:07:2a:33 inet6 fe80::412:ec:40df:4211%en0 prefixlen 64 secured scopeid 0x12 inet 10.42.0.5 netmask 0xffffff00 broadcast 10.42.0.255 nd6 options=201<PERFORMNUD,DAD> media: autoselect status: active It's evident that the interface is active and has a valid IPv4 address, but the retrieval methods using SystemConfiguration framework are not providing the expected output. I'm seeking assistance in resolving this discrepancy and accurately detecting active interfaces on macOS. Any insights or suggestions would be greatly appreciated. Thank you.
1
0
537
Mar ’24
Read user defined network interface names
Hi, I have a C++ application on OSX that normally works on systems with multiple network interfaces and I'd like to offer a dialog to the users to select the appropriate NIC for the different tasks. It would be fine to show the users the name they assigned to the NIC inside the system settings but I don't know how to read these names. I tried to use SCNetworkInterfaceGetLocalizedDisplayName() but that only gives me the name before I entered my own user defined name (something like "USB 10/100/1000 LAN"). Is there a way to read the user defined name of each NIC? Thanks and best regards, Johannes
3
0
564
Dec ’23
Reachability behaviour changed with Sonoma 14.2b
Hi, I'm looking for feedback regarding SCNetworkReachability under macOS Sonoma. It seems that since beta 3 the notifications behaviour changed. In a LaunchAgent I'm using SCNetworkReachabilityCreateWithName + SCNetworkReachabilitySetCallback + SCNetworkReachabilityScheduleWithRunLoop and wait for callbacks looking at the kSCNetworkReachabilityFlagsReachable flag. This is running fine under macOS 12.x, 13.x and 14.0 for more than a year. If I log all callback entries I observe unexpected notifications as if the looked host became unreachable for very small amount of time (ms). The host is flagged as unreachable then few ms later reachable again then unreachable again. Fast switching is fine, I can accept that the service is unreachable even for 1s but the probleme is the latest status do not reflect actual reachability of the service. This is in a corporate network with the complexity of using a proxy.pac. Does anybody noticed something similar ? I filled a Feedback FB13442134 in case it could be a regression of 14.2
1
0
491
Dec ’23
Monitoring Socket Viability
Working a DTS incident today, someone asked me exactly how you use SCNetworkReachabilityCreateWithAddressPair to monitor a socket’s viability (per the advice in TN3151). I thought I’d posted code for that many times but, on searching my records, it turns out that I haven’t. Ever. Weird! Anyway, this post rectifies that. If you have questions or comments, start a new thread here on DevForums. Tag it with System Configuration so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Monitoring Socket Viability The BSD Sockets best practices section of TN3151 Choosing the right networking API says: Once you’ve established a connection, use SCNetworkReachabilityCreateWithAddressPair to monitor its viability. Without this, your program won’t notice that a connection is stuck due to a TCP/IP stack reconfiguration. While this is correct, it’s not exactly expansive. This post shows how you might use that call to monitor the viability of a socket. It explains this technique using a Swift example, but there’s a C version of the code below for those with a “sad devotion to that ancient religion” (-: Seriously though, this code is very specific to Apple platforms, where you also have access to Network framework, and that has built-in support for this sort of thing. Only use this code if you absolutely must stick with BSD Sockets. IMPORTANT The Swift code in this post relies on the QSocket2023 library from Calling BSD Sockets from Swift. To start, I assume you have a class like this: final class QConnection { private var socket: FileDescriptor private var queue: DispatchQueue private var targetQ: SCNetworkReachability? … initialiser elided … } Each instance of this class ‘owns’ the socket. It uses a Dispatch queue that serialises all access to the instance. Finally, the targetQ property holds a reachability object that monitor’s the socket’s viability. Once an instance has connected its socket, it calls this method to start monitoring its viability: extension QConnection { fileprivate func startMonitoring() throws { let local = try socket.getSockName() let remote = try socket.getPeerName() let target = try scCall { try QSockAddr.withSockAddr(address: local.address, port: local.port) { saLocal, _ in try QSockAddr.withSockAddr(address: remote.address, port: remote.port) { saRemote, _ in SCNetworkReachabilityCreateWithAddressPair(nil, saLocal, saRemote) } } } var context = SCNetworkReachabilityContext() context.info = Unmanaged.passUnretained(self).toOpaque() try scCall{ SCNetworkReachabilitySetCallback(target, { target, flags, info in let obj = Unmanaged<QConnection>.fromOpaque(info!).takeUnretainedValue() let isViable = flags.contains(.reachable) obj.viabilityDidChange(isViable) }, &context) } try! scCall{ SCNetworkReachabilitySetDispatchQueue(target, self.queue) } self.targetQ = target } } This creates a reachability object with the socket’s local and remote addresses. It then sets up a callback on that object that runs on the instance’s Dispatch queue. That callback calls viabilityDidChange(_:) when the reachability flags change. Here’s the viabilityDidChange(_:) method: extension QConnection { fileprivate func viabilityDidChange(_ isViable: Bool) { dispatchPrecondition(condition: .onQueue(self.queue)) print("isViable: \(isViable)") } } This just prints the new value. In a real product you would: Merge duplicate changes. Debounce the change. The way that reachability works, you might see transient events, and it’s best to ignore those. If the socket is non-viable for too long, start the process of closing it down. Finally, here’s the code to stop viability monitoring. extension QConnection { fileprivate func stopMonitoring() { guard let target = self.targetQ else { return } self.targetQ = nil try! scCall { SCNetworkReachabilitySetCallback(target, nil, nil) } try! scCall { SCNetworkReachabilitySetDispatchQueue(target, nil) } } } Note The snippets above assume two simple helper routines that turn System Configuration framework errors into Swift errors: func scCall(_ body: () throws -> Bool) throws { let ok = try body() guard ok else { throw SCCopyLastError() } } func scCall<Result>(_ body: () throws -> Result?) throws -> Result { guard let result = try body() else { throw SCCopyLastError() } return result } And for those of you working with a C-based language, here’s pretty much the same code in plain ol’ C: struct QConnection { int sock; dispatch_queue_t queue; SCNetworkReachabilityRef target; }; typedef struct QConnection QConnection; static bool _QConnectionStartMonitoring(QConnection * connection) { struct sockaddr_storage local = {}; socklen_t localLen = sizeof(local); bool ok = getsockname(connection->sock, (struct sockaddr *) &local, &localLen) >= 0; if ( ! ok ) { return false; } struct sockaddr_storage remote = {}; socklen_t remoteLen = sizeof(remote); ok = getpeername(connection->sock, (struct sockaddr *) &remote, &remoteLen) >= 0; if ( ! ok ) { return false; } SCNetworkReachabilityRef target = SCNetworkReachabilityCreateWithAddressPair( NULL, (const struct sockaddr *) &local, (const struct sockaddr *) &remote ); if (target == NULL) { return false; } SCNetworkReachabilityContext context = { .info = connection }; ok = SCNetworkReachabilitySetCallback(target, _QConnectionReachabilityCallback, &context); if ( ! ok ) { CFRelease(target); return false; } ok = SCNetworkReachabilitySetDispatchQueue(target, connection->queue); if ( ! ok ) { ok = SCNetworkReachabilitySetCallback(target, NULL, NULL); assert(ok); CFRelease(target); return false; } connection->target = target; return true; } static void _QConnectionReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void * info) { #pragma unused(target) #pragma unused(info) QConnection * connection = (QConnection *) info; bool isViable = (flags & kSCNetworkReachabilityFlagsReachable) != 0; _QConnectionViabilityDidChange(connection, isViable); } static void _QConnectionViabilityDidChange(QConnection * connection, bool isViable) { dispatch_assert_queue(connection->queue); fprintf(stderr, "isViable: %d\n", isViable); } static void _QConnectionStopMonitoring(QConnection * connection) { SCNetworkReachabilityRef target = connection->target; if (target == NULL) { return; } connection->target = NULL; bool ok = SCNetworkReachabilitySetCallback(target, NULL, NULL); assert(ok); ok = SCNetworkReachabilitySetDispatchQueue(target, NULL); assert(ok); CFRelease(target); }
0
0
511
Oct ’23
Unexpected behavior of `AdditionalRoutes` property in DynamicStore
Hello, I experienced a strange (and in my opinion unexpected) behavior from DynamicStore/configd. In our application we setup the routes in the system by setting AdditionalRoutes property on a specific interface to route part of the network traffic through it. The routes are set properly, but I noticed that the they are not cleared once removed from AdditionalRoutes. After a while I figured, that the problem lies in the DestinationAddress I set in AdditionalRoutes. I was using the following configuration: var newRoutes: [[String: NSObject]] = [ ["DestinationAddress": "10.0.0.1" as NSObject, "SubnetMask": "255.0.0.0" as NSObject ] ] and it resulted in a new route: 10 link#16 UCS en0 ! which was not cleared when AdditionalRoutes were reset to the original value. When I changed the DestinationAddress to: var newRoutes: [[String: NSObject]] = [ ["DestinationAddress": "10.0.0.0" as NSObject, "SubnetMask": "255.0.0.0" as NSObject ] ] both, setting and clearing routes works as expected. The only difference is changing the DestinationAddress from 10.0.0.1 to 10.0.0.1. In my opinion this incosistent behavior. Although I can understand that the system might reject 10.0.0.1 as a valid DestinationAddress for creating routes, I don't think it's correct behavior to accept such address, but never clear the routes. The full source code which might be used to verify my claims: import Foundation import SystemConfiguration let en0ServiceIPv4 = "State:/Network/Service/***/IPv4" as CFString let store = SCDynamicStoreCreate(nil, "dseditor" as CFString, nil, nil)! let originalValue = SCDynamicStoreCopyValue(store, en0ServiceIPv4) as! [String: NSObject] var newValue = originalValue print("AdditionalRoutes: \(String(describing: originalValue["AdditionalRoutes"]))") var newRoutes: [[String: NSObject]] = [ ["DestinationAddress": "10.0.0.1" as NSObject, "SubnetMask": "255.0.0.0" as NSObject ] ] newValue["AdditionalRoutes"] = newRoutes as NSObject print("newValue: \(newValue)") var result = SCDynamicStoreSetValue(store, en0ServiceIPv4, newValue as CFPropertyList) print("set new value: \(result)") sleep(3) result = SCDynamicStoreSetValue(store, en0ServiceIPv4, originalValue as CFPropertyList) print("restore old value: \(result)") Naturally, the en0ServiceIPv4 needs to be changed and the program needs to be run as root. Can you please share your thoughts, if this is an OS bug or expected behavior? If it is expected, what is the reasoning behind it?
4
0
607
Oct ’23
Error in getting 802.1x status
Hey, I want to retrieve the 802.1x status when a user starts 802.1x authentication so that I'll know when the user gets successfully authenticated via 802.1x. I refered the eapolclient code on apple opensource and wrote the below code but it's failing to retrieve the state. #include &lt;CoreFoundation/CoreFoundation.h&gt; #include &lt;SystemConfiguration/SystemConfiguration.h&gt; #include &lt;iostream&gt; #ifndef kSCEntNetEAPOL #define kSCEntNetEAPOL CFSTR("EAPOL") #endif /* kSCEntNetEAPOL */ class MyService { public: static void handleEAPOLStatusChange( SCDynamicStoreRef store, CFArrayRef changedKeys, void *context) { MyService *serviceInstance = static_cast&lt;MyService *&gt;(context); serviceInstance-&gt;handleEAPOLStatus(store); } void handleEAPOLStatus(SCDynamicStoreRef store) { // Function to handle EAPOL status change events CFStringRef key = createEAPOLControlAnyInterfaceKey(); CFPropertyListRef eapolStatusValue = SCDynamicStoreCopyValue(store, key); CFShow(eapolStatusValue); CFRelease(key); if (eapolStatusValue) { if (CFGetTypeID(eapolStatusValue) == CFDictionaryGetTypeID()) { CFDictionaryRef eapolStatusDict = static_cast&lt;CFDictionaryRef&gt;(eapolStatusValue); std::cout &lt;&lt; "EAPOL Status Dictionary: " &lt;&lt; std::endl; CFShow(eapolStatusDict); CFRelease(eapolStatusDict); } else { std::cerr &lt;&lt; "Error: The retrieved value is not a dictionary." &lt;&lt; std::endl; } CFRelease(eapolStatusValue); } else { std::cerr &lt;&lt; "Error: Failed to get EAPOL status." &lt;&lt; std::endl; } } void setupDynamicStore() { CFStringRef key; CFArrayRef patterns; CFRunLoopSourceRef rls; SCDynamicStoreContext context; bzero(&amp;context, sizeof(context)); context.info = this; store_ = SCDynamicStoreCreate(NULL, CFSTR("eapolclient"), &amp;MyService::handleEAPOLStatusChange, &amp;context); if (store_ == NULL) { std::cerr &lt;&lt; "SCDynamicStoreCreate() failed." &lt;&lt; std::endl; return; } key = createEAPOLControlAnyInterfaceKey(); patterns = CFArrayCreate(NULL, (const void **)&amp;key, 1, &amp;kCFTypeArrayCallBacks); CFRelease(key); SCDynamicStoreSetNotificationKeys(store_, NULL, patterns); CFRelease(patterns); rls = SCDynamicStoreCreateRunLoopSource(NULL, store_, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRelease(rls); } private: SCDynamicStoreRef store_; CFStringRef createEAPOLControlAnyInterfaceKey() { return SCDynamicStoreKeyCreateNetworkInterfaceEntity( NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetEAPOL); } }; int main() { MyService myService; myService.setupDynamicStore(); CFRunLoopRun(); return 0; }
1
0
622
Aug ’23
how to sort the ip adresses returning from getaddrinfo() like /etc/gai.conf in linux
This is happening Mac M1 Monterey OS .Environment supports both IPv4 and IPV6. When a http client calls gettaddrinfo() it is returning both IPv6,IPv4 IPs . first v6 IPs and then v4 IPs. We need to have a way to sort gettaddrinfo() output to get v4 ip first and then v6. We tried changing DNS order with scutil by putting v4 DNS first , but still getaddrInfo() listing v6 IPs first . In linux there is a way to control gettaddrinfo() o/p with /etc/gai.conf https://man7.org/linux/man-pages/man5/gai.conf.5.html . In Mac I did not find any option like this , scutil changing order DNS is not effective . can you tell us what is way to do this in MAC OSx ?
6
0
1.9k
Feb ’24