Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 816 - (hide annotations) (download)
Fri Apr 24 18:33:46 2009 UTC (15 years, 1 month ago) by niro
File MIME type: text/plain
File size: 3733 byte(s)
-updated to busybox-1.13.4
1 niro 532 /* vi: set sw=4 ts=4: */
2     /*
3     * leases.c -- tools to manage DHCP leases
4     * Russ Dill <Russ.Dill@asu.edu> July 2001
5     */
6    
7     #include "common.h"
8     #include "dhcpd.h"
9    
10    
11 niro 816 /* Find the oldest expired lease, NULL if there are no expired leases */
12     static struct dhcpOfferedAddr *oldest_expired_lease(void)
13     {
14     struct dhcpOfferedAddr *oldest = NULL;
15     // TODO: use monotonic_sec()
16     unsigned long oldest_lease = time(0);
17     unsigned i;
18 niro 532
19 niro 816 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]);
23     }
24     return oldest;
25     }
26    
27    
28 niro 532 /* clear every lease out that chaddr OR yiaddr matches and is nonzero */
29 niro 816 static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr)
30 niro 532 {
31 niro 816 unsigned i, j;
32 niro 532
33 niro 816 for (j = 0; j < 16 && !chaddr[j]; j++)
34     continue;
35 niro 532
36     for (i = 0; i < server_config.max_leases; i++)
37 niro 816 if ((j != 16 && memcmp(leases[i].chaddr, chaddr, 16) == 0)
38     || (yiaddr && leases[i].yiaddr == yiaddr)
39     ) {
40     memset(&(leases[i]), 0, sizeof(leases[i]));
41 niro 532 }
42     }
43    
44    
45     /* add a lease into the table, clearing out any old ones */
46 niro 816 struct dhcpOfferedAddr* FAST_FUNC add_lease(const uint8_t *chaddr, uint32_t yiaddr, unsigned long lease)
47 niro 532 {
48     struct dhcpOfferedAddr *oldest;
49    
50     /* clean out any old ones */
51     clear_lease(chaddr, yiaddr);
52    
53     oldest = oldest_expired_lease();
54    
55     if (oldest) {
56     memcpy(oldest->chaddr, chaddr, 16);
57     oldest->yiaddr = yiaddr;
58     oldest->expires = time(0) + lease;
59     }
60    
61     return oldest;
62     }
63    
64    
65     /* true if a lease has expired */
66 niro 816 int FAST_FUNC lease_expired(struct dhcpOfferedAddr *lease)
67 niro 532 {
68     return (lease->expires < (unsigned long) time(0));
69     }
70    
71    
72     /* Find the first lease that matches chaddr, NULL if no match */
73 niro 816 struct dhcpOfferedAddr* FAST_FUNC find_lease_by_chaddr(const uint8_t *chaddr)
74 niro 532 {
75 niro 816 unsigned i;
76 niro 532
77     for (i = 0; i < server_config.max_leases; i++)
78 niro 816 if (!memcmp(leases[i].chaddr, chaddr, 16))
79     return &(leases[i]);
80 niro 532
81     return NULL;
82     }
83    
84    
85     /* Find the first lease that matches yiaddr, NULL is no match */
86 niro 816 struct dhcpOfferedAddr* FAST_FUNC find_lease_by_yiaddr(uint32_t yiaddr)
87 niro 532 {
88 niro 816 unsigned i;
89 niro 532
90     for (i = 0; i < server_config.max_leases; i++)
91 niro 816 if (leases[i].yiaddr == yiaddr)
92     return &(leases[i]);
93 niro 532
94     return NULL;
95     }
96    
97    
98     /* check is an IP is taken, if it is, add it to the lease table */
99 niro 816 static int nobody_responds_to_arp(uint32_t addr)
100 niro 532 {
101 niro 816 /* 16 zero bytes */
102     static const uint8_t blank_chaddr[16] = { 0 };
103     /* = { 0 } helps gcc to put it in rodata, not bss */
104    
105 niro 532 struct in_addr temp;
106 niro 816 int r;
107 niro 532
108 niro 816 r = arpping(addr, server_config.server, server_config.arp, server_config.interface);
109     if (r)
110     return r;
111    
112     temp.s_addr = addr;
113     bb_info_msg("%s belongs to someone, reserving it for %u seconds",
114     inet_ntoa(temp), (unsigned)server_config.conflict_time);
115     add_lease(blank_chaddr, addr, server_config.conflict_time);
116     return 0;
117 niro 532 }
118    
119    
120 niro 816 /* find an assignable address, if check_expired is true, we check all the expired leases as well.
121 niro 532 * Maybe this should try expired leases by age... */
122 niro 816 uint32_t FAST_FUNC find_address(int check_expired)
123 niro 532 {
124     uint32_t addr, ret;
125     struct dhcpOfferedAddr *lease = NULL;
126    
127 niro 816 addr = server_config.start_ip; /* addr is in host order here */
128     for (; addr <= server_config.end_ip; addr++) {
129 niro 532 /* ie, 192.168.55.0 */
130 niro 816 if (!(addr & 0xFF))
131     continue;
132 niro 532 /* ie, 192.168.55.255 */
133 niro 816 if ((addr & 0xFF) == 0xFF)
134     continue;
135     /* Only do if it isn't assigned as a static lease */
136     ret = htonl(addr);
137     if (!reservedIp(server_config.static_leases, ret)) {
138 niro 532 /* lease is not taken */
139     lease = find_lease_by_yiaddr(ret);
140     /* no lease or it expired and we are checking for expired leases */
141 niro 816 if ((!lease || (check_expired && lease_expired(lease)))
142     && nobody_responds_to_arp(ret) /* it isn't used on the network */
143 niro 532 ) {
144     return ret;
145     }
146     }
147     }
148     return 0;
149     }