2009-11-19 24 views
7

以下では、1つのネットワークカードを想定しています。あなた自身のブロードキャストUDPパケットを無視する方法

サブネット内の他の人にその存在を知らせるように設計されたプログラムのコンポーネントがあります。このために、プログラムが起動するたびに(そして定期的に)ブロードキャストをINADDR_BROADCASTに送信するソリューションを実装しました。必要なポートで受信した人は、後で使用するためにどこから来たのかを覚えています。

この問題は、私自身の放送を覚えたくないということです。理論的にはこれは簡単にできると思っていました。単にローカルのIPアドレスを見つけ、recvfromの情報と比較するだけです。

しかし、ローカルIPを取得するのが難しいことがわかりました。127.0.0.1getaddrinfoとNULLを返すgetaddrinfoは、ホスト名がパブリックIPを返します。誰かが実際のサブネットのIPを見つける方向に私を指すことができますか?私はここで非常に明白な何かを見逃しているに違いないと思っています...まだ私はそれを見逃しています:)

注:私はブロードキャスト、特にこの1つの他の質問を読んだ:UDP-Broadcast on all interfacesしかし、まだ複数のインタフェースの問題に回った。

+0

なぜmDNS(マルチキャストDNS)などの既存のソリューションを活用していないのですか? – jldupont

+0

mDNSは私のニーズには複雑すぎます。 – laura

答えて

7

スタートアップ時にランダムな(しかし追跡された)値で別のメッセージをブロードキャストしてから、そのメッセージを待って自分のアドレスを発見してから、あなたのソースメッセージを無視して通常のメッセージを送信できます。

+0

これはかなり良いアイデアですが、ちょっとハッキリしています。情報はすぐに入手できます(ipconfig/ifconfig)ので、何とか解凍できるはずです – laura

+0

true、アプリケーションのパラメータに変更してからスクリプトの問題私はそれが非常にハックされていることに同意します –

+0

これを受け入れるのは、ハッキーですが、特定のAPIコールなしでそれを行う唯一の方法です。さらに、私はすでに追跡された値を送信しているので、余分なコード行を追加するだけです。 – laura

0

scoketオプションを検索し、これらの作品かどうかを参照してください。 IP_MULTICAST_LOOP、IP_BLOCK_SOURCE

+1

これらはマルチキャストオプションです。放送とは関係ありません。 – EJP

1

getsocknamefunction documentation)は、特定のソケットに関連付けられたローカルIPアドレスを発見することができます。ブロードキャストの送信に使用しているソケットでこれを呼び出すと、返されるのと同じIPアドレスがrecvfromになるはずです。

+2

Windowsでは '0.0.0.0'、Linuxでは奇妙なことを返します。 – laura

1

Linuxでは、SIOCGIFADDRオプションを使用してioctlを使用して、特定のインターフェイスのIPアドレスを取得できます。私はこれがWindowsのために働くとは思わない。そのためには、thisのような馬鹿なことをする必要があります。

0

(私はあなたがWindows上で作業している前提としています)

GetIpAddrTableはまさにその!すべてのネットワークインターフェイスに関するデータを返します.IPアドレスはその中にあります。それらを手に入れるにはいくつかのトリッキーがありますが、Winsockの残りの部分ではありません。

ここでは、IP回線マスクとネットワークマスクを使用してすべてのネットワークインターフェイスを印刷し、ローカルコールバック(127.0.0.1)のフィルタを作成する準備ができている54行の例を示します。いつもそこに、あなたはそれを無視することはできませんので:私のマシン上でこの出力を生成する

#include "stdio.h" 
#include "Winsock2.h" 
#include "Iphlpapi.h" 

int main(){ 
    int error; 

    ULONG size = 0; 
    MIB_IPADDRTABLE* meta_table = nullptr; 

    error = GetIpAddrTable(meta_table, &size, false); 
    if(error != ERROR_INSUFFICIENT_BUFFER) 
     return -1; 

    meta_table = (MIB_IPADDRTABLE*)malloc(size); 

    error = GetIpAddrTable(meta_table, &size, false); 
    if(error != NO_ERROR) 
     return -1; 

    int os_interface_count = meta_table->dwNumEntries; 

    for(int i = 0; i < os_interface_count; i++){ 

     printf("interface:\n"); 

     { 
      in_addr mask; 
      in_addr address; 
      address.S_un.S_addr = meta_table->table[i].dwAddr; 
      mask.S_un.S_addr = meta_table->table[i].dwMask; 

      printf("index:  %d\n", meta_table->table[i].dwIndex); 
      printf("address: %s\n", inet_ntoa(address)); 
      printf("mask:  %s\n", inet_ntoa(mask)); 
     } 

     { 
      in_addr callback_address; 
      callback_address.S_un.S_un_b.s_b1 = 127; 
      callback_address.S_un.S_un_b.s_b2 = 0; 
      callback_address.S_un.S_un_b.s_b3 = 0; 
      callback_address.S_un.S_un_b.s_b4 = 1; 

      if(meta_table->table[i].dwAddr == callback_address.S_un.S_addr) 
       printf("local callback!\n"); 

     } 

    } 

    free(meta_table); 
    return 0; 
} 

(MSVC 19、窓10、Iphlpapi.libとWS2_32.LIBに対するリンクで働いていた):

interface: 
index:  7 
address: 192.168.56.1 
mask:  255.255.255.0 
interface: 
index:  1 
address: 127.0.0.1 
mask:  255.0.0.0 
local callback! 
interface: 
index:  11 
address: 192.168.178.181 
mask:  255.255.255.0 

奇妙なことは、GetIpAddrTableへの最初の呼び出しで、バッファーに割り当てる必要があるサイズだけです。私はコードの残りの部分はかなり自明であると思う、私は質問のためにここにいる。 (私は50議員がいないので、私は質問に返信することができるかどうかわからない、ありがとうStackoverflow!)

関連する問題