2011-06-02 30 views
1

我在一台Linux机器上有一个Python进程,它接收并处理原始UDP数据包。我想要另一台Linux机器server2能够收听正在接收的相同UDP数据包。我可以使用Python嗅探指向另一台Linux机器的UDP数据包吗?

是否有任何Python解决方案能够嗅探发往另一台(Linux)计算机的UDP数据包?

+0

流量通过一些非托管交换机,所以我不能从网络方面做很多事情。如何在同一台服务器上添加一个python进程:server1?是否有可能让多个Python进程在同一台机器上的相同端口号上侦听相同的UDP数据包? – avatar 2011-06-02 15:05:44

+0

否 - 只有一个进程可以侦听套接字。但是你可以有一些东西在监听套接字并将数据发送给其他多个子进程。无论是在同一台机器上还是其他机器上。它是什么样的数据? – tMC 2011-06-02 15:17:26

+0

这是一个UDP包,里面有大约150个文本字符。 – avatar 2011-06-02 15:25:03

回答

3

如果你想在多台计算机来处理同样的数据,你最好去到mulitcast(如果你能控制的发送方和基础设施)

否则,http://sourceforge.net/projects/pylibpcap/将使通过Python包捕获。您仍然必须配置基础设施以将数据包发送到要嗅探它们的机器。无论是iptables的(如果是一台Linux机器)或交换机上的端口镜像等

编辑:

如果你想在不同的机器上的进程(你认为一台机器不能做到这一切)我将有一台Linux机器接收数据,并使用iptables将其发送给多台其他机器。也许到同一台机器上的不同套接字。这是可能的,因为它的UDP。如果你想把它全部放在同一台机器上,我可能会有一个进程使用连接的PIPE产生子进程,绑定UDP套接字并将数据复制到每个子进程的管道;也许经过一些输入验证

+0

+1:我忘了他在使用UDP。多播可能是一个很好的选择 – Heisenbug 2011-06-02 14:53:48

3

这不取决于Python,而是取决于您的网络架构。如果服务器1和服务器2通过交换机连接(可能它们是),那么你不能这样做,因为通过路由器的数据包将只发送到请求的IP。

首先,告诉我们你的网络架构是如何组成的。 server1和server2在哪里?彼此如何达到?

您的问题解决方案既不取决于您的操作系统,也不取决于所使用的语言。 无论如何,你标记了你的问题“linux”,所以我认为你熟悉那个操作系统。 如果是这种情况,并且server1和server2通过同一个路由器访问局域网,则可以评估在您的路由器上安装linux的可能性(查看openwrt),并执行嗅探以及路由器本身的任何操作。

+1

+1因为任何解决方案都是关于网络架构,而不是编程...... – ig0774 2011-06-02 14:43:45

+0

虽然ARP欺骗可用于在交换机上嗅探。 – 2011-06-02 14:45:32

+0

如果它是一台管理型交换机,其中大部分都具有镜像端口选项。您可以设置一个镜像端口,并可以侦听来自配置的镜像端口的所有流量。 – tMC 2011-06-02 14:48:19

1

我有一个类似的问题,并写了一个小python脚本来转发传入udp数据包乘法主机。这里的一个缺点是,你丢失了原始udp数据包的源IP地址。

import socket 
import sys, time, string 

def sendUDP(remotehost,remoteport,UDPSock,data): 
    UDPSock.sendto(data, (remotehost,remoteport)) 

def serverLoop(listenport,remotes): 
    # Set up socket 
    UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 
    UDPSock.bind(("0.0.0.0",listenport)) 
    while 1: 
     data, addr = UDPSock.recvfrom(1024) 
     if not data: pass 
     else: 
      sys.stdout.write(".") ; sys.stdout.flush() 
      # Send udp packet to remotes... 
      for remote in remotes: 
       if remote[0] == addr: pass 
       else: sendUDP(remote[0],remote[1],UDPSock,data) 
     time.sleep(0.001) 

if __name__ == "__main__": 
    if len(sys.argv) < 3: 
     print "%s listenport remotehost1:port1 remotehostN:portN ..." % sys.argv[0] 
     sys.exit(-1) 
    listenport = int(sys.argv[1]) 
    print "Local foward port %d" % listenport 
    remotes = [] 
    for pair in sys.argv[2:]: 
     host,port = string.split(pair,":") 
     remotes.append((host,int(port))) 
     print "Adding remote forward %s:%s" % (host,port) 
    print "Starting serverloop" 
    serverLoop(listenport,remotes) 
+0

我写了类似的东西,我确实丢失了原来的IP,就像你说的那样。在我的情况下,我需要原始IP,因为我需要回传。任何想法如何解决IP问题? – avatar 2011-06-18 16:09:16

+0

刚刚注意到此代码中存在漏洞。您必须检查源IP是否是远程地址中的address:端口之一,否则您可能会有反馈循环,这会耗尽您的资源 – 2011-06-18 16:11:04

+0

@itgorilla,您将源IP地址放入数据中; data = struct.pack(“!LH”,ip2long(addr),port)+ data,然后将其解包到接收部分。 另一种方法是欺骗源地址,但需要超级用户权限。 – 2011-06-18 16:12:39