Skip to content

Instantly share code, notes, and snippets.

@leiless
Last active July 17, 2025 02:45
Show Gist options
  • Select an option

  • Save leiless/5dddcdfbb1d578bd96c44ff727b2cc05 to your computer and use it in GitHub Desktop.

Select an option

Save leiless/5dddcdfbb1d578bd96c44ff727b2cc05 to your computer and use it in GitHub Desktop.
Finding DNS server addresses programmatically on macOS
/**
* Finding DNS server addresses programmatically on macOS
* see:
* https://stackoverflow.com/questions/260518/finding-dns-server-settings-programmatically-on-mac-os-x
*/
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
int main(void) {
CFStringRef callerName = CFSTR("foobar");
SCPreferencesRef scPrefs = SCPreferencesCreate(NULL, callerName, NULL);
CFArrayRef services = SCNetworkServiceCopyAll(scPrefs);
if (services) {
CFIndex count = CFArrayGetCount(services);
for (CFIndex i = 0; i < count; i++) {
NSLog(@"> i = %ld", i);
SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, i);
SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
NSLog(@"%@", interface);
NSString *interfaceServiceID = (__bridge NSString *) SCNetworkServiceGetServiceID(service);
CFStringRef primaryServicePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("State:/Network/Service/%@/DNS"), interfaceServiceID);
NSLog(@"%@", primaryServicePath);
SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, callerName, NULL, NULL);
CFDictionaryRef dnskey = SCDynamicStoreCopyValue(dynRef, primaryServicePath);
// dnskey will give you the DNS server address.
NSLog(@"DNS dict: %@", dnskey);
}
}
return 0;
}
@leiless
Copy link
Author

leiless commented Jun 22, 2021

global_dns.m

/**
 * Get global DNS addresses on macOS
 * see:
 *  https://github.com/seladb/PcapPlusPlus/blob/master/Pcap%2B%2B/src/PcapLiveDeviceList.cpp#L163
 */

#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>

int main(void) {
    CFStringRef callerName = CFSTR("foobar");

	SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, callerName, NULL, NULL);
	if (dynRef == NULL) {
		NSLog(@"Couldn't set DNS server list: failed to retrieve SCDynamicStore");
		return 1;
	}

	CFDictionaryRef dnsDict = (CFDictionaryRef)SCDynamicStoreCopyValue(dynRef, CFSTR("State:/Network/Global/DNS"));
	if (dnsDict == NULL) {
		NSLog(@"Couldn't set DNS server list: failed to get DNS dictionary");
		CFRelease(dynRef);
		return 1;
	}

    NSLog(@"%@", dnsDict);

    CFRelease(dynRef);
    CFRelease(dnsDict);

    return 0;
}

Sample output

gcc -Wall -Wextra -lobjc -framework Foundation -framework SystemConfiguration global_dns.m


$ ./a.out
2021-06-22 22:29:44.876 a.out[11381:101072] {
    ServerAddresses =     (
        "192.168.200.1"
    );
    "__CONFIGURATION_ID__" = "Default: 0";
    "__FLAGS__" = 2;
    "__IF_INDEX__" = 5;
    "__ORDER__" = 0;
}


$ ./a.out
2021-06-22 22:30:47.812 a.out[11464:101860] {
    ServerAddresses =     (
        "2408:840c:de3e:ecbd::2a",
        "192.168.43.60"
    );
    "__CONFIGURATION_ID__" = "Default: 0";
    "__FLAGS__" = 6;
    "__IF_INDEX__" = 5;
    "__ORDER__" = 0;
}

@leiless
Copy link
Author

leiless commented Jun 22, 2021

Other commands

scutil --dns
networksetup -getdnsservers Wi-Fi
ipconfig getpacket en0

nm `which networksetup` | grep -Ev "^[0-9a-z]+\s"
nm `which scutil` | grep -Ev "^[0-9a-z]+\s"
nm `which ifconfig` | grep -Ev "^[0-9a-z]+\s"
nm `which ipconfig` | grep -Ev "^[0-9a-z]+\s"

scutil
> list
...

> show State:/Network/Interface
<dictionary> {
  Interfaces : <array> {
    0 : lo0
    1 : gif0
    2 : stf0
    3 : XHC20
    4 : en0
    5 : en1
    6 : en2
    7 : bridge0
    8 : p2p0
    9 : awdl0
    10 : llw0
    11 : utun0
    12 : utun1
  }
}

> show State:/Network/Global/DNS
<dictionary> {
  ServerAddresses : <array> {
    0 : 192.168.200.1
  }
  __CONFIGURATION_ID__ : Default: 0
  __FLAGS__ : 2
  __IF_INDEX__ : 5
  __ORDER__ : 0
}

> show State:/Network/Service/2CC351F0-1C0D-416F-BB89-77A3F7ECFEEE/DHCP
<dictionary> {
  LeaseExpirationTime : 06/23/2021 22:31:24
  LeaseStartTime : 06/22/2021 22:31:24
  Option_1 : <data> 0xffffff00
  Option_252 : <data> 0x0a
  Option_3 : <data> 0xc0a8c801
  Option_51 : <data> 0x00015180
  Option_53 : <data> 0x05
  Option_54 : <data> 0xc0a8c801
  Option_58 : <data> 0x0000a8c0
  Option_59 : <data> 0x00012750
  Option_6 : <data> 0xc0a8c801
}
# Option_1: Subnet Mask
# Option_3: Router
# Option_6: Domain Server
# SEE ALSO: https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment