使用Python中的原始套接字(Using raw socket in Python)

2019-10-19 01:05发布

我有正在发送消息到服务器这个简单的客户端代码,然后相呼应的服务器响应。

import socket, sys, time


HOST = 'localhost'   
PORT = 11000             
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
msg = raw_input()
s.send(msg)
data = s.recv(len(msg))
s.close()
print 'Received: ', data

我想,为了能够得到IP_ID场出服务器的响应报文在这里使用原始套接字,但我不知道怎么样。

不管我多么在互联网上读到它,我没有找到如何做到这一点的好例子。

(只是为了澄清,我并不真的需要一个原始数据包发送到服务器,我可以使用正常的SOCK_STREAM发送的消息,但我需要使用原始套接字获得响应” IP_ID。)

任何人都可以编辑我的代码,并告诉我,在simpliest方式,怎么办呢? 所有我设法找到了,是我需要socket.SOCK_RAW更换socket.SOCK_STREAM了,但是我还相距甚远。

非常感谢

Answer 1:

从原始套接字读和解析出IP_ID很简单:

response, addr = s.recvfrom(65535)
response_id = struct.unpack('!H', response[4:6])
print response_id

难的是让别人给你摆在首位的包。 我敢肯定,你不能在同一时间使用原始模式和流模式相同的插座,所以你将需要更换connect ,并send了一堆复杂得多的代码,构造并发送适当的TCP数据包发起的连接。 还有像图书馆scapy ,将尽一切坚硬的东西给你,但是如果你想要做手工,你只需要阅读RFC 791和RFC 793认真,做的所有繁琐的东西(确保你得到所有字节序权),你对你的方式。

在* BSD(包括OS X),内核将填写IP长度,TCP长度,而且,最重要的是,TCP校验和。 如果你要处理那些自己它变得更加痛苦。 (如果没有你的平台上工作,你可能做......要么,还是我搞砸了别的东西OS X修复我并自动将您的平台没有。)

import socket
import struct

def make_ip(proto, srcip, dstip, ident=54321):
    saddr = socket.inet_aton(srcip)
    daddr = socket.inet_aton(dstip)
    ihl_ver = (4 << 4) | 5
    return struct.pack('!BBHHHBBH4s4s' , 
                       ihl_ver, 0, 0, ident, 0, 255, proto, 0, saddr, daddr)

def make_tcp(srcport, dstport, payload, seq=123, ackseq=0,
             fin=False, syn=True, rst=False, psh=False, ack=False, urg=False,
             window=5840):
    offset_res = (5 << 4) | 0
    flags = (fin | (syn << 1) | (rst << 2) | 
             (psh <<3) | (ack << 4) | (urg << 5))
    return struct.pack('!HHLLBBHHH', 
                       srcport, dstport, seq, ackseq, offset_res, 
                       flags, window, 0, 0)

srcip = dstip = '127.0.0.1'
srcport, dstport = 11001, 11000
payload = '[TESTING]\n'

ip = make_ip(socket.IPPROTO_TCP, srcip, dstip)
tcp = make_tcp(srcport, dstport, payload)
packet = ip + tcp + payload

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
s.sendto(packet, (dstip, 0))
response, addr = s.recvfrom(65535)
response_id = struct.unpack('!H', response[4:6])
print response_id

每次我跑,我得到一个NAK(如果端口11000没有一个人听)或ACK报文,随机IP_ID ,正如你所期望的。



文章来源: Using raw socket in Python