用Scapy与Csockets通信

我有一个UDP连接并侦听端口(localhost),我也试图从localhost发送一个Scapy数据包。 出于某种原因,我的C代码实际上从未捕获过数据包,但是我可以看到数据包在Wireshark中显示就好了。 自从我使用套接字以来已经有一段时间了,但我是否需要设置一些特殊的套接字选项,或者为什么我能够在Wireshark中看到数据包就好但不是通过C套接字?

注意:当我编写相应的套接字代码来发送数据包(来自localhost)时,我能够成功捕获数据包但是当从另一台计算机发送时,我仍然无法获取侦听数据包来捕获数据包。

我发现了一个类似的问题但是当我尝试他们的方法(使用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需要稍微不同地配置以在Loopback接口上工作,请参阅标题为“ 我无法ping 127.0.0.1 ”的http://www.secdev.org/projects/scapy/doc/troubleshooting.html.Scapy 不会使用127.0.0.1或环回接口

我使用了那里给出的代码并发送了一个scapy数据包,它收到了一个C Socket,具体是:

 from scapy.all import * conf.L3socket=L3RawSocket packet=IP()/UDP(dport=32000)/"HELLO WORLD" send(packet) 

然后在端口32000上绑定到的UDP C Socket上接收到此消息(Scapy默认通过环回接口发送IP数据包)。

我有同样的问题,udp socket没有收到scapy数据包。 我想可能会有一些与此帖相关的内容: Raw Socket Help:为什么内核UDP不接收原始套接字创建的UDP数据包? 对我socket.IP_HDRINCLsocket.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上validation,虽然不适用于我的MBP …

我认为问题在于设置不兼容的接口,src和dst地址集。

当目的地是环回(127.0.0.1)时,接口应该是lo和地址(假设客户端和服务器在同一主机上运行):

 ip_pkt.dst = "127.0.0.1" ip_pkt.src = "127.0.0.1" 

另一种方法是发送到以太网地址(假设在eth0上配置了192.168.1.1 ,并且客户端和服务器都在同一主机上运行):

 ip_pkt.dst = "192.168.1.1" ip_pkt.src = "192.168.1.1" 

如果您尝试不同的主机,则无法使用127.0.0.1lo 。 将src设置为客户机的ip和dst到服务器机器的ip。