使用libpcap库实现抓包
首先pip install libpcap
其次,代码示例如下
import ctypes as ct
import libpcap as pcap
import socket
import struct
# 捕获包的回调函数
# 这个arg参数的作用未知
def packet_handler(arg, pkthdr, pktdata):
header = pkthdr.contents
print(f"Packet captured at {header.ts.tv_sec}.{header.ts.tv_usec}")
print(f"Packet length: {header.len}")
erp = ct.cast(arg, ct.POINTER(ct.c_int))
# 获取原始数据包数据
pkt_data = bytes(ct.string_at(pktdata, header.len))
# 解析以太网头部
eth_header = pkt_data[:14]
eth_fields = struct.unpack("!6s6sH", eth_header)
src_mac = ':'.join(format(x, '02x') for x in eth_fields[0])
dst_mac = ':'.join(format(x, '02x') for x in eth_fields[1])
eth_type = eth_fields[2]
print(f"Source MAC: {src_mac}, Destination MAC: {dst_mac}, Ethernet Type: {eth_type}")
print(f'pkt_data: {pkt_data}')
print(f'erp: {erp}')
# 检查以太网类型是否为IP (0x0800)
if eth_type == 0x0800:
# 解析IP头部
ip_header = pkt_data[14:34]
ip_fields = struct.unpack("!BBHHHBBH4s4s", ip_header)
src_ip = socket.inet_ntoa(ip_fields[8])
dst_ip = socket.inet_ntoa(ip_fields[9])
protocol = ip_fields[6]
print(f"Source IP: {src_ip}, Destination IP: {dst_ip}, Protocol: {protocol}")
# 检查协议类型是否为TCP (6)
if protocol == 6:
# 解析TCP头部
tcp_header = pkt_data[34:54]
tcp_fields = struct.unpack("!HHLLBBHHH", tcp_header)
src_port = tcp_fields[0]
dst_port = tcp_fields[1]
print(f"Source Port: {src_port}, Destination Port: {dst_port}")
elif protocol == 17:
# 解析UDP头部
udp_header = pkt_data[34:42]
udp_fields = struct.unpack("!HHHH", udp_header)
src_port = udp_fields[0]
dst_port = udp_fields[1]
payload = pkt_data[42:]
print(payload.decode('utf-8'))
print(f"Source Port: {src_port}, Destination Port: {dst_port}")
# 创建一个错误缓冲区
errbuf = ct.create_string_buffer(pcap.PCAP_ERRBUF_SIZE)
# 打开网络接口进行实时抓包
interface = b'\\Device\\NPF_{C86EFAD2-176C-4AB5-B6AD-441CFE0FCD2A}' # 请根据你的实际网络接口名称修改
snaplen = 65535 # 捕获数据包的最大长度
promisc = 1 # 设置为1以启用混杂模式
timeout = 1000 # 以毫秒为单位的超时时间
handle = pcap.open_live(interface, snaplen, promisc, timeout, errbuf)
# 检查是否成功打开接口
if not handle:
print(f"Error opening device {interface}: {errbuf.value}")
else:
print(f"Successfully opened device {interface} for capturing.")
# 设置一个示例过滤器(例如:只捕获TCP包)
filter_str = b"udp"
program = pcap.bpf_program()
netmask = pcap.bpf_u_int32()
# 编译过滤器
if pcap.compile(handle, ct.byref(program), filter_str, 0, netmask) == -1:
print(f"Error compiling filter: {pcap.geterr(handle).decode()}")
else:
print("Filter compiled successfully.")
# 应用过滤器
if pcap.setfilter(handle, ct.byref(program)) == -1:
print(f"Error setting filter: {pcap.geterr(handle).decode()}")
else:
print("Filter set successfully.")
# 开始捕获包
# 需要用pcap.pcap_handler将回调函数转换为cfunctiontype
packet_handler_callback = pcap.pcap_handler(packet_handler)
pcap.loop(handle, 0, packet_handler_callback, None)
print(type(packet_handler_callback))
# 关闭接口
pcap.close(handle)