4

CFHostクラスを使用して、このセグメントをスキャンしてアクティブなホスト(基本IPスキャナー)を探しているため、Macbookが含まれているネットワークセグメントを特定しようとしています。したがって、アクティブなインターフェイスのIPとネットマスクが必要です。これが私がIPを取得する方法です:

NSString *ipAddr = [[[NSHost currentHost] addresses] objectAtIndex:0];

しかし、ネットマスクの入手方法がまったくわからないので、行き詰まっています。特に、Objective-Cはかなり新しく、プレーンCについても十分な知識がないためです。CFHost、CFNetwork、NSHost、およびさまざまなGoogleのヒットを調べましたが、これまでのところ有用なものは何も見つかりませんでした。

最後の手段として、ある種のシステムコールを実行するか、ファイルから読み取ることができます(どちらですか?)が、可能であればそれを避けたいと思います。

では、NSHostを介して取得したIPに一致するネットマスクを取得するにはどうすればよいですか?任意の提案をいただければ幸いです。

ありがとう!

4

3 に答える 3

12

それで、これをまとめるために、私はついにシステム構成APIの調査に取り掛かりました。いつものように、一度あなたがそれがそれほど難しくない方法を知ったら。

@0xced-私を正しい方向に向けてくれてありがとう。私はあなたの答えに賛成しますが、そうするのに十分な評判がありません。

これは、好奇心旺盛な人や同じ状況にいる人のための私の解決策です。それはダイナミックストアを掘り下げることを含みます。APIの情報については、これを参照してください。scutilコマンドラインユーティリティを使用して、ダイナミックストアが保持する情報を確認できます(x-man-page://8 / scutilを参照)。

これが私のステップです。まず、セッションが必要です。

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

次に、プライマリインターフェイス(たとえば、en1)を取得しようとします。

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

最後に、正しいキーをクエリできるように、インターフェイスを含む文字列を作成します。もちろん、インターフェイスによっては、State:/ Network / Interface / en1/IPv4のようになります。これで、IPとネットマスクを使用して配列を取得できます。私のMacbookでは、これらの配列はそれぞれ1つのIPとネットマスクのみを保持します。これは他のMacとは異なる可能性があると思いますが、それを確認する必要があります。私のテストでは、配列の最初の(そして唯一の)要素を取得しただけですが、サイズのチェックをそこに実装する必要があります。

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);

これはテスト用なので、端が少し荒いです。保持カウントなどを探す必要があります。それはそれがどのように行われることができるかについての考えを得るために書かれただけです。

于 2011-08-10T21:58:43.840 に答える
3

マーティンはいい答えをしました。
そして、ARCバージョンの彼のコードはここにあります:

+ (NSDictionary *)primaryIPv4AddressInfoFromSystemConfiguration
{
    SCDynamicStoreRef storeRef = SCDynamicStoreCreate(NULL, (CFStringRef)@"FindCurrentInterfaceIpMac", NULL, NULL);
    if (!storeRef)
    {
        return nil;
    }

    NSDictionary *IPv4Dictionary = nil;
    CFPropertyListRef global = SCDynamicStoreCopyValue(storeRef, CFSTR("State:/Network/Global/IPv4"));
    id primaryInterface = [(NSDictionary *)CFBridgingRelease(global) valueForKey:@"PrimaryInterface"];
    if (primaryInterface)
    {
        NSString *interfaceState = @"State:/Network/Interface/";
        interfaceState = [[interfaceState stringByAppendingString:(NSString *)primaryInterface] stringByAppendingString:@"/IPv4"];
        CFPropertyListRef IPv4PropertyList = SCDynamicStoreCopyValue(storeRef, (__bridge CFStringRef)interfaceState);
        IPv4Dictionary = (NSDictionary *)CFBridgingRelease(IPv4PropertyList);
    }

    CFRelease(storeRef);
    return IPv4Dictionary;
}

+ (NSDictionary *)primaryIPv6AddressInfoFromSystemConfiguration
{
    SCDynamicStoreRef storeRef = SCDynamicStoreCreate(NULL, (CFStringRef)@"FindCurrentInterfaceIpMac", NULL, NULL);
    if (!storeRef)
    {
        return nil;
    }

    NSDictionary *IPv6Dictionary = nil;
    CFPropertyListRef global = SCDynamicStoreCopyValue(storeRef, CFSTR("State:/Network/Global/IPv6"));
    id primaryInterface = [(NSDictionary *)CFBridgingRelease(global) valueForKey:@"PrimaryInterface"];
    if (primaryInterface)
    {
        NSString *interfaceState = @"State:/Network/Interface/";
        interfaceState = [[interfaceState stringByAppendingString:(NSString *)primaryInterface] stringByAppendingString:@"/IPv6"];
        CFPropertyListRef IPv6PropertyList = SCDynamicStoreCopyValue(storeRef, (__bridge CFStringRef)interfaceState);
        IPv6Dictionary = (NSDictionary *)CFBridgingRelease(IPv6PropertyList);
    }

    CFRelease(storeRef);
    return IPv6Dictionary;
}
于 2015-07-07T16:26:30.383 に答える
2

システム構成APIを使用する必要があります。システム構成プログラミングガイドラインおよびシステム構成フレームワークリファレンスを参照してください。

于 2011-07-30T20:05:57.760 に答える