经常用到内网穿透,对UPNP也有所了解,但是具体的报文每次都去抓显然浪费时间。因此记录在下面。
报文是开启BitComet时抓取的,前面的python代码是自己用来获取NOTIFY消息的代码。

连接到组播地址接收NOTIFY消息

import socket
import re

ANY = "0.0.0.0"
DES_IP = "239.255.255.250"
PORT = 1900
# xml_str = b'<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>B2D5D4D2-808C-40F6-87CD-694C05C2B274</Uuid><Types>inquiry</Types></Probe> '
# xml_str = b'<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>CB09F608-E016-4EE8-869A-CA186852F12E</Uuid><Types>inquiry</Types></Probe> '
xml_str = b'M-SEARCH * HTTP/1.1\r\n' \
    + b'HOST: 239.255.255.250:1900\r\n' \
    + b'MAN: "ssdp:discover"\r\n' \
    + b'MX: 1\r\n' \
    + b'ST: urn:dial-multiscreen-org:service:dial:1\r\n' \
    + b'USER-AGENT: Google Chrome/87.0.4280.88 Windows\r\n\r\n\r\n'

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((ANY, PORT))
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
s.setsockopt(
    socket.IPPROTO_IP,
    socket.IP_ADD_MEMBERSHIP,
    socket.inet_aton(DES_IP) + socket.inet_aton(ANY)
)
s.setblocking(False)
s.sendto(xml_str, (DES_IP, PORT))
while True:
    try:
        data, address = s.recvfrom(2048)
    except Exception as e:
        pass
    else:
        print(address)
        print(data)

接收到的NOTIFY报文

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://192.168.1.1:1900/igd.xml
NT: upnp:rootdevice
NTS: ssdp:alive
SERVER: Mercury Router MR808, UPnP/1.0
USN: uuid:upnp-InternetGatewayDevice-192168115678900001::upnp:rootdevice

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://192.168.1.1:1900/igd.xml
NT: uuid:upnp-InternetGatewayDevice-192168115678900001
NTS: ssdp:alive
SERVER: Mercury Router MR808, UPnP/1.0
USN: uuid:upnp-InternetGatewayDevice-192168115678900001

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://192.168.1.1:1900/igd.xml
NT: urn:schemas-upnp-org:device:InternetGatewayDevice:1
NTS: ssdp:alive
SERVER: Mercury Router MR808, UPnP/1.0
USN: uuid:upnp-InternetGatewayDevice-192168115678900001::urn:schemas-upnp-org:device:InternetGatewayDevice:1

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://192.168.1.1:1900/igd.xml
NT: urn:schemas-upnp-org:service:Layer3Forwarding:1
NTS: ssdp:alive
SERVER: Mercury Router MR808, UPnP/1.0
USN: uuid:upnp-InternetGatewayDevice-192168115678900001::urn:schemas-upnp-org:service:Layer3Forwarding:1

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://192.168.1.1:1900/igd.xml
NT: uuid:upnp-WANDevice-192168115678900001
NTS: ssdp:alive
SERVER: Mercury Router MR808, UPnP/1.0
USN: uuid:upnp-WANDevice-192168115678900001

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://192.168.1.1:1900/igd.xml
NT: urn:schemas-upnp-org:device:WANDevice:1
NTS: ssdp:alive
SERVER: Mercury Router MR808, UPnP/1.0
USN: uuid:upnp-WANDevice-192168115678900001::urn:schemas-upnp-org:device:WANDevice:1

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://192.168.1.1:1900/igd.xml
NT: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
NTS: ssdp:alive
SERVER: Mercury Router MR808, UPnP/1.0
USN: uuid:upnp-WANDevice-192168115678900001::urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://192.168.1.1:1900/igd.xml
NT: uuid:upnp-WANConnectionDevice-192168115678900001
NTS: ssdp:alive
SERVER: Mercury Router MR808, UPnP/1.0
USN: uuid:upnp-WANConnectionDevice-192168115678900001

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://192.168.1.1:1900/igd.xml
NT: urn:schemas-upnp-org:device:WANConnectionDevice:1
NTS: ssdp:alive
SERVER: Mercury Router MR808, UPnP/1.0
USN: uuid:upnp-WANConnectionDevice-192168115678900001::urn:schemas-upnp-org:device:WANConnectionDevice:1

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://192.168.1.1:1900/igd.xml
NT: urn:schemas-upnp-org:service:WANIPConnection:1
NTS: ssdp:alive
SERVER: Mercury Router MR808, UPnP/1.0
USN: uuid:upnp-WANConnectionDevice-192168115678900001::urn:schemas-upnp-org:service:WANIPConnection:1

请求igd.xml

GET /igd.xml HTTP/1.1
Cache-Control: no-cache
Connection: Close
Pragma: no-cache
Accept: text/xml, application/xml
Host: 192.168.1.1:1900
User-Agent: Microsoft-Windows/10.0 UPnP/1.0

HTTP/1.1 200 OK
CONTENT-LENGTH: 2746
CONTENT-TYPE: text/xml
DATE: Thu, 07 Jan 2021 02:03:00 GMT
LAST-MODIFIED: Tue, 28 Oct 2003 08:46:08 GMT
SERVER: Mercury Router MR808, UPnP/1.0
CONNECTION: close

