How to correlate (a changed-key-string passed to SCDynamicStoreCreate()'s callback) to a network device?

StackOverflow https://stackoverflow.com/questions/19738757

Question

My C/C++ program uses MacOS/X's SystemConfiguration function SCDynamicsStoreCreate() and friends to detect when the Mac's network configuration has changed, more or less as shown in the example code Apple provides here.

This works pretty well; in particular, the callback function I pass in as the third parameter to SCDynamicsStoreCreate() does get called whenever any of the Mac's network interfaces comes up or go down.

I'd like to refine things a little, though, by finding out exactly which interface(s) in particular have come up or gone down. That way my program can be smart and only close sockets dependent on the now-departed network interfaces, instead of always recreating all sockets as it does currently.

Here's what my callback function looks like right now:

static void IPConfigChangedCallback(SCDynamicStoreRef /*store*/, CFArrayRef changedKeys, void * info)
{
   // Temporary debugging/exploratory code
   int c = CFArrayGetCount(changedKeys);
   for (int i=0; i<c; i++)
   {
      CFStringRef p = (CFStringRef) CFArrayGetValueAtIndex(changedKeys, i);
      const char *cs = CFStringGetCStringPtr( p, kCFStringEncodingMacRoman ) ;
      printf("   key %i: [%s]\n", i, cs);
   }

   RecreateSocketsAndStuff();
}

When (as a simple test) I enable or disable the WiFi interface on my Mac, the above function gets called, and prints output like this:

    key 0: [State:/Network/Service/F0B25E8E-AAEF-45A1-A484-5D8F0C2BC061/IPv4]

I suspect that that long hexadecimal string corresponds to my Mac's Wi-Fi interface, but how do I map that value to my Mac's WiFi IP address (or MAC address, or interface index, or anything that I could use to correlate this callback to the data returned by getaddrinfo())?

Was it helpful?

Solution

The key is to be interpreted relative to the System Configuration Schema. As noted elsewhere in the System Configuration Programming Guidelines:

Although the schema is not private system API, it is very low level. As much as possible, an application should avoid depending directly on the schema and employ higher-level interfaces instead.

That said, you could pass the key to SCDynamicStoreCopyValue() to examine what that gives you. I believe you get a dictionary of properties and their values.

You can also use the scutil command to explore the System Configuration store interactively. For example, issue the show command with the key you got from your callback. On my system, I get a dictionary showing subnet masks, the router, the interface name, and the IP addresses.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top