我使用以下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()
答案 0 :(得分:1)
socket
函数有第三个参数:protocol
。如果没有给出,则它默认为0.对于AF_PACKET / SOCK_RAW
,protocol
参数指定您有兴趣接收哪种类型的数据包。这些值记录在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))
...
对您的代码的其他评论:
如上所述,您发送的数据包不可能被任何人理解。您已获得dst和src MAC地址,但之后您还没有提供EtherType。相反,第一个" [("将被视为EtherType。这可能对包的任何接收者都有意义,因此它将被丢弃。
此外,您应该了解使用原始套接字,您将收到协议中指定类型的下一个数据包。这不一定(实际上可能不会是)对您刚发送的数据包的响应。
答案 1 :(得分:1)
现在感谢大家,我能够收到包含以下脚本的数据包。但是我仍然面临打印多个响应数据包的问题(在循环中进行)。
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