<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
......
</root>

igd.xml的详细内容如下

<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
	<specVersion>
		<major>1</major>
		<minor>0</minor>
	</specVersion>
	<URLBase></URLBase>
	<device>
		<deviceType>urn:schemas-upnp-org:device:InternetGatewayDevice:1</deviceType>
		<presentationURL>http://192.168.1.1:80       </presentationURL>
		<friendlyName            >Mercury Router MR808</friendlyName>
		<manufacturer                         >Mercury</manufacturer>
		<manufacturerURL    >http://www.mercurycom.com.cn</manufacturerURL>
		<modelDescription                       >MR808 2.0</modelDescription>
		<modelName                           >MR808</modelName>
		<modelNumber                             >2.0</modelNumber>
		<UDN>uuid:upnp-InternetGatewayDevice-192168115678900001</UDN>
		<UPC>123456789001</UPC>
		<serviceList>
			<service>
				<serviceType>urn:schemas-upnp-org:service:Layer3Forwarding:1</serviceType>
				<serviceId>urn:upnp-org:serviceId:L3Forwarding1</serviceId>
				<controlURL>/l3f</controlURL>
				<eventSubURL>/l3f</eventSubURL>
				<SCPDURL>/l3f.xml</SCPDURL>
			</service>
		</serviceList>
		<deviceList>
			<device>
				<deviceType>urn:schemas-upnp-org:device:WANDevice:1</deviceType>
				<friendlyName>WAN Device</friendlyName>
				<manufacturer                         >Mercury</manufacturer>
				<manufacturerURL    >http://www.mercurycom.com.cn</manufacturerURL>
				<modelDescription>WAN Device</modelDescription>
				<modelName>WAN Device</modelName>
				<modelNumber>1</modelNumber>
				<modelURL></modelURL>
				<serialNumber>12345678900001</serialNumber>
				<UDN>uuid:upnp-WANDevice-192168115678900001</UDN>
				<UPC>123456789001</UPC>
				<serviceList>
					<service>
						<serviceType>urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1</serviceType>
						<serviceId>urn:upnp-org:serviceId:WANCommonInterfaceConfig</serviceId>
						<controlURL>/ifc</controlURL>
						<eventSubURL>/ifc</eventSubURL>
						<SCPDURL>/ifc.xml</SCPDURL>
					</service>
				</serviceList>
				<deviceList>
					<device>
						<deviceType>urn:schemas-upnp-org:device:WANConnectionDevice:1</deviceType>
						<friendlyName>WAN Connection Device</friendlyName>
						<manufacturer                         >Mercury</manufacturer>
						<manufacturerURL    >http://www.mercurycom.com.cn</manufacturerURL>
						<modelDescription>WAN Connection Device</modelDescription>
						<modelName>WAN Connection Device</modelName>
						<modelNumber>1</modelNumber>
						<modelURL></modelURL>
						<serialNumber>12345678900001</serialNumber>
						<UDN>uuid:upnp-WANConnectionDevice-192168115678900001</UDN>
						<UPC>123456789001</UPC>
						<serviceList>
							<service>
								<serviceType>urn:schemas-upnp-org:service:WANIPConnection:1</serviceType>
								<serviceId>urn:upnp-org:serviceId:WANIPConnection</serviceId>
								<controlURL>/ipc</controlURL>
								<eventSubURL>/ipc</eventSubURL>
								<SCPDURL>/ipc.xml</SCPDURL>
							</service>
						</serviceList>
					</device>
				</deviceList>
			</device>
		</deviceList>
	</device>
</root>

请求ipc.xml的报文

GET /ipc.xml HTTP/1.1
Cache-Control: no-cache
Connection: Close
Pragma: no-cache
Accept: text/xml, application/xml
User-Agent: Microsoft-Windows/10.0 UPnP/1.0
Host: 192.168.1.1:1900

HTTP/1.1 200 OK
CONTENT-LENGTH: 8689
CONTENT-TYPE: text/xml
DATE: Thu, 07 Jan 2021 02:03:00 GMT
LAST-MODIFIED: Sat, 25 Oct 2003 03:22:56 GMT
SERVER: Mercury Router MR808, UPnP/1.0
CONNECTION: close

<?xml version="1.0"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
......
</scpd>

