use core_foundation::{ array::CFArray, base::{TCFType, ToVoid}, dictionary::CFDictionary, propertylist::CFPropertyList, string::{CFString, CFStringRef}, }; use system_configuration::{ dynamic_store::{SCDynamicStore, SCDynamicStoreBuilder}, sys::schema_definitions::{kSCDynamicStorePropNetPrimaryService, kSCPropNetDNSServerAddresses}, }; // This example will change the DNS settings on the primary // network interface to 8.8.8.8 and 8.8.4.4 fn main() { let store = SCDynamicStoreBuilder::new("my-test-dyn-store").build(); let primary_service_uuid = get_primary_service_uuid(&store).expect("No PrimaryService active"); println!("PrimaryService UUID: {}", primary_service_uuid); let primary_service_path = CFString::new(&format!( "State:/Network/Service/{}/DNS", primary_service_uuid )); println!("PrimaryService path: {}", primary_service_path); let dns_dictionary = create_dns_dictionary(&[ CFString::from_static_string("8.8.8.8"), CFString::from_static_string("8.8.4.4"), ]); let success = store.set(primary_service_path, dns_dictionary); println!("success? {}", success); } fn get_primary_service_uuid(store: &SCDynamicStore) -> Option { let dictionary = store .get("State:/Network/Global/IPv4") .and_then(CFPropertyList::downcast_into::)?; dictionary .find(unsafe { kSCDynamicStorePropNetPrimaryService }.to_void()) .map(|ptr| unsafe { CFString::wrap_under_get_rule(*ptr as CFStringRef) }) } fn create_dns_dictionary(addresses: &[CFString]) -> CFDictionary { let key = unsafe { CFString::wrap_under_get_rule(kSCPropNetDNSServerAddresses) }; let value = CFArray::from_CFTypes(addresses); let typed_dict = CFDictionary::from_CFType_pairs(&[(key, value)]); unsafe { CFDictionary::wrap_under_get_rule(typed_dict.as_concrete_TypeRef()) } }