Example #1
0
def dnssd_search(stype='_http._tcp'):
    dnssd = zeroconf.search(name=None, type=stype, domain="local")

    for key in dnssd:
        inst_type = key[1]
        # <Instance> must be a single DNS label, any dots should be escaped before concatenating
        # all portions of a Service Instance Name, according to DNS-SD (RFC6763).
        # A workaround is necessary for buggy software that does not adhere to the rules:
        inst_name = re.sub(r'(?<!\\)\.', r'\.', key[0])
        inst_fullname = dns.name.from_text(inst_name + '.' + inst_type).to_text(omit_final_dot=True)
        try:
            inst_hostname_rev_rr = dns.resolver.query(dns.reversename.from_address(dnssd[key]['address']), 'PTR')
        except DNSException, e:
            continue
        dnssd[key]['hostname_rev'] = [i.to_text(relativize=False) for i in inst_hostname_rev_rr]
        inst_port = dnssd[key]['port']
        inst_txt_rdata_rev = re.split(r'(?<=")\s+(?=")', dnssd[key]['txt'])[::-1]
        if not len(dnssd[key]['hostname_rev']) > 0:
            continue
        print "%-100s %-3s %-30s" % (inst_type, 'PTR', inst_fullname)
        for h in dnssd[key]['hostname_rev']:
            # replace hostname.local with reverse-resolved fqdn in TXT rdata
            inst_txt_rdata_rev_host = [ re.sub(r'%s\.?' % dnssd[key]['hostname'], r'%s' % h.rstrip('.'), blob) for blob in inst_txt_rdata_rev ]
            inst_txt_rdata_rev_host = ' '.join(inst_txt_rdata_rev_host)
            print "%-100s %-3s %2d %2d %-5s %-50s" % (inst_fullname, 'SRV', 0, 0, inst_port, h)
            if (dnssd[key]['txt'] != ''):
                print "%-100s %-3s %s" % (inst_fullname, 'TXT', inst_txt_rdata_rev_host)
Example #2
0
def zeroconf_search_multi(name=None,
                          types=[None],
                          domains=['local'],
                          sed_pattern=None,
                          sed_repl=None,
                          sed_service=[None]):
    import zeroconf

    default_subtypes = {
        '_ipp._tcp': ['_universal._sub._ipp._tcp', '_cups._sub._ipp._tcp'],
        '_ipps._tcp': ['_universal._sub._ipps._tcp', '_cups._sub._ipps._tcp'],
        '_http._tcp': ['_printer._sub._http._tcp']
    }

    types = set(types)
    domains = set(domains)

    # special handling for subtypes: they are not queried through _services
    # enumeration and we can not tell them apart in responses from the
    # corresponding master service)
    subtypes_all = {
        type
        for type in types
        if isinstance(type, basestring) and len(re.split(r'(?<!\\)\.', type)) >
        3 and re.split(r'(?<!\\)\.', type)[-3] == '_sub'
    }
    types -= subtypes_all
    # enumerate for well known sub-types if the master is requested
    for k in default_subtypes:
        if k in types:
            subtypes_all.update(default_subtypes[k])
        # but also enumerate the master if a sub-type is requested
        else:
            types |= {k for i in default_subtypes[k] if i in subtypes_all}

    filter_types = set()
    stype = None
    if len(types) > 1:
        filter_types = types
    elif types:
        stype = types.pop()

    results_all = {}
    for domain in domains:
        results = zeroconf.search(name=name, type=stype, domain=domain)

        subtypes = subtypes_all
        # add default subtypes to subtypes to be enumerated if the master is
        # found in results
        for subt_key in default_subtypes:
            if subt_key in [res_key[1] for res_key in results.keys()]:
                subtypes.update(default_subtypes[subt_key])
        # enumerate for each subtype individually
        for subtype in subtypes:
            for (key, val) in zeroconf.search(name=name,
                                              type=subtype,
                                              domain=domain).items():
                subtype = re.sub(r'._sub.%s' % key[1], '', subtype)
                # record in results for master type, add subtype
                if key in results and \
                        {k: results[key][k] for k in results[key]
                         if k != 'subtypes'} == val:
                    if 'subtypes' in results[key]:
                        results[key]['subtypes'].append(subtype)
                    else:
                        results[key]['subtypes'] = [subtype]
                # no record in results for master type, add record and subtype
                else:
                    results.update({key: val})
                    results[key]['subtypes'] = [subtype]

        results_all.update(results)

    if filter_types:
        for key in results_all.keys():
            _, svc_, _ = key
            if not svc_ in filter_types and \
                    not svc_ in subtypes:
                del results_all[key]

    for key in results_all.keys():
        name_, svc_, dom_ = key
        displayname = name_
        if sed_pattern is not None and sed_repl is not None:
            if sed_service != [None] and svc_ in sed_service:
                # newname = re.sub(r'^(.+)( @ cups)', r'AirPrint: \g<1>',
                #                  name_)
                displayname = re.sub(r'%s' % sed_pattern, r'%s' % sed_repl,
                                     name_)
        results_all[(displayname, svc_, dom_, name_)] = results_all[key]
        del results_all[key]

    return results_all  # if len(results) > 0 else None
