SSDP协议
0x01何为SSDP
SSDP 使用一个固定的组播地址 239.255.255.250 和 UDP 端口号 1900 来监听其他设备的请求。SSDP 协议的请求消息有两种类型,第一种是服务通知,设备和服务使用此类通知消息声明自己存在;第二种是查询请求,协议客户端用此请求查询某种类型的设备和服务。
“为了能被网络搜索发现,目标设备应该向发起多播请求的源IP地址及端口发送单播UDP响应。如果M-SEARCH请求报文的ST头部字段以“ssdp:all”、“upnp:rootdevice”或者“uuid:”开头,后面跟着与设备相匹配的UUID信息,或者如果M-SERCH请求与设备支持的设备类型或服务类型相匹配,那么该设备就会应答M-SEARCH请求报文”。这种策略在实际环境中能够正常工作。例如,我的Chrome浏览器经常会请求搜索智能电视:
1 | $ sudo tcpdump -ni eth0 udp and port 1900 -A IP 192.168.1.124.53044 > 239.255.255.250.1900: UDP, length 175 |
这个报文被发往一个多播IP地址。监听这一地址的其他设备如果与报文头部中指定的ST(search-target,搜索目标)多屏幕类型设备相匹配,那么这些设备应该会响应这个请求报文。除了请求具体的设备类型,请求报文中还可以包含两类“通用的”ST查询类型:
1、upnp:rootdevice:搜索root设备
2、ssdp:all:搜索所有的UPnP设备以及服务你可以运行以下python脚本(在另一脚本的基础上修改而得),使用前面提到的这些ST查询类型来枚举网络中的设备列表:
1 |
|
0x02设备查询
当一个客户端接入网络的时候,它可以向一个特定的多播地址的 SSDP 端口使用 M-SEARCH 方法发送 “ssdp:discover” 消息。当设备监听到这个保留的多播地址上由控制点发送的消息的时候,设备将通过单播的方式直接响应控制点的请求。
典型的设备查询请求消息格式:
1 | M-SEARCH * HTTP/1.1 |
响应消息
响应消息应该包含服务的位置信息(Location 或AL头),ST和USN头。响应消息应该包含cache控制信息(max-age 或者 Expires头)。
典型的响应消息格式:
1 | HTTP/1.1 200 OK |
设备通知消息
在设备加入网络时,它应当向一个特定的多播地址的 SSDP 端口使用 NOTIFY 方法发送 “ssdp:alive” 消息,以便宣布自己的存在,更新期限信息,更新位置信息。
1 ssdp:alive 消息
由于 UDP 协议是不可信的,设备应该定期发送它的公告消息。在设备加入网络时,它必须用 NOTIFY 方法发送一个多播传送请求。NOTIFY 方法发送的请求没有回应消息。
典型的设备通知消息格式如下:
1 |
|
2 ssdp:byebye消息
当一个设备计划从网络上卸载的时候,它也应当向一个特定的多播地址的 SSDP 端口使用 NOTIFY 方法发送 “ssdp:byebye” 消息。但是,即使没有发送 “ssdp:byebye” 消息,控制点也会根据 “ssdp:alive” 消息指定的超时值,将超时并且没有再次收到的 “ssdp:alive” 消息对应的设备认为是失效的设备。
典型的设备卸载消息格式如下:
1 | NOTIFY * HTTP/1.1 |
参考
P2P 网络核心技术:UPnP 和 SSDP 协议 - 知乎 (zhihu.com)