SYN数据包没有回复(Python)原始套接字

时间:2017-06-06 01:58:47

标签: python sockets networking tcp-ip

每当我使用我的程序发送SYN数据包时,我都没有回复。我知道服务器正在运行,因为我可以使用普通的套接字connect()方法连接到它但是当我尝试使用RAW套接字来执行它时我没有回复,甚至没有RST。

根据Wireshark

,这是我的数据包
    Transmission Control Protocol, Src Port: 5173 (5173), Dst Port: 5005 n (5005), Seq: 0, Len: 0
    Source Port: 5173
    Destination Port: 5005
    [Stream index: 15]
    [TCP Segment Len: 0]
    Sequence number: 0    (relative sequence number)
    Acknowledgment number: 0
    Header Length: 40 bytes
    Flags: 0x002 (SYN)
        000. .... .... = Reserved: Not set
        ...0 .... .... = Nonce: Not set
        .... 0... .... = Congestion Window Reduced (CWR): Not set
        .... .0.. .... = ECN-Echo: Not set
        .... ..0. .... = Urgent: Not set
        .... ...0 .... = Acknowledgment: Not set
        .... .... 0... = Push: Not set
        .... .... .0.. = Reset: Not set
        .... .... ..1. = Syn: Set
        .... .... ...0 = Fin: Not set
        [TCP Flags: **********S*]
    Window size value: 53270
    [Calculated window size: 53270]
    Checksum: 0x9f18 [incorrect, should be 0x90ae (maybe caused by "TCP checksum offload"?)]
    Urgent pointer: 0
    Options: (20 bytes), Maximum segment size, SACK permitted, Timestamps, No-Operation (NOP), Window scale
        Maximum segment size: 65495 bytes
            Kind: Maximum Segment Size (2)
            Length: 4
            MSS Value: 65495
        TCP SACK Permitted Option: True
            Kind: SACK Permitted (4)
            Length: 2
        Timestamps: TSval 378701, TSecr 0
            Kind: Time Stamp Option (8)
            Length: 10
            Timestamp value: 378701
            Timestamp echo reply: 0
        No-Operation (NOP)
            Type: 1
                0... .... = Copy on fragmentation: No
                .00. .... = Class: Control (0)
                ...0 0001 = Number: No-Operation (NOP) (1)
        Window scale: 7 (multiply by 128)
   [SEQ/ACK analysis]

这是我的Python代码

#!/usr/bin/python

import socket
from struct import *
import random

s = socket.socket()
host = "127.0.0.1"
destination = "127.0.0.1"

CLRF = '\r\n'
#socket.gethostname()
print destination
port = 5173

#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.connect((host, 5005))

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
except socket.error , msg:
    print 'Socket could not be created. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    sys.exit()

ipSource = '192.168.0.106'

#IP header

ipIHL = 5 # Header Length
ipVersion = 4 # ipv4/v6 
ipTOS = 0 # type of service
ipTotalLen = 0 ## Kernel will fill correct length apparently
ipPackID = random.randint(1,1000)

#Flags
ipReserved = 0
ipNoFrag = 1
ipMoreFrags = 0

ipFragOffset = 0 #Fragment offset
ipTTL = 64
ipProtocol = socket.IPPROTO_TCP
ipChecksum = 0 # Magic kernel filling in at work again
ipSource = socket.inet_aton (host) 
ipDest = socket.inet_aton (destination)

#Packing IP flags
ipFlags = ipMoreFrags + (ipNoFrag << 1) + (ipReserved << 2)
ipFragOffset = (ipFlags << 13) + ipFragOffset

ipIHLVersion  = (ipVersion << 4) + ipIHL

headerIP = pack('!BBHHHBBH4s4s',ipIHLVersion, ipTOS, ipTotalLen, ipPackID, ipFragOffset,  ipTTL, ipProtocol, ipChecksum, ipSource, ipDest)

#Checksum function
def carry_around_add(a, b):
    c = a + b
    return (c & 0xffff) + (c >> 16)

def checksum(msg):
    s = 0
    for i in range(0, len(msg), 2):
        w = ord(msg[i]) + (ord(msg[i+1]) << 8)
        s = carry_around_add(s, w)
    return ~s & 0xffff

#TCP Header
tcpSourcePort = port #Source Port
tcpDestPort = 5005 #Destination Port
tcpSeqNum = 0 #Packet sequence
tcpAckNum = 0 #Ackknowledge Number
tcpOffset = 10 #Size of tcp header 20 bytes
#tcpReserved = 0
#tcpECN = 0
#Control Flags
tcpURG = 0
tcpACK = 0
tcpPSH = 0
tcpRST = 0
tcpSYN = 1
tcpFIN = 0
tcpWindow = socket.htons (5840) #Dunno how this works
tcpChecksum = 0
tcpUrgentPointer = 0
#TCP Options
tcpMaxSegmentSize = (2 << 24) + (4 << 16) + 65495 # Kind + Length + Max Segment Size
tcpSACKPermitted  = (4 << 8) + 2#Kind + Length
#Split TCP TImestamps into 2 because too large

tcpTimestampPartOne = (8 << 8) + (10) #Kind + Length
tcpTimestampPartTwo = (378701 << 32) + 0 #Timestamp Value + Timestamp echo reply
tcpNoOp = (0 << 7) + (0 << 5) + 1 #Copy on fragmentation + Class + Number
tcpWindowScale = (3 << 16)+ (3 << 8) + 7 #Kind + Length(Bytes) +Shift CountS

#Combine both due to length issues
tcpNoOpAndWindowScale = (tcpNoOp << 24) + tcpWindowScale


tcpOffsetResult = (tcpOffset << 4) + 0 #Shift 4 bytes to left

#Putting together all the TCP Control Flags
tcpFlags = tcpFIN + (tcpSYN << 1) + (tcpRST << 2) + (tcpPSH << 3) + (tcpACK << 4) + (tcpURG << 5)

#Packing the pseudo TCP header
headerTCP = pack('!HHLLBBHHHLHHQL', tcpSourcePort, tcpDestPort, tcpSeqNum, tcpAckNum, tcpOffsetResult, tcpFlags, tcpWindow, tcpChecksum, tcpUrgentPointer, tcpMaxSegmentSize, tcpSACKPermitted, tcpTimestampPartOne, tcpTimestampPartTwo, tcpNoOpAndWindowScale)

#headerTCP = pack('!HHLLBBHHH', tcpSourcePort, tcpDestPort, tcpSeqNum, tcpAckNum, tcpOffsetResult, tcpFlags, tcpWindow, tcpChecksum, tcpUrgentPointer)

#data = 'GET ./asd HTTP/1.1'
data = ''

#Checksum Calculation
#Pseudo Header Fields
sourceAddr = socket.inet_aton(host)
destAddr = socket.inet_aton(destination)
placeholder = 0
protocol = socket.IPPROTO_TCP
tcpLen = len(headerTCP) + len(data)

psh = pack('!4s4sBBH', sourceAddr, destAddr, placeholder, protocol, tcpLen);
psh = psh + headerTCP + data;

#Calc checksum
tcpChecksumReal = (checksum(psh) << 1)

print(tcpChecksumReal)

#Pack actual tcp header with checksum
headerTCP = pack('!HHLLBBH', tcpSourcePort, tcpDestPort, tcpSeqNum, tcpAckNum, tcpOffsetResult, tcpFlags, tcpWindow) + pack('!H', 40728) + pack ('!H', tcpUrgentPointer) + pack('!LHHQL', tcpMaxSegmentSize, tcpSACKPermitted, tcpTimestampPartOne, tcpTimestampPartTwo, tcpNoOpAndWindowScale)

#Build full packet / ip with tcp with data
packet = headerIP + headerTCP + data
#print [hex(ord(c)) for c in packet]
s.sendto(packet, (destination,0))

任何帮助将不胜感激,提前谢谢。

1 个答案:

答案 0 :(得分:0)

致@KenCheung的答案

原来这是校验和,我用作参考的标题的校验和也不正确,但是网卡正在卸载它们。