Example #3
0
import zeroconf
import json
import sys

svc_list = []
hostname = {}

services = zeroconf.search(domain="local")
if len(services) is 0:
    print "No device found"
    sys.exit(0)

for host in services.items():
    if str(host[1]['hostname']) not in hostname:
        data = {}
        extra = {}
        port = []
        serv_type = []
        data['hostname'] = str(host[1]['hostname'])
        data['name'] = str(host[0][0])
        data['address'] = str(host[1]['address'])
        extra['type'] = str(host[0][1])
        extra['port'] = str(host[1]['port'])
        data['extra'] = extra
        hostname[str(host[1]['hostname'])] = data
    else:
        extra = hostname[str(host[1]['hostname'])]['extra']
        extra['type'] += ", " + str(host[0][1])
        extra['port'] += ", " + str(host[1]['port'])
        hostname[str(host[1]['hostname'])]['extra'] = extra
Example #4
0
File: rc.py Project: boisgera/rc
 def __iter__(self):
     for name, type, domain in zeroconf.search(type="_rc._tcp"):
         yield (name, get(name))
Example #5
0
File: rc.py Project: boisgera/rc
 def __init__(self, name):
     service_info = zeroconf.search(name, "_rc._tcp").items()[0][1]
     self.socket = context.socket(zmq.REQ)
     self.socket.connect("tcp://{address}:{port}".format(**service_info))
Example #6
0
def zeroconf_search_multi(name=None, types=[None], domains=['local'],
                          sed_pattern=None, sed_repl=None, sed_service=[None]):
    import zeroconf

    default_subtypes = {'_ipp._tcp':  ['_universal._sub._ipp._tcp',
                                        '_cups._sub._ipp._tcp'],
                        '_ipps._tcp': ['_universal._sub._ipps._tcp',
                                        '_cups._sub._ipps._tcp'],
                        '_http._tcp': ['_printer._sub._http._tcp']
                        }

    types = set(types)
    domains = set(domains)

    # special handling for subtypes: they are not queried through _services
    # enumeration and we can not tell them apart in responses from the
    # corresponding master service)
    subtypes_all = {type for type in types
                if isinstance(type, basestring) and
                len(re.split(r'(?<!\\)\.', type)) > 3 and
                re.split(r'(?<!\\)\.', type)[-3] == '_sub'}
    types -= subtypes_all
    # enumerate for well known sub-types if the master is requested
    for k in default_subtypes:
        if k in types:
            subtypes_all.update(default_subtypes[k])
        # but also enumerate the master if a sub-type is requested
        else:
            types |= {k for i in default_subtypes[k] if i in subtypes_all}

    filter_types = set()
    stype = None
    if len(types) > 1:
        filter_types = types
    elif types:
        stype = types.pop()

    results_all = {}
    for domain in domains:
        results = zeroconf.search(name=name, type=stype, domain=domain)

        subtypes = subtypes_all
        # add default subtypes to subtypes to be enumerated if the master is
        # found in results
        for subt_key in default_subtypes:
            if subt_key in [res_key[1] for res_key in results.keys()]:
                subtypes.update(default_subtypes[subt_key])
        # enumerate for each subtype individually
        for subtype in subtypes:
            for (key, val) in zeroconf.search(name=name, type=subtype,
                                              domain=domain).items():
                subtype = re.sub(r'._sub.%s' % key[1], '', subtype)
                # record in results for master type, add subtype
                if key in results and \
                        {k: results[key][k] for k in results[key]
                         if k != 'subtypes'} == val:
                        if 'subtypes' in results[key]:
                            results[key]['subtypes'].append(subtype)
                        else:
                            results[key]['subtypes'] = [subtype]
                # no record in results for master type, add record and subtype
                else:
                    results.update({key: val})
                    results[key]['subtypes'] = [subtype]

        results_all.update(results)

    if filter_types:
        for key in results_all.keys():
            _, svc_, _ = key
            if not svc_ in filter_types and \
                    not svc_ in subtypes:
                del results_all[key]

    for key in results_all.keys():
        name_, svc_, dom_ = key
        displayname = name_
        if sed_pattern is not None and sed_repl is not None:
            if sed_service != [None] and svc_ in sed_service:
                # newname = re.sub(r'^(.+)( @ cups)', r'AirPrint: \g<1>',
                #                  name_)
                displayname = re.sub(r'%s' % sed_pattern, r'%s' % sed_repl,
                                     name_)
        results_all[(displayname, svc_, dom_, name_)] = results_all[key]
        del results_all[key]

    return results_all  # if len(results) > 0 else None