一、实现目标
两台主机通过单网线(点对点通信)、双网线+交换机(简单局域网通信)进行网络通信,使用scapy进行pcap数据包的发送和接收。
具体实现效果如下所示:
主机A发送pcap数据包:
主机B接收pcap数据包:
二、操作步骤
1、单网线(点对点通信)搭建
操作方法:
如果二者可以ping通,则说明主机A和主机B可以正常通信;进行主机间收发包的代码编写工作(使用scapy收发pcap数据包):假设主机A为发包方,主机B为收包方;则二者对应代码分别为:
发包代码:
from scapy.all import *
# 该代码可有可无
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
src_ip = '192.168.1.2' # 主机A ip地址
dst_ip = '192.168.1.3' # 主机B ip地址
sport = 8000 # 源端口号
dport = 6666 # 目标端口号
pkts = rdpcap('aim_chat_3a.pcap') # 要发送的pcap文件
# pkts = rdpcap('vpn_aim_chat1a.pcap')
pkt = pkts[0]
pkt.show()
# 修改MAC地址、IP地址和端口号
if Ether in pkt:
pkt[Ether].dst = 'E8:6A:64:06:3C:BC' # 主机B mac地址
pkt[Ether].src = '84:7B:EB:24:F3:41' # 主机A mac地址
pkt[IP].src = src_ip
pkt[IP].dst = dst_ip
pkt[TCP].sport = sport
pkt[TCP].dport = dport
pkt[Raw].load = b"hello world"
# 手动重新计算校验和
del pkt[TCP].chksum
del pkt[IP].chksum
del pkt[IP].len
pkt = pkt.__class__(bytes(pkt))
pkt.show()
if Ether in pkt:
# iface表示主机A(发包方)的网卡名称
response = srp1(pkt, iface="Intel(R) Ethernet Connection I219-LM")
else:
response =sr1(pkt,iface="Intel(R) Ethernet Connection I219-LM")
if response:
print('TRUE')
print(response)
else:
print('false')
主机B收包代码:
from scapy.all import *
import time
receive_port = 6666 # 接收方检测端口
# 回调函数:用于处理接收数据包的后续操作
def packet_handler(packet) :
if TCP in packet and packet[TCP].dport == receive_port:
# packet.show()
now_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
print(str(now_time)+"\nThe server has received a message:\t"+packet[Raw].load.decode())
# iface表示主机B(收包方)的网卡名称
sniff(filter=f"host 192.168.1.3", iface="Realtek PCIe GbE Family Controller #2", prn=packet_handler)
注意:如果使用网线连接的话,网卡名称需要是对应的有线网卡,而不是连接热点或wifi的无线网卡,对应IP地址和MAC地址也是有线网卡对应的IP地址和MAC地址。
2、双网线+交换机(点对点通信)搭建
使用两根网线分别连接主机A和交换机、主机B和交换机,分别设置主机A和主机B的IP地址为192.168.1.2和192.168.1.3,子网掩码均为255.255.255.0;分别在主机A和主机B上测试二者是否可以正常通信(ping通),测试前注意关闭防火墙;
如果二者可以ping通,则说明主机A和主机B可以正常通信;进行主机间收发包的代码编写工作(使用scapy收发pcap数据包):假设主机A为发包方,主机B为收包方;则二者对应代码分别为:
发包代码同上。
搭建简易图如下: