The manual Page
English version
accueil | glossaire | downloads | liens ]
 

Libèrer les baux en fonction des adresses IP

Symptôme

Un problème peut survenir à la libération des baux sur certains "vieux" serveurs DHCP. Cela vient du fait que certains serveurs ne libèrent les baux qu'en regardant l'UID de la machine faisant la requête, et non pas l'UID et l'adresse IP, comme cela est recommandé dans la RFC2131. Pour la plupart des serveurs DHCP, l'UID (identifiant unique pour chaque client) lorsqu'elle n'est pas précisée par le client, est l'adresse MAC, et donc le DHCP peut confondre deux baux différents adressés au même client (le serveur va alors libébérer deux fois le même bail).

La conséquence est que le nom figure toujours dans le DNS et que l'adresse IP n'a pas été libérée, même si la requête de libération a été bonne et acceptée.

Pour vérifier s'il faut patcher un serveur DHCP il suffit de procéder comme suit :

  1. mettre un ordinateur dans un LAN
  2. faire une requête DHCP. On obtient une adresse IP IP1
  3. résilier le bail
  4. mettre l'ordinateur dans un autre LAN
  5. faire une nouvelle requête DHCP. On obteint une autre adresse IP IP2
  6. résilier le bail
  7. vérifier le fichier dhcpd.leases : si la dernière entrée commence par "lease IP1...", il faut patcher le serveur.

Remède

Il suffit d'utiliser une nouvelle version de la fonction dhcprelease() !

Cette fonction se trouve dans le fichier server/dhcp.c. On peut directement remplacer le code de cette fonction par celui d'une version récente. Le code suivant est celui de la version 2.0pl2 :

void dhcprelease (packet)
        struct packet *packet;
{
        struct lease *lease;
        struct iaddr cip;
        int i;

        /* DHCPRELEASE must not specify address in requested-address
           option, but old protocol specs weren't explicit about this,
           so let it go. */
        if (packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len) {
                note ("DHCPRELEASE from %s specified requested-address.",
                      print_hw_addr (packet -> raw -> htype,
                                     packet -> raw -> hlen,
                                     packet -> raw -> chaddr));
        }

        i = DHO_DHCP_CLIENT_IDENTIFIER;
        if (packet -> options [i].len) {
                lease = find_lease_by_uid (packet -> options [i].data,
                                           packet -> options [i].len);

                /* See if we can find a lease that matches the IP address
                   the client is claiming. */
                for (; lease; lease = lease -> n_uid) {
                        if (!memcmp (&packet -> raw -> ciaddr,
                                     lease -> ip_addr.iabuf, 4)) {
                                break;
                        }
                }
        } else {
                /* The client is supposed to pass a valid client-identifier,
                   but the spec on this has changed historically, so try the
                   IP address in ciaddr if the client-identifier fails. */
                cip.len = 4;
                memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
                lease = find_lease_by_ip_addr (cip);
        }

        note ("DHCPRELEASE of %s from %s via %s (%sfound)",
              inet_ntoa (packet -> raw -> ciaddr),
              print_hw_addr (packet -> raw -> htype,
                             packet -> raw -> hlen,
                             packet -> raw -> chaddr),
              packet -> raw -> giaddr.s_addr
              ? inet_ntoa (packet -> raw -> giaddr)
              : packet -> interface -> name,
              lease ? "" : "not ");

        /* If we found a lease, release it. */
        if (lease && lease -> ends > cur_time) {
                release_lease (lease);
        }
}

Le code se trouve dans ce fichier séparé.


format imprimable format imprimable



Copyright © 2000-2006 themanualpage.org - Ce site est soumis aux conditions décrites dans les licences GNU GPL et FDL.