2011-12-13 13 views
0

は、そう...思いやりてください。 私は必要な特権を持っています。パイソンICMP rawソケットの実装

は今、サーバ iは、そのように定義され:

host = socket.gethostbyname(socket.gethostname()) 
address = (host, 22224) 
sockSer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) 
sockSer.bind(address) 
sockSer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) 
packet, addr = sockSer .recvfrom(4096) # wait for packet from client 

Q1)なぜ単に入力することはできません:ホスト= 'localhostは'。 これを行うと、sockSer.ioctl(socket.SIO_RCVALL、socket.RCVALL_ON)という行を書くことができなくなります。サーバーはクライアントのメッセージを受信しません。 gethostbyname(socket.gethostname())を実行している場合にのみ、私は192.168.1.101 を取得して動作します。異なるクラスの

クライアントソケット:

host = socket.gethostbyname(socket.gethostname()) 
address = (host, 22224) 
sockCli = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) 

Q2)は私も入力する必要があります:sockCli.ioctl(socket.SIO_RCVALL、socket.RCVALL_ON) または多分sockCli .connect(アドレス)? connectコマンドなしで動作するようです。クライアントソケットの ? 1)クライアントからサーバにパケットを送信します:

header=... 
payload='a' 
sockCli.sendto(header + payload, address) 

2)は、サーバにパケットを受信し、クライアントに何かを送る:

while(true): 
    data, addr = sockSer.recvfrom(4096) 
    header2=... 
    payload2='b' 
    sockSer.sendto(header2 + payload2, addr) 

は今、問題は、私は次の操作を行うときに発生します

今、私の重要な質問は: Q3)サーバはペイロード 'b'を使ってクライアントに1パケットだけを送りました。 クライアントは実際にはwhileループで2パケットを受信します。 最初のパケットはクライアント自体がサーバに送信され、もう1つのパケットはクライアントがサーバから取得したものです。 したがって私の出力は単に 'b'の代わりに 'ab'です なぜこれが起こっていますか?

注:私はコード全体を入力しませんでしたが、私の構文、解析、ヘッダの構成などは正しいと思います。 私のコードに明らかな問題はありますか? 必要に応じてコード全体をアップロードします。

ありがとう

+0

あなたのシステムがそれらを許可しないように構成されていない限り、Rawソケットはループバックインターフェイス上でうまく動作するはずです。 –

+0

インターネットコントロールメッセージプロトコルソケットは、ホストとの間でデータを送信するために使用されません。ホストに短い制御メッセージを送信するためのものです。そのため、接続する必要はありません。 –

+0

ところで、通常のUDPの代わりにICMP(本当にデータ転送に使用されるはずのものではない)を使用する理由は何ですか? –

答えて

0

私もこれを手に入れました。 私の解決策は、私がPingのパッケージを送信する場合ので、私は唯一の希望など、受信コードで裁判官を追加でエコー応答(タイプ0コード0)、私は

if type != 0: 
    continue 

を書いて、あなたも かのADDRとして書くことができます== my_ip:私は、ローカルホストに結合し、うまく両方のパラメータでIOCTLを呼び出すことができました: は、それが任意の滑らかなソリューションに

0

Q1を持っていないようだ

を続けます。あなたのクライアントも同じシステムで動作していると仮定して、クライアントが "localhost"に送信していることを確認してください。そうしないと、サーバはパケットを受信しません。あなたのクライアントが別のシステムにある場合、明らかにサーバーはパケットを受信しません。

Q2:パケットの送信にIOCTLは必要ありません。単にsendto()で送信してください。

Q3:2つの返信が表示される理由は、カーネルが独自のユーザースペースコードに加えて、エコー要求も処理しているからです。

ICMPを任意のメッセージパッシングに使用することはできますが、他の人が指摘しているように、意図した設計ではありません。あなたのデータ部分がメッセージ返信で切り捨てられることがあります。たとえば、エコー要求を送信する場合、返信には送信したすべてのものが含まれている可能性があります。ただし、タイプ3コード3の応答には、データは含まれず、ICMPヘッダーの最初の8バイトのみが含まれる場合があります。

関連する問題