Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| zeroconf [Le 09/07/2011, 17:51] – 212.198.140.184 | zeroconf [Le 13/05/2026, 19:02] (Version actuelle) – màj lien lecteur vidéo krodelabestiole | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| - | # | + | {{tag> |
| - | """ | + | ====== Zeroconf ====== |
| - | Copyright (c) 2010 Timothy J Fontaine < | + | |
| - | Permission is hereby granted, free of charge, to any person obtaining a copy | + | **[[wpfr> |
| - | of this software and associated documentation files (the " | + | |
| - | in the Software without restriction, | + | |
| - | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | + | |
| - | copies of the Software, and to permit persons to whom the Software is | + | |
| - | furnished to do so, subject to the following conditions: | + | |
| - | The above copyright notice and this permission notice shall be included in | + | **[[wpfr> |
| - | all copies or substantial portions of the Software. | + | |
| - | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | + | Zeroconf offre différentes fonctionnalités utiles au [[: |
| - | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | + | * Résolution de noms avec [[#mDNS]] (// |
| - | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | + | * Publication de service sur le réseau ; |
| - | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | + | * Allocation d' |
| - | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | + | |
| - | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | + | |
| - | THE SOFTWARE. | + | |
| - | """ | + | |
| - | import cups, os, optparse, re, urlparse | + | Traditionnellement, la plupart de ce travail est réalisé par [[wpfr> |
| - | import os.path | + | |
| - | from StringIO import StringIO | + | |
| - | from xml.dom.minidom import parseString | + | Avahi s' |
| - | from xml.dom import minidom | + | Cette solution est donc très pratique avec [[:SMB]] ! |
| - | import sys | + | < |
| + | Si vous souhaitez utiliser Zeroconf sur un réseau qui ne vous appartient pas, il est préférable de contacter au préalable l' | ||
| + | </ | ||
| - | try: | + | Cette technologie peut actuellement être utilisée pour : |
| - | | + | * Partager de la musique : [[: |
| - | from lxml.etree import Element, ElementTree, tostring | + | * Échanger des fichiers |
| - | except: | + | * Découvrir automatiquement les autres clients VoIP : [[:Ekiga# |
| - | try: | + | * Discuter par messagerie instantanée sur le réseau local : [[:gajim]], [[:pidgin]], [[: |
| - | from xml.etree.ElementTree import Element, ElementTree, | + | * Partager des [[: |
| - | etree = None | + | * [[:tutoriel: |
| - | | + | * Publier les sites web servis avec [[: |
| - | try: | + | * Publier un serveur [[:SSH]] (voir discussion sur le [[https:// |
| - | from elementtree import Element, ElementTree, tostring | + | |
| - | etree = None | + | |
| - | | + | |
| - | | + | |
| - | XML_TEMPLATE | + | ===== Installation ===== |
| - | < | + | |
| - | <name replace-wildcards=" | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | #TODO XXX FIXME | + | Avahi est installé et activé par défaut sur Ubuntu. Vous n'avez donc rien de particulier à faire pour en profiter. |
| - | #< | + | |
| - | #< | + | |
| - | #< | + | |
| - | #< | + | |
| + | Si ce n'est pas le cas, il suffit d' | ||
| - | DOCUMENT_TYPES = { | + | Il se peut que la configuration du pare-feu bloque la communication [[#mDNS]] par défaut. Dans le panneau de configuration du pare-feu, on pourra si nécessaire changer le niveau de confiance par défaut (réseau public) pour un niveau plus permissif (réseau domestique ou //home//). |
| - | | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | 'image/urf': True, | + | |
| - | 'image/png': True, | + | |
| - | 'image/tiff': True, | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | # These content-types will never be reported | + | ===== Utilisation ===== |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | ' | + | |
| - | } | + | |
| - | class AirPrintGenerate(object): | + | ==== mDNS ==== |
| - | def __init__(self, | + | |
| - | directory=None, prefix=' | + | |
| - | self.host | + | |
| - | self.user = user | + | |
| - | self.port = port | + | |
| - | self.verbose = verbose | + | |
| - | self.directory = directory | + | |
| - | self.prefix = prefix | + | |
| - | self.adminurl = adminurl | + | |
| - | + | ||
| - | if self.user: | + | |
| - | cups.setUser(self.user) | + | |
| - | + | ||
| - | def generate(self): | + | |
| - | if not self.host: | + | |
| - | conn = cups.Connection() | + | |
| - | else: | + | |
| - | if not self.port: | + | |
| - | self.port = 631 | + | |
| - | conn = cups.Connection(self.host, | + | |
| - | + | ||
| - | printers = conn.getPrinters() | + | |
| - | + | ||
| - | for p, v in printers.items(): | + | |
| - | if v[' | + | |
| - | attrs = conn.getPrinterAttributes(p) | + | |
| - | uri = urlparse.urlparse(v[' | + | |
| - | tree = ElementTree() | + | Chaque machine utilisant Zeroconf s'identifie elle-même sur le réseau comme '' |
| - | tree.parse(StringIO(XML_TEMPLATE.replace('\n', '').replace('\r', '' | + | |
| - | name = tree.find('name') | + | <note importante> |
| - | name.text = 'AirPrint %s @ %%h' | + | |
| - | service = tree.find('service') | + | Dès lors, n' |
| + | < | ||
| + | ou [[:SSH]] | ||
| + | < | ||
| - | port = service.find(' | + | ==== Découvrir les services ==== |
| - | port_no | + | |
| - | if hasattr(uri, | + | |
| - | port_no | + | |
| - | if not port_no: | + | |
| - | port_no | + | |
| - | if not port_no: | + | |
| - | port_no | + | |
| - | port.text | + | |
| - | if hasattr(uri, ' | + | Sur Ubuntu, **[[:nautilus|GNOME Fichiers]]** est généralement le choix le plus simple pour visualiser et explorer les services exposés par **Zeroconf** |
| - | rp = uri.path | + | |
| - | else: | + | |
| - | rp = uri[2] | + | |
| - | + | ||
| - | re_match = re.match(r' | + | |
| - | if re_match: | + | |
| - | rp = re_match.group(3) | + | |
| - | + | ||
| - | | + | |
| - | #TODO XXX FIXME I'm worried this will match broken urlparse | + | |
| - | #results as well (for instance if they don't include a port) | + | |
| - | #the xml would be malform' | + | |
| - | rp = re.sub(r' | + | |
| - | + | ||
| - | path = Element(' | + | |
| - | path.text = ' | + | |
| - | service.append(path) | + | |
| - | desc = Element(' | + | De la même manière certains lecteurs [[: |
| - | desc.text = 'note=%s' | + | |
| - | service.append(desc) | + | |
| - | product | + | ==== Utilisation en ligne de commande === |
| - | product.text | + | |
| - | service.append(product) | + | |
| - | state = Element('txt-record') | + | Depuis un [[: |
| - | state.text = ' | + | avahi-browse -av |
| - | | + | ('' |
| - | ptype = Element('txt-record') | + | Pour résoudre l'adresse IPv4 d'une hypothétique machine //banane// : |
| - | | + | avahi-resolve |
| - | service.append(ptype) | + | |
| - | pdl = Element('txt-record') | + | À l'inverse, pour connaître le nom mDNS d'une machine : |
| - | fmts = [] | + | |
| - | defer = [] | + | en remplaçant '' |
| - | for a in attrs[' | + | ===== Problèmes connus ===== |
| - | if a in DOCUMENT_TYPES: | + | |
| - | if DOCUMENT_TYPES[a]: | + | |
| - | fmts.append(a) | + | |
| - | else: | + | |
| - | defer.append(a) | + | |
| - | fmts = ',' | + | ==== hostname-2.local ==== |
| - | dropped = [] | + | Parfois Avahi n' |
| - | # TODO XXX FIXME all fields should be checked for 255 limit | + | Pour retrouver un // |
| - | while len('pdl=%s' | + | |
| - | (fmts, drop) = fmts.rsplit(',', | + | |
| - | dropped.append(drop) | + | |
| - | if len(dropped) and self.verbose: | + | On modifie le nom d' |
| - | | + | sudo hostname HOSTNAME_CORRECT |
| + | Puis on redémarre le // | ||
| + | sudo systemctl restart avahi-daemon | ||
| + | Pour finir on s'assure que tout fonctionne correctement : | ||
| + | ps -ef | grep -i avahi | ||
| - | pdl.text | + | ==== Aucun trafic Zeroconf ==== |
| - | service.append(pdl) | + | |
| - | if self.adminurl: | + | La commande |
| - | admin = Element(' | + | avahi-browse |
| - | admin.text = ' | + | ne retourne rien par exemple. |
| - | | + | |
| - | + | ||
| - | fname = ' | + | |
| - | + | ||
| - | if self.directory: | + | |
| - | fname = os.path.join(self.directory, | + | |
| - | + | ||
| - | f = open(fname, ' | + | |
| - | if etree: | + | Le problème peut venir du [[:pare-feu]], qui bloque ce trafic. |
| - | tree.write(f, | + | |
| - | else: | + | |
| - | xmlstr = tostring(tree.getroot()) | + | |
| - | doc = parseString(xmlstr) | + | |
| - | dt= minidom.getDOMImplementation('' | + | |
| - | doc.insertBefore(dt, | + | |
| - | doc.writexml(f) | + | |
| - | f.close() | + | |
| - | + | ||
| - | if self.verbose: | + | |
| - | sys.stderr.write(' | + | |
| - | if __name__ | + | === Firewalld === |
| - | | + | |
| - | | + | Pour l'autoriser, avec **[[wp> |
| - | | + | sudo firewall-cmd --add-service=mdns --permanent |
| - | parser.add_option('-P', ' | + | sudo firewall-cmd --reload |
| - | dest='port', help='Port number of CUPS server', metavar='PORT') | + | sudo systemctl restart avahi-daemon |
| - | parser.add_option('-u', | + | |
| - | dest='username', help=' | + | === Guarddog === |
| - | | + | |
| - | | + | Si vous utilisez le pare-feu **[[wpfr> |
| - | dest=' | + | |
| - | | + | Appeler cette nouvelle zone // |
| - | | + | |
| - | help="Print debugging information to STDERR") | + | <file XML> |
| - | | + | < |
| - | | + | < |
| - | | + | < |
| - | | + | < |
| - | help="Include the printer specified uri as the adminurl") | + | < |
| - | + | < | |
| - | | + | < |
| - | + | < | |
| - | # TODO XXX FIXME -- if cups login required, need to add | + | |
| - | # air=username, | + | < |
| - | from getpass import getpass | + | < |
| - | | + | |
| - | + | < | |
| - | if options.directory: | + | < |
| - | if not os.path.exists(options.directory): | + | </ |
| - | | + | <udp source="client" dest=" |
| - | + | < | |
| - | | + | < |
| - | user=options.username, | + | </ |
| - | host=options.hostname, | + | </ |
| - | port=options.port, | + | < |
| - | verbose=options.verbose, | + | </ |
| - | directory=options.directory, | + | </ |
| - | prefix=options.prefix, | + | |
| - | adminurl=options.adminurl, | + | ===== Voir aussi ===== |
| - | ) | + | |
| - | + | ==== Ressources externes ==== | |
| - | apg.generate() | + | |
| + | * **(//en//)** [[http://www.zeroconf.org/|Site officiel]] | ||
| + | * **(//en//)** [[http:// | ||
| + | * **(//en//)** [[http:// | ||
| + | |||
| + | ==== Pages en rapport | ||
| + | |||
| + | {{backlinks> | ||
| + | |||
| + | ---- | ||
| + | // | ||
