How to determine netmask of active interface in Objective-C on a Mac?

前端 未结 3 1412
别跟我提以往
别跟我提以往 2021-02-10 16:54

I\'m trying to determine the network segment my Macbook is in, because I then want to scan this segment for active hosts (basic IP scanner) by using the CFHost class. Therefore

3条回答
  •  无人共我
    2021-02-10 17:41

    So, to wrap this up, I did finally get around to investigating the System Configuration API. As always, once you know how it's not that difficult.

    @0xced - Thanks for pointing me in the right direction. I'd upvote your answer, but I do not have enough reputation to do so.

    This is my solution, for anyone who is curious or in the same situation. It involves digging in the dynamic store. See this for infos on the API. You can look at the information the dynamic store holds by using the scutil command line utility (see x-man-page://8/scutil ).

    Here are my steps. First, you need a session:

    SCDynamicStoreRef storeRef = SCDynamicStoreCreate(NULL, (CFStringRef)@"FindCurrentInterfaceIpMac", NULL, NULL);
    

    Then, I try to get the primary interface (en1, for example):

    CFPropertyListRef global = SCDynamicStoreCopyValue (storeRef,CFSTR("State:/Network/Global/IPv4"));
    NSString *primaryInterface = [(__bridge NSDictionary *)global valueForKey:@"PrimaryInterface"];
    

    Last, I build a string containing the interface to be able to query the right key. It should look something like State:/Network/Interface/en1/IPv4, depending on the interface, of course. With that I am able to get an array with the ip and the netmask. On my Macbook these arrays hold only one ip and netmask, respectively. I suppose it is possible this could be different for other Macs, I will have to verify that. For my test I simply took the first (and only) element in the array, but some sort of checking for size would have to be implemented there.

    NSString *interfaceState = [NSString stringWithFormat:@"State:/Network/Interface/%@/IPv4", primaryInterface];
    
    CFPropertyListRef ipv4 = SCDynamicStoreCopyValue (storeRef, (CFStringRef)interfaceState);
    CFRelease(storeRef);
    
    NSString *ip = [(__bridge NSDictionary *)ipv4 valueForKey:@"Addresses"][0];
    NSString *netmask = [(__bridge NSDictionary *)ipv4 valueForKey:@"SubnetMasks"][0];
    CFRelease(ipv4);
    

    This is just for testing, so it is a little rough around the edges. You will have to look for retain counts and the like. It was only written to get an idea of how it could be done.

提交回复
热议问题