Я пытаюсь использовать SystemConfiguration в Mac OS, чтобы получить уведомление, когда на Mac появляется новый сетевой интерфейс и ему назначен новый IP-адрес.
Я настроил его для наблюдения засистемный конфигурационный ключ State:/Network/Interface
, и он работает так, что я получаю уведомление всякий раз, когда новый сетевой интерфейс появляется или исчезает.
Однако я хотел бы получать уведомление всякий раз, когда IPv4-адрес назначается на новом сетевом интерфейсе (например,по DHCP).Я знаю, что ключ State:/Network/Interface/en0/IPv4
содержит адрес IPv4 для интерфейса en0.Но использование регулярных выражений, как показано на странице руководства для всех адресов IPv4 State:/Network/Interface/.*/IPv4
, не работает для нового интерфейса.
Я собрал небольшой пример минимального кода на github, однако можно также использовать scutil
инструмент командной строки.
Ссылка на демонстрационный репозиторий
main.c
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
/* Callback used if a configuration change on monitored keys was detected.
*/
void dynamicStoreCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void* __nullable info) {
CFIndex count = CFArrayGetCount(changedKeys);
for (CFIndex i=0; i<count; i++) {
NSLog(@"Key \"%@\" was changed", CFArrayGetValueAtIndex(changedKeys, i));
}
}
int main(int argc, const char * argv[]) {
NSArray *SCMonitoringInterfaceKeys = @[@"State:/Network/Interface.*"];
@autoreleasepool {
SCDynamicStoreRef dsr = SCDynamicStoreCreate(NULL, CFSTR("network_interface_detector"), &dynamicStoreCallback, NULL);
SCDynamicStoreSetNotificationKeys(dsr, CFBridgingRetain(SCMonitoringInterfaceKeys), NULL);
CFRunLoopAddSource(CFRunLoopGetCurrent(), SCDynamicStoreCreateRunLoopSource(NULL, dsr, 0), kCFRunLoopDefaultMode);
NSLog(@"Starting RunLoop...");
while([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
}
return 0;
}