Re: notification of IP stack changes on OS X
Re: notification of IP stack changes on OS X
- Subject: Re: notification of IP stack changes on OS X
- From: Quinn <email@hidden>
- Date: Tue, 5 Feb 2002 12:02:06 +0000
At 12:39 +0100 5/2/02, Stiphane Sudre wrote:
Another solution can be to use the Kern Event APIs with this key:
vendor_code = KEV_VENDOR_APPLE;
kev_class = KEV_NETWORK_CLASS;
The KernelEventMonitor.bproj project in Darwin shows how to use it.
I recommend that you use SCF in priority to these kernel events. SCF
(well, actually, configd) is actually layered on top of these kernel
events. While I'm not aware of any plans to change the kernel
events, SCF is definitely Apple's application-level API for this sort
of thing.
And, to put my money where my mouth is, here's a trivial example of
using the SCF dynamic store API.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
/*
IMPORTANT: This Apple software is supplied to you by Apple
Computer, Inc. ("Apple") in consideration of your agreement to the
following terms, and your use, installation, modification or
redistribution of this Apple software constitutes acceptance of
these terms. If you do not agree with these terms, please do not
use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms,
and subject to these terms, Apple grants you a personal,
non-exclusive license, under Apple's copyrights in this original
Apple software (the "Apple Software"), to use, reproduce, modify and
redistribute the Apple Software, with or without modifications, in
source and/or binary forms; provided that if you redistribute the
Apple Software in its entirety and without modifications, you must
retain this notice and the following text and disclaimers in all
such redistributions of the Apple Software. Neither the name,
trademarks, service marks or logos of Apple Computer, Inc. may be
used to endorse or promote products derived from the Apple Software
without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses,
express or implied, are granted by Apple herein, including but not
limited to any patent rights that may be infringed by your
derivative works or by other works in which the Apple Software may
be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT
LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE
APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH
YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT,
INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE
USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE
SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE
HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <CoreFoundation/CoreFoundation.h>
#include <SystemConfiguration/SystemConfiguration.h>
static SCDynamicStoreRef store = NULL;
static CFRunLoopSourceRef rls;
void
networkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
{
/* DO WHATEVER YOU NEED TO DO HERE! */
fprintf(stdout, "the network configuration changed!\n");
fflush(stdout);
return;
}
void
watchForNetworkChanges()
{
CFStringRef key;
CFMutableArrayRef keys;
CFMutableArrayRef patterns;
SCDynamicStoreContext context = { 0, (void *)store, NULL, NULL, NULL };
store = SCDynamicStoreCreate(NULL,
CFSTR("watchForNetworkChanges"),
networkChanged,
&context);
if (!store) {
fprintf(stderr, "could not open session with configd\n");
fprintf(stderr, "error = %s\n", SCErrorString(SCError()));
return;
}
/*
* establish and register dynamic store keys to watch
* - global IPv4 configuration changes (e.g. new default route)
* - per-service IPv4 state changes (IP service added/removed/...)
*/
keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
kSCDynamicStoreDomainState,
kSCEntNetIPv4);
CFArrayAppendValue(keys, key);
CFRelease(key);
key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
kSCDynamicStoreDomainState,
kSCCompAnyRegex,
kSCEntNetIPv4);
CFArrayAppendValue(patterns, key);
CFRelease(key);
if (!SCDynamicStoreSetNotificationKeys(store, keys, patterns)) {
fprintf(stderr, "could not register notification keys\n");
fprintf(stderr, "error = %s\n", SCErrorString(SCError()));
CFRelease(store);
CFRelease(keys);
CFRelease(patterns);
return;
}
CFRelease(keys);
CFRelease(patterns);
/* add a callback */
rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
if (!rls) {
fprintf(stderr, "could not create runloop source\n");
fprintf(stderr, "error = %s\n", SCErrorString(SCError()));
CFRelease(store);
return;
}
CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
/* closing the session will cancel the notifier so we
leave it open until we no longer want any notifications */
return;
}
int
main(int argc, char **argv)
{
watchForNetworkChanges();
CFRunLoopRun();
exit(0);
}
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
This sample, which wasn't written by me, will eventually ship via a
more formal channel.
S+E
--
Quinn "The Eskimo!" <
http://www.apple.com/developer/>
Apple Developer Technical Support * Networking, Communications, Hardware