我有一个 UDP 连接并准备好在端口(本地主机)上接收消息,并且我也尝试从本地主机发送 Scapy 数据包。由于某种原因,我的 C 代码从未真正捕获数据包,但我可以看到数据包很好地显示在 Wireshark 中。我已经有一段时间没有使用套接字了,但是是否有一些特殊的套接字选项我必须设置,或者为什么我能够在 Wireshark 中很好地看到数据包,但不能通过 C 套接字看到?
注意:当我编写相应的套接字代码来发送数据包(从本地主机)时,我能够成功捕获数据包,但是当从另一台计算机发送时,我仍然无法获取侦听代码来捕获数据包。
我发现了一个类似的问题,但是当我尝试他们的方法(使用UDP而不是TCP)时,我仍然无法
netcat
捕获Scapy数据包。
C 代码(为了清晰起见,进行了精简)
int main() {
int sock, dataLen, inLen;
struct sockaddr_in inAddr;
short listen_port = 8080;
char buffer[2048];
if (sock = socket(AF_INET,SOCK_DGRAM,0) < 0) {
printf("ERROR: unable to establish socket\n");
return -1;
}
// zero out address structure
memset(&inAddr, 0, sizeof(inAddr));
inAddr.sin_family = AF_INET;
inAddr.sin_addr.s_addr = htonl(INADDR_ANY);
inAddr.sin_port = htons(listen_port);
if (bind(sock, (struct sockaddr*)&inAddr, sizeof(inAddr)) < 0) {
printf("ERROR: unable to bind\n");
return -1;
}
inLen = sizeof(inAddr);
printf("Now listening on port %d\n", listen_port);
while(1) {
dataLen = recvfrom(sock, buffer, 1500, 0, (struct sockaddr*)&inAddr, &inLen);
if (dataLen < 0)
printf("Error receiving datagram\n");
else
printf("Received packet of length %d\n", dataLen);
}
return 0;
}
Scapy 脚本
# set interface
conf.iface="lo0"
# create IP packet
ip_pkt = IP()/UDP()
ip_pkt.payload = "payload test message"
ip_pkt.dport = 8080
ip_pkt.dst = "127.0.0.1"
ip_pkt.src = "127.0.0.1"
# send out packet
send(ip_pkt)
Scapy 需要进行稍微不同的配置才能在环回接口上工作,请参阅标题“我无法 ping 127.0.0.1”下的 http://www.secdev.org/projects/scapy/doc/troubleshooting.html Scapy 不适用于 127.0.0.1 或环回接口”
我使用了那里给出的代码并发送了一个由 C Socket 接收的 scapy 数据包,具体是:
from scapy.all import *
conf.L3socket=L3RawSocket
packet=IP()/UDP(dport=32000)/"HELLO WORLD"
send(packet)
然后在绑定到端口 32000 的 UDP C 套接字上接收到该信息(Scapy 默认通过环回接口发送 IP 数据包)。
我有同样的问题,udp套接字没有收到scapy数据包。 我想可能有一些与这篇文章相关的内容:原始套接字帮助:为什么内核 UDP 不接收由原始套接字创建的 UDP 数据包? 对我有用的是
socket.IP_HDRINCL
选项。这是两者和发送者的工作代码。
发件人:
import socket
from scapy.all import *
rawudp=socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
rawudp.bind(('0.0.0.0',56789))
rawudp.setsockopt(socket.SOL_IP, socket.IP_HDRINCL,1)
pkt = IP()/UDP(sport=56789, dport=7890)/'hello'
rawudp.sendto(pkt.build(), ('127.0.0.1',7890))
接收者:
import socket
so = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
so.bind(('0.0.0.0',7890))
while True:
print so.recv(1024)
已在 Fedora 14 上验证,但不适用于我的 MBP...
我认为问题在于设置不兼容的接口、src 和 dst 地址集。
当目的地是环回(127.0.0.1)时,接口应该是
lo
和地址(假设客户端和服务器都在同一主机上运行):
ip_pkt.dst = "127.0.0.1"
ip_pkt.src = "127.0.0.1"
另一种方法是发送到以太网地址(假设
192.168.1.1
在eth0
上配置,并且客户端和服务器都在同一主机上运行):
ip_pkt.dst = "192.168.1.1"
ip_pkt.src = "192.168.1.1"
如果您尝试不同的主机,则无法使用
127.0.0.1
和 lo
。将 src 设置为客户端计算机的 ip,将 dst 设置为服务器计算机的 ip。