我用于tc
更改 TAP 接口 ( tap0
) 上传入数据包的 MAC 地址,如下所示,其中mac_org
是 QEMU 虚拟机中来宾的 MAC 地址,并且是应替换为的mac_new
不同 MAC 地址。mac_org
tc qdisc add dev tap0 ingress handle ffff:
tc filter add dev tap0 protocol ip parent ffff: \
flower src_mac ${mac_org} \
action pedit ex munge eth src set ${mac_new} pipe \
action csum ip pipe \
action xt -j LOG
我还添加了一条 iptables 规则来在输入挂钩上记录 UDP 数据包。
iptables -A INPUT -p udp -j LOG
syslog 显示 DHCP 发现数据包确实发生了相应更改。日志tc
条目如下所示:
IN=tap0 OUT= MAC=ff:ff:ff:ff:ff:ff:${mac_new}:08:00 SRC=0.0.0.0 DST=255.255.255.255 LEN=338 TOS=0x00 PREC=0xC0 TTL=64 ID=0 DF PROTO=UDP SPT=68 DPT=67 LEN=318
tc
当本地传入数据包传递到套接字时,netfilter 输入挂钩的日志条目会跟随入口挂钩,显示相同的结果,但格式略有不同。
IN=tap0 OUT= MACSRC=${mac_new} MACDST=ff:ff:ff:ff:ff:ff MACPROTO=0800 SRC=0.0.0.0 DST=255.255.255.255 LEN=338 TOS=0x00 PREC=0xC0 TTL=64 ID=0 DF PROTO=UDP SPT=68 DPT=67 LEN=318
在启动 QEMU 之前,我运行了dnsmasq
令人tap0
惊讶的输出:
DHCPDISCOVER(tap0) ${mac_org}
运行strace -f -x -s 10000 -e trace=network dnsmasq ...
显示recvmsg
包含${mac_org}
而不是 的调用${mac_new}
。
recvmsg(4, {msg_name={sa_family=AF_INET, sin_port=htons(68), sin_addr=inet_addr("0.0.0.0")}, msg_namelen=16, msg_iov=[{iov_base="... ${mac_org} ..." ...
怎么会这样呢?看起来好像数据包在 netfilter 输入挂钩之后被更改了。
答案1
我的理解是,您将修改的以太网地址(仅链路层)与客户端在请求中嵌入的tc
内部字段(客户端的硬件地址)混淆了(应用程序层永远不会被更改) 。CHADDR
DHCPDISCOVER
tc