|
| 1 | +extern crate core_foundation; |
1 | 2 | extern crate system_configuration;
|
2 | 3 |
|
3 |
| -extern crate core_foundation; |
| 4 | +use core_foundation::base::kCFAllocatorDefault; |
| 5 | + |
| 6 | + |
| 7 | +use system_configuration::dynamic_store::SCDynamicStoreBuilder; |
| 8 | +use system_configuration::network_configuration::SCNetworkService; |
| 9 | +use system_configuration::preferences::SCPreferences; |
4 | 10 |
|
5 |
| -use core_foundation::array::CFArray; |
6 |
| -use core_foundation::base::TCFType; |
7 |
| -use core_foundation::dictionary::CFDictionary; |
8 |
| -use core_foundation::propertylist::CFPropertyList; |
9 |
| -use core_foundation::string::{CFString, CFStringRef}; |
10 | 11 |
|
11 |
| -use system_configuration::dynamic_store::{SCDynamicStore, SCDynamicStoreBuilder}; |
| 12 | +use std::net::{IpAddr, Ipv4Addr}; |
| 13 | + |
12 | 14 |
|
13 | 15 | // This example will change the DNS settings on the primary
|
14 | 16 | // network interface to 8.8.8.8 and 8.8.4.4
|
15 | 17 |
|
| 18 | +// Usage: |
| 19 | + |
| 20 | +// $ cargo build --example set_dns |
| 21 | +// $ sudo ../target/debug/examples/set_dns |
| 22 | + |
16 | 23 | fn main() {
|
17 |
| - let store = SCDynamicStoreBuilder::new("my-test-dyn-store").build(); |
18 |
| - let primary_service_uuid = get_primary_service_uuid(&store).expect("No PrimaryService active"); |
19 |
| - println!("PrimaryService UUID: {}", primary_service_uuid); |
20 |
| - |
21 |
| - let primary_service_path = CFString::new(&format!( |
22 |
| - "State:/Network/Service/{}/DNS", |
23 |
| - primary_service_uuid |
24 |
| - )); |
25 |
| - println!("PrimaryService path: {}", primary_service_path); |
26 |
| - |
27 |
| - let dns_dictionary = create_dns_dictionary(&[ |
28 |
| - CFString::from_static_string("8.8.8.8"), |
29 |
| - CFString::from_static_string("8.8.4.4"), |
30 |
| - ]); |
31 |
| - |
32 |
| - let success = store.set(primary_service_path, dns_dictionary); |
33 |
| - println!("success? {}", success); |
34 |
| -} |
| 24 | + let addrs = vec![ |
| 25 | + IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8)), |
| 26 | + IpAddr::V4(Ipv4Addr::new(8, 8, 4, 4)), |
| 27 | + ]; |
35 | 28 |
|
36 |
| -fn get_primary_service_uuid(store: &SCDynamicStore) -> Option<CFString> { |
37 |
| - let dictionary = store |
38 |
| - .get("State:/Network/Global/IPv4") |
39 |
| - .and_then(CFPropertyList::downcast_into::<CFDictionary>); |
40 |
| - if let Some(dictionary) = dictionary { |
41 |
| - dictionary |
42 |
| - .find2(&CFString::from_static_string("PrimaryService")) |
43 |
| - .map(|ptr| unsafe { CFString::wrap_under_get_rule(ptr as CFStringRef) }) |
44 |
| - } else { |
45 |
| - None |
46 |
| - } |
47 |
| -} |
| 29 | + let session_name = "session_name"; |
| 30 | + let store = SCDynamicStoreBuilder::new(session_name).build(); |
| 31 | + let prefs = SCPreferences::new(unsafe { kCFAllocatorDefault }, session_name, None); |
| 32 | + |
| 33 | + let global_service = |
| 34 | + SCNetworkService::global(&prefs, &store).expect("No PrimaryService active"); |
| 35 | + let global_interface = global_service |
| 36 | + .interface() |
| 37 | + .expect("No PrimaryInterface active"); |
| 38 | + |
| 39 | + println!("Global Service:"); |
| 40 | + println!("\tid: {:?}", global_service.id()); |
| 41 | + println!("\tname: {:?}", global_service.name()); |
| 42 | + println!("\tenabled: {:?}", global_service.enabled()); |
| 43 | + println!("\tdns: {:?}", global_service.dns(&store)); |
| 44 | + println!("\tinterface: {:?}", global_interface.name().unwrap()); |
| 45 | + |
| 46 | + println!( |
| 47 | + "Set dns to {:?} on {:?} service ...", |
| 48 | + addrs, |
| 49 | + global_service.name() |
| 50 | + ); |
| 51 | + |
| 52 | + |
| 53 | + println!( |
| 54 | + "Success: {:?}", |
| 55 | + global_service.set_dns_server_addresses(&store, Some(addrs)) |
| 56 | + ); |
| 57 | + |
| 58 | + // Check |
| 59 | + // `networksetup -getdnsservers "Wi-Fi"` Or `scutil --dns` Or `dig` |
| 60 | + println!("{:?}", global_service.dns(&store)); |
48 | 61 |
|
49 |
| -fn create_dns_dictionary(addresses: &[CFString]) -> CFDictionary { |
50 |
| - let key = CFString::from_static_string("ServerAddresses"); |
51 |
| - let value = CFArray::from_CFTypes(addresses); |
52 |
| - CFDictionary::from_CFType_pairs(&[(key, value)]) |
| 62 | + println!( |
| 63 | + "\n\nUse Command `networksetup -setdnsservers \"{}\" \"Empty\"` to restore DNS setting. ", |
| 64 | + global_service.name() |
| 65 | + ); |
53 | 66 | }
|
0 commit comments