UPNP端口映射简单流程
文章目录
0 简介1 寻址2发现2.1 广播2.2 响应
3 描述3.1 GET描述文件3.2 获取并解析XML描述文件
4 控制4.1 获取状态信息4.2 获取外网IP4.3 获取端口映射信息4.4端口映射
5 一些疑问5.1 端口映射的有效期是多久?5.2 多级路由如何映射成功
6 开源库
参考文档:
1.RFC 6970
https://www.rfc-editor.org/info/rfc6970
2.《UDA1.0-ChinesePDF.pdf》 http://read.pudn.com/downloads37/doc/comm/125876/UDA1.0-ChinesePDF.pdf
3.UPnP基本原理以及在NAT中的应用 https://blog.csdn.net/wuruixn/article/details/23920871
4.UPnP的介绍和理解 https://blog.csdn.net/be_happy_mr_li/article/details/52919759
5.UPnP的工作过程 https://blog.csdn.net/ocean181/article/details/7406816
6.upnp协议简介(一) https://blog.csdn.net/braddoris/article/details/41646789
一些词语: control point(控制点):在本文中可以理解为需要端口映射的设备,比如内网的一些子设备 root device(根设备):提供服务的设备,在本文中可以简单理解为路由器 IGD(Internet Gateway Device):网络网关设备,比如路由器
0 简介
参考文档介绍了UPNP的相关原理,接下来进行一个简单的实战,用于练练手。 我们在内网的设备只有内网的IP:PORT,因此公网设备无法主动和内网的设备进行主动连接。一个简单的方法便是使用UPNP端口映射,将内网设备的PORT(P1)映射到公网的PORT(P2),当其他公网设备主动和P2通信后,路由会将数据转发到P1上。
下面就UPNP的端口映射功能整个流程做个梳理。
1 寻址
所谓的寻址,简单来说就是设备能够连上网络,能够获取IP。
2发现
发现设备,在《UDA1.0-ChinesePDF.pdf》中,有如下描述:
当设备被添加到网络后, UPnP 发现协议允许该设备向网络中的控制点宣告其服务。同样,当一个控制点被添加到网络后,UPnP 发现协议允许该控制点在网上搜索感兴趣的设备。
所以当控制点添加到网络中后,会搜索局域网内支持UPNP协议的设备。在本文中,可理解为发现支持UPNP端口映射的路由器。
2.1 广播
设备需要向239.255.255.250:1900发送多播信息,用于搜索周围支持UPNP的设备多播信息如下:
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1
MAN: "ssdp:discover"
MX: 2
各个字段含义如下:
SEARCH:SSDP定义的搜索请求方法
HTTP/1.1: HTTP版本
HOST: 由IANA为SSDP保留的多播信道和端口,必须为239.255.255.250:1900
MAN: 固定为"ssdp:discover",注意双引号不可少
MX: 最长等待时间,设备会在0和这个值之间随机选择延迟的值,用于均衡负载。
ST: 搜索目标,有以下类型:
ssdp:all
搜索所有设备和服务。
UPnP:rootdevice
只搜索根设备。
uuid:device-UUID
搜索特殊设备。设备 UUID 由 UPnP 厂商指定。
urn:schemas-UPnP-org:device:deviceType:v
搜索同类设备。设备类型与版本由 UPnP 论坛工作委员会定义。
2.2 响应
当设备收到多播消息后,会向控制点发送多播消息的源IP:PORT发送UDP响应,并回复给控制点信息。
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=100
DATE: Wed, 04 Jan 2006 00:58:36 GMT
EXT:
LOCATION: http://192.168.2.1:1900/igd.xml
SERVER: Wireless N Router WR745N, UPnP/1.0
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1
USN: uuid:upnp-InternetGatewayDevice-192168123178900001::urn:schemas-upnp-org:device:InternetGatewayDevice:1
各个字段含义如下:
CACHE-CONTROL: 表示宣告有效持续时间,如果超过此时间,控制点可以认为设备或服务不再可用
DATE: 响应生成时间,此字段可以不使用
EXT:表示上面discover中的MAN标头已经被理解
LOCATION: 表示设备的UPNP描述的URL
SERVER:记录设备的版本信息
ST: 搜索目标,取值如下:
ssdp:all
如果根设备带有 d 种嵌入式设备与 s 种嵌入服务且只有 K 种不同服务类型,那么其响应次数为 3+2d+k。 ST 标头值必须与采用ssdp:alive 的 NOTIFY 消息中的 NT 标头保持统一。
UPnP:rootdevice
向根设备响应一次。必须是 UPnP:rootdevice。
uuid:device-UUID
向每种设备(根设备或嵌入式设备)响应一次。必须是uuid:device-UUID。设备 UUID 由 UPnP 厂商指定。
urn:schemas-UPnP-org:device:deviceType:v
向每种设备(根设备或嵌入式设备)响应一次。必须是urn:schemas-UPnP-org:device:deviceType:v。设备类型与版本由 UPnP 论坛工作委员会定义。
USN:服务名称,取值如下:
uuid:device-UUID::UPnP:rootdevice
向根设备发送一次。设备 UUID 由 UPnP 厂商指定。
uuid:device-UUID
向每种设备(根设备或嵌入式设备)发送一次。 设备 UUID 由 UPnP厂商指定。
uuid:device-UUID::urn:schemas-UPnP-org:device:deviceType:v
向每种设备(根设备或嵌入式设备)发送一次。 设备 UUID 由 UPnP厂商指定。设备类型与版本由 UPnP 论坛工作委员会定义。
在上面信息中心,有一个比较重要的便是LOCATION,在下面我们会通过这个设备描述URL来获取设备的服务。
至此,整个发现过程便结束了,控制点已经获取到了局域网内的设备信息。
3 描述
在发现设备之后,我们只是发现了设备,但是并不知道设备有什么服务,有什么功能等等。因此我们需要从上面设备发现的消息中获取设备描述URL,从而来获取设备的描述。
3.1 GET描述文件
控制点会和设备描述URL中的IP:PORT建立TCP连接,并GET获取xml数据。请求如下:
GET /igd.xml HTTP/1.1
Host: 192.168.2.1:1900
Connection: Close
User-Agent: Ubuntu/12.04, UPnP/1.1, MiniUPnPc/1.9
3.2 获取并解析XML描述文件
控制点会收到如下描述文件:
HTTP/1.1 200 OK
CONTENT-LENGTH: 2746
CONTENT-TYPE: text/xml
DATE: Wed, 04 Jan 2006 00:58:40 GMT
LAST-MODIFIED: Tue, 28 Oct 2003 08:46:08 GMT
SERVER: Wireless N Router WR745N, UPnP/1.0
CONNECTION: close
部分字段含义如下:
UDN:全球唯一设备标识符
serviceType:UPNP服务类型。
在上面的报文中,有WANIPConnection/Layer3Forwarding/WANCommonInterfaceConfig等服务类型。其中,WANIPConnection便是我们下面端口映射需要的服务,关于这个描述,有如下定义:
此服务类型使UPnP控制点能够配置和控制符合UPnP的InternetGatewayDevice的WAN接口上的IP连接。 可以支持IP连接的任何类型的WAN接口(例如,DSL或电缆)都可以使用此服务。 […] 为WANConnectionDevice上的每个实际Internet连接实例激活WANIPConnection服务的实例(请参阅状态变量表)。 WANIPConnection服务为LAN上的联网客户端提供了与ISP的IP级连接。
SCPDURL: 服务描述URL
WANIPConnection的服务描述URL是/ipc.xml,因此我们可以在浏览器中输入设备的URL, http://192.168.2.1:1900/ipc.xml, 便可以看到详细的信息,里面包含了许多动作,如下:
controlURL:控制的URL
WANIPConnection的控制URL是/ipc
至此,描述结束。在这个阶段中,我们找到了需要的服务WANIPConnection,并且获取到了控制URL:/ipc
4 控制
在上面的过程中,我们获取了设备的服务,因此接下来便可以控制设备。在本文中,我们控制设备进行端口映射,相关的控制如下:
AddPortMapping:增加端口映射
DeletePortMapping:删除端口映射
GetGenericPortMappingEntry:获得端口映射信息
GetExternalIPAddress:获取外网IP
GetStatusInfo: 获取状态信息
4.1 获取状态信息
交互过程如下:
POST /ipc HTTP/1.1
Host: 192.168.2.1:1900
User-Agent: Ubuntu/12.04, UPnP/1.1, MiniUPnPc/1.9
Content-Length: 271
Content-Type: text/xml
SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#GetStatusInfo"
Connection: Close
Cache-Control: no-cache
Pragma: no-cache
上面信息中有几个需要关注的点: POST /ipc HTTP/1.1, 其中/ipc便是路径控制URL SOAPACTION:必须是要调用的服务类型、散列符号和动作名称
HTTP/1.1 200 OK
CONNECTION: close
SERVER: Wireless N Router WR745N, UPnP/1.0
CONTENT-LENGTH: 480
CONTENT-TYPE: text/xml; charset="utf-8"
4.2 获取外网IP
POST /ipc HTTP/1.1
Host: 192.168.2.1:1900
User-Agent: Ubuntu/12.04, UPnP/1.1, MiniUPnPc/1.9
Content-Length: 285
Content-Type: text/xml
SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress"
Connection: Close
Cache-Control: no-cache
Pragma: no-cache
HTTP/1.1 200 OK
CONNECTION: close
SERVER: Wireless N Router WR745N, UPnP/1.0
CONTENT-LENGTH: 402
CONTENT-TYPE: text/xml; charset="utf-8"
NewExternalIPAddress中的值便是外网IP,因为我的路由器是多级路由,所以并没有获取到真正的公网IP
4.3 获取端口映射信息
POST /ipc HTTP/1.1
Host: 192.168.2.1:1900
User-Agent: Ubuntu/12.04, UPnP/1.1, MiniUPnPc/1.9
Content-Length: 341
Content-Type: text/xml
SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#GetGenericPortMappingEntry"
Connection: Close
Cache-Control: no-cache
Pragma: no-cache
HTTP/1.1 200 OK
CONNECTION: close
SERVER: Wireless N Router WR745N, UPnP/1.0
CONTENT-LENGTH: 687
CONTENT-TYPE: text/xml; charset="utf-8"
4.4端口映射
POST /ipc HTTP/1.1
Host: 192.168.2.1:1900
User-Agent: Ubuntu/12.04, UPnP/1.1, MiniUPnPc/1.9
Content-Length: 604
Content-Type: text/xml
SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"
Connection: Close
Cache-Control: no-cache
Pragma: no-cache
上面有几个值需要关注一下: NewExternalPort:需要映射的外网端口 NewProtocol:TCP/UDP NewInternalPort:内部端口 NewInternalClient:内部IP,即控制点IP NewPortMappingDescription:端口映射的描述 NewLeaseDuration:控制点活动状态持续时间,0表示无限制
HTTP/1.1 200 OK
CONNECTION: close
SERVER: Wireless N Router WR745N, UPnP/1.0
CONTENT-LENGTH: 332
CONTENT-TYPE: text/xml; charset="utf-8"
设备返回200 OK,表示映射成功。如果是通过路由器上映射的话,我们便可以在路由器WEB页面看到相关信息。 以上便是UPNP端口映射的流程,本文只是简单介绍了端口映射。所以对UPNP后续的事件/展示等过程没有进行研究。
5 一些疑问
5.1 端口映射的有效期是多久?
关于端口映射的有效期是多久,了解时间太短,没有找到有效的信息。不过在miniUPnP的官网上找到了一些信息,在控制点进行端口映射的时候会有NewLeaseDuration字段,表示控制点活动状态持续时间,将这个值设置为0则表示无限制。
5.2 多级路由如何映射成功
由于UPNP只能穿透一层网络,所以如果遇到多级路由这样的复杂网络环境,虽然端口映射成功,但是并没有真正映射到公网。但是查询了一圈资料,并没有找到如何能在多级路由中映射到真正的公网,如果有了解的,麻烦告知一下,共同探讨。
6 开源库
网上有一些开源的UPNP库,可以将我们从这些繁杂的交互过程中独立出来,专注于应用。虽然了解了轮子的构造过程,但是就不需要重新造轮子了。 MiniUPnP: https://github.com/miniupnp/miniupnp Libupnp: http://pupnp.sourceforge.net/