如何使用 UPnP/SSDP 从路由器获取 WAN IP

如何使用 UPnP/SSDP 从路由器获取 WAN IP

我正在尝试找到一种方法,让我的路由器使用 UPnP/SSDP 报告我的 WAN IP,但到目前为止,我甚至无法获取网络上支持 UPnP 的互联网接入设备的列表。这是我发送的请求:

$ cat request.txt
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 3
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1

使用以下命令:

$ nc -uvv 239.255.255.250 1900 < request.txt
Connection to 239.255.255.250 1900 port [udp/ssdp] succeeded!

我只收到连接成功的消息,然后什么都没有......

有人能给我指点一下吗(没有内存地址请!)我做错了什么?

更新:好的,我尝试使用tcpdump它来获取回复,以下是我得到的:

$ sudo tcpdump -vv -A -s 0 -i en1 udp port 1900 and host 239.255.255.250 
NOTIFY * HTTP/1.1
Host: 239.255.255.250:1900
Cache-Control: max-age=60
Location: http://192.168.1.1:1780/InternetGatewayDevice.xml
NTS: ssdp:alive
Server: POSIX, UPnP/1.0 linux/5.100.104.2 
NT: urn:schemas-upnp-org:device:InternetGatewayDevice:1

我猜下一步是解析 tcpdump 的输出并过滤掉所有不包含NT: urn:schemas-upnp-org:device:InternetGatewayDevice:1标头的响应,然后向路由器发出实际的 SOAP 请求。

答案1

您需要使用tcpdump或类似工具来查看回复。

nc正在寻求您发送请求的端点的回复。但您发送请求的端点是通用广播目标。回复不是来自通用广播目标,而是来自回复的特定设备。

正如nc的输出所示,它已连接到广播目标。因此,它不会看到来自回复设备的回复。

答案2

尽管这个任务相当老了,但我还是发布了我自己正在寻找的答案。

您的 UPnP 回复发布了位置“http://192.168.1.1:1780/InternetGatewayDevice.xml

您可以在那里获取有关数据格式的更多信息。对于我的路由器:我在那里找到了更多 xml 路径。调用它们,会得到更多 UPnP 信息。结果如下:我调用了:

POST /upnp/control?WANIPConnection HTTP/1.1
Host: 192.168.1.1
SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress"
Accept-Language: de-de;q=1, de;q=0.5
Accept-Encoding: gzip
Content-Type: text/xml; charset="utf-8"
User-Agent: gupnp-universal-cp GUPnP/0.20.10 DLNADOC/1.50
Connection: Keep-Alive
Content-Length: 281

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

并得到答案:

HTTP/1.1 200 OK
EXT:
Content-Type: text/xml; charset="utf-8"
Date: Tue, 04 Aug 2015 23:55:01 GMT
Server: servername/2.0 UPnP/1.0 UPnP-Device-Host/1.0
Content-Length: 380

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

“UPnP Inspector” 给了我很多帮助

答案3

您可以使用socat

$ socat -T1 STDIO UDP4-DATAGRAM:239.255.255.250:1900 < request.txt

答案4

功能齐全的 BASH 脚本:

#!/usr/bin/env bash
function wan_ip_connection() {
    local host=$1
    result=$( curl -s "http://$host/upnp/control?WANIPConnection" \
       -H 'SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress"' \
       --data-binary '<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetExternalIPAddress xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"></u:GetExternalIPAddress></s:Body></s:Envelope>'
    )

    REGEX='ExternalIPAddress>([0-9.]+)<'
    if [[ $result =~ $REGEX ]]
    then
       echo "${BASH_REMATCH[@]:1}"
    fi
}

function initial_query() {
   echo -e 'M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: "ssdp:discover"\r\nMX: 3\r\nST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n\r\n' |
       socat STDIO UDP4-DATAGRAM:239.255.255.250:1900
}

function main() {
   location=$( initial_query | grep LOCATION )
   location=${location%/*}
   location=${location##*/}
   ip=$( wan_ip_connection "$location" )
   echo $ip
}

main

相关内容