home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / lib / hplip / base / mdns.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2007-04-29  |  7.4 KB  |  286 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. import sys
  5. import time
  6. import socket
  7. import select
  8. import struct
  9. import random
  10. import re
  11. import cStringIO
  12. from g import *
  13. import utils
  14. MAX_ANSWERS_PER_PACKET = 24
  15. QTYPE_A = 1
  16. QTYPE_TXT = 16
  17. QTYPE_SRV = 33
  18. QTYPE_AAAA = 28
  19. QTYPE_PTR = 12
  20. QCLASS_IN = 1
  21.  
  22. def read_utf8(offset, data, l):
  23.     return (offset + l, data[offset:offset + l].decode('utf-8'))
  24.  
  25.  
  26. def read_data(offset, data, l):
  27.     return (offset + l, data[offset:offset + l])
  28.  
  29.  
  30. def read_data_unpack(offset, data, fmt):
  31.     l = struct.calcsize(fmt)
  32.     return (offset + l, struct.unpack(fmt, data[offset:offset + l]))
  33.  
  34.  
  35. def read_name(offset, data):
  36.     result = ''
  37.     off = offset
  38.     next = -1
  39.     first = off
  40.     while True:
  41.         l = ord(data[off])
  42.         off += 1
  43.         if l == 0:
  44.             break
  45.         
  46.         t = l & 192
  47.         if t == 0:
  48.             (off, utf8) = read_utf8(off, data, l)
  49.             result = ''.join([
  50.                 result,
  51.                 utf8,
  52.                 '.'])
  53.             continue
  54.         if t == 192:
  55.             if next < 0:
  56.                 next = off + 1
  57.             
  58.             off = (l & 63) << 8 | ord(data[off])
  59.             if off >= first:
  60.                 log.error('Bad domain name (circular) at 0x%04x' % off)
  61.                 break
  62.             
  63.             first = off
  64.             continue
  65.         log.error('Bad domain name at 0x%04x' % off)
  66.         break
  67.     if next >= 0:
  68.         offset = next
  69.     else:
  70.         offset = off
  71.     return (offset, result)
  72.  
  73.  
  74. def write_name(packet, name):
  75.     for p in name.split('.'):
  76.         utf8_string = p.encode('utf-8')
  77.         packet.write(struct.pack('!B', len(utf8_string)))
  78.         packet.write(utf8_string)
  79.     
  80.  
  81.  
  82. def create_outgoing_packets(answers):
  83.     index = 0
  84.     num_questions = 1
  85.     first_packet = True
  86.     packets = []
  87.     packet = cStringIO.StringIO()
  88.     answer_record = cStringIO.StringIO()
  89.     while True:
  90.         packet.seek(0)
  91.         packet.truncate()
  92.         num_answers = len(answers[index:index + MAX_ANSWERS_PER_PACKET])
  93.         if num_answers == 0 and num_questions == 0:
  94.             break
  95.         
  96.         flags = 512
  97.         if len(answers) - index <= MAX_ANSWERS_PER_PACKET:
  98.             flags = 0
  99.         
  100.         packet.write(struct.pack('!HHHHHH', 0, flags, num_questions, num_answers, 0, 0))
  101.         if num_questions:
  102.             write_name(packet, '_pdl-datastream._tcp.local')
  103.             packet.write(struct.pack('!B', 0))
  104.             packet.write(struct.pack('!HH', QTYPE_PTR, QCLASS_IN))
  105.         
  106.         first_record = True
  107.         for d in answers[index:index + MAX_ANSWERS_PER_PACKET]:
  108.             answer_record.seek(0)
  109.             answer_record.truncate()
  110.             if not first_packet and first_record:
  111.                 first_record = False
  112.                 write_name(answer_record, '_pdl-datastream._tcp.local')
  113.                 answer_record.write(struct.pack('!B', 0))
  114.             else:
  115.                 answer_record.write(struct.pack('!H', 49164))
  116.             answer_record.write(struct.pack('!HH', QTYPE_PTR, QCLASS_IN))
  117.             answer_record.write(struct.pack('!I', 65535))
  118.             rdlength_pos = answer_record.tell()
  119.             answer_record.write(struct.pack('!H', 0))
  120.             write_name(answer_record, d)
  121.             answer_record.write(struct.pack('!H', 49164))
  122.             rdlength = answer_record.tell() - rdlength_pos - 2
  123.             answer_record.seek(rdlength_pos)
  124.             answer_record.write(struct.pack('!H', rdlength))
  125.             answer_record.seek(0)
  126.             packet.write(answer_record.read())
  127.         
  128.         packets.append(packet.getvalue())
  129.         index += 20
  130.         if first_packet:
  131.             num_questions = 0
  132.             first_packet = False
  133.             continue
  134.     return packets
  135.  
  136.  
  137. def detectNetworkDevices(ttl = 4, timeout = 10):
  138.     (mcast_addr, mcast_port) = ('224.0.0.251', 5353)
  139.     found_devices = { }
  140.     answers = []
  141.     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  142.     x = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  143.     x.connect(('1.2.3.4', 56))
  144.     intf = x.getsockname()[0]
  145.     x.close()
  146.     s.setblocking(0)
  147.     ttl = struct.pack('B', ttl)
  148.     
  149.     try:
  150.         s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  151.         s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
  152.     except (AttributeError, socket.error):
  153.         pass
  154.  
  155.     
  156.     try:
  157.         s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, ttl)
  158.         s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(intf) + socket.inet_aton('0.0.0.0'))
  159.         s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
  160.     except Exception:
  161.         e = None
  162.         log.error('Unable to setup multicast socket for mDNS: %s' % e)
  163.         return { }
  164.  
  165.     now = time.time()
  166.     next = now
  167.     last = now + timeout
  168.     delay = 1
  169.     while True:
  170.         now = time.time()
  171.         if now > last:
  172.             break
  173.         
  174.         if now >= next:
  175.             
  176.             try:
  177.                 for p in create_outgoing_packets(answers):
  178.                     log.debug('Outgoing: (%d)' % len(p))
  179.                     log.log_data(p, fmt = True, width = 16)
  180.                     s.sendto(p, 0, (mcast_addr, mcast_port))
  181.             except socket.error:
  182.                 e = None
  183.                 log.error('Unable to send broadcast DNS packet: %s' % e)
  184.  
  185.             next += delay
  186.             delay *= 2
  187.         
  188.         update_spinner()
  189.         (r, w, e) = select.select([
  190.             s], [], [
  191.             s], 0.5)
  192.         if not r:
  193.             continue
  194.         
  195.         (data, addr) = s.recvfrom(16384)
  196.         if data:
  197.             update_spinner()
  198.             y = {
  199.                 'num_devices': 1,
  200.                 'num_ports': 1,
  201.                 'product_id': '',
  202.                 'mac': '',
  203.                 'status_code': 0,
  204.                 'device2': '0',
  205.                 'device3': '0',
  206.                 'note': '' }
  207.             log.debug('Incoming: (%d)' % len(data))
  208.             log.log_data(data, fmt = True, width = 16)
  209.             offset = 0
  210.             (id, flags, num_questions, num_answers, num_authorities, num_additionals) = (offset,)
  211.             log.debug('Response: ID=%d FLAGS=0x%x Q=%d A=%d AUTH=%d ADD=%d' % (id, flags, num_questions, num_answers, num_authorities, num_additionals))
  212.             for question in range(num_questions):
  213.                 update_spinner()
  214.                 (offset, name) = read_name(offset, data)
  215.                 (typ, cls) = (offset,)
  216.                 log.debug('Q: %s TYPE=%d CLASS=%d' % (name, typ, cls))
  217.             
  218.             fmt = '!HHiH'
  219.             for record in range(num_answers + num_authorities + num_additionals):
  220.                 update_spinner()
  221.                 (offset, name) = read_name(offset, data)
  222.                 (offset, info) = read_data_unpack(offset, data, '!HHiH')
  223.                 if info[0] == QTYPE_A:
  224.                     (offset, result) = read_data(offset, data, 4)
  225.                     ip = []([ str(ord(x)) for x in result ])
  226.                     log.debug('A: %s' % ip)
  227.                     y['ip'] = ip
  228.                     continue
  229.                 []
  230.                 if info[0] == QTYPE_PTR:
  231.                     (offset, name) = read_name(offset, data)
  232.                     log.debug('PTR: %s' % name)
  233.                     y['mdns'] = name
  234.                     answers.append(name.replace('._pdl-datastream._tcp.local.', ''))
  235.                     continue
  236.                 '.'.join
  237.                 if info[0] == QTYPE_TXT:
  238.                     (offset, name) = read_data(offset, data, info[3])
  239.                     txt = { }
  240.                     off = 0
  241.                     while off < len(name):
  242.                         l = ord(name[off])
  243.                         off += 1
  244.                         result = name[off:off + l]
  245.                         
  246.                         try:
  247.                             (key, value) = result.split('=')
  248.                             txt[key] = value
  249.                         except ValueError:
  250.                             read_data_unpack(offset, data, '!HH')
  251.                             read_data_unpack(offset, data, '!HH')
  252.                             read_data_unpack(offset, data, '!HHHHHH')
  253.                             pas
  254.                         except:
  255.                             read_data_unpack(offset, data, '!HH')
  256.  
  257.                         off += l
  258.                         continue
  259.                         read_data_unpack(offset, data, '!HH')
  260.                     log.debug('TXT: %s' % repr(txt))
  261.                     y['device1'] = 'MFG:Hewlett-Packard;MDL:%s;CLS:PRINTER;' % txt['ty']
  262.                     if 'note' in txt:
  263.                         y['note'] = txt['note']
  264.                     
  265.                 'note' in txt
  266.                 if info[0] == QTYPE_SRV:
  267.                     (priority, weight, port) = (offset,)
  268.                     ttl = info[3]
  269.                     (offset, server) = read_name(offset, data)
  270.                     log.debug('SRV: %s TTL=%d PRI=%d WT=%d PORT=%d' % (server, ttl, priority, weight, port))
  271.                     y['hn'] = server.replace('.local.', '')
  272.                     continue
  273.                 read_data_unpack(offset, data, '!HHH')
  274.                 if info[0] == QTYPE_AAAA:
  275.                     (offset, result) = read_data(offset, data, 16)
  276.                     log.debug('AAAA: %s' % repr(result))
  277.                     continue
  278.                 read_data_unpack(offset, data, '!HHHHHH')
  279.                 log.error('Unknown DNS record type (%d).' % info[0])
  280.             
  281.         
  282.         found_devices[y['ip']] = y
  283.     log.debug('Found %d devices' % len(found_devices))
  284.     return found_devices
  285.  
  286.