【问题标题】:python socket.recv hangs, however I see the frame in tcpdumppython socket.recv 挂起,但是我在 tcpdump 中看到了框架
【发布时间】:2015-05-03 07:20:59
【问题描述】:

我有下面的代码来发送命令,但 python 脚本永远不会退出。它挂起。 我正在使用 RHEL 6.4 x86_64。 scapy srp1 也挂了。

from socket import *
from scapy.all import *
from myproto import *

def sendeth(REQUEST, interface = "eth0"):
    """Send raw Ethernet packet on interface."""
    s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
    s.bind((interface, 0))
    s.send(REQUEST)
    data = s.recv(2048)
    hexdump(data)


p = Ether()/MYPROTO()/MYPROTO1()
hexdump(p)

if __name__ == "__main__":
    print "Sent %d-byte Ethernet packet on eth3" % sendeth(str(p), 'eth3')

但是执行之后,我在tcpdump上看到了frame,但是python代码永远不会退出,需要一个control^C。

tcpdump: WARNING: eth3: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth3, link-type EN10MB (Ethernet), capture size 65535 bytes
17:10:37.122445 00:00:00:00:00:00 (oui Ethernet) > Broadcast, ethertype  Unknown (0x8096), length 34:
    0x0000:  ffff ffff ffff 0000 0000 0000 8096 0001
    0x0010:  0001 1500 0000 0000 0000 0000 0000 ffff
    0x0020:  eafe
17:10:37.133248 00:04:25:1c:a0:02 (oui Unknown) > Broadcast, ethertype Unknown (0x8096), length 76:
    0x0000:  ffff ffff ffff 0004 251c a002 8096 0001
    0x0010:  0001 9500 0028 0000 0000 0000 0000 0000
    0x0020:  0000 f1f0 f100 0000 0000 0000 0000 0000
    0x0030:  0000 0000 0000 0803 0087 1634 8096 8096
    0x0040:  e4f2 0000 0f21 fffc 5427 ffff

【问题讨论】:

    标签: python sockets rhel


    【解决方案1】:

    strace 在等待选择时帮助找到了解决方案 - 解决方案是 -

    from socket import *
    from scapy.all import *
    from myproto import *
    MYPROTOTYPE = 0x8096
    
    p = Ether()/MYPROTO()/MYPROTO1()
    hexdump(p)
    
    from socket import socket, PF_PACKET, SOCK_RAW
    
    s = socket(PF_PACKET, SOCK_RAW, MYPROTOTYPE)
    s.bind(("eth3", MYPROTOTYPE))
    s.send(str(p))
    data = s.recv(2048)
    hexdump(data)
    

    【讨论】:

      【解决方案2】:

      当您在套接字上调用recv() 时,内核中的网络堆栈已经分派了您正在发送的帧,并注意到本地主机上没有任何东西在等待它,将其丢弃。删除>

      尝试将发送方和接收方作为不同的进程运行。

      编辑 0:

      尝试将您的特定协议号作为第三个参数添加到socket()。这是一个从我在 Debian 上的 eth0 中抓取十个以太网帧的示例(需要 root 权限):

      import socket
      # from linux/if_etheer.h, all ethernet protocols, be very careful
      ETH_P_ALL=0x0003
      s=socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
      s.bind(('eth0', 0)) 
      for n in range(10):
          print n, len(s.recv(2048))
      

      【讨论】:

      • 嗯...不。内核缓冲发往打开的套接字的数据。
      • 使用 TCP 和 UDP 等普通传输协议 - 是的。使用原始套接字 - 我不太确定。
      • 嗯,现在我想起来了——我也不是。不幸的是,我无法再恢复我的反对票了。
      • 我尝试了不同的过程来接收,但我没有在 python 中看到框架。我不确定这是否与我丢失的一些秘密套接字标志或堆栈的某些系统问题有关,而不是 fwd 到 python。我的系统上有“libpcap-1.0.0-6.20091201git117cb5.el6.x86_64”。
      • 是的,我今天也试过了,今天也打算发同样的。无论如何,特定的以太类型解决了这个问题,而且在单个进程中也是如此。
      猜你喜欢
      • 1970-01-01
      • 2015-07-07
      • 2016-09-26
      • 1970-01-01
      • 2021-01-24
      • 1970-01-01
      • 1970-01-01
      • 2018-01-29
      • 1970-01-01
      相关资源
      最近更新 更多