尝试使用python脚本在我的网络上发现iOS设备

时间:2013-05-10 00:35:16

标签: python ios bonjour

尝试使用pybonjour但不确定它是否是我需要的。 https://code.google.com/p/pybonjour/

我希望能够发现自动出现在我网络上的iOS设备,稍后会基于此运行脚本,但首先我想在我的wifi上出现/消失后立即发现iOS设备网络

所以问题是,我该怎么做?在安装了python27和pybonjour软件包的windows机器上运行时,这两个示例在pybonjour页面上运行,但是我使用我的网络中包含的脚本运行什么命令来发现iOS设备?或者这个只在我的电脑上运行的运行此脚本的发现服务!

如果我走向错误的方向,请告诉我,我似乎无法找到此套餐的文件!

python browse_and_resolve.py xxxxxx

THX 太

...更新

本文和浏览器对查找我需要搜索的服务很有帮助,http://marknelson.us/2011/10/25/dns-service-discovery-on-windows/

实例; (这发现了我的苹果电视,不在家里,所以无法检查iphone的名字!我假设是iphone!

python browse_and_resolve.py _appletv._tcp

此外,如果你有Windows实用程序dns-sd.exe,它将搜索网络上可用的所有服务。我用它来找到我要找的东西。

dns-sd -B _services._dns-sd._udp

...更新

“Bonjour有两种使用方式: - 发布服务 - 检测(浏览)可用服务”。

对于我想做的事情,我认为它不会起作用,因为ipad / iPhone不会宣传服务,除非我正在运行一个宣传一个的应用程序(或越狱我的iPhone / ipad然后ssh将开放)。还有更多想法吗?

2 个答案:

答案 0 :(得分:3)

使用python-nmap而不是Bonjour。或者您可以使用pyzeroconf(Bonjour是zeroconf的一个实现),但它有点过时(但应该仍然有效)。

python-nmap可能是最简单的,让我们假设你想找到所有在主机名中都有“iPhone”或“iPad”的连接设备(只是简单的概念):

import nmap

...

def notify_me(ip, hostname):
  print("I found an iOS device! IP Address: %s, Hostname: %s" % (ip, hostname))

iOS_device_list = ['iPhone', 'iPad']
iOS_devices_on_net = {}
nm = nmap.PortScanner()

# scan ip range
for i in range(2, 50, 1):
  ip = "192.168.1." + str(i)
  # specify ports to scan
  nm.scan(ip, '62078') # Matt mentioned that it picks up iphone-sync on this port
  hostname = nm[ip].hostname()
  for device in iOS_device_list:
    if device.lower() in hostname.lower():
      iOS_devices_on_net.update({ip:hostname})
      notify_me(ip, hostname)

# show all iOS devices in ip range
print iOS_devices_on_net

这种方法的局限性在于它依赖于未更改主机名的个人,主机名最初包括其名称和设备名称。 它还假设有一个端口侦听iOS设备上将返回主机名(可能不是这种情况)。通过使用python-nmap库将其作为命令运行,可以使用首选的osscan。这显然是一种更好的方法。我上面的概念只是一个如何使用它的简单例子。

从命令行使用nmap(我相信python-nmap有nm.commandline()方法)是最简单的:

nmap -O -v ip

同时尝试添加--osscan-guess; --fuzzy以获得最佳效果。例如:

nmap -O -v --osscan-guess ip

然后只搜索iOS设备关键字的输出(请参阅this example)。这是人类可读的。请注意,您需要以管理员身份运行所有这些才能使其正常工作(Windows:runas,其他:sudo)。

答案 1 :(得分:0)

所以我已经在同一个问题上工作了大约一年。我很快就可以在Mac上运行它,但是要在PC上正常运行却遇到了很多麻烦。我尝试了许多不同的方法。我有一个家庭自动化系统,当我或我的伴侣在家时(即可以在家庭WiFi上检测到我们的iPhone),该系统可以打开暖气和热水(通过arduino和RF模块)。最后,我使用“ nslookup”查找iPhone的IP地址(以防IP地址因为动态而改变(但实际上在我的路由器上却从未更改过))和“ nmap”来检测iPhone是否开启网络。如果iPhone处于深度睡眠状态,则'nmap'并不总是能找到电话,因此我已经对其进行了10次检查,然后才说电话回家。以下是我的python家庭自动化代码的一部分。我已经使用了线程。有关以下代码的任何问题都会让我知道。

# Dictionary to store variables to reuse on program restart
v = {
    'boilerControlCH' : 'HIH', # 'scheduled' or 'HIH' (Honey I'm Home)
    'boilerControlHW' : 'scheduled',
    'thermostatSetPoint' : 20.8,
    'thermostatVariance' : 0.1,
    'morningTime' : datetime(1970,1,1,6,0,0),
    'nightTime' : datetime(1970,1,1,23,0,0),
    'someOneHome' : False,
    'guest' : False,
    'minimumTemperatureOO' : False,
    'minimumTemperature' : 4.0,
    'iPhoneMark' : {'iPhoneHostname' : 'marks-iphone', 'home' : False},
    'iPhoneJessica' : {'iPhoneHostname' :'jessicaesiphone', 'home' : False}
    }

# Check if anyone at home
def occupancyStatus(person, Bol = False):
    with lockOccupancyStatus:
        someOneHome = False

        if 'iPhone' in person:
            v[person]['home'] = Bol
        elif 'retest' in person:
            pass
        else:
            v[person] = Bol

        if v['guest'] == True:
            someOneHome = True

        for key in v:
            if 'iPhone' in key:
                if v[key]['home'] == True:
                    someOneHome = True

        v['someOneHome'] = someOneHome
        variablesToFile()
    return

和主要代码

# iPhone home status threading code
class nmapClass(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        global exitCounter

        nmapThread()
        msg.log('Exited nmapThread')    
        waitEvent.set()
        waitEventAdjustable.set()
        serialDataWaiting.set()
        exitCounter += 1


def nmapThread():
    iPhone = {}
    maxCounts = 10
    for phone in v:
        if 'iPhone' in phone:
            iPhone[phone] = {}
            iPhone[phone]['hostname'] = v[phone]['iPhoneHostname']
            iPhone[phone]['count'] = maxCounts
    #msg.log(iPhone)

    while exitFlag[0] == 0:
        for phone in iPhone:
            if iPhone[phone]['count'] > 0:
                phoneFound = False
                IPAddress = '0.0.0.0'

                # Find iPhones IP address using its hostname
                commandNsloolup = 'nslookup %s' %iPhone[phone]['hostname']
                childNslookup = pexpect.popen_spawn.PopenSpawn(commandNsloolup, timeout = None)
                output = childNslookup.readline()
                while '\r\n' in output:
                    #msg.log(output)
                    if 'Name:' in output:
                        output = childNslookup.readline()
                        if 'Address:' in output:
                            tempStr = output
                            startPoint = tempStr.find('192')
                            tempStr = tempStr[startPoint:]
                            IPAddress = tempStr.replace('\r\n', '')
                            #msg.log(IPAddress)
                    output = childNslookup.readline()


                if IPAddress == '0.0.0.0':
                    pass
                    #msg.error('Error finding IP address for %s' %iPhone[phone]['hostname'], GFI(CF()).lineno)
                else:
                    #commandNmap = 'nmap -PR -sn %s' %IPAddress
                    #commandNmap = 'nmap -p 62078 -Pn %s' %IPAddress # -p specifies ports to try and access, -Pn removes pinging
                    commandNmap = 'nmap -p 62078 --max-rate 100 %s' %IPAddress
                    childNmap = pexpect.popen_spawn.PopenSpawn(commandNmap, timeout = None)
                    output = childNmap.readline()
                    while '\r\n' in output:
                        if 'Host is up' in output:
                            phoneFound = True
                            break
                        output = childNmap.readline()
                    #if phoneFound:
                    #   break


                if phoneFound:              
                    iPhone[phone]['count'] = 0

                    if v[phone]['home'] == False:
                        msg.log('%s\'s iPhone has returned home' %phone)
                        occupancyStatus(phone, True)
                        waitEventAdjustable.set()
                    #else:
                        #msg.log('%s\'s iPhone still at home' %phone)
                else:
                    iPhone[phone]['count'] -= 1

                    if v[phone]['home'] == True and iPhone[phone]['count'] == 0:
                        msg.log('%s\'s iPhone has left home' %phone)
                        occupancyStatus(phone, False)
                        waitEventAdjustable.set()
                    #else:
                        #msg.log('%s\'s iPhone still away from home' %phone)

            elif iPhone[phone]['count'] < 0:
                msg.error('Error with count variable in iPhone dictionary', GFI(CF()).lineno)


        longWait = True
        for phone in iPhone:
            if iPhone[phone]['count'] > 0:
                longWait = False
                #msg.log('%s: %s' %(phone, iPhone[phone]['count']))

        if longWait:
            #msg.log('wait long')               
            # 600 = run every 10 minutes
            waitEvent.wait(timeout=600)
            for phone in iPhone:
                iPhone[phone]['count'] = maxCounts
        else:
            #msg.log('wait short')
            waitEvent.wait(timeout=60)  

    return

如果直接将其复制到自己的脚本中,则该代码可能无法正常工作,因为有些部分我还没有复制,因此为了使事情保持简单易读,我没有进行复制,但是希望上面的代码能给大家一个感觉我做事的方式。