Surowe gniazda i sendto w Pythonie

Pracuję nad integracją scapy z twisted, ale natknąłem się na ten bardzo dziwny błąd w OSX, którego nie mogę zrozumieć.

Zasadniczo nie mogę wysłać poprawnego pakietu TCP (włącznie z nagłówkami IP) przez gniazdo surowe. Oto co robię:

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

Po uruchomieniu otrzymuję następujący błąd:

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

W przypadku, gdy nie masz scapy na nie chcesz go używać, jest to kodowany pakiet base64:

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

Dziwne jest to, że pakiet, który jest prawie identyczny, wydaje się być prawidłowo wysyłany:

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

Tak wyglądają dwa pakiety:

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........

Sprawdzając je w wireshark, różnią się tylko częścią TCP.

Przeprowadziłem wiele różnych eksperymentów i udało mi się w końcu ustawić pewne specyficzne opcje TCP, aby wysłać pakiet, ale nie ma sensu, aby taki pakiet nie działał.

Czy ktoś ma pomysł, dlaczego tak się dzieje?

EDYTOWAĆ:

Ten pakiet wydaje się działać:

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

Jeśli nie dodasz zer, to nie działa.

questionAnswers(6)

yourAnswerToTheQuestion