IPC返回的是以xml方式呈现的接口详情,整理之后如下:

	SetConnectionType
	SetConnectionType
	  |--param:NewConnectionType
	  |--param:NewConnectionType
	GetConnectionTypeInfo
	GetConnectionTypeInfo
	  |--param:NewConnectionType
	  |--param:NewConnectionType
	  |--param:NewPossibleConnectionTypes
	  |--param:NewPossibleConnectionTypes
	ForceTermination
	ForceTermination
	RequestConnection
	RequestConnection
	GetStatusInfo
	GetStatusInfo
	  |--param:NewConnectionStatus
	  |--param:NewConnectionStatus
	  |--param:NewLastConnectionError
	  |--param:NewLastConnectionError
	  |--param:NewUptime
	  |--param:NewUptime
	GetNATRSIPStatus
	GetNATRSIPStatus
	  |--param:NewRSIPAvailable
	  |--param:NewRSIPAvailable
	  |--param:NewNATEnabled
	  |--param:NewNATEnabled
	GetGenericPortMappingEntry
	GetGenericPortMappingEntry
	  |--param:NewPortMappingIndex
	  |--param:NewPortMappingIndex
	  |--param:NewRemoteHost
	  |--param:NewRemoteHost
	  |--param:NewExternalPort
	  |--param:NewExternalPort
	  |--param:NewProtocol
	  |--param:NewProtocol
	  |--param:NewInternalPort
	  |--param:NewInternalPort
	  |--param:NewInternalClient
	  |--param:NewInternalClient
	  |--param:NewEnabled
	  |--param:NewEnabled
	  |--param:NewPortMappingDescription
	  |--param:NewPortMappingDescription
	  |--param:NewLeaseDuration
	  |--param:NewLeaseDuration
	GetSpecificPortMappingEntry
	GetSpecificPortMappingEntry
	  |--param:NewRemoteHost
	  |--param:NewRemoteHost
	  |--param:NewExternalPort
	  |--param:NewExternalPort
	  |--param:NewProtocol
	  |--param:NewProtocol
	  |--param:NewInternalPort
	  |--param:NewInternalPort
	  |--param:NewInternalClient
	  |--param:NewInternalClient
	  |--param:NewEnabled
	  |--param:NewEnabled
	  |--param:NewPortMappingDescription
	  |--param:NewPortMappingDescription
	  |--param:NewLeaseDuration
	  |--param:NewLeaseDuration
	AddPortMapping
	AddPortMapping
	DeletePortMapping
	DeletePortMapping
	GetExternalIPAddress
	GetExternalIPAddress
	  |--param:NewExternalIPAddress
	  |--param:NewExternalIPAddress
	ConnectionType
	ConnectionType
	PossibleConnectionTypes
	PossibleConnectionTypes
	ConnectionStatus
	ConnectionStatus
	Uptime
	Uptime
	LastConnectionError
	LastConnectionError
	RSIPAvailable
	RSIPAvailable
	NATEnabled
	NATEnabled
	ExternalIPAddress
	ExternalIPAddress
	PortMappingNumberOfEntries
	PortMappingNumberOfEntries
	PortMappingEnabled
	PortMappingEnabled
	PortMappingLeaseDuration
	PortMappingLeaseDuration
	RemoteHost
	RemoteHost
	ExternalPort
	ExternalPort
	InternalPort
	InternalPort
	PortMappingProtocol
	PortMappingProtocol
	InternalClient
	InternalClient
	PortMappingDescription
	PortMappingDescription

调用ipc的接口报文

POST /ipc HTTP/1.1
Cache-Control: no-cache
Connection: Close
Pragma: no-cache
Content-Type: text/xml; charset="utf-8"
User-Agent: Microsoft-Windows/10.0 UPnP/1.0
SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"
Content-Length: 1127
Host: 192.168.1.1:1900

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><m:AddPortMapping xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1"><NewRemoteHost xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string"></NewRemoteHost><NewExternalPort xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui2">16849</NewExternalPort><NewProtocol xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">UDP</NewProtocol><NewInternalPort xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui2">16849</NewInternalPort><NewInternalClient xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">192.168.1.100</NewInternalClient><NewEnabled xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="boolean">1</NewEnabled><NewPortMappingDescription xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">BitComet UDP</NewPortMappingDescription><NewLeaseDuration xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui4">0</NewLeaseDuration></m:AddPortMapping></SOAP-ENV:Body></SOAP-ENV:Envelope>
HTTP/1.1 200 OK
CONNECTION: close
SERVER: Mercury Router MR808, UPnP/1.0
CONTENT-LENGTH: 332
CONTENT-TYPE: text/xml; charset="utf-8"

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<u:AddPortMappingResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"></u:AddPortMappingResponse></SOAP-ENV:Body>
</SOAP-ENV:Envelope>

调用的ipc的接口和接口顺序如下

调用ipc接口之后的结果

结论

添加映射的主要操作是POST的方式调用AddPortMapping接口。
显然libtorrent在这之前要先通过M-SEARCH和NOTIFY的UDP报文找到路由器,通过igd找ipc,通过ipc接口操作删除或添加映射。
添加完映射要用GetExternalIPAddress获取外网地址,这样就能把地址传给别人让别人找到你。

参考网址

www.upnp.org已经面目全非了,只能借助weiki的存档才能看见
https://web.archive.org/web/20050708020002/http://www.upnp.org/
https://web.archive.org/web/20051104061236if_/http://www.upnp.org:80/standardizeddcps/upnpresource20050517.zip
upnpresource20050517/documents/UPnP_Vendor_Implementation_Guide_Jan2001.htm
upnpresource20050517/documents/UPnPDA10_20000613.htm
https://github.com/jupnp/jupnp
https://github.com/hubing8658/UPnP-DLNA-Demo

posted on 2021-01-07 20:02  步孤天  阅读(1508)  评论(0编辑  收藏  举报