我想在python中实现一个自定义NAT,就这样做而言,我想接收所有客户端数据包并修改它们。然后将它们转发到另一台设备。
我找到了可以轻松操作和发送数据包scapy
。但找不到接收数据包的方法。那么是否可以接收数据包然后像编辑source IP
和destination IP
一样编辑它们,并读取 UDP 标头并转发它们,然后转发响应数据包?
您也可以使用scapy
的sniff()
函数来接收数据包:
>>> help(sniff)
Sniff packets and return a list of packets.
Args:
count: number of packets to capture. 0 means infinity.
store: whether to store sniffed packets or discard them
prn: function to apply to each packet. If something is returned, it
is displayed.
--Ex: prn = lambda x: x.summary()
filter: BPF filter to apply.
lfilter: Python function applied to each packet to determine if
further action may be done.
--Ex: lfilter = lambda x: x.haslayer(Padding)
offline: PCAP file (or list of PCAP files) to read packets from,
instead of sniffing them
timeout: stop sniffing after a given time (default: None).
L2socket: use the provided L2socket (default: use conf.L2listen).
opened_socket: provide an object (or a list of objects) ready to use
.recv() on.
stop_filter: Python function applied to each packet to determine if
we have to stop the capture after this packet.
--Ex: stop_filter = lambda x: x.haslayer(TCP)
iface: interface or list of interfaces (default: None for sniffing
on all interfaces).
monitor: use monitor mode. May not be available on all OS
started_callback: called as soon as the sniffer starts sniffing
(default: None).
The iface, offline and opened_socket parameters can be either an
element, a list of elements, or a dict object mapping an element to a
label (see examples below).
Examples:
>>> sniff(filter="arp")
>>> sniff(lfilter=lambda pkt: ARP in pkt)
>>> sniff(iface="eth0", prn=Packet.summary)
>>> sniff(iface=["eth0", "mon0"],
... prn=lambda pkt: "%s: %s" % (pkt.sniffed_on,
... pkt.summary()))
>>> sniff(iface={"eth0": "Ethernet", "mon0": "Wifi"},
... prn=lambda pkt: "%s: %s" % (pkt.sniffed_on,
... pkt.summary()))
特别是prn
参数允许您对每个收到的数据包执行操作。他们有很多很棒的教程
根据您的评论,下面是一个示例:
def _process(pkt):
if IP in pkt:
pkt[IP].dst = "y.y.y.y"
pkt[Ether].dst = None # Force scapy to re-calculate the MAC dst
sendp(pkt) # send the packet
sniff(iface="eth0", prn=_process)