手动转发不同VLAN的mDNS报文

由于我的网络为上网设备和IoT设备划分了不同的VLAN, 提供AirPlay服务的电视在IoT设备的VLAN, 且手机在上网设备的VLAN, 而mDNS组播报文在默认情况下不会跨越VLAN转发, 因此, 我需要某种方法来让手机收到电视发出的mDNS组播报文。为此, 我尝试了avahi的mDNS Reflector。然而, 我又发现它会导致某些设备觉得自己的主机名有冲突, 于是, 我决定研究一种新方法。后来, 考虑到我实际上只需要让上网设备的VLAN收到电视的AirPlay服务发出的mDNS组播报文, 我决定先在IoT设备的VLAN下抓包获得相应的mDNS报文, 然后再手动在上网设备的VLAN中重放。具体方案记录如下:

一、抓包

如上所述, 先在IoT设备的VLAN下抓相应的mDNS组播包, 保存备用。

二、重放

然后, 我研制了一份脚本, 来定期通过ICMP Echo Request (俗称ping)检测电视是否开启, 若开启了, 则手动重放相应的mDNS组播包:

#!/usr/bin/env python3

import binascii
import time
from scapy.all import conf
from scapy.layers.l2 import *
from scapy.layers.inet import *
from scapy.sendrecv import *

conf.promisc = False
conf.sniff_promisc = False

payload = '''
这里粘贴mDNS报文的有效载荷部分, 从UDP头结束之后开始,
格式为:
00 00 84 00 00 00 00 0e 00 00 00 05 01 31 01 31
03 31 31 31 03 31 31 31 07 69 6e 2d 61 64 64 72
...
'''.replace(' ', '').replace('\n', '')
payload = binascii.a2b_hex(payload)

SERVER_ADDR = '111.111.1.1'  # 这里修改为服务器(电视)的IP地址
mdns = IP(src=SERVER_ADDR, dst='224.0.0.251', ttl=255) / UDP(sport=5353, dport=5353) / payload

while True:
  echo = sr1(IP(dst=SERVER_ADDR) / ICMP(), timeout=1)
  if echo:
    send(mdns * 5, iface='eth0')  # 这里修改为接入上网设备的VLAN的网络接口
  time.sleep(10)

经测试, 非常好用!

请注意, 该脚本工作的前提是两个VLAN在三层互通。

发表评论

注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

:wink: :twisted: :roll: :oops: :mrgreen: :lol: :idea: :evil: :cry: :arrow: :?: :-| :-x :-o :-P :-D :-? :) :( :!: 8-O 8)

本文链接:https://twd2.me/archives/17985QrCode