Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/networking/udhcp/leases.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * leases.c -- tools to manage DHCP leases
    43 * Russ Dill <Russ.Dill@asu.edu> July 2001
     4 *
     5 * Licensed under GPLv2, see file LICENSE in this source tree.
    56 */
    6 
    77#include "common.h"
    88#include "dhcpd.h"
    99
    10 
    1110/* Find the oldest expired lease, NULL if there are no expired leases */
    12 static struct dhcpOfferedAddr *oldest_expired_lease(void)
     11static struct dyn_lease *oldest_expired_lease(void)
    1312{
    14     struct dhcpOfferedAddr *oldest = NULL;
    15 // TODO: use monotonic_sec()
    16     unsigned long oldest_lease = time(0);
     13    struct dyn_lease *oldest_lease = NULL;
     14    leasetime_t oldest_time = time(NULL);
    1715    unsigned i;
    1816
    19     for (i = 0; i < server_config.max_leases; i++)
    20         if (oldest_lease > leases[i].expires) {
    21             oldest_lease = leases[i].expires;
    22             oldest = &(leases[i]);
     17    /* Unexpired leases have g_leases[i].expires >= current time
     18     * and therefore can't ever match */
     19    for (i = 0; i < server_config.max_leases; i++) {
     20        if (g_leases[i].expires < oldest_time) {
     21            oldest_time = g_leases[i].expires;
     22            oldest_lease = &g_leases[i];
    2323        }
    24     return oldest;
     24    }
     25    return oldest_lease;
    2526}
    2627
     28/* Clear out all leases with matching nonzero chaddr OR yiaddr.
     29 * If chaddr == NULL, this is a conflict lease.
     30 */
     31static void clear_leases(const uint8_t *chaddr, uint32_t yiaddr)
     32{
     33    unsigned i;
    2734
    28 /* clear every lease out that chaddr OR yiaddr matches and is nonzero */
    29 static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr)
    30 {
    31     unsigned i, j;
    32 
    33     for (j = 0; j < 16 && !chaddr[j]; j++)
    34         continue;
    35 
    36     for (i = 0; i < server_config.max_leases; i++)
    37         if ((j != 16 && memcmp(leases[i].chaddr, chaddr, 16) == 0)
    38          || (yiaddr && leases[i].yiaddr == yiaddr)
     35    for (i = 0; i < server_config.max_leases; i++) {
     36        if ((chaddr && memcmp(g_leases[i].lease_mac, chaddr, 6) == 0)
     37         || (yiaddr && g_leases[i].lease_nip == yiaddr)
    3938        ) {
    40             memset(&(leases[i]), 0, sizeof(leases[i]));
     39            memset(&g_leases[i], 0, sizeof(g_leases[i]));
    4140        }
     41    }
    4242}
    4343
    44 
    45 /* add a lease into the table, clearing out any old ones */
    46 struct dhcpOfferedAddr *add_lease(const uint8_t *chaddr, uint32_t yiaddr, unsigned long lease)
     44/* Add a lease into the table, clearing out any old ones.
     45 * If chaddr == NULL, this is a conflict lease.
     46 */
     47struct dyn_lease* FAST_FUNC add_lease(
     48        const uint8_t *chaddr, uint32_t yiaddr,
     49        leasetime_t leasetime,
     50        const char *hostname, int hostname_len)
    4751{
    48     struct dhcpOfferedAddr *oldest;
     52    struct dyn_lease *oldest;
    4953
    5054    /* clean out any old ones */
    51     clear_lease(chaddr, yiaddr);
     55    clear_leases(chaddr, yiaddr);
    5256
    5357    oldest = oldest_expired_lease();
    5458
    5559    if (oldest) {
    56         memcpy(oldest->chaddr, chaddr, 16);
    57         oldest->yiaddr = yiaddr;
    58         oldest->expires = time(0) + lease;
     60        memset(oldest, 0, sizeof(*oldest));
     61        if (hostname) {
     62            char *p;
     63
     64            hostname_len++; /* include NUL */
     65            if (hostname_len > sizeof(oldest->hostname))
     66                hostname_len = sizeof(oldest->hostname);
     67            p = safe_strncpy(oldest->hostname, hostname, hostname_len);
     68            /* sanitization (s/non-ASCII/^/g) */
     69            while (*p) {
     70                if (*p < ' ' || *p > 126)
     71                    *p = '^';
     72                p++;
     73            }
     74        }
     75        if (chaddr)
     76            memcpy(oldest->lease_mac, chaddr, 6);
     77        oldest->lease_nip = yiaddr;
     78        oldest->expires = time(NULL) + leasetime;
    5979    }
    6080
     
    6282}
    6383
    64 
    65 /* true if a lease has expired */
    66 int lease_expired(struct dhcpOfferedAddr *lease)
     84/* True if a lease has expired */
     85int FAST_FUNC is_expired_lease(struct dyn_lease *lease)
    6786{
    68     return (lease->expires < (unsigned long) time(0));
     87    return (lease->expires < (leasetime_t) time(NULL));
    6988}
    7089
    71 
    72 /* Find the first lease that matches chaddr, NULL if no match */
    73 struct dhcpOfferedAddr *find_lease_by_chaddr(const uint8_t *chaddr)
     90/* Find the first lease that matches MAC, NULL if no match */
     91struct dyn_lease* FAST_FUNC find_lease_by_mac(const uint8_t *mac)
    7492{
    7593    unsigned i;
    7694
    7795    for (i = 0; i < server_config.max_leases; i++)
    78         if (!memcmp(leases[i].chaddr, chaddr, 16))
    79             return &(leases[i]);
     96        if (memcmp(g_leases[i].lease_mac, mac, 6) == 0)
     97            return &g_leases[i];
    8098
    8199    return NULL;
    82100}
    83101
    84 
    85 /* Find the first lease that matches yiaddr, NULL is no match */
    86 struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr)
     102/* Find the first lease that matches IP, NULL is no match */
     103struct dyn_lease* FAST_FUNC find_lease_by_nip(uint32_t nip)
    87104{
    88105    unsigned i;
    89106
    90107    for (i = 0; i < server_config.max_leases; i++)
    91         if (leases[i].yiaddr == yiaddr)
    92             return &(leases[i]);
     108        if (g_leases[i].lease_nip == nip)
     109            return &g_leases[i];
    93110
    94111    return NULL;
    95112}
    96113
    97 
    98 /* check is an IP is taken, if it is, add it to the lease table */
    99 static int nobody_responds_to_arp(uint32_t addr)
     114/* Check if the IP is taken; if it is, add it to the lease table */
     115static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac)
    100116{
    101     static const uint8_t blank_chaddr[16]; /* 16 zero bytes */
    102 
    103117    struct in_addr temp;
    104118    int r;
    105119
    106     r = arpping(addr, server_config.server, server_config.arp, server_config.interface);
     120    r = arpping(nip, safe_mac,
     121            server_config.server_nip,
     122            server_config.server_mac,
     123            server_config.interface);
    107124    if (r)
    108125        return r;
    109126
    110     temp.s_addr = addr;
     127    temp.s_addr = nip;
    111128    bb_info_msg("%s belongs to someone, reserving it for %u seconds",
    112129        inet_ntoa(temp), (unsigned)server_config.conflict_time);
    113     add_lease(blank_chaddr, addr, server_config.conflict_time);
     130    add_lease(NULL, nip, server_config.conflict_time, NULL, 0);
    114131    return 0;
    115132}
    116133
    117 
    118 /* find an assignable address, if check_expired is true, we check all the expired leases as well.
    119  * Maybe this should try expired leases by age... */
    120 uint32_t find_address(int check_expired)
     134/* Find a new usable (we think) address */
     135uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac)
    121136{
    122     uint32_t addr, ret;
    123     struct dhcpOfferedAddr *lease = NULL;
     137    uint32_t addr;
     138    struct dyn_lease *oldest_lease = NULL;
    124139
    125140    addr = server_config.start_ip; /* addr is in host order here */
    126141    for (; addr <= server_config.end_ip; addr++) {
     142        uint32_t nip;
     143        struct dyn_lease *lease;
     144
    127145        /* ie, 192.168.55.0 */
    128         if (!(addr & 0xFF))
     146        if ((addr & 0xff) == 0)
    129147            continue;
    130148        /* ie, 192.168.55.255 */
    131         if ((addr & 0xFF) == 0xFF)
     149        if ((addr & 0xff) == 0xff)
    132150            continue;
    133         /* Only do if it isn't assigned as a static lease */
    134         ret = htonl(addr);
    135         if (!reservedIp(server_config.static_leases, ret)) {
    136             /* lease is not taken */
    137             lease = find_lease_by_yiaddr(ret);
    138             /* no lease or it expired and we are checking for expired leases */
    139             if ((!lease || (check_expired && lease_expired(lease)))
    140              && nobody_responds_to_arp(ret) /* it isn't used on the network */
    141             ) {
    142                 return ret;
    143             }
     151        nip = htonl(addr);
     152        /* is this a static lease addr? */
     153        if (is_nip_reserved(server_config.static_leases, nip))
     154            continue;
     155
     156        lease = find_lease_by_nip(nip);
     157        if (!lease) {
     158//TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping!
     159            if (nobody_responds_to_arp(nip, safe_mac))
     160                return nip;
     161        } else {
     162            if (!oldest_lease || lease->expires < oldest_lease->expires)
     163                oldest_lease = lease;
    144164        }
    145165    }
     166
     167    if (oldest_lease
     168     && is_expired_lease(oldest_lease)
     169     && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac)
     170    ) {
     171        return oldest_lease->lease_nip;
     172    }
     173
    146174    return 0;
    147175}
Note: See TracChangeset for help on using the changeset viewer.