linux - How to get sender IP of a desired broadcast address:port combination? -
i see broadcast packets on wireshark i'd able check on using simple linux command-line utility. this:
getsenders bcast_ip port timeout
and print each new sender ip encountered during timeout period.
for example:
getsenders 192.168.0.255 12345 0.150
or (alternatively)
getsenders 192.168.0.0/8 12345 0.150
would listen broadcast packets sent 192.168.0.255:12345, print each unique sender encountered. alternate approach listed broadcast senders on specified interface.
unfortunately, socket-fu weak. know program must run root permissions (suid) listen on broadcast socket.
i've put in lots of time (days) trying python, looks route require using raw socket , parsing packets (a packet sniffer, ugh!). looked @ using socat/netcat (via execute-only suid bash script) got nowhere.
is there simple linux code available me? don't care tool or source language is, long can set suid-root , run command line.
btw, have simple python solution works under ms windows dies under linux:
myip = <ip address of local interface listen on> p = <broadcast port> timeout = 0.150 # 150 ms addresses = {} if "windows" in sys.platform.tolower(): # create broadcast reception socket bsock = socket.socket(socket.af_inet, socket.sock_dgram) bsock.setsockopt(socket.sol_socket, socket.so_reuseaddr, 1) bsock.setsockopt(socket.sol_socket, socket.so_broadcast, 1) bsock.settimeout(timeout) bsock.bind((myip, p)) while true: # senders try: __, address = bsock.recvfrom(1024) # don't care payload except baseexception, e: break # nothing found else: # desired broadcast packet detected if address[0] not in addresses: addresses[address[0]] = 1 else: addresses[address[0]] += 1 if addresses[address[0]] >= 3: break # go until timeout or sender seen 3 times finally: bsock.close() bsock = none print(', '.join([k k in addresses]))
after downloading , testing many examples, got working, bisected , combined code until had minimal difference worked on both platforms.
it came down 1 line: linux must bind specific broadcast address (as root), windows can bind local interface address (as normal user) broadcast packets expected arrive.
here's revised code snippet:
bcast_addr = <ip addr of broadcast: must end @ least 1 '.255'> myip = <ip addr of local interface receiving bcast_addr> p = <broadcast port> timeout = 0.150 # 150 ms addresses = {} # create broadcast reception socket bsock = socket.socket(socket.af_inet, socket.sock_dgram) bsock.setsockopt(socket.sol_socket, socket.so_reuseaddr, 1) bsock.setsockopt(socket.sol_socket, socket.so_broadcast, 1) bsock.settimeout(timeout) if "windows" in sys.platform.tolower(): bsock.bind((myip, p)) elif os.getuid() == 0: # must root linux! bsock.bind((bcast_addr, p)) while true: # senders try: __, address = bsock.recvfrom(1024) # don't care payload except baseexception, e: break # nothing found else: # desired broadcast packet detected if address[0] not in addresses: addresses[address[0]] = 1 else: addresses[address[0]] += 1 if addresses[address[0]] >= 3: break # go until timeout or sender seen 3 times finally: bsock.close() bsock = none print(', '.join([k k in addresses]))
Comments
Post a Comment