2011-07-22 5 views
4

私は、アクティブなホスト(基本的なIPスキャナ)に対してこのセグメントをCFHostクラスを使ってスキャンしたいので、Macbookが入っているネットワークセグメントを特定しようとしています。したがって、アクティブなインターフェイスのIPとネットマスクが必要です。これは私がIPを取得する方法です:MacでObjective-Cでアクティブなインターフェイスのネットマスクを特定するにはどうすればよいですか?

しかし、私はネットマスクを取得する方法は全く考えられていないので、私は固執しています。特に私はObjective-Cでかなり新しく、またCの広範な知識も持っていないので、CFHost、CFNetwork、NSHost、そしてさまざまなGoogleのヒットを見てきましたが、これまで有用でないことは何も見つかりませんでした。

最後の手段として、システムコールをソートすることができますか、それともファイルから読み込むことができますか?可能であれば、それを避けたいです。

NSHostで取得したIPに一致するネットマスクを取得するにはどうすればよいですか?どんな提案も大歓迎です。

ありがとうございます!

+0

おそらく、私があまりにも狭く、これを定義しています。 Objective-Cには、ネットマスクなどを介して、私が入っているネットワークセグメントを見つける方法がありますか? – Martin

答えて

3

システム構成APIを使用する必要があります。 System Configuration Programming GuidelinesSystem Configuration Framework Reference

+0

ありがとう、私はまだテストに回っていないが、まだ。私はそれがSCNetworkInterfaceGetConfigurationまたはSCNetworkInterfaceGetExtendedConfigurationであると思いますが、リファレンスドキュメントだけから何が返ってくるのか分かりません。また、リファレンスページから収集したものから、ホストへのパケットがローカルマシンを離れる場合に限り、ホストがCFHostを使用してアップまたはダウンしているかどうかを調べることはできません。ですから実際のICMPエコー要求を実装する必要があります。これはかなり複雑です。 – Martin

12

これをまとめて、私はついにシステムコンフィグレーションAPIを調査しました。いつものように、一度それがそれほど難しくない方法を知っている。

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

これは私の解決策です。好奇心が強い人や同じ状況の人のためです。ダイナミックストアを掘り下げることです。 APIの情報については、thisを参照してください。 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とnetmaskで配列を取得できます。私のMacbookでは、これらの配列はそれぞれ1つのipとnetmaskしか保持しません。私はこれが他の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); 

これはテストのためのものであり、エッジの周りはやや粗いです。あなたは保持カウントなどを探す必要があります。どのようにして行うことができるのかを知るために書かれただけです。

0

マーティンは素敵な答えをくれました。
アークバージョンの彼のコードはここにある:

+ (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; 
} 
+0

この回答は私を大いに助けてくれました、ありがとうございました。 –

関連する問題