【问题标题】:Python raw socket receive issuePython原始套接字接收问题
【发布时间】:2017-09-14 15:25:15
【问题描述】:

我正在使用以下 python 脚本进行原始套接字数据包传输。数据包传输很好,但我无法打印从另一端传入的数据包。

from socket import socket, AF_PACKET, SOCK_RAW

s = socket(AF_PACKET, SOCK_RAW)
s.bind(("eth0", 0))
src_addr = "\x54\xbe\xf7\x40\xf5\x82"
dst_addr = "\xff\xff\xff\xff\xff\xff"

payload = ("[("*30)+"Hello"+("]"*30)
checksum = "\x1a\x2b\x3c\x4d"

data = payload+checksum

s.send(dst_addr+src_addr+data)

#for receive function 

response=s.recv(4096)
print response
s.close()

【问题讨论】:

  • 接收端有没有报错? print 语句的输出是什么?
  • 接收消息的服务器应该始终处于活动状态,但您似乎关闭了套接字。
  • 不,我从“打印响应”布兰登那里得到任何打印。它继续等待recv fn。即使它从客户那里收到。
  • 我也试过不关闭套接字,但它没有捕获传入的数据包

标签: python python-2.7 sockets raw-sockets


【解决方案1】:

socket 函数还有第三个参数:protocol。如果未给出,则默认为 0。对于AF_PACKET / SOCK_RAWprotocol 参数指定您有兴趣接收的数据包类型。这些值记录在 packet(7) 手册页中:http://man7.org/linux/man-pages/man7/packet.7.html

我不认为这些值实际上是在核心 python2 模块中的任何地方定义的。其中一些可以在 scapy (http://www.secdev.org/projects/scapy/) 中找到,或者您可以只查找定义它们的 linux 头文件 (/usr/include/linux/if_ether.h)。

因此,要解决此问题,请将代码更改为:

from socket import socket, AF_PACKET, SOCK_RAW, htons

ETH_P_ALL = 3
ETH_P_IP = 0x800   # Alternatively using this will receive the next IP packet
s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
...

您的代码中的其他 cmets:

正如所写,您发送的数据包不太可能被任何人理解。你有一个 dst 和 src MAC 地址,但是你没有提供一个 EtherType。相反,第一个“[(”将被视为 EtherType。这可能对任何数据包的接收者都没有意义,因此它将被丢弃。

此外,您应该了解,使用原始套接字,您将收到您在协议中指定的类型的下一个数据包。这不一定(实际上可能不会)是对您刚刚发送的数据包的响应。

【讨论】:

  • 我检查了 linux 手册页链接,那里没有协议声明...在 if_ether.h 文件中找到它们完成了这项工作...gr8!
【解决方案2】:

感谢大家,现在我可以使用以下脚本接收数据包。但我仍然面临打印多个响应数据包的问题(在循环中执行时)。

from socket import socket, AF_PACKET, SOCK_RAW, htons
from struct import *
import select
import time

ETH_P_ALL = 3
ETH_P_IP = 0x800  
s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
s.bind(("eth0", 0))

src_addr = "\x54\xbe\xf7\x40\xf7\x82"
dst_addr = "\xff\xff\xff\xff\xff\xff"   
l = "\x00\x21"

ethertype = "\x08\x01"

a ="\x00\x10\x00\x10\x00\x10"
b = "\x00\x11\x00\x11\x00\x11"

payload = ethertype + l + a + b

for i in range(5):

    time.sleep(5)   
    s.send(dst_addr+src_addr+ payload)
    message=s.recv(4096)
    print message

【讨论】:

  • 能否请您提供更好的变量名称,例如什么是a,什么是b
猜你喜欢
  • 2018-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多