
Я пытаюсь найти способ заставить свой маршрутизатор сообщать мой WAN IP с помощью UPnP/SSDP, но до сих пор я не смог даже получить список устройств доступа в Интернет с поддержкой 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"
Там вы можете получить больше информации о формате данных. Для моего маршрутизатора: я получил там больше путей к xmls. Вызывая их, есть больше информации 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