#!/usr/bin/env python2 from __future__ import print_function, division import socket from io import BytesIO # in memory binary strings from collections import namedtuple try: # Py 2.7 import httplib except ImportError: # Py 3 import http.client as httplib # fix path for now import sys sys.path.append("../") from netscan.lib import GetHostName, MacLookup import sys import subprocess # use commandline import requests # whois import re from netaddr import valid_ipv4, valid_mac import os # import platform # socket alternative to get hostname import socket def command(cmd): return subprocess.Popen( [cmd], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()[0] HostInfo = namedtuple("HostInfo", "cidr netname netrange org updated") def whois(ip): """ Given a valid ipv4 address, it returns the whois info as a namedtuple: whois('172.217.12.4') HostInfo(cidr=u'172.217.0.0/16', netname=u'GOOGLE', netrange=u'172.217.0.0 - 172.217.255.255', org=u'Google LLC (GOGL)', updated=u'2012-04-16') """ if not valid_ipv4(ip): print('Error: the IPv4 address {} is invalid'.format(ip)) return rec = requests.get('http://whois.arin.net/rest/ip/{}.txt'.format(ip)) if rec.status_code != 200: print('Error') return ans = {} r = re.compile(r"\s\s+") b = rec.text.split('\n') for i, s in enumerate(b): if len(s) == 0: b.pop(i) elif s[0] == u'#': b.pop(i) print('---------') print(b) for l in b: if l and l[0] != '#': l = r.sub('', l) a = l.split(':') ans[a[0]] = a[1] return HostInfo( ans['CIDR'], ans['NetName'], ans['NetRange'], ans['Organization'], ans['Updated']) def get_host_name(ip): """ Use the avahi (zeroconfig) tools or dig to find a host name given an ip address. in: ip out: string w/ host name or 'unknown' if the host name couldn't be found """ # ret = None # handle invalid ip address if not valid_ipv4(ip): print('Error: the IPv4 address {} is invalid'.format(ip)) return 'unknown' # handle a localhost ip address if ip == '127.0.0.1' or ip == 'localhost': return socket.gethostname() # ok, now do more complex stuff if sys.platform == 'linux' or sys.platform == 'linux2': name = command("avahi-resolve-address {} | awk '{print $2}'".format(ip)).rstrip().rstrip('.') elif sys.platform == 'darwin': name = command('dig +short -x {} -p 5353 @224.0.0.251'.format(ip)).rstrip().rstrip('.') else: raise Exception("get_host_name is unsupported on your OS, get a better one :)") # detect any remaining errors if name.find('connection timed out') >= 0 or len(name) == 0: name = 'unknown' return name class SSDPResponse(object): """ Simple class to find Roku's on your network. I don't remember where I found it online, but I made it Python 2/3 compatable and changed some stuff. """ class _FakeSocket(BytesIO): def makefile(self, *args, **kw): return self def __init__(self, response): s = self._FakeSocket(response) r = httplib.HTTPResponse(s) r.begin() self.location, self.port = r.getheader("location").replace('http://','').replace('/','').split(':') self.usn = r.getheader("usn") self.st = r.getheader("st") self.cache = r.getheader("cache-control").split("=")[1] self.mac = r.getheader("WAKEUP").split(";")[0].split("=")[1].upper() self.server = r.getheader("server") self.hostname = "Roku-" + self.usn.split(":")[3] self.msg = r.msg def __repr__(self): return "SSDPResponse ------------\n {hostname}\n {location}:{port}\n {mac}\n {usn}\n {server}\n".format(**self.__dict__) def discover(service, timeout=5, retries=1, mx=3): group = (b"239.255.255.250", 1900) message = "\r\n".join([ 'M-SEARCH * HTTP/1.1', 'HOST: {0}:{1}', 'MAN: "ssdp:discover"', 'ST: {st}', 'MX: {mx}', '', '']) socket.setdefaulttimeout(timeout) responses = [] for _ in range(retries): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) sock.sendto(message.format(*group, st=service, mx=mx).encode('utf-8'), group) while True: try: resp = SSDPResponse(sock.recv(1024)) # responses[resp.location] = resp responses.append(resp) except socket.timeout: break return responses if __name__ == "__main__": # print("hostname:", get_host_name("192.168.86.213")) print(whois('172.217.12.4')) exit(0) # start scan print('** scan **') ans = discover("roku:ecp") for roku in ans: print(roku)