Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/networking/udhcp/leases.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1123 - (hide annotations) (download)
Wed Aug 18 21:56:57 2010 UTC (13 years, 9 months ago) by niro
File MIME type: text/plain
File size: 4372 byte(s)
-updated to busybox-1.17.1
1 niro 532 /* vi: set sw=4 ts=4: */
2     /*
3     * Russ Dill <Russ.Dill@asu.edu> July 2001
4 niro 984 *
5     * Licensed under GPLv2, see file LICENSE in this tarball for details.
6 niro 532 */
7     #include "common.h"
8     #include "dhcpd.h"
9    
10 niro 816 /* Find the oldest expired lease, NULL if there are no expired leases */
11 niro 984 static struct dyn_lease *oldest_expired_lease(void)
12 niro 816 {
13 niro 984 struct dyn_lease *oldest_lease = NULL;
14     leasetime_t oldest_time = time(NULL);
15 niro 816 unsigned i;
16 niro 532
17 niro 984 /* 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];
23 niro 816 }
24 niro 984 }
25     return oldest_lease;
26 niro 816 }
27    
28 niro 1123 /* Clear out all leases with matching nonzero chaddr OR yiaddr.
29     * If chaddr == NULL, this is a conflict lease.
30     */
31     static void clear_leases(const uint8_t *chaddr, uint32_t yiaddr)
32 niro 532 {
33 niro 1123 unsigned i;
34 niro 532
35 niro 984 for (i = 0; i < server_config.max_leases; i++) {
36 niro 1123 if ((chaddr && memcmp(g_leases[i].lease_mac, chaddr, 6) == 0)
37 niro 984 || (yiaddr && g_leases[i].lease_nip == yiaddr)
38 niro 816 ) {
39 niro 984 memset(&g_leases[i], 0, sizeof(g_leases[i]));
40 niro 532 }
41 niro 984 }
42 niro 532 }
43    
44 niro 1123 /* Add a lease into the table, clearing out any old ones.
45     * If chaddr == NULL, this is a conflict lease.
46     */
47 niro 984 struct 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)
51 niro 532 {
52 niro 984 struct dyn_lease *oldest;
53 niro 532
54     /* clean out any old ones */
55 niro 1123 clear_leases(chaddr, yiaddr);
56 niro 532
57     oldest = oldest_expired_lease();
58    
59     if (oldest) {
60 niro 1123 memset(oldest, 0, sizeof(*oldest));
61 niro 984 if (hostname) {
62     char *p;
63 niro 987
64     hostname_len++; /* include NUL */
65 niro 984 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 niro 1123 if (chaddr)
76     memcpy(oldest->lease_mac, chaddr, 6);
77 niro 984 oldest->lease_nip = yiaddr;
78     oldest->expires = time(NULL) + leasetime;
79 niro 532 }
80    
81     return oldest;
82     }
83    
84 niro 984 /* True if a lease has expired */
85     int FAST_FUNC is_expired_lease(struct dyn_lease *lease)
86 niro 532 {
87 niro 984 return (lease->expires < (leasetime_t) time(NULL));
88 niro 532 }
89    
90 niro 984 /* Find the first lease that matches MAC, NULL if no match */
91     struct dyn_lease* FAST_FUNC find_lease_by_mac(const uint8_t *mac)
92 niro 532 {
93 niro 816 unsigned i;
94 niro 532
95     for (i = 0; i < server_config.max_leases; i++)
96 niro 984 if (memcmp(g_leases[i].lease_mac, mac, 6) == 0)
97     return &g_leases[i];
98 niro 532
99     return NULL;
100     }
101    
102 niro 984 /* Find the first lease that matches IP, NULL is no match */
103     struct dyn_lease* FAST_FUNC find_lease_by_nip(uint32_t nip)
104 niro 532 {
105 niro 816 unsigned i;
106 niro 532
107     for (i = 0; i < server_config.max_leases; i++)
108 niro 984 if (g_leases[i].lease_nip == nip)
109     return &g_leases[i];
110 niro 532
111     return NULL;
112     }
113    
114 niro 984 /* Check if the IP is taken; if it is, add it to the lease table */
115     static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac)
116 niro 532 {
117     struct in_addr temp;
118 niro 816 int r;
119 niro 532
120 niro 984 r = arpping(nip, safe_mac,
121     server_config.server_nip,
122     server_config.server_mac,
123     server_config.interface);
124 niro 816 if (r)
125     return r;
126    
127 niro 984 temp.s_addr = nip;
128 niro 816 bb_info_msg("%s belongs to someone, reserving it for %u seconds",
129     inet_ntoa(temp), (unsigned)server_config.conflict_time);
130 niro 1123 add_lease(NULL, nip, server_config.conflict_time, NULL, 0);
131 niro 816 return 0;
132 niro 532 }
133    
134 niro 984 /* Find a new usable (we think) address */
135     uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac)
136 niro 532 {
137 niro 984 uint32_t addr;
138     struct dyn_lease *oldest_lease = NULL;
139 niro 532
140 niro 816 addr = server_config.start_ip; /* addr is in host order here */
141     for (; addr <= server_config.end_ip; addr++) {
142 niro 984 uint32_t nip;
143     struct dyn_lease *lease;
144    
145 niro 532 /* ie, 192.168.55.0 */
146 niro 984 if ((addr & 0xff) == 0)
147 niro 816 continue;
148 niro 532 /* ie, 192.168.55.255 */
149 niro 984 if ((addr & 0xff) == 0xff)
150 niro 816 continue;
151 niro 984 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 niro 1123 //TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping!
159 niro 984 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;
164 niro 532 }
165     }
166 niro 984
167 niro 1123 if (oldest_lease
168     && is_expired_lease(oldest_lease)
169 niro 984 && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac)
170     ) {
171     return oldest_lease->lease_nip;
172     }
173    
174 niro 532 return 0;
175     }