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

1

0

urn:schemas-upnp-org:device:InternetGatewayDevice:1

http://192.168.2.1:80

Wireless N Router WR745N

TP-LINK

http://www.tp-link.com.cn

TL-WR745N 1.0

TL-WR745N

1.0

uuid:upnp-InternetGatewayDevice-192168123178900001

123456789001

urn:schemas-upnp-org:service:Layer3Forwarding:1

urn:upnp-org:serviceId:L3Forwarding1

/l3f

/l3f

/l3f.xml

urn:schemas-upnp-org:device:WANDevice:1

WAN Device

TP-LINK

http://www.tp-link.com.cn

WAN Device

WAN Device

1

12345678900001

uuid:upnp-WANDevice-192168123178900001

123456789001

urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1

urn:upnp-org:serviceId:WANCommonInterfaceConfig

/ifc

/ifc

/ifc.xml

urn:schemas-upnp-org:device:WANConnectionDevice:1

WAN Connection Device

TP-LINK

http://www.tp-link.com.cn

WAN Connection Device

WAN Connection Device

1

12345678900001

uuid:upnp-WANConnectionDevice-192168123178900001

123456789001

urn:schemas-upnp-org:service:WANIPConnection:1

urn:upnp-org:serviceId:WANIPConnection

/ipc

/ipc

/ipc.xml

部分字段含义如下:

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"

ConnectedERROR_NONE3 Days, 01:46:46

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"

192.168.100.34

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

0

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"

10154TCP554192.168.2.1371MasonUpnp_554_101540

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

26780TCP554192.168.2.1381MasonUpnp_554_267800

上面有几个值需要关注一下: 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/