13

私は scapy と twisted の統合に取り組んでいますが、OSX でこの非常に奇妙なバグに遭遇しました。

基本的に、生のソケット経由で有効な TCP パケット (IP ヘッダーを含む) を送信できません。これは私がやっていることです:

import socket
from scapy.all import IP, TCP
pkt = IP(src='0.0.0.0', dst='127.0.0.1')/TCP()
spkt1 = str(pkt)
outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
outs.sendto(spkt1, ('127.0.0.1', 0))

これを実行すると、次のエラーが表示されます。

outs.sendto(spkt1, ('127.0.0.1', 0)) socket.error: [Errno 22] Invalid argument

scapy をオンにしておらず、使用したくない場合は、base64 でエンコードされたパケットを次に示します。

import base64
spkt1 = base64.b64decode("RQAAKAABAABABvvOAAAAAH8AAAEAFABQAAAAAAAAAABQAiAAEH4AAA==")

非常に奇妙なことは、ほぼ同一のパケットが適切に送信されているように見えることです。

spkt2 = base64.b64decode("RQBAAAWwAAACBgAAAAAAAH8AAAEAyAOEAAAAAAAAAACwAgDIAHsAAAIEBbQBAwMBAQEICk3PUjMAAAAABAIAAA==")

2 つのパケットは次のようになります。

SPKT1
0000   45 00 00 28 00 01 00 00  40 06 FB CE 00 00 00 00   E..(....@.......
0010   7F 00 00 01 00 14 00 50  00 00 00 00 00 00 00 00   .......P........
0020   50 02 20 00 10 7E 00 00                            P. ..~..
SPKT2
0000   45 00 40 00 05 B0 00 00  02 06 00 00 00 00 00 00   E.@.............
0010   7F 00 00 01 00 C8 03 84  00 00 00 00 00 00 00 00   ................
0020   B0 02 00 C8 00 7B 00 00  02 04 05 B4 01 03 03 01   .....{..........
0030   01 01 08 0A 4D CF 52 33  00 00 00 00 04 02 00 00   ....M.R3........

それらをwiresharkでチェックアウトすると、TCP部分のみが異なります。

私は多くの異なる実験を行い、最終的に特定の TCP オプションを設定してパケットを送信することができましたが、そのようなパケットが機能しないことは意味がありません。

なぜこれが起こっているのか誰にも分かりますか?

編集:

このパケットは動作しているように見えます:

pkt = IP(len=16384, src='0.0.0.0', dst='127.0.0.1',
     id=RandShort(), ttl=2)/TCP(sport=255,
      dport=900, flags="S", window=200,
      options=[('MSS', 1460), ('WScale', 2)])
spkt = bytes(pkt)
spkt += '\x00'*20

ゼロを追加しないと機能しません。

4

6 に答える 6

3

私は結局、RawSocketsはバグを抱えて使用できるようにするだけだと判断しました。特にこのソフトウェアはクロスプラットフォームである必要があるため、OSXの癖は他のOSには適用できない場合があります。

とりあえず、scapyが提供する「ソケット」を包んだだけです。将来的には、libdnetのみに依存するものを作成します(これは、scapyがrawフレームを作成するために行うことです)。

これはここに実装されています:

https://github.com/hellais/txscapy

于 2012-06-13T14:34:51.200 に答える
0
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> from scapy.all import IP, TCP
WARNING: No route found for IPv6 destination :: (no default route?)
>>> pkt = IP(src='0.0.0.0', dst='127.0.0.1')/TCP()
>>> spkt1 = str(pkt)
>>> 
>>> outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
>>> outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
>>> outs.sendto(spkt1, ('127.0.0.1', 0))
40

その特定のパケットセットの書き込みにエラーはないようです-2.6.38でx86_64を使用しています-*Gnu/Linuxカーネル。

おそらく、あなたの問題は、rawソケットによるMac OS Xの脳の損傷に関連していますか?

于 2012-06-12T21:49:09.873 に答える
0

0.0.0.0 は有効な IP ソース アドレスとは思えません。これを他の値に変更しても違いはありますか?

于 2012-06-12T21:38:05.397 に答える
0

別の関連する問題。Pythonimpacketモジュールにはping.py、ホストに ping を実行するためのスクリプトがあります。Mac OS X Lion では、次のスクリプトを使用中にエラーが発生しました。

Traceback (most recent call last):
  File "/private/var/www/env/bin/ping.py", line 73, in <module>
    s.sendto(ip.get_packet(), (dst, 0))
socket.error: [Errno 22] Invalid argument

しかし、Ubuntu ではすべて正常に動作し、ホストから返信が来ています。

于 2012-08-21T20:17:57.987 に答える
0

確かな証拠はありませんが、これはイーサネットの最小ペイロード サイズに関連している可能性があると思います。

ウィキペディアから:

最小ペイロードは、802.1Q タグが存在する場合は 42 オクテット、存在しない場合は 46 オクテットです。

最初の例のパケットはわずか 40 バイトだったので、どちらの場合も制限を下回っています。パディングを 20 バイトからこれらの値に変更して実験し、制限の 1 つで動作が停止することを確認できます。

もしそうなら、動作は完全に理にかなっています。有効なパケットを構築するのに十分なデータを与えていないため、OS はパケットを拒否しています。

于 2012-08-21T22:04:05.380 に答える