防火墙拦截了一个svchost到239.255.255.250:1900的访问请求,经查原来是UPnP端口映射,顺便把搜集的有关实现方法放上。
UPnP 端口映射的实现
原作者: yoqi(优奇)
原文网址:http://blog.youkuaiyun.com/yoqi/archive/2005/06/28/405260.aspx
Bitcomet、比特精灵等软件已经实现了内网程序往网关端口自行开启端口映射的功能,以便外网程序直接TCP连接内网机器,去年我的一个项目刚好需要这个功能,找了些资料,了解了一下UPnP规范,实现了这个功能。
UPnP端口映射的过程和简单原理:
UPnP设备一般支持HTTP控制,就像现在某些无线AP,可以在浏览器输入 http://ip:port 的方式去访问操控一样。
所以照着普通的网络编程,TCP连接过去,发送HTTP包,包头和包数据遵照一定规格填写就是。至于这个ip/port的获得,只要往UPnP规定的ip/port(比如239.255.255.250:1900)发送一定规格的UDP广播包,就能查询得到(比如http://192.168.0.1:2869/upnphost/udhisapi.dll?content=uuid:fb6bbc52-aa87-4939-a4fa-289d3bbccc61等等)
所以客户端无操作系统的限制,只要支持最普通的tcp/ip即可
简单的步骤:
1、搜索UPnP设备:
UDP 往 239.255.255.250:1900 广播一个"搜索"的HTTP包(格式当然有规定,就不贴上来了,以免啰嗦,查一下资料即可),如果收到返回,分析一下,会得到包含类似 http://192.168.0.1:2869/upnphost/udhisapi.dll?content=uuid:fb6bbc52-aa87-4939-a4fa-289d3bbccc61 的数据
2、得到UPnP设备属性和描述信息:
TCP 往前面得到的ip/port发一个GET的HTTP包,也就是类似在浏览器中访问http://192.168.0.1:2869/,分析返回的数据,即可得到UPnP的一些描述信息,和 controlurl。
3、对UPnP设备发送控制命令,查询属性。(比如下达增删端口映射的命令)
TCP 往 controlurl 发送一定规格的指令数据即可,比如增加端口是 AddPortMapping,再填一些参数就可以,删除端口是 DeletePortMapping。也可以往这个 controlurl 查询一下,看是否支持一些指令操作,和查询一些属性等等
这些操作都是用TCP或UDP发送HTTP包,包内是XML格式的数据,返回的也是标准的HTTP返回,表明成功失败等等。
UPnP只不过是TCP/UDP、XML、HTTP,还有其它通用协议的综合运用,并没有创新什么新协议。端口映射,只是UPnP一个小的功能模块,严格来说,不算是UPnP特别指定要的,只不过是网关设备支持UPnP操作,提供了增删端口映射的功能调用而已。
UPnP的一个目标是各种设备能自动的互相发现、查询、访问和操作(比如数码相机、电脑、打印机、数码像框都能自动的互相发现和访问对方的相片,等等),具体我也没深究,有兴趣的话查一下资料。
上面所说的 UPnP 端口映射代码,大家可以在 eMule 0.46a 的源码里找到,它跟比特精灵所公开的源码基本一样,不知是谁抄谁的了,哈