I would like to preface that I am new to networking and still working on my python skills so go easy on me.
I have started working on a network scanning project and have played with multiple protocols to try and find what works best for my purposes. SSDP seems to be the best for me thus I have been playing with a little universal plug and play script I found to try and test how things are working on my network.
import socket
import sys
dst = "239.255.255.250"
st = "upnp:rootdevice"
msg = [
'M-SEARCH * HTTP/1.1',
'Host:239.255.255.250:1900',
'Man:"ssdp:discover"',
'MX:1',
'ST:%s' % (st,),
'']
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.bind((socket.gethostbyname(socket.gethostname()), 0))
print(s.getsockname())
s.settimeout(60)
byte_data = '\r\n'.join(msg)
s.sendto(bytes(byte_data, 'utf-8'), (dst, 1900))
while True:
try:
data, addr = s.recvfrom(32*1024)
except socket.timeout:
print("timeout has occurred")
break
print (f"$ {addr}\n{data}")
s.close()
For some reason this always times out for me and never displays any data. After investigating using WireShark, I can see that my computer is sending out searches and devices are sending replies back to my computer. Does anyone know why this might be occurring (OS is windows 10). I will say I have increased the timeout numerous times to high amounts and still nothing is getting through.
As pointed out in the comments, there should be an extra blank line in the M-SEARCH request header, so.
Now it works. Also, with the SSDP MX header set to 1 it is pointless setting timeout to 60 - any device responding to the request MUST reply within MX seconds or not at all.
As it is, this should work fine on a system with a single network interface. But on a multi-homed system you will need to send the request on each interface by binding a socket to that interface, otherwise some UPNP devices might not be reachable.